From 5a28feb2ca92d5d00897e72a7e075649560a7798 Mon Sep 17 00:00:00 2001 From: Lorenzo Rossi Date: Tue, 23 Apr 2024 00:13:54 +0200 Subject: [PATCH 1/5] Remove priority backref --- behaviours/priority.gd | 13 +++++-------- behaviours/sampler.gd | 18 ++++++++++++++---- behaviours/sampler_priority.gd | 21 ++++++++++++++++++++- entities/imp.tscn | 3 --- entities/sheep.tscn | 5 ----- 5 files changed, 39 insertions(+), 21 deletions(-) diff --git a/behaviours/priority.gd b/behaviours/priority.gd index 54509b1..9a4f924 100644 --- a/behaviours/priority.gd +++ b/behaviours/priority.gd @@ -9,12 +9,9 @@ class_name Priority ## Emitted when the priority is changed. signal priority_changed(new: int, old: int) -## Emitted when the priority is changed. No args are provided to work around a Godot bug. -signal priority_changed_no_args - - @export var default_priority: int = 0 @export var alternative_priority: int = 1 +@export var setup_signals_on_ready: bool = true var priority: int = 0: get: @@ -61,9 +58,9 @@ func get_ref() -> Node: func log_priority() -> void: Log.p(self, "Priority: %d" % priority) - -func _on_priority_changed(_new: int, _old: int) -> void: - priority_changed_no_args.emit() - func _ready() -> void: priority = default_priority + +func link(parent: SamplerPriority) -> void: + if setup_signals_on_ready: + priority_changed.connect(func(_old, _new): parent.on_priority_changed(self)) diff --git a/behaviours/sampler.gd b/behaviours/sampler.gd index 00b87eb..bf26ace 100644 --- a/behaviours/sampler.gd +++ b/behaviours/sampler.gd @@ -9,6 +9,8 @@ class_name Sampler ## [Array] of [Node]s that can be [func sample]d by this [Sampler]. @export var possibilities: Array[Node] = [] +var selected: Node = null; + ## Get a reference. func sample() -> Node: @@ -16,11 +18,19 @@ func sample() -> Node: return null ## Set the [field enabled] property to true on a [method sample]d node, and to false on all others. -func enable() -> void: - var selected = sample() - for possibility in get_all_refs(): - possibility.enabled = (selected == possibility) +func sample_and_enable() -> void: + set_enabled(sample()) +func set_enabled(node: Node) -> void: + if node == selected: + return + selected = node + var selected_ref = get_ref(selected) + for possibility in get_all_refs(): + possibility.enabled = (selected_ref == possibility) + +func get_ref(node: Node) -> Node: + return node ## Get all possible nodes referenced by [field possibilities]. ## diff --git a/behaviours/sampler_priority.gd b/behaviours/sampler_priority.gd index c925afb..b5a9487 100644 --- a/behaviours/sampler_priority.gd +++ b/behaviours/sampler_priority.gd @@ -3,7 +3,11 @@ class_name SamplerPriority ## Always sample the object with the highest priority in the queue. +var selected_priority = 0; +func _ready(): + for possibility in possibilities: + possibility.link(self) ## Get a reference. func sample() -> Priority: @@ -19,10 +23,25 @@ func sample() -> Priority: if highest_possibility == null: return null - return highest_possibility.get_ref() + selected_priority = highest_possibility.priority + + return highest_possibility + +func on_priority_changed(node: Node): + if node == selected: + if node.priority > selected_priority: + selected_priority = node.priority + else: + sample_and_enable() + else: + if selected == null or node.priority > selected.priority: + set_enabled(node) func get_all_refs() -> Array[Node]: var refs: Array[Node] = [] for possibility in possibilities: refs.append(possibility.get_ref()) return refs + +func get_ref(node: Node) -> Node: + return node.get_ref() \ No newline at end of file diff --git a/entities/imp.tscn b/entities/imp.tscn index e58fc3e..0f5a120 100644 --- a/entities/imp.tscn +++ b/entities/imp.tscn @@ -124,11 +124,9 @@ stream = ExtResource("19_7la6c") [connection signal="ready" from="MovementSampler" to="MovementSampler" method="enable"] [connection signal="changed_direction" from="MovementWander" to="MovementWander/WanderPriority" method="priority_conditional"] [connection signal="move" from="MovementWander" to="." method="_on_move"] -[connection signal="priority_changed_no_args" from="MovementWander/WanderPriority" to="MovementSampler" method="enable"] [connection signal="timeout" from="MovementWander/ChangeDirectionTimer" to="MovementWander" method="randomize_direction"] [connection signal="changed_target" from="MovementHunt" to="MovementHunt/HuntPriority" method="priority_conditional"] [connection signal="move" from="MovementHunt" to="." method="_on_move"] -[connection signal="priority_changed_no_args" from="MovementHunt/HuntPriority" to="MovementSampler" method="enable"] [connection signal="tracked" from="MovementHunt/TrackerMeat" to="MovementHunt/TrackerMeat/TargetPicker" method="sample_target_if_null" unbinds=1] [connection signal="untracked" from="MovementHunt/TrackerMeat" to="MovementHunt/TrackerMeat/TargetPicker" method="clear_if_target"] [connection signal="target_changed" from="MovementHunt/TrackerMeat/TargetPicker" to="MovementHunt" method="set_target" unbinds=1] @@ -140,7 +138,6 @@ stream = ExtResource("19_7la6c") [connection signal="fallen" from="MovementDrag" to="MovementDrag/DragPriority" method="priority_default"] [connection signal="fallen" from="MovementDrag" to="MovementDrag/FallSound" method="play"] [connection signal="move" from="MovementDrag" to="." method="_on_move"] -[connection signal="priority_changed_no_args" from="MovementDrag/DragPriority" to="MovementSampler" method="enable"] [connection signal="dragged" from="MovementDrag/Draggable" to="MovementDrag" method="drag"] [connection signal="dropped" from="MovementDrag/Draggable" to="MovementDrag" method="drop"] [connection signal="eaten" from="Eater" to="." method="_on_eater_eaten"] diff --git a/entities/sheep.tscn b/entities/sheep.tscn index b07e995..777129e 100644 --- a/entities/sheep.tscn +++ b/entities/sheep.tscn @@ -188,24 +188,20 @@ stream = ExtResource("17_8kst2") [connection signal="move" from="MovementIdle" to="." method="_on_move"] [connection signal="move_disabled" from="MovementIdle" to="MovementIdle/BoredTimer" method="stop"] [connection signal="move_enabled" from="MovementIdle" to="MovementIdle/BoredTimer" method="start"] -[connection signal="priority_changed_no_args" from="MovementIdle/IdlePriority" to="MovementSampler" method="enable"] [connection signal="timeout" from="MovementIdle/BoredTimer" to="MovementWander" method="randomize_direction"] [connection signal="changed_direction" from="MovementWander" to="MovementWander/WanderPriority" method="priority_conditional"] [connection signal="move" from="MovementWander" to="." method="_on_move"] [connection signal="move_disabled" from="MovementWander" to="MovementWander/TiredTimer" method="stop"] [connection signal="move_enabled" from="MovementWander" to="MovementWander/TiredTimer" method="start"] -[connection signal="priority_changed_no_args" from="MovementWander/WanderPriority" to="MovementSampler" method="enable"] [connection signal="timeout" from="MovementWander/TiredTimer" to="MovementWander" method="clear_direction"] [connection signal="changed_target" from="MovementRunFromMouse" to="MovementRunFromMouse/RunFromMousePriority" method="priority_conditional"] [connection signal="move" from="MovementRunFromMouse" to="." method="_on_move"] [connection signal="move_enabled" from="MovementRunFromMouse" to="MovementWander" method="clear_direction"] -[connection signal="priority_changed_no_args" from="MovementRunFromMouse/RunFromMousePriority" to="MovementSampler" method="enable"] [connection signal="cursor_entered" from="MovementRunFromMouse/CursorSense" to="MovementRunFromMouse" method="set_target"] [connection signal="cursor_exited" from="MovementRunFromMouse/CursorSense" to="MovementRunFromMouse" method="clear_target" unbinds=1] [connection signal="changed_target" from="MovementRunFromHunter" to="MovementRunFromHunter/RunFromHunterPriority" method="priority_conditional"] [connection signal="move" from="MovementRunFromHunter" to="." method="_on_move"] [connection signal="move_disabled" from="MovementRunFromHunter" to="MovementWander" method="clear_direction"] -[connection signal="priority_changed_no_args" from="MovementRunFromHunter/RunFromHunterPriority" to="MovementSampler" method="enable"] [connection signal="tracked" from="MovementRunFromHunter/HunterSense" to="MovementRunFromHunter/HunterSense/TargetPicker" method="set_target_if_null"] [connection signal="untracked" from="MovementRunFromHunter/HunterSense" to="MovementRunFromHunter/HunterSense/TargetPicker" method="clear_if_target"] [connection signal="target_changed" from="MovementRunFromHunter/HunterSense/TargetPicker" to="MovementRunFromHunter" method="set_target" unbinds=1] @@ -217,6 +213,5 @@ stream = ExtResource("17_8kst2") [connection signal="fallen" from="MovementDrag" to="MovementDrag/FallSound" method="play"] [connection signal="move" from="MovementDrag" to="." method="_on_move"] [connection signal="move_enabled" from="MovementDrag" to="MovementWander" method="clear_direction"] -[connection signal="priority_changed_no_args" from="MovementDrag/DragPriority" to="MovementSampler" method="enable"] [connection signal="dragged" from="MovementDrag/Draggable" to="MovementDrag" method="drag"] [connection signal="dropped" from="MovementDrag/Draggable" to="MovementDrag" method="drop"] From 73c4cce99cbf9e5734c14f8b247af1ffbae5eb1b Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 23 Apr 2024 09:16:09 +0200 Subject: [PATCH 2/5] Add `autodetect_possibilities` option to `Sampler` --- behaviours/sampler.gd | 15 ++++++++++++++- behaviours/sampler_priority.gd | 7 ++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/behaviours/sampler.gd b/behaviours/sampler.gd index bf26ace..5ce7ce7 100644 --- a/behaviours/sampler.gd +++ b/behaviours/sampler.gd @@ -9,9 +9,17 @@ class_name Sampler ## [Array] of [Node]s that can be [func sample]d by this [Sampler]. @export var possibilities: Array[Node] = [] +## If true, the [Sampler] will attempt to automatically detect the [field possibilities] on NOTIFICATION_READY. +@export var autodetect_possibilities_on_ready: bool = true + + var selected: Node = null; +## Update [field possibilities] with the most likely subset of nodes. +func autodetect_possibilities(): + possibilities = get_children() + ## Get a reference. func sample() -> Node: Log.e(self, "Not implemented.") @@ -36,4 +44,9 @@ func get_ref(node: Node) -> Node: ## ## Useful as it may be overridden by some other [Sampler]s, such as [SamplerPriority]. func get_all_refs() -> Array[Node]: - return possibilities \ No newline at end of file + return possibilities + + +func _ready() -> void: + if autodetect_possibilities_on_ready: + autodetect_possibilities() diff --git a/behaviours/sampler_priority.gd b/behaviours/sampler_priority.gd index b5a9487..5221fa3 100644 --- a/behaviours/sampler_priority.gd +++ b/behaviours/sampler_priority.gd @@ -9,6 +9,11 @@ func _ready(): for possibility in possibilities: possibility.link(self) + +## Update [field possibilities] with the most likely subset of nodes. +func autodetect_possibilities(): + possibilities = find_children("*", "Priority", true, false) + ## Get a reference. func sample() -> Priority: if len(possibilities) == 0: @@ -44,4 +49,4 @@ func get_all_refs() -> Array[Node]: return refs func get_ref(node: Node) -> Node: - return node.get_ref() \ No newline at end of file + return node.get_ref() From 1abd1c1ec34cde274718b10fee4a37a05467a31d Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 23 Apr 2024 09:28:45 +0200 Subject: [PATCH 3/5] Move the autosetup code up to `SamplerPriority` --- behaviours/priority.gd | 5 ----- behaviours/sampler_priority.gd | 41 ++++++++++++++++++---------------- entities/imp.tscn | 3 +-- entities/sheep.tscn | 3 +-- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/behaviours/priority.gd b/behaviours/priority.gd index 9a4f924..cda9e94 100644 --- a/behaviours/priority.gd +++ b/behaviours/priority.gd @@ -11,7 +11,6 @@ signal priority_changed(new: int, old: int) @export var default_priority: int = 0 @export var alternative_priority: int = 1 -@export var setup_signals_on_ready: bool = true var priority: int = 0: get: @@ -60,7 +59,3 @@ func log_priority() -> void: func _ready() -> void: priority = default_priority - -func link(parent: SamplerPriority) -> void: - if setup_signals_on_ready: - priority_changed.connect(func(_old, _new): parent.on_priority_changed(self)) diff --git a/behaviours/sampler_priority.gd b/behaviours/sampler_priority.gd index 5221fa3..5ea3e95 100644 --- a/behaviours/sampler_priority.gd +++ b/behaviours/sampler_priority.gd @@ -2,18 +2,19 @@ extends Sampler class_name SamplerPriority -## Always sample the object with the highest priority in the queue. -var selected_priority = 0; - -func _ready(): - for possibility in possibilities: - possibility.link(self) +## If true, the [SamplerPriority] will attempt to automatically setup the recommended signals for all the [field possibilities] on NOTIFICATION_READY. +@export var autosetup_signals_on_ready: bool = true ## Update [field possibilities] with the most likely subset of nodes. -func autodetect_possibilities(): +func autodetect_possibilities() -> void: possibilities = find_children("*", "Priority", true, false) +## Setup the recommended signals for each node in [field possibilities]. +func autosetup_signals() -> void: + for possibility in possibilities: + possibility.priority_changed.connect(_autosetup_on_possibility_priority_changed.bind(possibility)) + ## Get a reference. func sample() -> Priority: if len(possibilities) == 0: @@ -27,21 +28,9 @@ func sample() -> Priority: if highest_possibility == null: return null - - selected_priority = highest_possibility.priority return highest_possibility -func on_priority_changed(node: Node): - if node == selected: - if node.priority > selected_priority: - selected_priority = node.priority - else: - sample_and_enable() - else: - if selected == null or node.priority > selected.priority: - set_enabled(node) - func get_all_refs() -> Array[Node]: var refs: Array[Node] = [] for possibility in possibilities: @@ -50,3 +39,17 @@ func get_all_refs() -> Array[Node]: func get_ref(node: Node) -> Node: return node.get_ref() + + +func _ready(): + if autosetup_signals_on_ready: + autosetup_signals() + +func _autosetup_on_possibility_priority_changed(node: Priority, new: int, old: int): + if node == selected: + if new < old: + sample_and_enable() + else: + # A nice optimization! + if selected == null or new > selected.priority: + set_enabled(node) diff --git a/entities/imp.tscn b/entities/imp.tscn index 0f5a120..d761f73 100644 --- a/entities/imp.tscn +++ b/entities/imp.tscn @@ -57,8 +57,7 @@ deviation = 4.0 min_secs = 1.0 max_secs = 9.0 -[node name="MovementSampler" parent="." node_paths=PackedStringArray("possibilities") instance=ExtResource("7_ech8d")] -possibilities = [NodePath("../MovementWander/WanderPriority"), NodePath("../MovementHunt/HuntPriority"), NodePath("../MovementDrag/DragPriority")] +[node name="MovementSampler" parent="." instance=ExtResource("7_ech8d")] [node name="MovementWander" parent="." instance=ExtResource("8_ffcw0")] speed = 25.0 diff --git a/entities/sheep.tscn b/entities/sheep.tscn index 777129e..c0cb53c 100644 --- a/entities/sheep.tscn +++ b/entities/sheep.tscn @@ -107,8 +107,7 @@ libraries = { [node name="Edible" parent="." instance=ExtResource("6_3odsh")] diet = &"Meat" -[node name="MovementSampler" parent="." node_paths=PackedStringArray("possibilities") instance=ExtResource("9_s5lod")] -possibilities = [NodePath("../MovementIdle/IdlePriority"), NodePath("../MovementWander/WanderPriority"), NodePath("../MovementRunFromMouse/RunFromMousePriority"), NodePath("../MovementRunFromHunter/RunFromHunterPriority"), NodePath("../MovementDrag/DragPriority")] +[node name="MovementSampler" parent="." instance=ExtResource("9_s5lod")] [node name="MovementIdle" parent="." instance=ExtResource("10_05kcd")] speed = 0.0 From 7b54a55dd5638c697094b2137b37460e70d84b21 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 23 Apr 2024 09:43:17 +0200 Subject: [PATCH 4/5] Use inheritance properly (oops, my fault!) --- behaviours/sampler.gd | 12 ++++-------- behaviours/sampler_priority.gd | 12 +++++++++--- entities/imp.tscn | 1 - entities/sheep.tscn | 1 - 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/behaviours/sampler.gd b/behaviours/sampler.gd index 5ce7ce7..fb9ba27 100644 --- a/behaviours/sampler.gd +++ b/behaviours/sampler.gd @@ -9,17 +9,13 @@ class_name Sampler ## [Array] of [Node]s that can be [func sample]d by this [Sampler]. @export var possibilities: Array[Node] = [] -## If true, the [Sampler] will attempt to automatically detect the [field possibilities] on NOTIFICATION_READY. -@export var autodetect_possibilities_on_ready: bool = true +## If true, the [Sampler] will attempt to automatically [method sample_and_enable] on NOTIFICATION_READY. +@export var autoenable_on_ready: bool = true var selected: Node = null; -## Update [field possibilities] with the most likely subset of nodes. -func autodetect_possibilities(): - possibilities = get_children() - ## Get a reference. func sample() -> Node: Log.e(self, "Not implemented.") @@ -48,5 +44,5 @@ func get_all_refs() -> Array[Node]: func _ready() -> void: - if autodetect_possibilities_on_ready: - autodetect_possibilities() + if autoenable_on_ready: + sample_and_enable.call_deferred() diff --git a/behaviours/sampler_priority.gd b/behaviours/sampler_priority.gd index 5ea3e95..1f32196 100644 --- a/behaviours/sampler_priority.gd +++ b/behaviours/sampler_priority.gd @@ -2,13 +2,16 @@ extends Sampler class_name SamplerPriority +## If true, the [Sampler] will attempt to automatically detect the [field possibilities] on NOTIFICATION_READY. +@export var autodetect_possibilities_on_ready: bool = true + ## If true, the [SamplerPriority] will attempt to automatically setup the recommended signals for all the [field possibilities] on NOTIFICATION_READY. @export var autosetup_signals_on_ready: bool = true ## Update [field possibilities] with the most likely subset of nodes. func autodetect_possibilities() -> void: - possibilities = find_children("*", "Priority", true, false) + possibilities = get_parent().find_children("*", "Priority", true, false) ## Setup the recommended signals for each node in [field possibilities]. func autosetup_signals() -> void: @@ -41,11 +44,14 @@ func get_ref(node: Node) -> Node: return node.get_ref() -func _ready(): +func _ready() -> void: + super._ready() + if autodetect_possibilities_on_ready: + autodetect_possibilities() if autosetup_signals_on_ready: autosetup_signals() -func _autosetup_on_possibility_priority_changed(node: Priority, new: int, old: int): +func _autosetup_on_possibility_priority_changed(new: int, old: int, node: Priority): if node == selected: if new < old: sample_and_enable() diff --git a/entities/imp.tscn b/entities/imp.tscn index d761f73..161275e 100644 --- a/entities/imp.tscn +++ b/entities/imp.tscn @@ -120,7 +120,6 @@ debug_color = Color(1, 0, 0, 0) stream = ExtResource("19_7la6c") [connection signal="timeout" from="GoldSpawner/TimerStddev" to="GoldSpawner" method="spawn"] -[connection signal="ready" from="MovementSampler" to="MovementSampler" method="enable"] [connection signal="changed_direction" from="MovementWander" to="MovementWander/WanderPriority" method="priority_conditional"] [connection signal="move" from="MovementWander" to="." method="_on_move"] [connection signal="timeout" from="MovementWander/ChangeDirectionTimer" to="MovementWander" method="randomize_direction"] diff --git a/entities/sheep.tscn b/entities/sheep.tscn index c0cb53c..e4795f2 100644 --- a/entities/sheep.tscn +++ b/entities/sheep.tscn @@ -183,7 +183,6 @@ stream = ExtResource("16_nswfl") [node name="FallSound" type="AudioStreamPlayer2D" parent="MovementDrag"] stream = ExtResource("17_8kst2") -[connection signal="ready" from="MovementSampler" to="MovementSampler" method="enable"] [connection signal="move" from="MovementIdle" to="." method="_on_move"] [connection signal="move_disabled" from="MovementIdle" to="MovementIdle/BoredTimer" method="stop"] [connection signal="move_enabled" from="MovementIdle" to="MovementIdle/BoredTimer" method="start"] From 4241cd35413e5ef14e3923b1f027500ed30ce85a Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 23 Apr 2024 09:44:00 +0200 Subject: [PATCH 5/5] Remove semicolon --- behaviours/sampler.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/behaviours/sampler.gd b/behaviours/sampler.gd index fb9ba27..bd9dc66 100644 --- a/behaviours/sampler.gd +++ b/behaviours/sampler.gd @@ -13,7 +13,7 @@ class_name Sampler @export var autoenable_on_ready: bool = true -var selected: Node = null; +var selected: Node = null ## Get a reference.