From e972a90ba98ee2bfa979674763f8d276d12ecb3b Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 13 Aug 2017 01:27:51 -0500 Subject: [PATCH] Adds callback select system --- code/datums/callback.dm | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/code/datums/callback.dm b/code/datums/callback.dm index 1b5c25fe18..624fed58a6 100644 --- a/code/datums/callback.dm +++ b/code/datums/callback.dm @@ -100,3 +100,57 @@ if (object == GLOBAL_PROC) return call(delegate)(arglist(calling_arguments)) return call(object, delegate)(arglist(calling_arguments)) + + +/datum/callback_select + var/list/finished + var/pendingcount + var/total + +/datum/callback_select/New(count, savereturns) + total = count + if (savereturns) + finished = new(count) + + +/datum/callback_select/proc/invoke_callback(index, datum/callback/callback, list/callback_args, savereturn = TRUE) + set waitfor = FALSE + if (!callback || !istype(callback)) + //This check only exists because the alternative is callback_select would block forever if given invalid data + CRASH("invalid callback passed to invoke_callback") + if (!length(callback_args)) + callback_args = list() + pendingcount++ + var/rtn = callback.Invoke(arglist(callback_args)) + pendingcount-- + if (savereturn) + finished[index] = rtn + + + + +//runs a list of callbacks asynchronously, returning once all of them return. +//callbacks can be repeated. +//callbacks-args is a optional list of argument lists, in the same order as the callbacks, +// the inner lists will be sent to the callbacks when invoked() as additional args. +//can optionly save and return a list of return values, in the same order as the original list of callbacks +//resolution is the number of byond ticks between checks. +/proc/callback_select(list/callbacks, list/callback_args, savereturns = TRUE, resolution = 1) + if (!callbacks) + return + var/count = length(callbacks) + if (!count) + return + if (!callback_args) + callback_args = list() + + callback_args.len = count + + var/datum/callback_select/CS = new(count, savereturns) + for (var/i in 1 to count) + CS.invoke_callback(i, callbacks[i], callback_args[i], savereturns) + + while(CS.pendingcount) + sleep(resolution*world.tick_lag) + return CS.finished +