Added WebSockets
Fixed HTTP request
This commit is contained in:
parent
4366930f88
commit
c008e89412
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
|||||||
.godot/
|
.godot/
|
||||||
addons/
|
addons/
|
||||||
build/
|
build/
|
||||||
|
*.tmp
|
@ -9,14 +9,18 @@ const WorkingDayEnd = 20
|
|||||||
const MinimalMinutesToShowTitle = 30
|
const MinimalMinutesToShowTitle = 30
|
||||||
const MinimalMinutesForBigSize = 60
|
const MinimalMinutesForBigSize = 60
|
||||||
|
|
||||||
|
const DateUpdateInterval := 1.0
|
||||||
|
|
||||||
@onready var _main: Main = get_tree().get_current_scene()
|
@onready var _main: Main = get_tree().get_current_scene()
|
||||||
@onready var _timeline = $Panel/Timeline
|
@onready var _timeline = $Panel/Timeline
|
||||||
@onready var _reservations = $Panel/Reservations
|
@onready var _reservations = $Panel/Reservations
|
||||||
@onready var _date = $TopBar/DateButton
|
@onready var _date = $TopBar/DateButton
|
||||||
|
|
||||||
|
var _date_update_timer = 0.0
|
||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
_process_hour_size()
|
_process_hour_size()
|
||||||
_process_date()
|
_process_date(delta)
|
||||||
|
|
||||||
func _process_hour_size():
|
func _process_hour_size():
|
||||||
var hour_size = get_viewport_rect().size.y/15
|
var hour_size = get_viewport_rect().size.y/15
|
||||||
@ -24,17 +28,29 @@ func _process_hour_size():
|
|||||||
for time_slot in _timeline.get_children():
|
for time_slot in _timeline.get_children():
|
||||||
time_slot.set_height(hour_size)
|
time_slot.set_height(hour_size)
|
||||||
|
|
||||||
func _process_date():
|
func _process_date(delta):
|
||||||
|
_date_update_timer += delta
|
||||||
|
if _date_update_timer >= DateUpdateInterval:
|
||||||
|
_date.text = _main.get_date()
|
||||||
|
_date_update_timer = 0.0
|
||||||
|
|
||||||
var date = Time.get_date_dict_from_system()
|
var date = Time.get_date_dict_from_system()
|
||||||
_date.text = "%02d.%02d.%04d" % [date.day, date.month, date.year]
|
_date.text = "%02d.%02d.%04d" % [date.day, date.month, date.year]
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
_connect_signals()
|
||||||
|
|
||||||
_remove_time_slots()
|
_remove_time_slots()
|
||||||
_remove_reservations()
|
_remove_reservations()
|
||||||
|
|
||||||
_fill_with_slots()
|
_fill_with_slots()
|
||||||
_update_schedule()
|
_update_schedule()
|
||||||
|
|
||||||
|
func _connect_signals():
|
||||||
|
await _main.ready
|
||||||
|
var event_handler = _main.get_event_handler()
|
||||||
|
event_handler.reservations_updated.connect(_on_reservations_updated)
|
||||||
|
|
||||||
func _remove_time_slots():
|
func _remove_time_slots():
|
||||||
for time_slot in _timeline.get_children():
|
for time_slot in _timeline.get_children():
|
||||||
time_slot.queue_free()
|
time_slot.queue_free()
|
||||||
@ -49,13 +65,16 @@ func _remove_reservations():
|
|||||||
for reservation in _reservations.get_children():
|
for reservation in _reservations.get_children():
|
||||||
reservation.queue_free()
|
reservation.queue_free()
|
||||||
|
|
||||||
func _update_schedule():
|
func _update_schedule(reservations=null):
|
||||||
if not _main.is_node_ready():
|
if not _main.is_node_ready():
|
||||||
await _main.ready
|
await _main.ready
|
||||||
|
|
||||||
var repo = _main.get_reservation_repo()
|
var repo = _main.get_reservation_repo()
|
||||||
|
|
||||||
for reservation in repo.list_reservations():
|
if reservations == null:
|
||||||
|
reservations = await repo.list_reservations({"date": _main.get_date()})
|
||||||
|
|
||||||
|
for reservation in reservations:
|
||||||
var start_time_hours = reservation.start_time.hours
|
var start_time_hours = reservation.start_time.hours
|
||||||
var start_time_minutes = reservation.start_time.minutes
|
var start_time_minutes = reservation.start_time.minutes
|
||||||
var start_time = (start_time_hours - WorkingDayStart)*60 + start_time_minutes
|
var start_time = (start_time_hours - WorkingDayStart)*60 + start_time_minutes
|
||||||
@ -123,5 +142,8 @@ func _on_room_button_pressed():
|
|||||||
func _on_date_button_pressed():
|
func _on_date_button_pressed():
|
||||||
print("emit change date signal")
|
print("emit change date signal")
|
||||||
|
|
||||||
|
func _on_reservations_updated(reservations):
|
||||||
|
update()
|
||||||
|
|
||||||
func update():
|
func update():
|
||||||
_ready()
|
_ready()
|
||||||
|
@ -46,7 +46,7 @@ func set_duration_time(minutes):
|
|||||||
|
|
||||||
func set_color(color):
|
func set_color(color):
|
||||||
var new_style_box: StyleBoxFlat = _panel.get("theme_override_styles/panel").duplicate()
|
var new_style_box: StyleBoxFlat = _panel.get("theme_override_styles/panel").duplicate()
|
||||||
new_style_box.bg_color = Colors[color]
|
new_style_box.bg_color = Colors[int(color)]
|
||||||
_panel.set("theme_override_styles/panel", new_style_box)
|
_panel.set("theme_override_styles/panel", new_style_box)
|
||||||
|
|
||||||
func set_font(font: Fonts):
|
func set_font(font: Fonts):
|
||||||
|
@ -14,7 +14,7 @@ script = ExtResource("1_2wxyg")
|
|||||||
[node name="TimeEdit" type="LineEdit" parent="."]
|
[node name="TimeEdit" type="LineEdit" parent="."]
|
||||||
visible = false
|
visible = false
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "1:34 "
|
text = "11:10 "
|
||||||
placeholder_text = "hh:mm (a/p)m"
|
placeholder_text = "hh:mm (a/p)m"
|
||||||
script = ExtResource("2_7d4ae")
|
script = ExtResource("2_7d4ae")
|
||||||
current_time = true
|
current_time = true
|
||||||
|
@ -20,5 +20,11 @@ func go_to_previous_page(with_update=true):
|
|||||||
func get_reservation_repo() -> AbstractReservationRepo:
|
func get_reservation_repo() -> AbstractReservationRepo:
|
||||||
return AbstractReservationRepo.new()
|
return AbstractReservationRepo.new()
|
||||||
|
|
||||||
|
func get_event_handler() -> EventHandler:
|
||||||
|
return EventHandler.new()
|
||||||
|
|
||||||
func get_reservation_service() -> ReservationService:
|
func get_reservation_service() -> ReservationService:
|
||||||
return ReservationService.new()
|
return ReservationService.new()
|
||||||
|
|
||||||
|
func get_date() -> String:
|
||||||
|
return ""
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
[ext_resource type="PackedScene" uid="uid://c431r28ef5edp" path="res://scenes/board/board.tscn" id="2_brvql"]
|
[ext_resource type="PackedScene" uid="uid://c431r28ef5edp" path="res://scenes/board/board.tscn" id="2_brvql"]
|
||||||
[ext_resource type="PackedScene" uid="uid://csfn8q6b5hj4y" path="res://scenes/reservation/reservation_creation.tscn" id="3_qr4p2"]
|
[ext_resource type="PackedScene" uid="uid://csfn8q6b5hj4y" path="res://scenes/reservation/reservation_creation.tscn" id="3_qr4p2"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cxs8xe5w32jo4" path="res://scenes/common/time/time_setting.tscn" id="4_popa2"]
|
[ext_resource type="PackedScene" uid="uid://cxs8xe5w32jo4" path="res://scenes/common/time/time_setting.tscn" id="4_popa2"]
|
||||||
[ext_resource type="Script" path="res://src/infra/repos/local/reservation.gd" id="5_50dbn"]
|
[ext_resource type="Script" path="res://src/infra/repos/local/reservation_local.gd" id="5_50dbn"]
|
||||||
|
|
||||||
[node name="Main" type="Control"]
|
[node name="Main" type="Control"]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
|
@ -16,6 +16,7 @@ enum Status {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@onready var _reservation_repo : AbstractReservationRepo = $Repos/Reservation
|
@onready var _reservation_repo : AbstractReservationRepo = $Repos/Reservation
|
||||||
|
@onready var _event_handler : EventHandler = $Repos/EventHandler
|
||||||
@onready var _reservation_service : ReservationService = $Services/ReservationService
|
@onready var _reservation_service : ReservationService = $Services/ReservationService
|
||||||
|
|
||||||
@export var current_page : Pages:
|
@export var current_page : Pages:
|
||||||
@ -48,6 +49,7 @@ func _ready():
|
|||||||
initialize_signals()
|
initialize_signals()
|
||||||
|
|
||||||
func initialize_signals():
|
func initialize_signals():
|
||||||
|
_event_handler.reservations_updated.connect(_on_reservations_updated)
|
||||||
_create_reservation_button.pressed.connect(_on_create_reservation_button_pressed)
|
_create_reservation_button.pressed.connect(_on_create_reservation_button_pressed)
|
||||||
_15_min_button.pressed.connect(_on_15_min_button_pressed)
|
_15_min_button.pressed.connect(_on_15_min_button_pressed)
|
||||||
_30_min_button.pressed.connect(_on_30_min_button_pressed)
|
_30_min_button.pressed.connect(_on_30_min_button_pressed)
|
||||||
@ -59,7 +61,6 @@ func _process(delta):
|
|||||||
|
|
||||||
var time = Time.get_time_dict_from_system()
|
var time = Time.get_time_dict_from_system()
|
||||||
_process_time(time)
|
_process_time(time)
|
||||||
_process_status(time)
|
|
||||||
|
|
||||||
func _process_time_status_indent():
|
func _process_time_status_indent():
|
||||||
var indent = get_viewport_rect().size.y/3
|
var indent = get_viewport_rect().size.y/3
|
||||||
@ -69,36 +70,36 @@ func _process_time_status_indent():
|
|||||||
func _process_time(time):
|
func _process_time(time):
|
||||||
_time_label.text = "%02d:%02d" % [time.hour, time.minute]
|
_time_label.text = "%02d:%02d" % [time.hour, time.minute]
|
||||||
|
|
||||||
func _process_status(time):
|
func _update_status(reservations=null):
|
||||||
var reservations = _reservation_repo.list_reservations()
|
var time = Time.get_time_dict_from_system()
|
||||||
var current_time_in_minutes = time.hour*60 + time.minute
|
var current_time_in_minutes = time.hour*60 + time.minute
|
||||||
|
|
||||||
|
if reservations == null:
|
||||||
|
reservations = await _reservation_repo.list_reservations({"date": get_date()})
|
||||||
|
|
||||||
for reservation in reservations:
|
for reservation in reservations:
|
||||||
var start_time_in_minutes = reservation.start_time.hours*60 + reservation.start_time.minutes
|
var start_time_in_minutes = reservation.start_time.hours*60 + reservation.start_time.minutes
|
||||||
var finish_time_in_minutes = reservation.finish_time.hours*60 + reservation.finish_time.minutes
|
var finish_time_in_minutes = reservation.finish_time.hours*60 + reservation.finish_time.minutes
|
||||||
|
|
||||||
if current_time_in_minutes >= start_time_in_minutes \
|
if current_time_in_minutes >= start_time_in_minutes \
|
||||||
and current_time_in_minutes < finish_time_in_minutes:
|
and current_time_in_minutes < finish_time_in_minutes:
|
||||||
_status = Status.BUSY
|
_update_ui_status(Status.BUSY, "Занято", BgColors.busy)
|
||||||
_status_label.text = "Занято"
|
|
||||||
_background.color = BgColors.busy
|
|
||||||
return
|
return
|
||||||
|
|
||||||
elif current_time_in_minutes <= start_time_in_minutes \
|
elif current_time_in_minutes <= start_time_in_minutes \
|
||||||
and current_time_in_minutes + MinutesForTemporarilyFree > start_time_in_minutes:
|
and current_time_in_minutes + MinutesForTemporarilyFree > start_time_in_minutes:
|
||||||
_status = Status.FREE
|
_update_ui_status(Status.FREE, "Свободно", BgColors.temporarily_free)
|
||||||
_status_label.text = "Свободно"
|
|
||||||
_background.color = BgColors.temporarily_free
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if len(reservations) > 0:
|
if len(reservations) > 0:
|
||||||
_status = Status.FREE
|
_update_ui_status(Status.FREE, "Свободно", BgColors.free)
|
||||||
_status_label.text = "Свободно"
|
|
||||||
_background.color = BgColors.free
|
|
||||||
else:
|
else:
|
||||||
_status = Status.FREE
|
_update_ui_status(Status.FREE, "Свободно", BgColors.standart)
|
||||||
_status_label.text = "Свободно"
|
|
||||||
_background.color = BgColors.standart
|
func _update_ui_status(status: Status, text: String, color: Color):
|
||||||
|
_status = status
|
||||||
|
_status_label.text = text
|
||||||
|
_background.color = color
|
||||||
|
|
||||||
func get_current_page():
|
func get_current_page():
|
||||||
return _current_page
|
return _current_page
|
||||||
@ -124,6 +125,9 @@ func go_to_previous_page(with_update=true):
|
|||||||
func get_reservation_repo() -> AbstractReservationRepo:
|
func get_reservation_repo() -> AbstractReservationRepo:
|
||||||
return _reservation_repo
|
return _reservation_repo
|
||||||
|
|
||||||
|
func get_event_handler() -> EventHandler:
|
||||||
|
return _event_handler
|
||||||
|
|
||||||
func get_reservation_service() -> ReservationService:
|
func get_reservation_service() -> ReservationService:
|
||||||
return _reservation_service
|
return _reservation_service
|
||||||
|
|
||||||
@ -143,7 +147,7 @@ func _create_default_reservation(minutes_of_reservation):
|
|||||||
var finish_time_hours = floor(finish_time_in_minutes/60)
|
var finish_time_hours = floor(finish_time_in_minutes/60)
|
||||||
var finish_time_minutes = finish_time_in_minutes - finish_time_hours * 60
|
var finish_time_minutes = finish_time_in_minutes - finish_time_hours * 60
|
||||||
|
|
||||||
if get_reservation_service().is_time_busy(start_time_in_minutes, finish_time_in_minutes):
|
if await get_reservation_service().is_time_busy(start_time_in_minutes, finish_time_in_minutes):
|
||||||
return
|
return
|
||||||
|
|
||||||
var dto = CreateReservationDTO.new()
|
var dto = CreateReservationDTO.new()
|
||||||
@ -163,6 +167,9 @@ func _create_default_reservation(minutes_of_reservation):
|
|||||||
|
|
||||||
load_page(Main.Pages.Board, true)
|
load_page(Main.Pages.Board, true)
|
||||||
|
|
||||||
|
func _on_reservations_updated(reservations):
|
||||||
|
_update_status()
|
||||||
|
|
||||||
func _on_create_reservation_button_pressed():
|
func _on_create_reservation_button_pressed():
|
||||||
load_page(Pages.ReservationCreation)
|
load_page(Pages.ReservationCreation)
|
||||||
|
|
||||||
@ -177,3 +184,7 @@ func _on_45_min_button_pressed():
|
|||||||
|
|
||||||
func _on_1_hour_button_pressed():
|
func _on_1_hour_button_pressed():
|
||||||
_create_default_reservation(60)
|
_create_default_reservation(60)
|
||||||
|
|
||||||
|
func get_date() -> String:
|
||||||
|
var date = Time.get_date_dict_from_system()
|
||||||
|
return "%02d.%02d.%04d" % [date.day, date.month, date.year]
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
[gd_scene load_steps=13 format=3 uid="uid://bkrvh8vjpgqot"]
|
[gd_scene load_steps=14 format=3 uid="uid://bkrvh8vjpgqot"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://scenes/main/main_tablet.gd" id="1_fr6s5"]
|
[ext_resource type="Script" path="res://scenes/main/main_tablet.gd" id="1_fr6s5"]
|
||||||
[ext_resource type="PackedScene" uid="uid://c431r28ef5edp" path="res://scenes/board/board.tscn" id="2_n47h4"]
|
[ext_resource type="PackedScene" uid="uid://c431r28ef5edp" path="res://scenes/board/board.tscn" id="2_n47h4"]
|
||||||
[ext_resource type="PackedScene" uid="uid://csfn8q6b5hj4y" path="res://scenes/reservation/reservation_creation.tscn" id="3_j6x1g"]
|
[ext_resource type="PackedScene" uid="uid://csfn8q6b5hj4y" path="res://scenes/reservation/reservation_creation.tscn" id="3_j6x1g"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cu6e3hfdorwcg" path="res://scenes/reservation/reservation_edit.tscn" id="4_hyj5n"]
|
[ext_resource type="PackedScene" uid="uid://cu6e3hfdorwcg" path="res://scenes/reservation/reservation_edit.tscn" id="4_hyj5n"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cxs8xe5w32jo4" path="res://scenes/common/time/time_setting.tscn" id="4_wyf5q"]
|
[ext_resource type="PackedScene" uid="uid://cxs8xe5w32jo4" path="res://scenes/common/time/time_setting.tscn" id="4_wyf5q"]
|
||||||
[ext_resource type="Script" path="res://src/infra/repos/local/reservation.gd" id="5_6h0eq"]
|
|
||||||
[ext_resource type="Theme" uid="uid://byopik87nb8vv" path="res://assets/themes/status_font.tres" id="5_atujq"]
|
[ext_resource type="Theme" uid="uid://byopik87nb8vv" path="res://assets/themes/status_font.tres" id="5_atujq"]
|
||||||
[ext_resource type="Theme" uid="uid://yn1nbokvmv6n" path="res://assets/themes/small.tres" id="6_nde4h"]
|
[ext_resource type="Theme" uid="uid://yn1nbokvmv6n" path="res://assets/themes/small.tres" id="6_nde4h"]
|
||||||
[ext_resource type="Theme" uid="uid://b8tbd62jtmgdx" path="res://assets/themes/instant_button_font.tres" id="8_bmn8p"]
|
[ext_resource type="Theme" uid="uid://b8tbd62jtmgdx" path="res://assets/themes/instant_button_font.tres" id="8_bmn8p"]
|
||||||
[ext_resource type="Theme" uid="uid://cmhwbyqu6nh38" path="res://assets/themes/big.tres" id="9_wpf8g"]
|
[ext_resource type="Theme" uid="uid://cmhwbyqu6nh38" path="res://assets/themes/big.tres" id="9_wpf8g"]
|
||||||
|
[ext_resource type="Script" path="res://src/infra/repos/backend/reservation_http.gd" id="10_v7sup"]
|
||||||
[ext_resource type="Script" path="res://src/domain/services/reservation.gd" id="11_5xy2x"]
|
[ext_resource type="Script" path="res://src/domain/services/reservation.gd" id="11_5xy2x"]
|
||||||
|
[ext_resource type="Script" path="res://src/infra/repos/backend/event_handler_ws.gd" id="11_de30t"]
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_uus54"]
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_uus54"]
|
||||||
bg_color = Color(0.6, 0.6, 0.6, 0)
|
bg_color = Color(0.6, 0.6, 0.6, 0)
|
||||||
@ -70,14 +71,14 @@ size_flags_horizontal = 10
|
|||||||
size_flags_vertical = 0
|
size_flags_vertical = 0
|
||||||
|
|
||||||
[node name="Indent" type="BoxContainer" parent="Left/TimeStatusContainer"]
|
[node name="Indent" type="BoxContainer" parent="Left/TimeStatusContainer"]
|
||||||
custom_minimum_size = Vector2(0, 207.333)
|
custom_minimum_size = Vector2(0, 195)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
|
|
||||||
[node name="TimeLabel" type="Label" parent="Left/TimeStatusContainer"]
|
[node name="TimeLabel" type="Label" parent="Left/TimeStatusContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme = ExtResource("5_atujq")
|
theme = ExtResource("5_atujq")
|
||||||
text = "01:38"
|
text = "20:38"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
|
|
||||||
[node name="StatusLabel" type="Label" parent="Left/TimeStatusContainer"]
|
[node name="StatusLabel" type="Label" parent="Left/TimeStatusContainer"]
|
||||||
@ -142,7 +143,10 @@ text = "Забронировать"
|
|||||||
[node name="Repos" type="Node" parent="."]
|
[node name="Repos" type="Node" parent="."]
|
||||||
|
|
||||||
[node name="Reservation" type="Node" parent="Repos"]
|
[node name="Reservation" type="Node" parent="Repos"]
|
||||||
script = ExtResource("5_6h0eq")
|
script = ExtResource("10_v7sup")
|
||||||
|
|
||||||
|
[node name="EventHandler" type="Node" parent="Repos"]
|
||||||
|
script = ExtResource("11_de30t")
|
||||||
|
|
||||||
[node name="Services" type="Node" parent="."]
|
[node name="Services" type="Node" parent="."]
|
||||||
|
|
||||||
|
@ -51,19 +51,19 @@ func _on_delete_button_pressed():
|
|||||||
func _load_info():
|
func _load_info():
|
||||||
var repo = _main.get_reservation_repo()
|
var repo = _main.get_reservation_repo()
|
||||||
var reservation_id = repo.get_current_reservation_id()
|
var reservation_id = repo.get_current_reservation_id()
|
||||||
var reservation = repo.get_reservation(reservation_id)
|
var reservation = await repo.get_reservation(reservation_id)
|
||||||
|
|
||||||
_title_field.set_value(reservation.title)
|
_title_field.set_value(reservation.title)
|
||||||
_start_time_field.set_value(reservation.start_time)
|
_start_time_field.set_value(reservation.start_time)
|
||||||
_finish_time_field.set_value(reservation.finish_time)
|
_finish_time_field.set_value(reservation.finish_time)
|
||||||
|
|
||||||
func _create_reservation():
|
func _create_reservation():
|
||||||
if not _fields_are_correct():
|
if not await _fields_are_correct():
|
||||||
return
|
return
|
||||||
|
|
||||||
var dto = CreateReservationDTO.new()
|
var dto = CreateReservationDTO.new()
|
||||||
dto.title = _title_field.get_value()
|
dto.title = _title_field.get_value()
|
||||||
dto.date = _date_field.get_value()
|
dto.date = _main.get_date()
|
||||||
dto.start_time = _start_time_field.get_value()
|
dto.start_time = _start_time_field.get_value()
|
||||||
dto.finish_time = _finish_time_field.get_value()
|
dto.finish_time = _finish_time_field.get_value()
|
||||||
dto.creator = _creator_field.get_value()
|
dto.creator = _creator_field.get_value()
|
||||||
@ -80,7 +80,7 @@ func _create_reservation():
|
|||||||
clean()
|
clean()
|
||||||
|
|
||||||
func _update_reservation():
|
func _update_reservation():
|
||||||
if not _fields_are_correct():
|
if not await _fields_are_correct():
|
||||||
return
|
return
|
||||||
|
|
||||||
var dto = UpdateReservationDTO.new()
|
var dto = UpdateReservationDTO.new()
|
||||||
@ -119,7 +119,7 @@ func _fields_are_correct():
|
|||||||
# _error_box.set_message("Не введено название встречи")
|
# _error_box.set_message("Не введено название встречи")
|
||||||
# successful = false
|
# successful = false
|
||||||
|
|
||||||
if not _time_is_correct():
|
if not await _time_is_correct():
|
||||||
successful = false
|
successful = false
|
||||||
|
|
||||||
return successful
|
return successful
|
||||||
@ -149,7 +149,7 @@ func _time_is_correct():
|
|||||||
var start_time_in_minutes = start_time.hours*60 + start_time.minutes
|
var start_time_in_minutes = start_time.hours*60 + start_time.minutes
|
||||||
var finish_time_in_minutes = finish_time.hours*60 + finish_time.minutes
|
var finish_time_in_minutes = finish_time.hours*60 + finish_time.minutes
|
||||||
var service = _main.get_reservation_service()
|
var service = _main.get_reservation_service()
|
||||||
var is_busy = service.is_time_busy(start_time_in_minutes, finish_time_in_minutes)
|
var is_busy = await service.is_time_busy(start_time_in_minutes, finish_time_in_minutes)
|
||||||
|
|
||||||
if is_busy:
|
if is_busy:
|
||||||
print("The selected time slot is busy.")
|
print("The selected time slot is busy.")
|
||||||
|
@ -5,7 +5,7 @@ class_name ReservationService
|
|||||||
|
|
||||||
func is_time_busy(new_start_time_minutes, new_finish_time_minutes):
|
func is_time_busy(new_start_time_minutes, new_finish_time_minutes):
|
||||||
var repo = _main.get_reservation_repo()
|
var repo = _main.get_reservation_repo()
|
||||||
var reservations = repo.list_reservations()
|
var reservations = await repo.list_reservations({"date": _main.get_date()})
|
||||||
var current_reservation_id = repo.get_current_reservation_id()
|
var current_reservation_id = repo.get_current_reservation_id()
|
||||||
|
|
||||||
for reservation in reservations:
|
for reservation in reservations:
|
||||||
|
5
src/infra/dtos/common/time.gd
Normal file
5
src/infra/dtos/common/time.gd
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
class_name TimeDTO
|
||||||
|
extends RefCounted
|
||||||
|
|
||||||
|
var hours: int
|
||||||
|
var minutes: int
|
13
src/infra/repos/abstract/event_handler.gd
Normal file
13
src/infra/repos/abstract/event_handler.gd
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
extends Node
|
||||||
|
class_name EventHandler
|
||||||
|
|
||||||
|
signal connected()
|
||||||
|
signal disconnected()
|
||||||
|
signal reservations_updated(reservations)
|
||||||
|
signal error_occurred(message)
|
||||||
|
|
||||||
|
func connect_to_server():
|
||||||
|
pass
|
||||||
|
|
||||||
|
func subscribe_to_room(room_id: String):
|
||||||
|
pass
|
@ -2,6 +2,9 @@
|
|||||||
extends Node
|
extends Node
|
||||||
class_name AbstractReservationRepo
|
class_name AbstractReservationRepo
|
||||||
|
|
||||||
|
signal connected
|
||||||
|
signal not_connected
|
||||||
|
|
||||||
var _current_reservation_id = null
|
var _current_reservation_id = null
|
||||||
|
|
||||||
func create_reservation(dto: CreateReservationDTO):
|
func create_reservation(dto: CreateReservationDTO):
|
||||||
@ -16,7 +19,7 @@ func change_reservation(reservation_id, dto: UpdateReservationDTO):
|
|||||||
func get_reservation(reservation_id):
|
func get_reservation(reservation_id):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
func list_reservations():
|
func list_reservations(filters: Dictionary = {}):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
func set_current_reservation_id(value):
|
func set_current_reservation_id(value):
|
||||||
|
66
src/infra/repos/backend/event_handler_ws.gd
Normal file
66
src/infra/repos/backend/event_handler_ws.gd
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
class_name EventHandlerWS
|
||||||
|
extends EventHandler
|
||||||
|
|
||||||
|
const BACKEND_URL = "http://127.0.0.1:5000/socket.io"
|
||||||
|
var _room_id: String = ""
|
||||||
|
var _jwt_token: String = ""
|
||||||
|
var _client: SocketIOClient
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
initialize_client()
|
||||||
|
setup_connections()
|
||||||
|
|
||||||
|
func initialize_client():
|
||||||
|
_client = SocketIOClient.new(
|
||||||
|
BACKEND_URL,
|
||||||
|
{"token": _jwt_token, "EIO": "4", "transport": "websocket"}
|
||||||
|
)
|
||||||
|
add_child(_client)
|
||||||
|
|
||||||
|
func setup_connections():
|
||||||
|
_client.on_engine_connected.connect(_on_engine_connected)
|
||||||
|
_client.on_connect.connect(_on_socket_connect)
|
||||||
|
_client.on_disconnect.connect(_on_socket_disconnect)
|
||||||
|
_client.on_event.connect(_on_socket_event)
|
||||||
|
|
||||||
|
func connect_to_server(jwt: String = ""):
|
||||||
|
if !jwt.is_empty():
|
||||||
|
_jwt_token = jwt
|
||||||
|
_client.update_query_params({"token": _jwt_token})
|
||||||
|
_client.socketio_connect()
|
||||||
|
|
||||||
|
func _on_engine_connected(_sid: String):
|
||||||
|
print("Engine.IO connected")
|
||||||
|
_client.socketio_connect()
|
||||||
|
|
||||||
|
func _on_socket_connect(_payload, _namespace, error: bool):
|
||||||
|
if error:
|
||||||
|
error_occurred.emit("Connection failed")
|
||||||
|
else:
|
||||||
|
print("Socket.IO connected")
|
||||||
|
subscribe_to_room(_room_id)
|
||||||
|
|
||||||
|
func _on_socket_disconnect():
|
||||||
|
print("Disconnected from server")
|
||||||
|
disconnected.emit()
|
||||||
|
|
||||||
|
func _on_socket_event(event: String, payload: Variant, _namespace):
|
||||||
|
print(event, payload)
|
||||||
|
match event:
|
||||||
|
"reservations_update":
|
||||||
|
reservations_updated.emit(payload)
|
||||||
|
"error":
|
||||||
|
error_occurred.emit(payload.get("message", "Unknown error"))
|
||||||
|
|
||||||
|
func subscribe_to_room(room_id: String):
|
||||||
|
_room_id = room_id
|
||||||
|
_client.socketio_send(
|
||||||
|
"subscribe_reservations",
|
||||||
|
{"room_id": room_id}
|
||||||
|
)
|
||||||
|
|
||||||
|
func disconnect_from_server():
|
||||||
|
_client.socketio_disconnect()
|
||||||
|
|
||||||
|
func _exit_tree():
|
||||||
|
disconnect_from_server()
|
192
src/infra/repos/backend/reservation_http.gd
Normal file
192
src/infra/repos/backend/reservation_http.gd
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
@tool
|
||||||
|
extends AbstractReservationRepo
|
||||||
|
class_name ReservationRepoHTTP
|
||||||
|
|
||||||
|
const BASE_URL = "http://127.0.0.1:5000"
|
||||||
|
const RESERVATION_ENDPOINT = "/reservation/"
|
||||||
|
const HEALTH_ENDPOINT = "/health/"
|
||||||
|
|
||||||
|
signal request_failed(error_message: String)
|
||||||
|
|
||||||
|
var _jwt_token: String = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTc0MDA0MDQzNywianRpIjoiOTM4NTUyMjMtMjhiNC00OWVhLWI3ZjUtZmYxMTg4YzI1Mjg2IiwidHlwZSI6ImFjY2VzcyIsInN1YiI6InRlc3RfdXNlciIsIm5iZiI6MTc0MDA0MDQzNywiY3NyZiI6ImMwYzI2MTU0LTdkNjItNGYyZi04ZjBhLWI0MjA0ODJlMmEzZCIsImV4cCI6MTc0MDA0MTMzN30.esPRTXNxrtziuOc2dUsc9XqbedErjcyvPlL3aUZIaaA"
|
||||||
|
|
||||||
|
var _timed_out := false
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
if await _backend_is_accessible():
|
||||||
|
connected.emit()
|
||||||
|
else:
|
||||||
|
not_connected.emit()
|
||||||
|
|
||||||
|
func _backend_is_accessible():
|
||||||
|
var result = await _make_request(HEALTH_ENDPOINT, HTTPClient.METHOD_GET)
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
push_error("Server initialization failed")
|
||||||
|
return false
|
||||||
|
if result.has("error"):
|
||||||
|
push_error("Server initialization failed: " + result.error)
|
||||||
|
return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
func create_reservation(dto: CreateReservationDTO) -> void:
|
||||||
|
_make_request(RESERVATION_ENDPOINT, HTTPClient.METHOD_POST, _dto_to_json(dto))
|
||||||
|
|
||||||
|
func cancel_reservation(reservation_id: String) -> void:
|
||||||
|
_make_request(RESERVATION_ENDPOINT + "%s" % reservation_id, HTTPClient.METHOD_DELETE)
|
||||||
|
|
||||||
|
func change_reservation(reservation_id: String, dto: UpdateReservationDTO) -> void:
|
||||||
|
_make_request(RESERVATION_ENDPOINT + "%s" % reservation_id, HTTPClient.METHOD_PUT, _dto_to_json(dto))
|
||||||
|
|
||||||
|
func get_reservation(reservation_id: String) -> ReservationEntity:
|
||||||
|
var result = await _make_request(RESERVATION_ENDPOINT + "%s" % reservation_id, HTTPClient.METHOD_GET)
|
||||||
|
return _parse_reservation_entity(result) if result is Dictionary else null
|
||||||
|
|
||||||
|
func list_reservations(filters: Dictionary = {}) -> Array:
|
||||||
|
var query = "?"
|
||||||
|
for key in filters:
|
||||||
|
query += "%s=%s&" % [key, filters[key]]
|
||||||
|
query = query.rstrip("&") if filters else ""
|
||||||
|
|
||||||
|
var endpoint = RESERVATION_ENDPOINT + query
|
||||||
|
var result = await _make_request(endpoint, HTTPClient.METHOD_GET)
|
||||||
|
return _parse_reservation_list(result) if result is Array else []
|
||||||
|
|
||||||
|
func set_current_reservation_id(value):
|
||||||
|
_current_reservation_id = value
|
||||||
|
|
||||||
|
func get_current_reservation_id():
|
||||||
|
return _current_reservation_id
|
||||||
|
|
||||||
|
func set_jwt_token(token: String):
|
||||||
|
_jwt_token = token
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Methods
|
||||||
|
func _get_headers() -> PackedStringArray:
|
||||||
|
return PackedStringArray([
|
||||||
|
"Content-Type: application/json",
|
||||||
|
"Authorization: Bearer %s" % _jwt_token
|
||||||
|
])
|
||||||
|
|
||||||
|
func _dto_to_json(dto) -> String:
|
||||||
|
var dict = {}
|
||||||
|
match typeof(dto):
|
||||||
|
TYPE_OBJECT when dto is CreateReservationDTO:
|
||||||
|
dict = {
|
||||||
|
"title": dto.title,
|
||||||
|
"description": dto.description,
|
||||||
|
"room_id": dto.room_id,
|
||||||
|
"date": dto.date,
|
||||||
|
"start_time": dto.start_time,
|
||||||
|
"finish_time": dto.finish_time,
|
||||||
|
"color": dto.color
|
||||||
|
}
|
||||||
|
TYPE_OBJECT when dto is UpdateReservationDTO:
|
||||||
|
if dto.title: dict["title"] = dto.title
|
||||||
|
if dto.description: dict["description"] = dto.description
|
||||||
|
if dto.room_id: dict["room_id"] = dto.room_id
|
||||||
|
if dto.date: dict["date"] = dto.date
|
||||||
|
if dto.start_time: dict["start_time"] = dto.start_time
|
||||||
|
if dto.finish_time: dict["finish_time"] = dto.finish_time
|
||||||
|
if dto.color: dict["color"] = dto.color
|
||||||
|
return JSON.stringify(dict)
|
||||||
|
|
||||||
|
func _time_dto_to_dict(time_dto: TimeDTO) -> Dictionary:
|
||||||
|
return {"hours": time_dto.hours, "minutes": time_dto.minutes}
|
||||||
|
|
||||||
|
func _make_request(endpoint: String, method: int, body: String = "") -> Variant:
|
||||||
|
var request = HTTPRequest.new()
|
||||||
|
|
||||||
|
add_child(request)
|
||||||
|
|
||||||
|
var url = BASE_URL + endpoint
|
||||||
|
var error = request.request(url, _get_headers(), method, body)
|
||||||
|
if error != OK:
|
||||||
|
request.queue_free()
|
||||||
|
emit_signal("request_failed", "Request creation failed: %d" % error)
|
||||||
|
return null
|
||||||
|
|
||||||
|
var response = await _wait_for_request_or_timeout(request)
|
||||||
|
|
||||||
|
request.queue_free()
|
||||||
|
|
||||||
|
var result = response[0]
|
||||||
|
var response_code = response[1]
|
||||||
|
var response_body = response[3]
|
||||||
|
|
||||||
|
if result != HTTPRequest.RESULT_SUCCESS:
|
||||||
|
emit_signal("request_failed", "HTTP request failed: %d" % result)
|
||||||
|
return null
|
||||||
|
|
||||||
|
var json = JSON.new()
|
||||||
|
var parse_error = json.parse(response_body.get_string_from_utf8())
|
||||||
|
|
||||||
|
if parse_error != OK:
|
||||||
|
emit_signal("request_failed", "JSON parse error: %d" % parse_error)
|
||||||
|
return null
|
||||||
|
|
||||||
|
var response_data = json.get_data()
|
||||||
|
|
||||||
|
if response_code >= 400:
|
||||||
|
emit_signal("request_failed", response_data.get("error", "Unknown error"))
|
||||||
|
return null
|
||||||
|
|
||||||
|
return response_data
|
||||||
|
|
||||||
|
func _wait_for_request_or_timeout(request: HTTPRequest) -> Array:
|
||||||
|
var timer = Timer.new()
|
||||||
|
add_child(timer)
|
||||||
|
|
||||||
|
timer.wait_time = 5.0
|
||||||
|
timer.one_shot = true
|
||||||
|
|
||||||
|
timer.timeout.connect(func():
|
||||||
|
_timed_out = true
|
||||||
|
if request.get_http_client_status() != HTTPClient.STATUS_DISCONNECTED:
|
||||||
|
request.cancel_request()
|
||||||
|
)
|
||||||
|
|
||||||
|
timer.start()
|
||||||
|
|
||||||
|
while true:
|
||||||
|
if _timed_out:
|
||||||
|
_timed_out = false
|
||||||
|
timer.queue_free()
|
||||||
|
return [HTTPRequest.RESULT_REQUEST_FAILED, 408, [], PackedByteArray()]
|
||||||
|
if request.get_http_client_status() == HTTPClient.STATUS_REQUESTING:
|
||||||
|
break
|
||||||
|
await get_tree().process_frame
|
||||||
|
|
||||||
|
timer.queue_free()
|
||||||
|
return await request.request_completed
|
||||||
|
|
||||||
|
func _parse_reservation_entity(data: Dictionary) -> ReservationEntity:
|
||||||
|
var entity = ReservationEntity.new()
|
||||||
|
entity.id = data.get("id", "")
|
||||||
|
entity.title = data.get("title", "")
|
||||||
|
entity.description = data.get("description", "")
|
||||||
|
entity.room_id = data.get("room_id", "")
|
||||||
|
entity.creator = data.get("creator", "")
|
||||||
|
entity.date = data.get("date", "")
|
||||||
|
entity.color = data.get("color", 0)
|
||||||
|
entity.start_time = data.get("start_time", {})
|
||||||
|
entity.finish_time = data.get("finish_time", {})
|
||||||
|
|
||||||
|
return entity
|
||||||
|
|
||||||
|
func _parse_reservation_list(data: Array) -> Array[ReservationEntity]:
|
||||||
|
var entities: Array[ReservationEntity] = []
|
||||||
|
for item in data:
|
||||||
|
entities.append(_parse_reservation_entity(item))
|
||||||
|
|
||||||
|
entities.sort_custom(_compare_reservations_by_start_time)
|
||||||
|
return entities
|
||||||
|
|
||||||
|
func _compare_reservations_by_start_time(a: ReservationEntity, b: ReservationEntity) -> int:
|
||||||
|
var time_a = a.start_time.get("hours", 0) * 60 + a.start_time.get("minutes", 0)
|
||||||
|
var time_b = b.start_time.get("hours", 0) * 60 + b.start_time.get("minutes", 0)
|
||||||
|
return time_a < time_b
|
||||||
|
#endregion
|
2
src/infra/repos/local/event_handler_local.gd
Normal file
2
src/infra/repos/local/event_handler_local.gd
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
extends EventHandler
|
||||||
|
class_name EventHandlerLocal
|
@ -6,6 +6,9 @@ const uuid_util = preload('res://addons/uuid/uuid.gd')
|
|||||||
|
|
||||||
var _reservations = {}
|
var _reservations = {}
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
connected.emit()
|
||||||
|
|
||||||
func create_reservation(dto: CreateReservationDTO):
|
func create_reservation(dto: CreateReservationDTO):
|
||||||
var entity = ReservationEntity.new()
|
var entity = ReservationEntity.new()
|
||||||
|
|
||||||
@ -38,7 +41,7 @@ func change_reservation(reservation_id, dto: UpdateReservationDTO):
|
|||||||
func get_reservation(reservation_id):
|
func get_reservation(reservation_id):
|
||||||
return _reservations[reservation_id]
|
return _reservations[reservation_id]
|
||||||
|
|
||||||
func list_reservations():
|
func list_reservations(filters: Dictionary = {}):
|
||||||
var reservations = []
|
var reservations = []
|
||||||
|
|
||||||
for key in _reservations:
|
for key in _reservations:
|
247
src/libs/socketio_client.gd
Normal file
247
src/libs/socketio_client.gd
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
class_name SocketIOClient extends Node
|
||||||
|
|
||||||
|
enum EngineIOPacketType {
|
||||||
|
open = 0,
|
||||||
|
close = 1,
|
||||||
|
ping = 2,
|
||||||
|
pong = 3,
|
||||||
|
message = 4,
|
||||||
|
upgrade = 5,
|
||||||
|
noop = 6,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SocketIOPacketType {
|
||||||
|
CONNECT = 0,
|
||||||
|
DISCONNECT = 1,
|
||||||
|
EVENT = 2,
|
||||||
|
ACK = 3,
|
||||||
|
CONNECT_ERROR = 4,
|
||||||
|
BINARY_EVENT = 5,
|
||||||
|
BINARY_ACK = 6,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ConnectionState {
|
||||||
|
DISCONNECTED,
|
||||||
|
CONNECTED,
|
||||||
|
RECONNECTING,
|
||||||
|
}
|
||||||
|
|
||||||
|
var _url: String
|
||||||
|
var _client: WebSocketPeer = WebSocketPeer.new()
|
||||||
|
var _sid: String
|
||||||
|
var _pingTimeout: int = 0
|
||||||
|
var _pingInterval: int = 0
|
||||||
|
var _auth: Variant = null
|
||||||
|
var _connection_state: ConnectionState = ConnectionState.DISCONNECTED
|
||||||
|
var _reconnect_timer: Timer = null
|
||||||
|
|
||||||
|
# triggered when engine.io connection is established
|
||||||
|
signal on_engine_connected(sid: String)
|
||||||
|
# triggered when engine.io connection is closed
|
||||||
|
signal on_engine_disconnected(code: int, reason: String)
|
||||||
|
# triggered when engine.io message is received
|
||||||
|
signal on_engine_message(payload: String)
|
||||||
|
|
||||||
|
# triggered when socket.io connection is established
|
||||||
|
signal on_connect(payload: Variant, name_space: String, error: bool)
|
||||||
|
# triggered when socket.io connection is closed
|
||||||
|
signal on_disconnect(name_space: String)
|
||||||
|
# triggered when socket.io event is received
|
||||||
|
signal on_event(event_name: String, payload: Variant, name_space: String)
|
||||||
|
|
||||||
|
# triggered when lost connection in not-clean way (i.e. service shut down)
|
||||||
|
# and now trying to reconnect. When re-connects successfully,
|
||||||
|
# the on_reconnected signal is emitted, instead of on_connect
|
||||||
|
signal on_connection_lost
|
||||||
|
|
||||||
|
# triggered when connects again after losing connection
|
||||||
|
# it's alternative to on_connect signal, but only emitted
|
||||||
|
# after automatically re-connecting with socket.io server
|
||||||
|
signal on_reconnected(payload: Variant, name_space: String, error: bool)
|
||||||
|
|
||||||
|
|
||||||
|
func _init(url: String, auth: Variant=null):
|
||||||
|
_auth = auth
|
||||||
|
url = _preprocess_url(url)
|
||||||
|
_url = "%s?EIO=4&transport=websocket" % url
|
||||||
|
|
||||||
|
func _preprocess_url(url: String) -> String:
|
||||||
|
if not url.ends_with("/"):
|
||||||
|
url = url + "/"
|
||||||
|
if url.begins_with("https"):
|
||||||
|
url = "wss" + url.erase(0, len("https"))
|
||||||
|
elif url.begins_with("http"):
|
||||||
|
url = "ws" + url.erase(0, len("http"))
|
||||||
|
return url
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
_client.connect_to_url(_url)
|
||||||
|
|
||||||
|
func _process(_delta):
|
||||||
|
_client.poll()
|
||||||
|
|
||||||
|
var state = _client.get_ready_state()
|
||||||
|
if state == WebSocketPeer.STATE_OPEN:
|
||||||
|
while _client.get_available_packet_count():
|
||||||
|
var packet = _client.get_packet()
|
||||||
|
var packetString = packet.get_string_from_utf8()
|
||||||
|
if len(packetString) > 0:
|
||||||
|
_engineio_decode_packet(packetString)
|
||||||
|
# TODO: handle binary data?
|
||||||
|
|
||||||
|
elif state == WebSocketPeer.STATE_CLOSED:
|
||||||
|
set_process(false)
|
||||||
|
|
||||||
|
var code = _client.get_close_code()
|
||||||
|
var reason = _client.get_close_reason()
|
||||||
|
|
||||||
|
if code == -1:
|
||||||
|
# -1 is not-clean disconnect (i.e. Service shut down)
|
||||||
|
# we should try to reconnect
|
||||||
|
|
||||||
|
_connection_state = ConnectionState.RECONNECTING
|
||||||
|
|
||||||
|
_reconnect_timer = Timer.new()
|
||||||
|
_reconnect_timer.wait_time = 1.0
|
||||||
|
_reconnect_timer.timeout.connect(_on_reconnect_timer_timeout)
|
||||||
|
_reconnect_timer.autostart = true
|
||||||
|
add_child(_reconnect_timer)
|
||||||
|
|
||||||
|
on_connection_lost.emit()
|
||||||
|
else:
|
||||||
|
_connection_state = ConnectionState.DISCONNECTED
|
||||||
|
on_engine_disconnected.emit(code, reason)
|
||||||
|
|
||||||
|
func _on_reconnect_timer_timeout():
|
||||||
|
_client.poll()
|
||||||
|
var state = _client.get_ready_state()
|
||||||
|
if state == WebSocketPeer.STATE_CLOSED:
|
||||||
|
_client.connect_to_url(_url)
|
||||||
|
else:
|
||||||
|
set_process(true)
|
||||||
|
_reconnect_timer.queue_free()
|
||||||
|
|
||||||
|
func _exit_tree():
|
||||||
|
if _connection_state == ConnectionState.CONNECTED:
|
||||||
|
_engineio_send_packet(EngineIOPacketType.close)
|
||||||
|
|
||||||
|
_client.close()
|
||||||
|
|
||||||
|
func _engineio_decode_packet(packet: String):
|
||||||
|
var packetType = int(packet.substr(0, 1))
|
||||||
|
var packetPayload = packet.substr(1)
|
||||||
|
|
||||||
|
match packetType:
|
||||||
|
EngineIOPacketType.open:
|
||||||
|
var json = JSON.new()
|
||||||
|
json.parse(packetPayload)
|
||||||
|
_sid = json.data["sid"]
|
||||||
|
_pingTimeout = int(json.data["pingTimeout"])
|
||||||
|
_pingInterval = int(json.data["pingInterval"])
|
||||||
|
on_engine_connected.emit(_sid)
|
||||||
|
|
||||||
|
EngineIOPacketType.ping:
|
||||||
|
_engineio_send_packet(EngineIOPacketType.pong)
|
||||||
|
|
||||||
|
EngineIOPacketType.message:
|
||||||
|
_socketio_parse_packet(packetPayload)
|
||||||
|
on_engine_message.emit(packetPayload)
|
||||||
|
|
||||||
|
func _engineio_send_packet(type: EngineIOPacketType, payload: String=""):
|
||||||
|
if len(payload) == 0:
|
||||||
|
_client.send_text("%d" % type)
|
||||||
|
else:
|
||||||
|
_client.send_text("%d%s" % [type, payload])
|
||||||
|
|
||||||
|
func _socketio_parse_packet(payload: String):
|
||||||
|
var packetType = int(payload.substr(0, 1))
|
||||||
|
payload = payload.substr(1)
|
||||||
|
|
||||||
|
var regex = RegEx.new()
|
||||||
|
regex.compile("(\\d+)-")
|
||||||
|
var regexMatch = regex.search(payload)
|
||||||
|
if regexMatch and regexMatch.get_start() == 0:
|
||||||
|
payload = payload.substr(regexMatch.get_end())
|
||||||
|
push_error("Binary data payload not supported!")
|
||||||
|
|
||||||
|
var name_space = "/"
|
||||||
|
regex.compile("(\\w),")
|
||||||
|
regexMatch = regex.search(payload)
|
||||||
|
if regexMatch and regexMatch.get_start() == 0:
|
||||||
|
payload = payload.substr(regexMatch.get_end())
|
||||||
|
name_space = regexMatch.get_string(1)
|
||||||
|
|
||||||
|
# var ack_id = null
|
||||||
|
regex.compile("(\\d+)")
|
||||||
|
regexMatch = regex.search(payload)
|
||||||
|
if regexMatch and regexMatch.get_start() == 0:
|
||||||
|
payload = payload.substr(regexMatch.get_end())
|
||||||
|
push_warning("Ignoring acknowledge ID!")
|
||||||
|
|
||||||
|
var data = null
|
||||||
|
if len(payload) > 0:
|
||||||
|
var json = JSON.new()
|
||||||
|
if json.parse(payload) == OK:
|
||||||
|
data = json.data
|
||||||
|
|
||||||
|
match packetType:
|
||||||
|
SocketIOPacketType.CONNECT:
|
||||||
|
if _connection_state == ConnectionState.RECONNECTING:
|
||||||
|
_connection_state = ConnectionState.CONNECTED
|
||||||
|
on_reconnected.emit(data, name_space, false)
|
||||||
|
else:
|
||||||
|
_connection_state = ConnectionState.CONNECTED
|
||||||
|
on_connect.emit(data, name_space, false)
|
||||||
|
|
||||||
|
SocketIOPacketType.CONNECT_ERROR:
|
||||||
|
if _connection_state == ConnectionState.RECONNECTING:
|
||||||
|
_connection_state = ConnectionState.CONNECTED
|
||||||
|
on_reconnected.emit(data, name_space, true)
|
||||||
|
else:
|
||||||
|
_connection_state = ConnectionState.CONNECTED
|
||||||
|
on_connect.emit(data, name_space, true)
|
||||||
|
|
||||||
|
SocketIOPacketType.EVENT:
|
||||||
|
if typeof(data) != TYPE_ARRAY:
|
||||||
|
push_error("Invalid socketio event format!")
|
||||||
|
var eventName = data[0]
|
||||||
|
var eventData = data[1] if len(data) > 1 else null
|
||||||
|
on_event.emit(eventName, eventData, name_space)
|
||||||
|
|
||||||
|
func _socketio_send_packet(type: SocketIOPacketType, name_space: String, data: Variant=null, binaryData: Array[PackedByteArray]=[], ack_id: Variant=null):
|
||||||
|
var payload = "%d" % type
|
||||||
|
if binaryData.size() > 0:
|
||||||
|
payload += "%d-" % binaryData.size()
|
||||||
|
if name_space != "/":
|
||||||
|
payload += "%s," % name_space
|
||||||
|
if ack_id != null:
|
||||||
|
payload += "%d" % ack_id
|
||||||
|
if data != null:
|
||||||
|
payload += "%s" % JSON.stringify(data)
|
||||||
|
|
||||||
|
_engineio_send_packet(EngineIOPacketType.message, payload)
|
||||||
|
|
||||||
|
for binary in binaryData:
|
||||||
|
_client.put_packet(binary)
|
||||||
|
|
||||||
|
# connect to socket.io server by namespace
|
||||||
|
func socketio_connect(name_space: String="/"):
|
||||||
|
_socketio_send_packet(SocketIOPacketType.CONNECT, name_space, _auth)
|
||||||
|
|
||||||
|
# disconnect from socket.io server by namespace
|
||||||
|
func socketio_disconnect(name_space: String="/"):
|
||||||
|
if _connection_state == ConnectionState.CONNECTED:
|
||||||
|
# We should ONLY send disconnect packet when we're connected
|
||||||
|
_socketio_send_packet(SocketIOPacketType.DISCONNECT, name_space)
|
||||||
|
|
||||||
|
on_disconnect.emit(name_space)
|
||||||
|
|
||||||
|
# send event to socket.io server by namespace
|
||||||
|
func socketio_send(event_name: String, payload: Variant=null, name_space: String="/"):
|
||||||
|
if payload == null:
|
||||||
|
_socketio_send_packet(SocketIOPacketType.EVENT, name_space, [event_name])
|
||||||
|
else:
|
||||||
|
_socketio_send_packet(SocketIOPacketType.EVENT, name_space, [event_name, payload])
|
||||||
|
|
||||||
|
func get_connection_state() -> ConnectionState:
|
||||||
|
return _connection_state
|
Loading…
x
Reference in New Issue
Block a user