-
Notifications
You must be signed in to change notification settings - Fork 0
/
scr_witchcraft_chanel.gml
94 lines (88 loc) · 2.39 KB
/
scr_witchcraft_chanel.gml
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
//! A micro-library for handling the publish-subscribe pattern.
//!
//! No it isn't a typo, that's her name.
//# feather use syntax-errors
/// @ignore
///
/// @return {Id.DsMap}
function __wchanel_info() {
static info = ds_map_create();
return info;
}
/// @ignore
///
/// @param {Any} chanName
/// @return {Any}
function __wchanel_sanitise_channel_name(chanName) {
gml_pragma("forceinline");
if (is_nan(chanName)) {
return "NaN";
}
return chanName;
}
/// Subscribe to a channel to get notified when updates happen. Returns the
/// unique ID of this subscription to be used with `wchanel_unsubscribe`.
///
/// @param {Any} chanName
/// The channel name or id to subscribe to.
///
/// @param {Function} onUpdate
/// The function to call when this channel receives an update.
///
/// @return {Real}
function wchanel_subscribe(chanName, onUpdate) {
var info = __wchanel_info();
chanName = __wchanel_sanitise_channel_name(chanName);
if (!ds_map_exists(info, chanName)) {
info[? chanName] = {
lastUpdate : undefined,
hasUpdate : false,
subscribers : [],
};
}
var chan = info[? chanName];
var subId = array_length(chan.subscribers);
array_push(chan.subscribers, onUpdate);
if (chan.hasUpdate) {
onUpdate(chan.lastUpdate);
}
return subId;
}
/// Unsubscribe from a channel.
///
/// @param {Any} chanName
/// The channel name or id to unsubscribe from.
///
/// @param {Real} subId
/// The ID of the subscription to cancel.
function wchanel_unsubscribe(chanName, subId) {
var info = __wchanel_info();
chanName = __wchanel_sanitise_channel_name(chanName);
if (!ds_map_exists(info, chanName)) {
return;
}
var chan = info[? chanName];
array_delete(chan.subscribers, subId, 1);
}
/// Publish an update to a channel.
///
/// @param {Any} chanName
/// The channel name or id to publish to.
///
/// @param {Any} value
/// The value to publish.
function wchanel_publish(chanName, value) {
var info = __wchanel_info();
chanName = __wchanel_sanitise_channel_name(chanName);
if (!ds_map_exists(info, chanName)) {
return;
}
var chan = info[? chanName];
chan.hasUpdate = true;
chan.lastUpdate = value;
var subs = chan.subscribers;
for (var i = array_length(subs) - 1; i >= 0; i -= 1) {
var onUpdate = subs[i];
onUpdate(value);
}
}