108 lines
2.0 KiB
GDScript3
108 lines
2.0 KiB
GDScript3
|
|
extends RefCounted
|
||
|
|
|
||
|
|
class Promise:
|
||
|
|
enum State {
|
||
|
|
Waiting,
|
||
|
|
Success,
|
||
|
|
Failed
|
||
|
|
}
|
||
|
|
var result
|
||
|
|
|
||
|
|
signal completed
|
||
|
|
|
||
|
|
var _state: State = State.Waiting
|
||
|
|
|
||
|
|
func get_state() -> State:
|
||
|
|
return _state
|
||
|
|
|
||
|
|
func resolve(res = null):
|
||
|
|
if res is Promise:
|
||
|
|
await res.completed
|
||
|
|
result = res.result
|
||
|
|
_state = res.get_state()
|
||
|
|
emit_signal("completed")
|
||
|
|
else:
|
||
|
|
result = res
|
||
|
|
_state = State.Success
|
||
|
|
emit_signal("completed")
|
||
|
|
|
||
|
|
func reject(error = null):
|
||
|
|
result = error
|
||
|
|
_state = State.Failed
|
||
|
|
emit_signal("completed")
|
||
|
|
|
||
|
|
var data:get = get_data
|
||
|
|
func get_data():
|
||
|
|
if _state == State.Success:
|
||
|
|
return result
|
||
|
|
return null
|
||
|
|
|
||
|
|
var error:get = get_error
|
||
|
|
func get_error():
|
||
|
|
if _state == State.Failed:
|
||
|
|
return result
|
||
|
|
return null
|
||
|
|
|
||
|
|
var is_failed : bool :
|
||
|
|
get():
|
||
|
|
return _state == State.Failed
|
||
|
|
|
||
|
|
func wait():
|
||
|
|
if _state == State.Waiting:
|
||
|
|
await self.completed
|
||
|
|
return self
|
||
|
|
|
||
|
|
func _to_string():
|
||
|
|
match _state:
|
||
|
|
State.Waiting:
|
||
|
|
return "[Waiting]"
|
||
|
|
State.Success:
|
||
|
|
return str("[Success:",result,"]")
|
||
|
|
State.Failed:
|
||
|
|
return str("[Failed:",result,"]")
|
||
|
|
|
||
|
|
func _next(promise, callback: Callable, argv: Array):
|
||
|
|
await wait()
|
||
|
|
if _state == State.Success:
|
||
|
|
var arr = [get_data(), promise]
|
||
|
|
arr.append_array(argv)
|
||
|
|
var ret = await callback.callv(arr)
|
||
|
|
promise.resolve(ret)
|
||
|
|
|
||
|
|
func then(callback: Callable, argv: Array = []) -> Promise:
|
||
|
|
return RunPromise.new(Callable(self, "_next"), [callback, argv])
|
||
|
|
|
||
|
|
class FramePromise extends Promise:
|
||
|
|
var cb: Callable
|
||
|
|
var argv: Array
|
||
|
|
|
||
|
|
func _init(callback: Callable,argv: Array = []):
|
||
|
|
cb = callback
|
||
|
|
self.argv = argv
|
||
|
|
_run()
|
||
|
|
|
||
|
|
func _run():
|
||
|
|
var root = Engine.get_main_loop()
|
||
|
|
while true:
|
||
|
|
if root is SceneTree:
|
||
|
|
await root.process_frame
|
||
|
|
var arr = [self]
|
||
|
|
arr.append_array(argv)
|
||
|
|
cb.callv(arr)
|
||
|
|
if get_state() != State.Waiting:
|
||
|
|
break
|
||
|
|
|
||
|
|
class RunPromise extends Promise:
|
||
|
|
var cb: Callable
|
||
|
|
var argv: Array
|
||
|
|
|
||
|
|
func _init(callback: Callable,argv: Array = []):
|
||
|
|
cb = callback
|
||
|
|
self.argv = argv
|
||
|
|
_run()
|
||
|
|
|
||
|
|
func _run():
|
||
|
|
var arr = [self]
|
||
|
|
arr.append_array(argv)
|
||
|
|
await cb.callv(arr)
|