forked from NebulaSS13/Nebula
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmachinery_public_vars.dm
More file actions
140 lines (118 loc) · 4.37 KB
/
Copy pathmachinery_public_vars.dm
File metadata and controls
140 lines (118 loc) · 4.37 KB
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/decl/public_access
var/name
var/desc
/decl/public_access/public_variable
var/expected_type
var/can_write = FALSE
var/var_type = VAR_FORMAT_BOOLEAN // Reuses IC defines for better compatibility.
var/has_updates = FALSE // Can register listeners for updates on change.
var/list/listeners = list()
/*
Must be implemented by subtypes.
*/
// Reads off the var value and returns it
/decl/public_access/public_variable/proc/access_var(datum/owner)
// Writes to the var. Returns true if change occurred, false otherwise.
// Subtypes shall call parent, and perform the actual write if the return value is true.
// If the var has_updates, you must never modify the var except through this proc.
/decl/public_access/public_variable/proc/write_var(datum/owner, new_value)
if(!check_input_type(new_value))
return FALSE
var/old_value = access_var(owner)
if(old_value == new_value)
return FALSE
if(has_updates)
var_changed(owner, old_value, new_value)
return TRUE
// Any sanitization should be done in here.
/decl/public_access/public_variable/proc/write_var_protected(datum/owner, new_value)
if(!can_write)
return FALSE
return write_var(owner, new_value)
// Checks the input type of the passed value without modification.
/decl/public_access/public_variable/proc/check_input_type(new_value)
. = FALSE
switch(var_type)
if(VAR_FORMAT_ANY)
return TRUE
if(VAR_FORMAT_STRING)
return istext(new_value)
if(VAR_FORMAT_CHAR)
return istext(new_value) && length(new_value) == 1
if(VAR_FORMAT_COLOR)
return sanitize_hexcolor(new_value, null) == new_value
if(VAR_FORMAT_NUMBER)
return isnum(new_value)
if(VAR_FORMAT_DIR)
return new_value in global.alldirs
if(VAR_FORMAT_BOOLEAN)
return new_value == !!new_value
if(VAR_FORMAT_REF)
return isweakref(new_value)
// Public variables of these types need to against the contents of the list and the index for validity themselves.
if(VAR_FORMAT_LIST)
return islist(new_value)
if(VAR_FORMAT_INDEX)
return isnum(new_value)
/*
Listener registration. You must unregister yourself if you are destroyed; the owner being destroyed will be handled automatically.
*/
/decl/public_access/public_variable/proc/register_listener(datum/listener, datum/owner, registered_proc)
. = FALSE
if(!istype(owner, expected_type))
CRASH("[log_info_line(listener)] attempted to register for the public variable [type], but passed an invalid owner of type [owner.type].")
if(!has_updates)
return // Can try and register, but updates aren't coming
if(!listeners[owner])
listeners[owner] = list()
events_repository.register(/decl/observ/destroyed, owner, src, PROC_REF(owner_destroyed))
LAZYADD(listeners[owner][listener], registered_proc)
return TRUE
/decl/public_access/public_variable/proc/unregister_listener(datum/listener, datum/owner, registered_proc)
if(!listeners[owner])
return
if(!listeners[owner][listener])
return
if(registered_proc) // Remove the proc and remove the listener if no more procs
listeners[owner][listener] -= registered_proc
if(!length(listeners[owner][listener]))
listeners[owner] -= listener
else // Remove the listener
listeners[owner] -= listener
if(!length(listeners[owner])) // Clean up the list if no longer listening to anything.
listeners -= owner
events_repository.unregister(/decl/observ/destroyed, owner, src)
/*
Internal procs. Do not modify.
*/
/decl/public_access/public_variable/proc/owner_destroyed(datum/owner)
events_repository.unregister(/decl/observ/destroyed, owner, src)
listeners -= owner
/decl/public_access/public_variable/proc/var_changed(owner, old_value, new_value)
var/list/to_alert = listeners[owner]
for(var/thing in to_alert)
for(var/call_proc in to_alert[thing])
call(thing, call_proc)(src, owner, old_value, new_value)
/*
Public methods machines can expose. Pretty bare-bones; just wraps a proc and gives it a name for UI purposes.
*/
/decl/public_access/public_method
var/call_proc
var/forward_args = FALSE
/decl/public_access/public_method/proc/perform(datum/owner, ...)
if(forward_args)
return call(owner, call_proc)(arglist(args.Copy(2)))
else
return call(owner, call_proc)()
/*
Machinery implementation
*/
/obj/machinery
var/list/public_variables
var/list/public_methods
/obj/machinery/Initialize()
for(var/path in public_variables)
public_variables[path] = GET_DECL(path)
for(var/path in public_methods)
public_methods[path] = GET_DECL(path)
. = ..()