@dcl/sdk 7.0.0-3548419522.commit-ddcf4b7 → 7.0.0
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/ecs.d.ts +1 -0
- package/ecs.js +2 -0
- package/index.d.ts +1 -0
- package/index.js +11 -0
- package/internal/Observable.d.ts +36 -0
- package/internal/Observable.js +190 -0
- package/internal/transports/networkTransport.d.ts +2 -0
- package/internal/transports/networkTransport.js +16 -0
- package/internal/transports/rendererTransport.d.ts +7 -0
- package/internal/transports/rendererTransport.js +39 -0
- package/math.d.ts +3 -0
- package/math.js +4 -0
- package/messageBus.d.ts +10 -0
- package/messageBus.js +43 -0
- package/observables.d.ts +225 -0
- package/observables.js +75 -0
- package/package.json +12 -18
- package/react-ecs.d.ts +3 -0
- package/react-ecs.js +4 -0
- package/src/ecs.ts +1 -0
- package/src/index.ts +18 -0
- package/src/internal/Observable.ts +425 -0
- package/src/internal/transports/networkTransport.ts +24 -0
- package/src/internal/transports/rendererTransport.ts +60 -0
- package/src/math.ts +3 -0
- package/src/messageBus.ts +62 -0
- package/src/observables.ts +579 -0
- package/src/react-ecs.ts +3 -0
- package/tsconfig.json +11 -0
- package/types/tsconfig.ecs7.json +3 -8
- package/dist/ecs7/index.d.ts +0 -4679
- package/dist/ecs7/index.js +0 -15202
- package/dist/ecs7/index.min.js +0 -1
- package/dist/ecs7/index.min.js.map +0 -1
- package/dist/ecs7/proto-definitions/README.md +0 -32
- package/dist/ecs7/proto-definitions/Transform.md +0 -25
- package/dist/ecs7/proto-definitions/animator.proto +0 -19
- package/dist/ecs7/proto-definitions/audio_source.proto +0 -13
- package/dist/ecs7/proto-definitions/audio_stream.proto +0 -11
- package/dist/ecs7/proto-definitions/avatar_attach.proto +0 -19
- package/dist/ecs7/proto-definitions/avatar_modifier_area.proto +0 -19
- package/dist/ecs7/proto-definitions/avatar_shape.proto +0 -32
- package/dist/ecs7/proto-definitions/billboard.proto +0 -17
- package/dist/ecs7/proto-definitions/camera_mode.proto +0 -10
- package/dist/ecs7/proto-definitions/camera_mode_area.proto +0 -14
- package/dist/ecs7/proto-definitions/common/camera_type.proto +0 -8
- package/dist/ecs7/proto-definitions/common/id.md +0 -2
- package/dist/ecs7/proto-definitions/common/id.proto +0 -8
- package/dist/ecs7/proto-definitions/common/input_action.proto +0 -20
- package/dist/ecs7/proto-definitions/common/texts.proto +0 -20
- package/dist/ecs7/proto-definitions/gltf_container.proto +0 -13
- package/dist/ecs7/proto-definitions/material.proto +0 -56
- package/dist/ecs7/proto-definitions/mesh_collider.proto +0 -35
- package/dist/ecs7/proto-definitions/mesh_renderer.proto +0 -30
- package/dist/ecs7/proto-definitions/nft_shape.proto +0 -40
- package/dist/ecs7/proto-definitions/pointer_events_result.proto +0 -25
- package/dist/ecs7/proto-definitions/pointer_hover_feedback.proto +0 -31
- package/dist/ecs7/proto-definitions/pointer_lock.proto +0 -9
- package/dist/ecs7/proto-definitions/raycast.proto +0 -20
- package/dist/ecs7/proto-definitions/raycast_result.proto +0 -25
- package/dist/ecs7/proto-definitions/text_shape.proto +0 -33
- package/dist/ecs7/proto-definitions/ui_background.proto +0 -11
- package/dist/ecs7/proto-definitions/ui_text.proto +0 -17
- package/dist/ecs7/proto-definitions/ui_transform.proto +0 -141
- package/dist/ecs7/proto-definitions/visibility_component.proto +0 -9
- package/dist/playground/snippets/billboard.ts +0 -108
- package/dist/playground/snippets/cube-spawner.ts +0 -39
- package/dist/playground/snippets/info.json +0 -1
- package/dist/playground/snippets/material.ts +0 -48
- package/dist/playground/snippets/mesh.ts +0 -68
- package/dist/playground/snippets/pointer-events.ts +0 -50
- package/dist/playground/snippets/raycast-hit-many.ts +0 -63
- package/dist/playground/snippets/raycast-hit.ts +0 -62
- package/dist/playground/snippets/ui.tsx +0 -134
- package/types/ecs7/index.d.ts +0 -4679
@@ -0,0 +1,425 @@
|
|
1
|
+
/**
|
2
|
+
* A class serves as a medium between the observable and its observers
|
3
|
+
* @deprecated This function is an inheritance of ECS6, it's here temporary for the feature parity, please read the news and docs to know how handle when it's removed
|
4
|
+
*/
|
5
|
+
export class ObserverEventState {
|
6
|
+
/**
|
7
|
+
* An Observer can set this property to true to prevent subsequent observers of being notified
|
8
|
+
*/
|
9
|
+
public skipNextObservers!: boolean
|
10
|
+
|
11
|
+
/**
|
12
|
+
* Get the mask value that were used to trigger the event corresponding to this EventState object
|
13
|
+
*/
|
14
|
+
public mask!: number
|
15
|
+
|
16
|
+
/**
|
17
|
+
* The object that originally notified the event
|
18
|
+
*/
|
19
|
+
public target?: any
|
20
|
+
|
21
|
+
/**
|
22
|
+
* The current object in the bubbling phase
|
23
|
+
*/
|
24
|
+
public currentTarget?: any
|
25
|
+
|
26
|
+
/**
|
27
|
+
* This will be populated with the return value of the last function that was executed.
|
28
|
+
* If it is the first function in the callback chain it will be the event data.
|
29
|
+
*/
|
30
|
+
public lastReturnValue?: any
|
31
|
+
|
32
|
+
/**
|
33
|
+
* Create a new EventState
|
34
|
+
* @param mask - defines the mask associated with this state
|
35
|
+
* @param skipNextObservers - defines a flag which will instruct the observable to skip following observers when set to true
|
36
|
+
* @param target - defines the original target of the state
|
37
|
+
* @param currentTarget - defines the current target of the state
|
38
|
+
*/
|
39
|
+
constructor(
|
40
|
+
mask: number,
|
41
|
+
skipNextObservers = false,
|
42
|
+
target?: any,
|
43
|
+
currentTarget?: any
|
44
|
+
) {
|
45
|
+
this.initalize(mask, skipNextObservers, target, currentTarget)
|
46
|
+
}
|
47
|
+
|
48
|
+
/**
|
49
|
+
* Initialize the current event state
|
50
|
+
* @param mask - defines the mask associated with this state
|
51
|
+
* @param skipNextObservers - defines a flag which will instruct the observable to skip following observers when set to true
|
52
|
+
* @param target - defines the original target of the state
|
53
|
+
* @param currentTarget - defines the current target of the state
|
54
|
+
* @returns the current event state
|
55
|
+
*/
|
56
|
+
public initalize(
|
57
|
+
mask: number,
|
58
|
+
skipNextObservers = false,
|
59
|
+
target?: any,
|
60
|
+
currentTarget?: any
|
61
|
+
): ObserverEventState {
|
62
|
+
this.mask = mask
|
63
|
+
this.skipNextObservers = skipNextObservers
|
64
|
+
this.target = target
|
65
|
+
this.currentTarget = currentTarget
|
66
|
+
return this
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
/**
|
71
|
+
* Represent an Observer registered to a given Observable object.
|
72
|
+
* @deprecated This function is an inheritance of ECS6, it's here temporary for the feature parity, please read the news and docs to know how handle when it's removed
|
73
|
+
*/
|
74
|
+
export class Observer<T> {
|
75
|
+
/**
|
76
|
+
* Gets or sets a property defining that the observer as to be unregistered after the next notification
|
77
|
+
*/
|
78
|
+
public unregisterOnNextCall = false
|
79
|
+
|
80
|
+
/** For internal usage */
|
81
|
+
public _willBeUnregistered = false
|
82
|
+
|
83
|
+
/**
|
84
|
+
* Creates a new observer
|
85
|
+
* @param callback - defines the callback to call when the observer is notified
|
86
|
+
* @param mask - defines the mask of the observer (used to filter notifications)
|
87
|
+
* @param scope - defines the current scope used to restore the JS context
|
88
|
+
*/
|
89
|
+
constructor(
|
90
|
+
/**
|
91
|
+
* Defines the callback to call when the observer is notified
|
92
|
+
*/
|
93
|
+
public callback: (eventData: T, eventState: ObserverEventState) => void,
|
94
|
+
/**
|
95
|
+
* Defines the mask of the observer (used to filter notifications)
|
96
|
+
*/
|
97
|
+
public mask: number,
|
98
|
+
/**
|
99
|
+
* Defines the current scope used to restore the JS context
|
100
|
+
*/
|
101
|
+
public scope: any = null
|
102
|
+
) {}
|
103
|
+
}
|
104
|
+
|
105
|
+
/**
|
106
|
+
* The Observable class is a simple implementation of the Observable pattern.
|
107
|
+
*
|
108
|
+
* There's one slight particularity though: a given Observable can notify its observer using a particular mask value, only the Observers registered with this mask value will be notified.
|
109
|
+
* This enable a more fine grained execution without having to rely on multiple different Observable objects.
|
110
|
+
* For instance you may have a given Observable that have four different types of notifications: Move (mask = 0x01), Stop (mask = 0x02), Turn Right (mask = 0X04), Turn Left (mask = 0X08).
|
111
|
+
* A given observer can register itself with only Move and Stop (mask = 0x03), then it will only be notified when one of these two occurs and will never be for Turn Left/Right.
|
112
|
+
*
|
113
|
+
* @deprecated This function is an inheritance of ECS6, it's here temporary for the feature parity, please read the news and docs to know how handle when it's removed
|
114
|
+
*/
|
115
|
+
export class Observable<T> {
|
116
|
+
private _observers = new Array<Observer<T>>()
|
117
|
+
|
118
|
+
private _eventState: ObserverEventState
|
119
|
+
|
120
|
+
private _onObserverAdded: null | ((observer: Observer<T>) => void) = null
|
121
|
+
|
122
|
+
/**
|
123
|
+
* Creates a new observable
|
124
|
+
* @param onObserverAdded - defines a callback to call when a new observer is added
|
125
|
+
*/
|
126
|
+
constructor(onObserverAdded?: (observer: Observer<T>) => void) {
|
127
|
+
this._eventState = new ObserverEventState(0)
|
128
|
+
|
129
|
+
if (onObserverAdded) {
|
130
|
+
this._onObserverAdded = onObserverAdded
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
/**
|
135
|
+
* Create a new Observer with the specified callback
|
136
|
+
* @param callback - the callback that will be executed for that Observer
|
137
|
+
* @param mask - the mask used to filter observers
|
138
|
+
* @param insertFirst - if true the callback will be inserted at the first position, hence executed before the others ones. If false (default behavior) the callback will be inserted at the last position, executed after all the others already present.
|
139
|
+
* @param scope - optional scope for the callback to be called from
|
140
|
+
* @param unregisterOnFirstCall - defines if the observer as to be unregistered after the next notification
|
141
|
+
* @returns the new observer created for the callback
|
142
|
+
*/
|
143
|
+
public add(
|
144
|
+
callback: (eventData: T, eventState: ObserverEventState) => void,
|
145
|
+
mask: number = -1,
|
146
|
+
insertFirst = false,
|
147
|
+
scope: any = null,
|
148
|
+
unregisterOnFirstCall = false
|
149
|
+
): null | Observer<T> {
|
150
|
+
if (!callback) {
|
151
|
+
return null
|
152
|
+
}
|
153
|
+
|
154
|
+
const observer = new Observer(callback, mask, scope)
|
155
|
+
observer.unregisterOnNextCall = unregisterOnFirstCall
|
156
|
+
|
157
|
+
if (insertFirst) {
|
158
|
+
this._observers.unshift(observer)
|
159
|
+
} else {
|
160
|
+
this._observers.push(observer)
|
161
|
+
}
|
162
|
+
|
163
|
+
if (this._onObserverAdded) {
|
164
|
+
this._onObserverAdded(observer)
|
165
|
+
}
|
166
|
+
|
167
|
+
return observer
|
168
|
+
}
|
169
|
+
|
170
|
+
/**
|
171
|
+
* Create a new Observer with the specified callback and unregisters after the next notification
|
172
|
+
* @param callback - the callback that will be executed for that Observer
|
173
|
+
* @returns the new observer created for the callback
|
174
|
+
*/
|
175
|
+
public addOnce(
|
176
|
+
callback: (eventData: T, eventState: ObserverEventState) => void
|
177
|
+
): null | Observer<T> {
|
178
|
+
return this.add(callback, undefined, undefined, undefined, true)
|
179
|
+
}
|
180
|
+
|
181
|
+
/**
|
182
|
+
* Remove an Observer from the Observable object
|
183
|
+
* @param observer - the instance of the Observer to remove
|
184
|
+
* @returns false if it doesn't belong to this Observable
|
185
|
+
*/
|
186
|
+
public remove(observer: null | Observer<T>): boolean {
|
187
|
+
if (!observer) {
|
188
|
+
return false
|
189
|
+
}
|
190
|
+
|
191
|
+
const index = this._observers.indexOf(observer)
|
192
|
+
|
193
|
+
if (index !== -1) {
|
194
|
+
this._deferUnregister(observer)
|
195
|
+
return true
|
196
|
+
}
|
197
|
+
|
198
|
+
return false
|
199
|
+
}
|
200
|
+
|
201
|
+
/**
|
202
|
+
* Remove a callback from the Observable object
|
203
|
+
* @param callback - the callback to remove
|
204
|
+
* @param scope - optional scope. If used only the callbacks with this scope will be removed
|
205
|
+
* @returns false if it doesn't belong to this Observable
|
206
|
+
*/
|
207
|
+
public removeCallback(
|
208
|
+
callback: (eventData: T, eventState: ObserverEventState) => void,
|
209
|
+
scope?: any
|
210
|
+
): boolean {
|
211
|
+
for (let index = 0; index < this._observers.length; index++) {
|
212
|
+
if (
|
213
|
+
this._observers[index].callback === callback &&
|
214
|
+
(!scope || scope === this._observers[index].scope)
|
215
|
+
) {
|
216
|
+
this._deferUnregister(this._observers[index])
|
217
|
+
return true
|
218
|
+
}
|
219
|
+
}
|
220
|
+
|
221
|
+
return false
|
222
|
+
}
|
223
|
+
|
224
|
+
/**
|
225
|
+
* Notify all Observers by calling their respective callback with the given data
|
226
|
+
* Will return true if all observers were executed, false if an observer set skipNextObservers to true, then prevent the subsequent ones to execute
|
227
|
+
* @param eventData - defines the data to send to all observers
|
228
|
+
* @param mask - defines the mask of the current notification (observers with incompatible mask (ie mask & observer.mask === 0) will not be notified)
|
229
|
+
* @param target - defines the original target of the state
|
230
|
+
* @param currentTarget - defines the current target of the state
|
231
|
+
* @returns false if the complete observer chain was not processed (because one observer set the skipNextObservers to true)
|
232
|
+
*/
|
233
|
+
public notifyObservers(
|
234
|
+
eventData: T,
|
235
|
+
mask: number = -1,
|
236
|
+
target?: any,
|
237
|
+
currentTarget?: any
|
238
|
+
): boolean {
|
239
|
+
if (!this._observers.length) {
|
240
|
+
return true
|
241
|
+
}
|
242
|
+
|
243
|
+
const state = this._eventState
|
244
|
+
state.mask = mask
|
245
|
+
state.target = target
|
246
|
+
state.currentTarget = currentTarget
|
247
|
+
state.skipNextObservers = false
|
248
|
+
state.lastReturnValue = eventData
|
249
|
+
|
250
|
+
for (const obs of this._observers) {
|
251
|
+
if (obs._willBeUnregistered) {
|
252
|
+
continue
|
253
|
+
}
|
254
|
+
|
255
|
+
if (obs.mask & mask) {
|
256
|
+
if (obs.scope) {
|
257
|
+
state.lastReturnValue = obs.callback.apply(obs.scope, [
|
258
|
+
eventData,
|
259
|
+
state
|
260
|
+
])
|
261
|
+
} else {
|
262
|
+
state.lastReturnValue = obs.callback(eventData, state)
|
263
|
+
}
|
264
|
+
|
265
|
+
if (obs.unregisterOnNextCall) {
|
266
|
+
this._deferUnregister(obs)
|
267
|
+
}
|
268
|
+
}
|
269
|
+
if (state.skipNextObservers) {
|
270
|
+
return false
|
271
|
+
}
|
272
|
+
}
|
273
|
+
return true
|
274
|
+
}
|
275
|
+
|
276
|
+
/**
|
277
|
+
* Calling this will execute each callback, expecting it to be a promise or return a value.
|
278
|
+
* If at any point in the chain one function fails, the promise will fail and the execution will not continue.
|
279
|
+
* This is useful when a chain of events (sometimes async events) is needed to initialize a certain object
|
280
|
+
* and it is crucial that all callbacks will be executed.
|
281
|
+
* The order of the callbacks is kept, callbacks are not executed parallel.
|
282
|
+
*
|
283
|
+
* @param eventData - The data to be sent to each callback
|
284
|
+
* @param mask - is used to filter observers defaults to -1
|
285
|
+
* @param target - defines the callback target (see EventState)
|
286
|
+
* @param currentTarget - defines he current object in the bubbling phase
|
287
|
+
* @returns will return a Promise than resolves when all callbacks executed successfully.
|
288
|
+
*/
|
289
|
+
public notifyObserversWithPromise(
|
290
|
+
eventData: T,
|
291
|
+
mask: number = -1,
|
292
|
+
target?: any,
|
293
|
+
currentTarget?: any
|
294
|
+
): Promise<T> {
|
295
|
+
// create an empty promise
|
296
|
+
let p: Promise<any> = Promise.resolve(eventData)
|
297
|
+
|
298
|
+
// no observers? return this promise.
|
299
|
+
if (!this._observers.length) {
|
300
|
+
return p
|
301
|
+
}
|
302
|
+
|
303
|
+
const state = this._eventState
|
304
|
+
state.mask = mask
|
305
|
+
state.target = target
|
306
|
+
state.currentTarget = currentTarget
|
307
|
+
state.skipNextObservers = false
|
308
|
+
|
309
|
+
// execute one callback after another (not using Promise.all, the order is important)
|
310
|
+
this._observers.forEach((obs) => {
|
311
|
+
if (state.skipNextObservers) {
|
312
|
+
return
|
313
|
+
}
|
314
|
+
if (obs._willBeUnregistered) {
|
315
|
+
return
|
316
|
+
}
|
317
|
+
if (obs.mask & mask) {
|
318
|
+
if (obs.scope) {
|
319
|
+
p = p.then((lastReturnedValue) => {
|
320
|
+
state.lastReturnValue = lastReturnedValue
|
321
|
+
return obs.callback.apply(obs.scope, [eventData, state])
|
322
|
+
})
|
323
|
+
} else {
|
324
|
+
p = p.then((lastReturnedValue) => {
|
325
|
+
state.lastReturnValue = lastReturnedValue
|
326
|
+
return obs.callback(eventData, state)
|
327
|
+
})
|
328
|
+
}
|
329
|
+
if (obs.unregisterOnNextCall) {
|
330
|
+
this._deferUnregister(obs)
|
331
|
+
}
|
332
|
+
}
|
333
|
+
})
|
334
|
+
|
335
|
+
// return the eventData
|
336
|
+
return p.then(() => {
|
337
|
+
return eventData
|
338
|
+
})
|
339
|
+
}
|
340
|
+
|
341
|
+
/**
|
342
|
+
* Notify a specific observer
|
343
|
+
* @param observer - defines the observer to notify
|
344
|
+
* @param eventData - defines the data to be sent to each callback
|
345
|
+
* @param mask - is used to filter observers defaults to -1
|
346
|
+
*/
|
347
|
+
public notifyObserver(
|
348
|
+
observer: Observer<T>,
|
349
|
+
eventData: T,
|
350
|
+
mask: number = -1
|
351
|
+
): void {
|
352
|
+
const state = this._eventState
|
353
|
+
state.mask = mask
|
354
|
+
state.skipNextObservers = false
|
355
|
+
|
356
|
+
observer.callback(eventData, state)
|
357
|
+
}
|
358
|
+
|
359
|
+
/**
|
360
|
+
* Gets a boolean indicating if the observable has at least one observer
|
361
|
+
* @returns true is the Observable has at least one Observer registered
|
362
|
+
*/
|
363
|
+
public hasObservers(): boolean {
|
364
|
+
return this._observers.length > 0
|
365
|
+
}
|
366
|
+
|
367
|
+
/**
|
368
|
+
* Clear the list of observers
|
369
|
+
*/
|
370
|
+
public clear(): void {
|
371
|
+
this._observers = new Array<Observer<T>>()
|
372
|
+
this._onObserverAdded = null
|
373
|
+
}
|
374
|
+
|
375
|
+
/**
|
376
|
+
* Clone the current observable
|
377
|
+
* @returns a new observable
|
378
|
+
*/
|
379
|
+
public clone(): Observable<T> {
|
380
|
+
const result = new Observable<T>()
|
381
|
+
|
382
|
+
result._observers = this._observers.slice(0)
|
383
|
+
|
384
|
+
return result
|
385
|
+
}
|
386
|
+
|
387
|
+
/**
|
388
|
+
* Does this observable handles observer registered with a given mask
|
389
|
+
* @param mask - defines the mask to be tested
|
390
|
+
* @returns whether or not one observer registered with the given mask is handeled
|
391
|
+
*/
|
392
|
+
public hasSpecificMask(mask: number = -1): boolean {
|
393
|
+
for (const obs of this._observers) {
|
394
|
+
if (obs.mask & mask || obs.mask === mask) {
|
395
|
+
return true
|
396
|
+
}
|
397
|
+
}
|
398
|
+
return false
|
399
|
+
}
|
400
|
+
|
401
|
+
private _deferUnregister(observer: Observer<T>): void {
|
402
|
+
observer.unregisterOnNextCall = false
|
403
|
+
observer._willBeUnregistered = true
|
404
|
+
Promise.resolve()
|
405
|
+
.then.bind(Promise.resolve())(async () => this._remove(observer))
|
406
|
+
.catch(console.error)
|
407
|
+
}
|
408
|
+
|
409
|
+
// This should only be called when not iterating over _observers to avoid callback skipping.
|
410
|
+
// Removes an observer from the _observer Array.
|
411
|
+
private _remove(observer: null | Observer<T>): boolean {
|
412
|
+
if (!observer) {
|
413
|
+
return false
|
414
|
+
}
|
415
|
+
|
416
|
+
const index = this._observers.indexOf(observer)
|
417
|
+
|
418
|
+
if (index !== -1) {
|
419
|
+
this._observers.splice(index, 1)
|
420
|
+
return true
|
421
|
+
}
|
422
|
+
|
423
|
+
return false
|
424
|
+
}
|
425
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { TransportMessage, Transport } from '@dcl/ecs'
|
2
|
+
|
3
|
+
export function createNetworkTransport(): Transport {
|
4
|
+
// const rpc = new RpcTransport()
|
5
|
+
function send(..._args: any[]) {
|
6
|
+
// console.log('NetworkMessage Sent: ', ...args)
|
7
|
+
}
|
8
|
+
|
9
|
+
const type = 'network-transport'
|
10
|
+
return {
|
11
|
+
send,
|
12
|
+
type,
|
13
|
+
filter(message: TransportMessage): boolean {
|
14
|
+
// Echo message, ignore them
|
15
|
+
if (message.transportType === type) {
|
16
|
+
return false
|
17
|
+
}
|
18
|
+
|
19
|
+
// TODO: Static entities & Network components
|
20
|
+
|
21
|
+
return !!message // validComponents.includes(componentId)
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
@@ -0,0 +1,60 @@
|
|
1
|
+
import { Transport, TransportMessage } from '@dcl/ecs'
|
2
|
+
import { ECSComponentIDs } from '@dcl/ecs/dist/components/generated/ids.gen'
|
3
|
+
import type {
|
4
|
+
CrdtSendToRendererRequest,
|
5
|
+
CrdtSendToResponse
|
6
|
+
} from '~system/EngineApi'
|
7
|
+
|
8
|
+
const componentIds = Object.values(ECSComponentIDs)
|
9
|
+
.filter((a) => typeof a === 'number')
|
10
|
+
.map(Number)
|
11
|
+
|
12
|
+
export type EngineApiForTransport = {
|
13
|
+
crdtSendToRenderer(
|
14
|
+
body: CrdtSendToRendererRequest
|
15
|
+
): Promise<CrdtSendToResponse>
|
16
|
+
}
|
17
|
+
|
18
|
+
export function createRendererTransport(
|
19
|
+
engineApi: EngineApiForTransport
|
20
|
+
): Transport {
|
21
|
+
async function sendToRenderer(message: Uint8Array) {
|
22
|
+
const response = await engineApi.crdtSendToRenderer({
|
23
|
+
data: new Uint8Array(message)
|
24
|
+
})
|
25
|
+
|
26
|
+
if (response && response.data && response.data.length) {
|
27
|
+
if (rendererTransport.onmessage) {
|
28
|
+
for (const byteArray of response.data) {
|
29
|
+
rendererTransport.onmessage(byteArray)
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
const type = 'renderer'
|
36
|
+
const rendererTransport: Transport = {
|
37
|
+
type,
|
38
|
+
send(message: Uint8Array): void {
|
39
|
+
sendToRenderer(message).catch((error) => {
|
40
|
+
console.error(error)
|
41
|
+
debugger
|
42
|
+
})
|
43
|
+
},
|
44
|
+
filter(message: TransportMessage): boolean {
|
45
|
+
// Echo message, ignore them
|
46
|
+
if (message.transportType === type) {
|
47
|
+
return false
|
48
|
+
}
|
49
|
+
|
50
|
+
// Only send renderer components (Proto Generated)
|
51
|
+
if (!componentIds.includes(message.componentId)) {
|
52
|
+
return false
|
53
|
+
}
|
54
|
+
|
55
|
+
return !!message
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
return rendererTransport
|
60
|
+
}
|
package/src/math.ts
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
import { Observer } from './internal/Observable'
|
2
|
+
import { IEvents, onCommsMessage } from './observables'
|
3
|
+
import * as communicationsController from '~system/CommunicationsController'
|
4
|
+
|
5
|
+
/**
|
6
|
+
* @alpha
|
7
|
+
* @deprecated this will only exist for a few releases in ECS7
|
8
|
+
*/
|
9
|
+
export class MessageBus {
|
10
|
+
private messageQueue: string[] = []
|
11
|
+
private flushing = false
|
12
|
+
|
13
|
+
constructor() {}
|
14
|
+
|
15
|
+
on(
|
16
|
+
message: string,
|
17
|
+
callback: (value: any, sender: string) => void
|
18
|
+
): Observer<IEvents['comms']> {
|
19
|
+
return onCommsMessage.add((e) => {
|
20
|
+
const m = JSON.parse(e.message)
|
21
|
+
|
22
|
+
if (m.message === message) {
|
23
|
+
callback(m.payload, e.sender)
|
24
|
+
}
|
25
|
+
})!
|
26
|
+
}
|
27
|
+
|
28
|
+
// @internal
|
29
|
+
sendRaw(message: string) {
|
30
|
+
this.messageQueue.push(message)
|
31
|
+
|
32
|
+
this.flush()
|
33
|
+
}
|
34
|
+
|
35
|
+
emit(message: string, payload: Record<any, any>) {
|
36
|
+
const messageToSend = JSON.stringify({ message, payload })
|
37
|
+
this.sendRaw(messageToSend)
|
38
|
+
onCommsMessage.notifyObservers({
|
39
|
+
message: messageToSend,
|
40
|
+
sender: 'self'
|
41
|
+
})
|
42
|
+
}
|
43
|
+
|
44
|
+
private flush() {
|
45
|
+
if (this.messageQueue.length === 0) return
|
46
|
+
if (this.flushing) return
|
47
|
+
|
48
|
+
const message = this.messageQueue.shift()!
|
49
|
+
|
50
|
+
this.flushing = true
|
51
|
+
|
52
|
+
communicationsController.send({ message }).then(
|
53
|
+
(_) => {
|
54
|
+
this.flushing = false
|
55
|
+
this.flush()
|
56
|
+
},
|
57
|
+
(_) => {
|
58
|
+
this.flushing = false
|
59
|
+
}
|
60
|
+
)
|
61
|
+
}
|
62
|
+
}
|