Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimized changeDetector.gd, some static typing #4

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/scenes/GUI/GUI.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ script = ExtResource("1_73joy")
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 9.0
offset_top = 9.0
offset_right = -9.0
offset_bottom = -9.0
offset_left = 4.0
offset_top = 4.0
offset_right = -4.0
offset_bottom = -4.0
grow_horizontal = 2
grow_vertical = 2

Expand Down Expand Up @@ -476,10 +476,10 @@ borderless = false
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 9.0
offset_top = 9.0
offset_right = -9.0
offset_bottom = -9.0
offset_left = 4.0
offset_top = 4.0
offset_right = -4.0
offset_bottom = -4.0
grow_horizontal = 2
grow_vertical = 2

Expand Down
30 changes: 16 additions & 14 deletions src/scenes/GUI/gui.gd
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func _joined() -> void:
$main/session/top/end.text = "Disconnect"

func alert(text: String, title := "") -> AcceptDialog:
var popup = AcceptDialog.new()
var popup := AcceptDialog.new()

popup.dialog_text = text
popup.title = title
Expand All @@ -83,7 +83,7 @@ func alert(text: String, title := "") -> AcceptDialog:
return popup

func confirm(text: String) -> bool:
var p = ConfirmationDialog.new()
var p := ConfirmationDialog.new()
p.dialog_text = text

var status = null
Expand All @@ -109,26 +109,28 @@ func end_session() -> void:
main_menu()

func main_menu() -> void:
$main/sessionInit.visible = true
$main/sessionInit/pre.visible = true
# ImmortalOctogen: to show
$main/sessionInit.show()
$main/sessionInit/pre.show()

$main/sessionInit/start.visible = false
$main/sessionInit/start/host.visible = false
$main/sessionInit/start/join.visible = false
$main/session.visible = false
# ImmortalOctogen: to hide
$main/sessionInit/start.hide()
$main/sessionInit/start/host.hide()
$main/sessionInit/start/join.hide()
$main/session.hide()

func session_start_menu():
$main/sessionInit/start.visible = true
$main/sessionInit/pre.visible = false
$main/sessionInit/start.show()
$main/sessionInit/pre.hide()
# Layout glitch fix
await get_tree().process_frame
$main/sessionInit/start.visible = false
$main/sessionInit/start.hide()
await get_tree().process_frame
$main/sessionInit/start.visible = true
$main/sessionInit/start.show()

func session_menu() -> void:
$main/sessionInit.visible = false
$main/session.visible = true
$main/sessionInit.hide()
$main/session.show()

func visuals_available() -> bool:
return main or not Engine.is_editor_hint()
10 changes: 5 additions & 5 deletions src/scenes/GUI/userEntry.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ class_name GodotTogetherGUIUser

var user: GodotTogetherUser

var color_node = $color
var name_node = $name
var id_node = $id
var ip_node = $ip/value
var rank_node = $rank
@onready var color_node = $color
@onready var name_node = $name
@onready var id_node = $id
@onready var ip_node = $ip/value
@onready var rank_node = $rank

func _process(_delta: float) -> void:
if user and not user.is_peer_connected():
Expand Down
5 changes: 2 additions & 3 deletions src/scenes/GUI/users.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ class_name GodotTogetherUserList

var main: GodotTogether

var template = $vbox/user
@onready var template = $vbox/user

func _ready() -> void:
if not main: return

template.visible = false
template.hide()

func add_user(user: GodotTogetherUser):
if get_entry(user):
Expand Down
7 changes: 5 additions & 2 deletions src/scripts/GodotTogether.gd
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var dual = GodotTogetherDual.new(self, "dual")
var change_detector = GodotTogetherChangeDetector.new(self, "changeDetector")

#var menu: GodotTogetherMainMenu = load("res://addons/GodotTogether/src/scenes/GUI/MainMenu/MainMenu.tscn").instantiate()
var gui: GodotTogetherGUI = load("res://addons/GodotTogether/src/scenes/GUI/GUI.tscn").instantiate()
var gui: GodotTogetherGUI = preload("res://addons/GodotTogether/src/scenes/GUI/GUI.tscn").instantiate()
var button = Button.new()

