Skip to content

Instantly share code, notes, and snippets.

@Capital-EX
Created June 10, 2024 01:03
Show Gist options
  • Save Capital-EX/021a77e630e3cb49adef961fefd11337 to your computer and use it in GitHub Desktop.
Save Capital-EX/021a77e630e3cb49adef961fefd11337 to your computer and use it in GitHub Desktop.
extends Node
var _routing = {}
func listen_for(listener: String, message: String, callback: FuncRef, once = false) -> void:
if message in _routing:
_routing[message][listener] = { callback = callback, once = once }
else:
_routing[message] = {listener: { callback = callback, once = once }}
func await_for(listener: String, message: String):
listen_for(listener, message, null, true)
return yield(Sleeper.wait("%s/%s" % [listener, message]), "completed")
func cast(listener: String, message: String, data: Dictionary = {}) -> void:
prints(listener, message)
if message in _routing:
var router: Dictionary = _routing[message]
if listener in router:
_try_call(router, message, listener, data)
func broadcast(message: String, data: Dictionary = {}) -> void:
if message in _routing:
var router: Dictionary = _routing[message]
for listener in router.keys():
_try_call(router, message, listener, data)
func randomcast(message: String, data: Dictionary = {}) -> void:
if message in _routing:
var routes := _routing[message] as Dictionary
var route_list := routes.keys()
var listener := route_list[randi() % len(route_list)] as String
_try_call(routes, message, listener, data)
func _try_call(router: Dictionary, message: String, listener: String, data: Dictionary):
var actor: Dictionary = router[listener]
var callback: FuncRef = actor.callback
var once: bool = actor.once
data.msg = { message = message, listener = listener }
if callback and callback.is_valid():
callback.call_func(data)
if once:
router.erase(listener) # warning-ignore:return_value_discarded
else:
router.erase(listener) # warning-ignore:return_value_discarded
Sleeper.notify("%s/%s" % [listener, message], data)
extends Node
class CoroutineLock:
extends Reference
signal unlocked(data)
func unlock(data = null):
emit_signal("unlocked", data)
const _wait_locks = {}
const _action_locks = {}
func wait(name: String) -> void:
if not name in _wait_locks:
_wait_locks[name] = CoroutineLock.new()
return yield(_wait_locks[name], "unlocked")
func wait_action(action: String) -> void:
assert(InputMap.has_action(action), "Action %s does not exist in InputMap. Lock will never release." % action)
if not action in _action_locks:
_action_locks[action] = CoroutineLock.new()
yield(_action_locks[action], "unlocked")
func wait_time(time: float) -> void:
yield(get_tree().create_timer(time), "timeout")
func notify(who: String, data = null) -> void:
_notify(who, _wait_locks, data)
func _input(event: InputEvent) -> void:
for action in _action_locks:
if event.is_action_released(action) and not event.is_echo():
_notify(action, _action_locks)
func _notify(who: String, locks = _wait_locks, data = null) -> void:
if who in locks:
locks[who].unlock(data)
locks.erase(who)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment