EvilCocoGame1/addons/reactivex/engine/scheduler/godotsignalscheduler.gd
2025-01-11 00:25:52 +01:00

214 lines
6.8 KiB
GDScript

extends GodotSignalSchedulerBase
class_name GodotSignalScheduler
const UTC_ZERO : float = Scheduler.UTC_ZERO
const DELTA_ZERO : float = Scheduler.DELTA_ZERO
func _init(verify_ = null):
if not verify_ == "GDRx":
push_warning("Warning! Must only instance Scheduler from GDRx singleton!")
static func singleton() -> GodotSignalScheduler:
return GDRx.GodotSignalScheduler_
## Represents a notion of time for this scheduler. Tasks being
## scheduled on a scheduler will adhere to the time denoted by this
## property.
## [br]
## [b]Returns:[/b]
## [br]
## The scheduler's current time, as a datetime instance.
func now() -> float:
return GDRx.basic.default_now()
## Invoke the given given action. This is typically called by instances
## of [ScheduledItem].
## [br]
## [b]Args:[/b]
## [br]
## [code]action[/code] Action to be executed.
## [br]
## [code]state[/code] [Optional] state to be given to the action function.
## [br][br]
## [b]Returns:[/b]
## [br]
## The disposable object returned by the action, if any; or a new
## (no-op) disposable otherwise.
func invoke_action(action : Callable, state = null) -> DisposableBase:
var ret = action.call(self, state)
if ret is DisposableBase:
return ret
return Disposable.new()
## Schedules an action to be executed when the [Signal] is emitted.
## [br]
## [b]Args:[/b]
## [br]
## [code]sig[/code] A Godot [Signal] instance to schedule.
## [br]
## [code]n_args[/code] Number of signal arguments. This is the same number
## of parameters for [code]action[/code].
## [br]
## [code]action[/code] Scheduled callback action for the signal. This is a
## function with [code]n_args[/code] parameters.
## [br]
## [code]state[/code] [Optional] state to be given to the action function.
## [br][br]
##
## [b]Returns:[/b]
## [br]
## The disposable object used to cancel the scheduled action.
func schedule_signal(
sig : Signal,
n_args : int,
action : Callable,
state = null
) -> DisposableBase:
var disp : Disposable = Disposable.new()
var signal_callback : Callable
match n_args:
0:
signal_callback = func():
var action_ = func(_scheduler : SchedulerBase, _state = null):
action.call()
disp = self.invoke_action(action_, state)
1:
signal_callback = func(arg1):
var action_ = func(_scheduler : SchedulerBase, _state = null):
action.call(arg1)
disp = self.invoke_action(action_, state)
2:
signal_callback = func(arg1, arg2):
var action_ = func(_scheduler : SchedulerBase, _state = null):
action.call(arg1, arg2)
disp = self.invoke_action(action_, state)
3:
signal_callback = func(arg1, arg2, arg3):
var action_ = func(_scheduler : SchedulerBase, _state = null):
action.call(arg1, arg2, arg3)
disp = self.invoke_action(action_, state)
4:
signal_callback = func(arg1, arg2, arg3, arg4):
var action_ = func(_scheduler : SchedulerBase, _state = null):
action.call(arg1, arg2, arg3, arg4)
disp = self.invoke_action(action_, state)
5:
signal_callback = func(arg1, arg2, arg3, arg4, arg5):
var action_ = func(_scheduler : SchedulerBase, _state = null):
action.call(arg1, arg2, arg3, arg4, arg5)
disp = self.invoke_action(action_, state)
6:
signal_callback = func(arg1, arg2, arg3, arg4, arg5, arg6):
var action_ = func(_scheduler : SchedulerBase, _state = null):
action.call(arg1, arg2, arg3, arg4, arg5, arg6)
disp = self.invoke_action(action_, state)
7:
signal_callback = func(arg1, arg2, arg3, arg4, arg5, arg6, arg7):
var action_ = func(_scheduler : SchedulerBase, _state = null):
action.call(arg1, arg2, arg3, arg4, arg5, arg6, arg7)
disp = self.invoke_action(action_, state)
8:
signal_callback = func(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8):
var action_ = func(_scheduler : SchedulerBase, _state = null):
action.call(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
disp = self.invoke_action(action_, state)
_:
GDRx.raise(TooManyArgumentsError.new(
"Only up to 8 signal parameters supported! Use lists instead!"))
return null
var obj = instance_from_id(sig.get_object_id())
var dispose = func():
if obj != null:
sig.disconnect(signal_callback)
sig.connect(signal_callback)
var cd : CompositeDisposable = CompositeDisposable.new([disp, Disposable.new(dispose)])
return cd
## Schedules an action to be executed.
## [br]
## [b]Args:[/b]
## [br]
## [code]action[/code] Action to be executed.
## [br]
## [code]state[/code] [Optional] state to be given to the action function.
## [br][br]
## [b]Returns:[/b]
## [br]
## The disposable object used to cancel the scheduled action
## (best effort).
func schedule(action : Callable, state = null) -> DisposableBase:
var sad : SingleAssignmentDisposable = SingleAssignmentDisposable.new()
var interval = func():
sad.disposable = self.invoke_action(action, state)
var timer : SceneTreeTimer = GDRx.get_tree().create_timer(0.0)
timer.connect("timeout", func(): interval.call() ; _cancel_timer(timer))
var dispose = func():
_cancel_timer(timer)
return CompositeDisposable.new([sad, Disposable.new(dispose)])
## Schedules an action to be executed after duetime.
## [br]
## [b]Args:[/b]
## [br]
## [code]duetime[/code] Relative time after which to execute the action.
## [br]
## [code]action[/code] Action to be executed.
## [br]
## [code]state[/code] [Optional] state to be given to the action function.
## [br][br]
##
## [b]Returns:[/b]
## [br]
## The disposable object used to cancel the scheduled action
## (best effort).
func schedule_relative(duetime, action : Callable, state = null) -> DisposableBase:
var seconds : float = duetime
if seconds <= 0.0:
return self.schedule(action, state)
var sad : SingleAssignmentDisposable = SingleAssignmentDisposable.new()
var interval = func():
sad.disposable = self.invoke_action(action, state)
var timer = GDRx.get_tree().create_timer(seconds)
timer.connect("timeout", func(): interval.call() ; _cancel_timer(timer))
var dispose = func():
_cancel_timer(timer)
return CompositeDisposable.new([sad, Disposable.new(dispose)])
## Schedules an action to be executed at duetime.
## [br]
## [b]Args:[/b]
## [br]
## [code]duetime[/code] Absolute time at which to execute the action.
## [br]
## [code]action[/code] Action to be executed.
## [br]
## [code]state[/code] [Optional] state to be given to the action function.
## [br][br]
##
## [b]Returns:[/b]
## [br]
## The disposable object used to cancel the scheduled action
## (best effort).
func schedule_absolute(duetime, action : Callable, state = null) -> DisposableBase:
return self.schedule_relative(duetime - self.now(), action, state)
## Utility function to cancel a timer
func _cancel_timer(timer : SceneTreeTimer):
for conn in timer.timeout.get_connections():
timer.timeout.disconnect(conn["callable"])