78 lines
2.4 KiB
GDScript3
78 lines
2.4 KiB
GDScript3
|
|
## Generates an observable sequence by iterating a state from an
|
||
|
|
## initial state until the condition fails.
|
||
|
|
## [br]
|
||
|
|
## [b]Example:[/b]
|
||
|
|
## [codeblock]
|
||
|
|
## var res = GDRx.obs.generate_with_relative_time(
|
||
|
|
## 0, func(x): return true, func(x): return x + 1, func(x): return 0.5
|
||
|
|
## )
|
||
|
|
## [/codeblock]
|
||
|
|
## [br]
|
||
|
|
## [b]Args:[/b]
|
||
|
|
## [br]
|
||
|
|
## [code]initial_state[/code] Initial state.
|
||
|
|
## [br]
|
||
|
|
## [code]condition[/code] Condition to terminate generation (upon returning
|
||
|
|
## false).
|
||
|
|
## [br]
|
||
|
|
## [code]iterate[/code] Iteration step function.
|
||
|
|
## [br]
|
||
|
|
## [code]time_mapper[/code] Time mapper function to control the speed of
|
||
|
|
## values being produced each iteration, returning relative
|
||
|
|
## times, i.e. either floats denoting seconds or instances of
|
||
|
|
## timedelta.
|
||
|
|
## [br][br]
|
||
|
|
## [b]Returns:[/b]
|
||
|
|
## [br]
|
||
|
|
## The generated sequence.
|
||
|
|
static func generate_with_relative_time_(
|
||
|
|
initial_state,
|
||
|
|
condition : Callable = GDRx.basic.default_condition,
|
||
|
|
iterate : Callable = GDRx.basic.identity,
|
||
|
|
time_mapper : Callable = func(_state) -> float: return 1.0
|
||
|
|
) -> Observable:
|
||
|
|
|
||
|
|
var subscribe = func(
|
||
|
|
observer : ObserverBase,
|
||
|
|
scheduler : SchedulerBase = null
|
||
|
|
) -> DisposableBase:
|
||
|
|
var _scheduler : SchedulerBase = scheduler if scheduler != null else SceneTreeTimeoutScheduler.singleton()
|
||
|
|
var mad = MultipleAssignmentDisposable.new()
|
||
|
|
var state = RefValue.Set(initial_state)
|
||
|
|
var has_result = RefValue.Set(false)
|
||
|
|
var result = RefValue.Null()
|
||
|
|
var first = RefValue.Set(true)
|
||
|
|
var time = RefValue.Null()
|
||
|
|
|
||
|
|
var action = func(scheduler : SchedulerBase, __, action_ : Callable):
|
||
|
|
if has_result.v:
|
||
|
|
observer.on_next(result.v)
|
||
|
|
|
||
|
|
if GDRx.try(func():
|
||
|
|
if first.v:
|
||
|
|
first.v = false
|
||
|
|
else:
|
||
|
|
state.v = iterate.call(state.v)
|
||
|
|
|
||
|
|
has_result.v = condition.call(state.v)
|
||
|
|
|
||
|
|
if has_result.v:
|
||
|
|
result.v = state.v
|
||
|
|
time.v = time_mapper.call(state.v)
|
||
|
|
) \
|
||
|
|
.catch("Error", func(e):
|
||
|
|
observer.on_error(e)
|
||
|
|
) \
|
||
|
|
.end_try_catch(): return
|
||
|
|
|
||
|
|
if has_result.v:
|
||
|
|
if GDRx.assert_(time.v != null): return
|
||
|
|
mad.disposable = scheduler.scheduler_relative(time.v, action_.bind(action_))
|
||
|
|
else:
|
||
|
|
observer.on_completed()
|
||
|
|
|
||
|
|
mad.disposable = _scheduler.schedule_relative(0, action.bind(action))
|
||
|
|
return mad
|
||
|
|
|
||
|
|
return Observable.new(subscribe)
|