/
callbacks.dm
108 lines (93 loc) · 3.36 KB
/
callbacks.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/**
** Callbacks
Callbacks wrap a target, callable, and arguments to pass. See the dm reference for call().
When the target is GLOBAL_PROC, the callable is global - otherwise it is a datum (or dead) reference.
Callbacks are created with the new keyword via a global alias like:
- var/datum/callback/instance = new Callback(GLOBAL_PROC, /proc/get_area, someObject)
Callbacks are thin - they should be used with invoke or invoke_async.
** Invocation
invoke and invoke_async call a callable against a target with optional params. They accept either:
invoke(target, callable, params...)
or invoke(<callback>, extra params...)
and return the result of calling those. invoke_async does not wait for an outcome and will return (.)
on the first sleep, and so should be used only where results are not required.
** Callables
Callables are proc names or proc references, with references preferred for safety (in most cases).
These vary between 515 and older major versions:
Before 515:
- .proc/name refers to the last override of name on target, OR the global proc name.
After 515:
- src::name() must be used for the last override, or ::name() for the global.
- nameof() is available at compile time to resolve safe proc names like nameof(/datum::fooBehavior()).
This can be preferable to direct refs in complex cases.
A specific version of a proc may be called by fully specifying its type depth, like
invoke(myLivingMob, /mob/living/proc/handle_vision)
** Timers
Timers accept callbacks as their first argument. For full timer documentation, see the timedevent
datum. For example:
addTimer(new Callback(myMob, myMob::drop_l_hand()), 10 SECONDS)
*/
var/global/const/GLOBAL_PROC = FALSE
var/global/const/Callback = /datum/callback
/datum/callback
//var/const/Global = FALSE //515 - GLOBAL_PROC becomes Callback::Global
var/identity
var/datum/target = GLOBAL_PROC
var/callable
var/list/params
/datum/callback/Destroy()
target = null
callable = null
LAZYCLEARLIST(params)
return ..()
/datum/callback/New(datum/target, callable, ...)
src.target = target
src.callable = callable
if (length(args) > 2)
params = args.Copy(3)
switch (target)
if (null)
identity = "(null) [callable]"
if (FALSE)
identity = "(global) [callable]"
else
identity = "([target.type] \ref[target]) [callable]"
/proc/invoke(datum/callback/target, callable, ...)
if (target == GLOBAL_PROC)
var/list/params
if (length(args) > 2)
params = args.Copy(3)
return call(callable)(arglist(params))
else if (QDELETED(target))
return
else if (istype(target))
var/list/params = list(target.target, target.callable)
if (LAZYLEN(target.params))
params += target.params
if (length(args) > 1)
params += args.Copy(2)
return invoke(arglist(params))
else
var/list/params
if (length(args) > 2)
params = args.Copy(3)
return call(target, callable)(arglist(params))
/proc/invoke_async(datum/callback/target, callable, ...)
set waitfor = FALSE
if (target == GLOBAL_PROC)
var/list/params
if (length(args) > 2)
params = args.Copy(3)
return call(callable)(arglist(params))
else if (QDELETED(target))
return
else if (istype(target))
var/list/params = list(target.target, target.callable) + target.params
if (length(args) > 1)
params += args.Copy(2)
return invoke(arglist(params))
else
var/list/params
if (length(args) > 2)
params = args.Copy(3)
return call(target, callable)(arglist(params))