@nativewrappers/common 0.0.57 → 0.0.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/GlobalData.d.ts +1 -0
- package/GlobalData.js +1 -0
- package/net/NetworkedMap.d.ts +4 -1
- package/net/NetworkedMap.js +69 -17
- package/package.json +1 -1
package/GlobalData.d.ts
CHANGED
package/GlobalData.js
CHANGED
package/net/NetworkedMap.d.ts
CHANGED
|
@@ -5,10 +5,13 @@ type ChangeListener<V> = (value: V) => void;
|
|
|
5
5
|
export declare class NetworkedMap<K, V> extends Map<K, V> {
|
|
6
6
|
#private;
|
|
7
7
|
constructor(syncName: string, initialValue?: [K, V][]);
|
|
8
|
+
get SyncName(): string;
|
|
8
9
|
private onPlayerDropped;
|
|
9
|
-
|
|
10
|
+
resync(source: number): void;
|
|
11
|
+
addSubscriber(source: number): void;
|
|
10
12
|
removeSubscriber(sub: number): boolean;
|
|
11
13
|
hasSubscriber(sub: number): boolean;
|
|
14
|
+
private handleSync;
|
|
12
15
|
listenForChange(key: K, fn: ChangeListener<V>): void;
|
|
13
16
|
set(key: K, value: V): this;
|
|
14
17
|
clear(): void;
|
package/net/NetworkedMap.js
CHANGED
|
@@ -12,6 +12,48 @@ var MapChangeType;
|
|
|
12
12
|
// Whenever they're subscribed initially and get the initial load of data
|
|
13
13
|
MapChangeType[MapChangeType["Init"] = 4] = "Init";
|
|
14
14
|
})(MapChangeType || (MapChangeType = {}));
|
|
15
|
+
// Used to not make a bunch of on/raw events, we just reuse the same one and look up the data in the map
|
|
16
|
+
class NetworkedMapEventManager {
|
|
17
|
+
#syncedCalls = new Map();
|
|
18
|
+
#playerDropped = new Map();
|
|
19
|
+
constructor() {
|
|
20
|
+
SERVER: if (GlobalData.IS_SERVER) {
|
|
21
|
+
on("playerDropped", () => {
|
|
22
|
+
// call the player dropped for each call
|
|
23
|
+
for (const [_k, fn] of this.#playerDropped) {
|
|
24
|
+
fn();
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
CLIENT: {
|
|
30
|
+
RegisterResourceAsEventHandler(`${GlobalData.CurrentResource}:syncChanges`);
|
|
31
|
+
addRawEventListener(`${GlobalData.CurrentResource}:syncChanges`, (msgpack_data) => {
|
|
32
|
+
const data = msgpack_unpack(msgpack_data);
|
|
33
|
+
const syncName = data[0];
|
|
34
|
+
const syncData = data[1];
|
|
35
|
+
const map = this.#syncedCalls.get(syncName);
|
|
36
|
+
if (!map) {
|
|
37
|
+
throw new Error(`Tried to sync changes for a networked map but ${syncName} does't exist.`);
|
|
38
|
+
}
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
map.handleSync(syncData);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
addNetworkedMap(map) {
|
|
45
|
+
// abuse typescript, we don't want the end user to use these calls but we still want it to be accessible internally.
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
this.#syncedCalls.set(map.SyncName, map);
|
|
48
|
+
// @ts-ignore
|
|
49
|
+
this.#playerDropped.set(map.SyncName, map.onPlayerDropped);
|
|
50
|
+
}
|
|
51
|
+
removeNetworkedMap(syncName) {
|
|
52
|
+
this.#syncedCalls.delete(syncName);
|
|
53
|
+
this.#playerDropped.delete(syncName);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const netManager = new NetworkedMapEventManager();
|
|
15
57
|
/**
|
|
16
58
|
* not ready to be used just thoughts right now
|
|
17
59
|
*/
|
|
@@ -24,7 +66,7 @@ export class NetworkedMap extends Map {
|
|
|
24
66
|
super(initialValue);
|
|
25
67
|
this.#syncName = syncName;
|
|
26
68
|
GlobalData.NetworkedTicks.push(this);
|
|
27
|
-
|
|
69
|
+
netManager.addNetworkedMap(this);
|
|
28
70
|
// if we don't have a network tick then we want to register it.
|
|
29
71
|
SERVER: {
|
|
30
72
|
if (!GlobalData.NetworkTick && GlobalData.IS_SERVER) {
|
|
@@ -35,26 +77,32 @@ export class NetworkedMap extends Map {
|
|
|
35
77
|
});
|
|
36
78
|
}
|
|
37
79
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
RegisterResourceAsEventHandler(`${this.#syncName}:syncChanges`);
|
|
42
|
-
addRawEventListener(`${this.#syncName}:syncChanges`, (data) => this.#handleSync(data));
|
|
43
|
-
}
|
|
80
|
+
}
|
|
81
|
+
get SyncName() {
|
|
82
|
+
return this.#syncName;
|
|
44
83
|
}
|
|
45
84
|
// handles removing the player from the map whenever they're dropped
|
|
46
85
|
onPlayerDropped() {
|
|
47
86
|
this.removeSubscriber(source);
|
|
48
87
|
}
|
|
49
88
|
/*
|
|
50
|
-
*
|
|
89
|
+
* Resyncs the entire map to the client, useful for if there's a mismatch in the clients map (when multiple players change things, in cases like inventories)
|
|
90
|
+
*
|
|
91
|
+
* NOTE: This doesn't check that the player is already subscribed to the map, you should do your own due-diligence to only call this for players already subscribed
|
|
51
92
|
*/
|
|
52
|
-
|
|
53
|
-
this.#subscribers.add(sub);
|
|
93
|
+
resync(source) {
|
|
54
94
|
const packed_data = msgpack_pack([
|
|
55
|
-
|
|
95
|
+
this.#syncName,
|
|
96
|
+
[[MapChangeType.Init, this.size === 0 ? [] : Array.from(this)]],
|
|
56
97
|
]);
|
|
57
|
-
TriggerClientEventInternal(`${
|
|
98
|
+
TriggerClientEventInternal(`${GlobalData.CurrentResource}:syncChanges`, source, packed_data, packed_data.length);
|
|
99
|
+
}
|
|
100
|
+
/*
|
|
101
|
+
* Adds a new subscriber to the map
|
|
102
|
+
*/
|
|
103
|
+
addSubscriber(source) {
|
|
104
|
+
this.#subscribers.add(source);
|
|
105
|
+
this.resync(source);
|
|
58
106
|
}
|
|
59
107
|
removeSubscriber(sub) {
|
|
60
108
|
return this.#subscribers.delete(sub);
|
|
@@ -62,8 +110,7 @@ export class NetworkedMap extends Map {
|
|
|
62
110
|
hasSubscriber(sub) {
|
|
63
111
|
return this.#subscribers.has(sub);
|
|
64
112
|
}
|
|
65
|
-
|
|
66
|
-
const data = msgpack_unpack(msgpack_data);
|
|
113
|
+
handleSync(data) {
|
|
67
114
|
for (const [change_type, key, value, possibly_undefined_subvalue] of data) {
|
|
68
115
|
switch (change_type) {
|
|
69
116
|
case MapChangeType.Add: {
|
|
@@ -79,6 +126,8 @@ export class NetworkedMap extends Map {
|
|
|
79
126
|
continue;
|
|
80
127
|
}
|
|
81
128
|
case MapChangeType.Init: {
|
|
129
|
+
// We also use this for whenever we want to resync a table
|
|
130
|
+
super.clear();
|
|
82
131
|
const key_value = key;
|
|
83
132
|
for (const [k, v] of key_value) {
|
|
84
133
|
this.set(k, v);
|
|
@@ -103,9 +152,9 @@ export class NetworkedMap extends Map {
|
|
|
103
152
|
listener ? listener.push(fn) : this.#changeListeners.set(key, [fn]);
|
|
104
153
|
}
|
|
105
154
|
#triggerEventForSubscribers(data) {
|
|
106
|
-
const packed_data = msgpack_pack(data);
|
|
155
|
+
const packed_data = msgpack_pack([this.#syncName, data]);
|
|
107
156
|
for (const sub of this.#subscribers) {
|
|
108
|
-
TriggerClientEventInternal(`${
|
|
157
|
+
TriggerClientEventInternal(`${GlobalData.CurrentResource}:syncChanges`, sub, packed_data, packed_data.length);
|
|
109
158
|
}
|
|
110
159
|
}
|
|
111
160
|
#pushChangeForListener(key, value) {
|
|
@@ -153,6 +202,9 @@ export class NetworkedMap extends Map {
|
|
|
153
202
|
}
|
|
154
203
|
return this;
|
|
155
204
|
}
|
|
205
|
+
/*
|
|
206
|
+
* Resets the map to its default state
|
|
207
|
+
*/
|
|
156
208
|
clear() {
|
|
157
209
|
CLIENT: throw new Error(`Cannot call 'clear' on client`);
|
|
158
210
|
// if we're clearing our map then we want to remove all queued changes and
|
|
@@ -173,10 +225,10 @@ export class NetworkedMap extends Map {
|
|
|
173
225
|
}
|
|
174
226
|
}
|
|
175
227
|
[Symbol.dispose]() {
|
|
176
|
-
removeEventListener("playerDropped", this.onPlayerDropped);
|
|
177
228
|
this.#subscribers.clear();
|
|
178
229
|
this.#changeListeners.clear();
|
|
179
230
|
this.#queuedChanges = [];
|
|
231
|
+
netManager.removeNetworkedMap(this.#syncName);
|
|
180
232
|
GlobalData.NetworkedTicks.filter((v) => v !== this);
|
|
181
233
|
}
|
|
182
234
|
/**
|