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

Optional time slicing system #358

Open
wants to merge 3 commits into
base: godot-4.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
15 changes: 14 additions & 1 deletion addons/beehave/nodes/beehave_tree.gd
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ signal tree_disabled
## tick() runs every frame.
@export var tick_rate: int = 1

## If the tree should opt into time slicing. If enabled, the tree will not
## execute it's own ticks directly. It will instead push its ticks
## to a global queue where they will be executed as resources allow
@export var time_slice : bool = false

## An optional node path this behavior tree should apply to.
@export_node_path var actor_node_path: NodePath:
set(anp):
Expand Down Expand Up @@ -97,6 +102,8 @@ signal tree_disabled
var status: int = -1
var last_tick: int = 0

var tick_queued : bool = false

var _internal_blackboard: Blackboard
var _process_time_metric_name: String
var _process_time_metric_value: float = 0.0
Expand Down Expand Up @@ -192,7 +199,11 @@ func _process_internally() -> void:
BeehaveDebuggerMessages.process_begin(get_instance_id())

if self.get_child_count() == 1:
tick()
if not time_slice:
tick()
elif not tick_queued:
BeehaveTimeSlicer.tick_queue.push_back(Callable(self, "tick"))
tick_queued = true

if _can_send_message:
BeehaveDebuggerMessages.process_end(get_instance_id())
Expand All @@ -202,6 +213,8 @@ func _process_internally() -> void:


func tick() -> int:
tick_queued = false

if actor == null or get_child_count() == 0:
return FAILURE
var child := self.get_child(0)
Expand Down
4 changes: 4 additions & 0 deletions addons/beehave/plugin.gd
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ func _init():
name = "BeehavePlugin"
add_autoload_singleton("BeehaveGlobalMetrics", "metrics/beehave_global_metrics.gd")
add_autoload_singleton("BeehaveGlobalDebugger", "debug/global_debugger.gd")
add_autoload_singleton("BeehaveTimeSlicer", "time_slicer/beehave_time_slicer.gd")
print("Beehave initialized!")


Expand All @@ -24,3 +25,6 @@ func _enter_tree() -> void:

func _exit_tree() -> void:
remove_debugger_plugin(editor_debugger)
remove_autoload_singleton("BeehaveGlobalMetrics")
remove_autoload_singleton("BeehaveGlobalDebugger")
remove_autoload_singleton("BeehaveTimeSlicer")
12 changes: 12 additions & 0 deletions addons/beehave/time_slicer/beehave_time_slicer.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
extends Node

var tick_queue : Array[Callable] = []
var max_ticks_per_frame : int = 100

func _physics_process(delta: float) -> void:
var ticks_done : int = 0
while ticks_done < max_ticks_per_frame and tick_queue.size() != 0:
var tick : Callable = tick_queue.pop_front()
if is_instance_valid(tick.get_object()):
tick.call()
ticks_done += 1