func _enter_tree():
Expand All @@ -37,13 +37,16 @@ func _enter_tree():
gui.visible = false
button.text = "Godot Together"
add_control_to_container(EditorPlugin.CONTAINER_TOOLBAR, button)
button.get_parent().move_child(button, button.get_index() - 5)
# ImmortalOctogen: No need in runtime button index detection
button.get_parent().move_child(button, 1)
button.pressed.connect(gui.popup)


func _exit_tree():
close_connection()
button.queue_free()
# ImmortalOctogen: To prevent from endless executing unfreed scripts + nodes
queue_free()

func is_session_active():
return multiplayer.has_multiplayer_peer() and Engine.is_editor_hint() and (
Expand Down
92 changes: 79 additions & 13 deletions src/scripts/changeDetector.gd
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,26 @@ signal node_properties_changed(node: Node, changed_keys: Array)
signal node_removed(node: Node)
signal node_added(node: Node)

const IGNORED_PROPERTY_USAGE_FLAGS = [
const IGNORED_PROPERTY_USAGE_FLAGS := [
PROPERTY_USAGE_GROUP,
PROPERTY_USAGE_CATEGORY,
PROPERTY_USAGE_SUBGROUP
]

var observed_nodes = {}
var observed_nodes_cache = {}
var incoming_nodes = {
var observed_nodes := {}
var observed_nodes_cache := {}
var incoming_nodes := {
# scene path: Array[NodePath]
}
var refrate: Timer = Timer.new()

var last_scene := ""

static func get_property_keys(node: Node) -> Array[String]:
var res: Array[String] = []

for i in node.get_property_list():
var con = true
var con := true

for usage in IGNORED_PROPERTY_USAGE_FLAGS:
if i.usage & usage:
Expand All @@ -40,17 +41,36 @@ static func get_property_keys(node: Node) -> Array[String]:
return res

static func get_property_dict(node: Node) -> Dictionary:
var res = {}
var res := {}

for i in get_property_keys(node):
res[i] = node[i]

return res

func _process(_delta):
func _ready() -> void:
# ImmortalOctogen: there is no data races and other data sync problems
# 'observed_nodes', 'observed_nodes_cache', 'incoming_nodes' is only used by other thread
var t: Thread = Thread.new() # Creating thread once saves fps
refrate.wait_time = 0.1
refrate.timeout.connect(func():
if t.start(cycle) == ERR_CANT_CREATE:
print_debug(error_string(ERR_CANT_CREATE)) # for smth
return
while true:
if !t.is_alive():
t.wait_to_finish()
break
)
add_child(refrate)
refrate.start()

# The thread-only function
func cycle() -> void:
if not main: return

var root = EditorInterface.get_edited_scene_root()

var root := EditorInterface.call_deferred("get_edited_scene_root")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

call_deferred() doesn't return the called function's result.
Here's how it can be fixed:

func _ready() -> void:
	var t: Thread = Thread.new()
	refrate.wait_time = 0.1

	var root = EditorInterface.get_edited_scene_root() # Get scene root in the main thread

	refrate.timeout.connect(func():
		if t.start(cycle.bind(root)) == ERR_CANT_CREATE: # Pass `root` to the thread
			print_debug(error_string(ERR_CANT_CREATE))
			return
		while true:
			if not t.is_alive():
				t.wait_to_finish()
				break
	)

	add_child(refrate)
	refrate.start()
func cycle(root: Node) -> void:
	if not main: return
	if not root: return

        ....

if not root: return

var current_scene_path = root.scene_file_path
Expand All @@ -66,10 +86,10 @@ func _process(_delta):
observed_nodes.erase(node)
continue

var cached = observed_nodes_cache[node]
var current = get_property_dict(node)
var cached: Dictionary = observed_nodes_cache[node]
var current := get_property_dict(node)

var changed_keys = []
var changed_keys: Array[Array] = []

for i in current.keys():
if cached[i] != current[i]:
Expand All @@ -81,9 +101,45 @@ func _process(_delta):
node_properties_changed.emit(node, changed_keys)
observed_nodes_cache[node] = current

# Calculation is freed from main thread. Commented with String.
func _process(_delta) -> void:
"if not main: return


var root = EditorInterface.get_edited_scene_root()
if not root: return

var current_scene_path = root.scene_file_path
if last_scene != current_scene_path:
last_scene = current_scene_path
scene_changed.emit()

for node in observed_nodes:
if not is_instance_valid(node):
continue # Freed nodes are automatically erased from arrays

if not node.is_inside_tree():
observed_nodes.erase(node)
continue

var cached: Dictionary = observed_nodes_cache[node]
var current := get_property_dict(node)

var changed_keys: Array[Array] = []

for i in current.keys():
if cached[i] != current[i]:
#node_property_changed.emit(node, i)
#node_property_differs.emit(node, i, cached[i], current[i])
changed_keys.append(i)

if changed_keys.size() != 0:
node_properties_changed.emit(node, changed_keys)
observed_nodes_cache[node] = current"

func _node_added(node: Node):
var current_scene = EditorInterface.get_edited_scene_root()
var scene_path = current_scene.scene_file_path
var current_scene := EditorInterface.get_edited_scene_root()
var scene_path := current_scene.scene_file_path

if scene_path in incoming_nodes:
var incoming = incoming_nodes[scene_path]
Expand Down Expand Up @@ -118,6 +174,16 @@ func observe(node: Node):
node.tree_exiting.connect(node_removed.emit.bind(node))
node.child_entered_tree.connect(_node_added)

# ImmortalOctogen: gigachad coding??!!!
# property_list_changed doesn't fire in editor
# so let's fire `em!
# P.S. forget for while
#var script: GDScript = node.get_script() as GDScript
#if script == null:
# return
#print(script.get_global_name())
#print(script.get_script_method_list())

# property_list_changed doesn't fire in editor
#var cache = get_property_dict(node)
#
Expand Down
2 changes: 1 addition & 1 deletion src/scripts/component.gd
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ func _init(main: GodotTogether, name: String = "") -> void:
self.main = main

if name != "":
self.name = name
self.name = name
2 changes: 1 addition & 1 deletion src/scripts/net/client.gd
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func _ready():
multiplayer.connected_to_server.connect(_connected)
multiplayer.server_disconnected.connect(_disconnected)

# Doesn't fire, probably a Goodt bug
# Doesn't fire, probably a Godot bug
#multiplayer.connection_failed.connect(_connecting_finished.bind(false))

func _connected():
Expand Down
4 changes: 2 additions & 2 deletions src/scripts/net/dual.gd
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ var prev_mouse_pos := Vector2()
var prev_3d_pos := Vector3()
var prev_3d_rot := Vector3()

var avatar_3d_scene = load("res://addons/GodotTogether/src/scenes/Avatar3D/Avatar3D.tscn")
var avatar_2d_scene = load("res://addons/GodotTogether/src/scenes/Avatar2D/Avatar2D.tscn")
var avatar_3d_scene = preload("res://addons/GodotTogether/src/scenes/Avatar3D/Avatar3D.tscn")
var avatar_2d_scene = preload("res://addons/GodotTogether/src/scenes/Avatar2D/Avatar2D.tscn")

var avatar_3d_markers: Array[GodotTogetherAvatar3D] = []
var avatar_2d_markers: Array[GodotTogetherAvatar2D] = []
Expand Down
2 changes: 1 addition & 1 deletion src/scripts/net/server.gd
Original file line number Diff line number Diff line change
Expand Up @@ -215,4 +215,4 @@ static func is_local(ip: String) -> bool:
if a == 172 and b >= 16 and b <= 31: return true
if a == 192 and b == 168: return true

return false
return false