@rbxts/replecs 0.3.1 → 0.4.0-rc.2

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.
@@ -1,1695 +0,0 @@
1
- --!native
2
- --!optimize 2
3
-
4
- local common = require (script.Parent:WaitForChild('common'))
5
- local utils = require (script.Parent:WaitForChild('utils'))
6
- local mask_generator = require (script:WaitForChild('mask_generator'))
7
-
8
- type Entity = common.Entity
9
- type Component<T = any> = common.Component<T>
10
-
11
- type Bitmask = utils.Bitmask
12
- type MaskGenerator = mask_generator.MaskGenerator
13
- type MaskGeneratorWithBitmask = mask_generator.MaskGeneratorWithBitmask
14
-
15
- type GivenFilter = MemberFilter | any
16
- type MemberFilter = Set<Member>
17
- type Member = any
18
- type MaskHash = string
19
-
20
- type Set<T> = { [T]: boolean }
21
- type Map<K, V> = { [K]: V }
22
- type Array<T> = { T }
23
-
24
- export type FunctionFilter = (player: Player) -> boolean
25
-
26
- export type ComponentIndex<T> = {
27
- [number]: { [Entity]: T },
28
- }
29
-
30
- export type EntityComponentIndex<T> = {
31
- [Entity]: ComponentIndex<T>,
32
- }
33
-
34
- export type Lookup = {
35
- generator: MaskGenerator,
36
- filter: MemberFilter?,
37
- storage_group: StorageGroup,
38
- }
39
-
40
- export type ComponentLookup = Lookup & {
41
- band_generator: MaskGenerator,
42
- }
43
-
44
- export type EntityLookup = Lookup & {
45
- filtered_components: ComponentIndex<ComponentLookup>,
46
- components: ComponentIndex<true>,
47
- }
48
-
49
- export type EntityChanges = {
50
- changed: ComponentIndex<any>,
51
- removed: ComponentIndex<any>,
52
-
53
- -- these are just aliases for changes.changed, and changes.removed
54
- -- changes need specific types, so you access these if you need the types, as the other ones are just arrays
55
- tag_removed: Set<Component>,
56
- component_removed: Set<Component>,
57
- unreliable_removed: Set<Component>,
58
- unreliable_pair_removed: Set<Component>,
59
- pair_tag_removed: Set<Component>,
60
- pair_component_removed: Set<Component>,
61
- relation_tag_removed: { [Component]: Set<Entity> },
62
- relation_component_removed: { [Component]: Set<Entity> },
63
-
64
- tag_added: Set<Component>,
65
- component_changed: Map<Component, any>,
66
- unreliable_added: Set<Component>,
67
- unreliable_pair_added: Set<Component>,
68
- pair_tag_added: Set<Component>,
69
- pair_component_changed: Map<Component, any>,
70
- relation_tag_added: { [Component]: Set<Entity> },
71
- relation_component_changed: { [Component]: Map<Entity, any> },
72
- }
73
-
74
- type PostponedList = ComponentIndex<{ filter: MemberFilter? }>
75
-
76
- type LookupsList = {
77
- entities: Map<Entity, EntityLookup>,
78
-
79
- deletions: {
80
- entities: Map<Entity, Lookup>,
81
- components: EntityComponentIndex<Lookup>,
82
- },
83
- filter_deltas: {
84
- entities: Map<Entity, Map<Entity, boolean>>,
85
- components: EntityComponentIndex<Map<Entity, boolean>>,
86
- },
87
-
88
- postponed: { [Entity]: PostponedList },
89
- }
90
-
91
- export type ActiveEntity = {
92
- components: ComponentIndex<boolean>,
93
- component_count: number,
94
- is_entity_mask: boolean,
95
- }
96
-
97
- type MaskInfo = {
98
- bitmask: Bitmask,
99
- hash: MaskHash,
100
- members: Array<Member>,
101
- }
102
-
103
- export type StorageGroup = {
104
- mask: MaskInfo,
105
- shared_with: EntityComponentIndex<boolean>,
106
- is_empty: boolean,
107
-
108
- deletions: {
109
- entities: Set<Entity>,
110
- components: EntityComponentIndex<boolean>,
111
- },
112
- deletions_count: number,
113
-
114
- active: Map<Entity, ActiveEntity>, -- set of active entities
115
- active_count: number,
116
-
117
- changes: {
118
- added: Map<Entity, boolean>,
119
- added_components: EntityComponentIndex<boolean>,
120
- changed: Map<Entity, EntityChanges>,
121
- },
122
- }
123
-
124
- type Storages = {
125
- [MaskHash]: StorageGroup,
126
- }
127
-
128
- export type MaskingControllerClass = {
129
- member_count: number,
130
-
131
- client_indexes: { [Member]: number },
132
- group_indexes: { [number]: number },
133
- client_aliases: { [any]: Member },
134
-
135
- compact_count: number,
136
- unreplicated: Set<Member>,
137
-
138
- all_members_generator: MaskGeneratorWithBitmask,
139
- active_members_generator: MaskGenerator,
140
- unactive_members_generator: MaskGeneratorWithBitmask,
141
-
142
- storages: Storages,
143
- lookups: LookupsList,
144
- }
145
-
146
- local COMPONENT_TYPES = {
147
- tag = 1,
148
- component = 2,
149
- pair_tag = 3,
150
- pair_component = 4,
151
- relation = 5,
152
- relation_component = 6,
153
- unreliable = 7,
154
- unreliable_pair = 8,
155
- }
156
-
157
- local COMPONENT_TYPES_COUNT = COMPONENT_TYPES.unreliable
158
-
159
- local masking_controller = {}
160
- masking_controller.__index = masking_controller
161
-
162
- export type MaskingController = MaskingControllerClass & typeof(masking_controller)
163
-
164
- function masking_controller.get_clients_from_bitmask(controller: MaskingController, bitmask: Bitmask): Array<Member>
165
- local members: { Member } = {}
166
- for player, index in controller.client_indexes do
167
- if bitmask:get(index) then
168
- table.insert(members, player :: any)
169
- end
170
- end
171
- return members
172
- end
173
-
174
- local function get_usable_filter(filter: (MemberFilter | any)?): MemberFilter?
175
- if filter then
176
- if type(filter) == "table" then
177
- return filter :: MemberFilter
178
- else
179
- return { [filter] = true }
180
- end
181
- else
182
- return nil
183
- end
184
- end
185
-
186
- local function create_component_indexes<T>(): ComponentIndex<T>
187
- local indexes = {}
188
- for i = 1, COMPONENT_TYPES_COUNT do
189
- indexes[i] = {}
190
- end
191
- return indexes
192
- end
193
-
194
- local function create_entity_changes(): EntityChanges
195
- local tag_removed = {}
196
- local component_removed = {}
197
- local unreliable_removed = {}
198
- local unreliable_pair_removed = {}
199
- local pair_tag_removed = {}
200
- local pair_component_removed = {}
201
- local relation_tag_removed = {}
202
- local relation_component_removed = {}
203
-
204
- local tag_added = {}
205
- local component_changed = {}
206
- local unreliable_added = {}
207
- local unreliable_pair_added = {}
208
- local pair_tag_added = {}
209
- local pair_component_changed = {}
210
- local relation_tag_added = {}
211
- local relation_component_changed = {}
212
-
213
- local changed_changes = create_component_indexes() :: ComponentIndex<any>
214
- local removed_changes = create_component_indexes() :: ComponentIndex<any>
215
-
216
- changed_changes[COMPONENT_TYPES.tag] = tag_added
217
- changed_changes[COMPONENT_TYPES.component] = component_changed
218
-
219
- changed_changes[COMPONENT_TYPES.unreliable] = unreliable_added
220
- changed_changes[COMPONENT_TYPES.unreliable_pair] = unreliable_pair_added
221
-
222
- changed_changes[COMPONENT_TYPES.pair_tag] = pair_tag_added
223
- changed_changes[COMPONENT_TYPES.pair_component] = pair_component_changed
224
-
225
- changed_changes[COMPONENT_TYPES.relation] = relation_tag_added
226
- changed_changes[COMPONENT_TYPES.relation_component] = relation_component_changed
227
-
228
- removed_changes[COMPONENT_TYPES.tag] = tag_removed
229
- removed_changes[COMPONENT_TYPES.component] = component_removed
230
-
231
- removed_changes[COMPONENT_TYPES.unreliable] = unreliable_removed
232
- removed_changes[COMPONENT_TYPES.unreliable_pair] = unreliable_pair_removed
233
-
234
- removed_changes[COMPONENT_TYPES.pair_tag] = pair_tag_removed
235
- removed_changes[COMPONENT_TYPES.pair_component] = pair_component_removed
236
-
237
- removed_changes[COMPONENT_TYPES.relation] = relation_tag_removed
238
- removed_changes[COMPONENT_TYPES.relation_component] = relation_component_removed
239
-
240
- return {
241
- removed = removed_changes,
242
- changed = changed_changes,
243
-
244
- tag_removed = tag_removed,
245
- component_removed = component_removed,
246
- unreliable_removed = unreliable_removed,
247
- unreliable_pair_removed = unreliable_pair_removed,
248
- pair_tag_removed = pair_tag_removed,
249
- pair_component_removed = pair_component_removed,
250
- relation_tag_removed = relation_tag_removed,
251
- relation_component_removed = relation_component_removed,
252
-
253
- tag_added = tag_added,
254
- component_changed = component_changed,
255
- unreliable_added = unreliable_added,
256
- unreliable_pair_added = unreliable_pair_added,
257
- pair_tag_added = pair_tag_added,
258
- pair_component_changed = pair_component_changed,
259
- relation_tag_added = relation_tag_added,
260
- relation_component_changed = relation_component_changed,
261
- }
262
- end
263
-
264
- function masking_controller.create_new_storage(
265
- controller: MaskingController,
266
- bitmask: Bitmask,
267
- hash: string?,
268
- members: Array<Member>?
269
- ): StorageGroup
270
- return {
271
- mask = {
272
- bitmask = bitmask,
273
- hash = hash or bitmask:tostring(),
274
- members = members or controller:get_clients_from_bitmask(bitmask),
275
- },
276
- is_empty = true,
277
- shared_with = {},
278
-
279
- changes = {
280
- added = {},
281
- added_components = {},
282
- changed = {},
283
- },
284
-
285
- active = {},
286
- active_count = 0,
287
-
288
- deletions = {
289
- entities = {},
290
- components = {},
291
- },
292
- deletions_count = 0,
293
- }
294
- end
295
-
296
- local function is_include_filter(filter: MemberFilter): boolean
297
- for _, allow in filter do
298
- if allow then
299
- return true
300
- else
301
- return false
302
- end
303
- end
304
- return true
305
- end
306
- local function create_new_active(): ActiveEntity
307
- return {
308
- components = create_component_indexes() :: ComponentIndex<boolean>,
309
- component_count = 0,
310
- is_entity_mask = false,
311
- }
312
- end
313
-
314
- local function get_component_index_entry<T>(
315
- index: EntityComponentIndex<T>,
316
- entity: Entity,
317
- component: Component,
318
- component_type: number
319
- ): T?
320
- local entity_index = index[entity]
321
- if entity_index == nil then
322
- return nil
323
- end
324
- local component_index = entity_index[component_type]
325
-
326
- return component_index and component_index[component] :: T?
327
- end
328
-
329
- local function set_component_index_entry<T>(
330
- index: EntityComponentIndex<T>,
331
- entity: Entity,
332
- component: Component,
333
- component_type: number,
334
- value: T
335
- )
336
- local entity_index = index[entity]
337
- if entity_index == nil then
338
- entity_index = create_component_indexes()
339
- index[entity] = entity_index
340
- end
341
- entity_index[component_type][component] = value
342
- end
343
-
344
- local function remove_component_index_entry(
345
- index: EntityComponentIndex<any>,
346
- entity: Entity,
347
- component: Component,
348
- component_type: number
349
- )
350
- local entity_index = index[entity]
351
- if entity_index == nil then
352
- return
353
- end
354
- entity_index[component_type][component] = nil
355
- end
356
-
357
- local function get_bitmask_deltas(current: Bitmask, target: Bitmask): (Bitmask, Bitmask)
358
- local added = target:band(current:bnot())
359
- local removed = current:band(target:bnot())
360
- return added, removed
361
- end
362
-
363
- local function merge_bitmask_deltas(added: Bitmask, removed: Bitmask, new_added: Bitmask, new_removed: Bitmask)
364
- local merged_added = added:bor(new_added)
365
- local merged_removed = removed:bor(new_removed)
366
- local common = merged_added:band(merged_removed):bnot()
367
-
368
- local added_final = merged_added:band(common)
369
- local removed_final = merged_removed:band(common)
370
- return added_final, removed_final
371
- end
372
-
373
- masking_controller.get_component_index_entry = get_component_index_entry
374
- masking_controller.set_component_index_entry = set_component_index_entry
375
- masking_controller.remove_component_index_entry = remove_component_index_entry
376
- masking_controller.get_bitmask_deltas = get_bitmask_deltas
377
- masking_controller.merge_bitmask_deltas = merge_bitmask_deltas
378
-
379
- local function get_or_set_changed(storage: StorageGroup, entity: Entity, changed: EntityChanges?): EntityChanges
380
- local storage_changed = storage.changes.changed[entity]
381
- if storage_changed == nil then
382
- storage_changed = changed or create_entity_changes()
383
- storage.changes.changed[entity] = storage_changed
384
- end
385
- return storage_changed
386
- end
387
-
388
- local function get_or_set_active(storage: StorageGroup, entity: Entity, active: ActiveEntity?): ActiveEntity
389
- local storage_active = storage.active[entity]
390
- if storage_active == nil then
391
- storage_active = active or create_new_active()
392
- storage.active[entity] = storage_active
393
- storage.active_count += 1
394
- end
395
- return storage_active
396
- end
397
-
398
- local function get_or_set_component_added(
399
- storage: StorageGroup,
400
- entity: Entity,
401
- added: ComponentIndex<boolean>?
402
- ): ComponentIndex<boolean>
403
- local storage_added = storage.changes.added_components[entity]
404
- if storage_added == nil then
405
- storage_added = added or create_component_indexes() :: ComponentIndex<boolean>
406
- storage.changes.added_components[entity] = storage_added
407
- end
408
- return storage_added
409
- end
410
-
411
- local function remove_active(storage: StorageGroup, entity: Entity): ActiveEntity
412
- local active = storage.active[entity]
413
- if active then
414
- storage.active[entity] = nil
415
- storage.active_count -= 1
416
- -- todo: check if empty
417
- return active
418
- end
419
- return common.log_error "attempted to remove an entity that wasn't active"
420
- end
421
-
422
- local function set_component_active(active: ActiveEntity, component: Component, component_type: number)
423
- local components = active.components[component_type]
424
- if components[component] == nil then
425
- components[component] = true
426
- active.component_count += 1
427
- end
428
- end
429
-
430
- local function remove_component_active(
431
- storage: StorageGroup,
432
- entity: Entity,
433
- component: Component,
434
- component_type: number
435
- )
436
- local active = storage.active[entity]
437
- if not active then
438
- return
439
- end
440
- local components = active.components[component_type]
441
-
442
- if components[component] then
443
- components[component] = nil
444
- active.component_count -= 1
445
-
446
- if active.component_count <= 0 and not active.is_entity_mask then
447
- remove_active(storage, entity)
448
- end
449
- end
450
- end
451
-
452
- function masking_controller.get_or_create_storage_group(masking: MaskingController, bitmask: Bitmask): StorageGroup
453
- local hash = bitmask:tostring()
454
- local storage = masking.storages[hash]
455
-
456
- if not storage then
457
- storage = masking:create_new_storage(bitmask, hash)
458
- masking.storages[hash] = storage
459
- end
460
- return storage
461
- end
462
-
463
- function masking_controller.get_component_lookup(
464
- masking: MaskingController,
465
- entity: Entity,
466
- component: Component,
467
- component_type: number
468
- ): (ComponentLookup, EntityLookup)
469
- local entity_lookup = masking.lookups.entities[entity]
470
- if not entity_lookup then
471
- return nil :: any
472
- end
473
-
474
- return entity_lookup.filtered_components[component_type][component], entity_lookup
475
- end
476
-
477
- local function dissect_component_actives(
478
- storage: StorageGroup,
479
- entity: Entity,
480
- shared_index: ComponentIndex<boolean>
481
- ): ActiveEntity?
482
- local new_active: ActiveEntity
483
- local active = storage.active[entity]
484
-
485
- for component_type, components in active.components do
486
- for component in components do
487
- local is_shared = shared_index[component_type] and shared_index[component_type][component]
488
- if is_shared then
489
- new_active = new_active or create_new_active()
490
-
491
- set_component_active(new_active, component, component_type)
492
- remove_component_active(storage, entity, component, component_type)
493
- end
494
- end
495
- end
496
- return new_active
497
- end
498
-
499
- local function dissect_component_additions(added: ComponentIndex<boolean>, shared_index: ComponentIndex<boolean>)
500
- local new_added: ComponentIndex<boolean>
501
-
502
- for component_type, components in added do
503
- for component in components do
504
- local is_shared = shared_index[component_type] and shared_index[component_type][component]
505
- if is_shared then
506
- new_added = (new_added or create_component_indexes()) :: ComponentIndex<boolean>
507
- new_added[component_type][component] = true
508
- added[component_type][component] = nil
509
- end
510
- end
511
- end
512
- return new_added
513
- end
514
-
515
- local function dissect_component_changes(
516
- entity_changes: EntityChanges,
517
- shared_index: ComponentIndex<boolean>
518
- ): EntityChanges
519
- local new_entity_changes: EntityChanges = nil :: any
520
- local new_removed: ComponentIndex<boolean> = nil :: any
521
- local new_changed: ComponentIndex<any> = nil :: any
522
-
523
- for component_type, components_changed in entity_changes.changed do
524
- local shared_set = shared_index[component_type]
525
- for component, change in components_changed do
526
- local is_shared = shared_set and shared_set[component]
527
- if is_shared then
528
- if new_changed then
529
- new_changed[component_type][component] = change
530
- components_changed[component] = nil
531
- else
532
- new_entity_changes = create_entity_changes()
533
- new_changed = new_entity_changes.changed
534
- new_removed = new_entity_changes.removed
535
- end
536
- end
537
- end
538
- end
539
-
540
- for component_type, components_removed in entity_changes.removed do
541
- local shared_set = shared_index[component_type]
542
- for component in components_removed do
543
- local is_shared = shared_set and shared_set[component]
544
-
545
- if is_shared then
546
- if new_removed then
547
- new_removed[component_type][component] = true
548
- components_removed[component] = nil
549
- else
550
- new_entity_changes = create_entity_changes()
551
- new_changed = new_entity_changes.changed
552
- new_removed = new_entity_changes.removed
553
- end
554
- end
555
- end
556
- end
557
-
558
- return new_entity_changes
559
- end
560
-
561
- local function merge_component_actives(current: ActiveEntity, target: ActiveEntity)
562
- for component_type, components in current.components do
563
- for component in components do
564
- set_component_active(target, component, component_type)
565
- end
566
- end
567
- end
568
-
569
- local function merge_component_additions(current: ComponentIndex<boolean>, target: ComponentIndex<boolean>)
570
- for component_type, components in current do
571
- for component in components do
572
- target[component_type][component] = true
573
- end
574
- end
575
- end
576
-
577
- local function merge_component_changes(current: EntityChanges, destination: EntityChanges)
578
- -- COMPONENTS/TAGS
579
- local destination_changed = destination.changed
580
- local destination_removed = destination.removed
581
-
582
- for component_type, components_changed in current.changed do
583
- local destination_components = destination_changed[component_type]
584
- for component, change in components_changed do
585
- destination_components[component] = change
586
- end
587
- end
588
-
589
- for component_type, components_removed in current.removed do
590
- local destination_components = destination_removed[component_type]
591
- for component, change in components_removed do
592
- destination_components[component] = change
593
- end
594
- end
595
- end
596
-
597
- function masking_controller.merge_component_filter(
598
- masking: MaskingController,
599
- entity: Entity,
600
- component: Component,
601
- component_type: number
602
- )
603
- local component_lookup, entity_lookup = masking:get_component_lookup(entity, component, component_type)
604
- if not entity_lookup then
605
- common.log_error "attempted to merge a component filter to an unactive entity"
606
- end
607
-
608
- if component_lookup ~= nil then
609
- local new_storage = masking:move_component_storage(
610
- entity,
611
- component,
612
- component_type,
613
- component_lookup.storage_group,
614
- entity_lookup.generator.result
615
- )
616
- entity_lookup.filtered_components[component_type][component] = nil
617
- remove_component_index_entry(new_storage.shared_with, entity, component, component_type)
618
- else
619
- set_component_active(entity_lookup.storage_group.active[entity], component, component_type)
620
- end
621
- entity_lookup.components[component_type][component] = true
622
- end
623
-
624
- function masking_controller.move_entity_storage(
625
- masking: MaskingController,
626
- entity: Entity,
627
- storage: StorageGroup,
628
- destination: Bitmask
629
- )
630
- local destination_storage = masking:get_or_create_storage_group(destination)
631
- if destination_storage == storage then
632
- return storage
633
- end
634
- local shared_with = storage.shared_with[entity]
635
-
636
- local old_active = storage.active[entity]
637
- local new_active = get_or_set_active(destination_storage, entity, old_active)
638
-
639
- new_active.is_entity_mask = true
640
-
641
- if shared_with then
642
- local dissected_active = dissect_component_actives(storage, entity, shared_with)
643
- if dissected_active then
644
- storage.active[entity] = dissected_active
645
- else
646
- remove_active(storage, entity)
647
- end
648
- else
649
- remove_active(storage, entity)
650
- end
651
-
652
- if old_active ~= new_active then
653
- merge_component_actives(old_active, new_active)
654
- end
655
-
656
- local old_component_added = storage.changes.added_components[entity]
657
- if old_component_added then
658
- local new_component_added = get_or_set_component_added(destination_storage, entity, old_component_added)
659
-
660
- if shared_with then
661
- local dissected_added = dissect_component_additions(old_component_added, shared_with)
662
- if dissected_added then
663
- storage.changes.added_components[entity] = dissected_added
664
- else
665
- storage.changes.added_components[entity] = nil
666
- end
667
- end
668
-
669
- if old_component_added ~= new_component_added then
670
- merge_component_additions(old_component_added, new_component_added)
671
- end
672
- end
673
-
674
- local old_changes = storage.changes.changed[entity]
675
- if old_changes then
676
- local new_changes = get_or_set_changed(destination_storage, entity, old_changes)
677
-
678
- if shared_with then
679
- local dissected_changes = dissect_component_changes(old_changes, shared_with)
680
- if dissected_changes then
681
- storage.changes.changed[entity] = dissected_changes
682
- else
683
- storage.changes.changed[entity] = nil
684
- end
685
- end
686
-
687
- if old_changes ~= new_changes then
688
- merge_component_changes(old_changes, new_changes)
689
- end
690
- end
691
-
692
- if storage.changes.added[entity] then
693
- destination_storage.changes.added[entity] = true
694
- storage.changes.added[entity] = nil
695
- end
696
-
697
- return destination_storage
698
- end
699
-
700
- function masking_controller.move_component_storage(
701
- masking: MaskingController,
702
- entity: Entity,
703
- component: Component,
704
- component_type: number,
705
- storage: StorageGroup,
706
- destination: Bitmask
707
- )
708
- local destination_storage = masking:get_or_create_storage_group(destination)
709
- if destination_storage == storage then
710
- return storage
711
- end
712
-
713
- local new_active = get_or_set_active(destination_storage, entity)
714
-
715
- remove_component_active(storage, entity, component, component_type)
716
- set_component_active(new_active, component, component_type)
717
-
718
- set_component_index_entry(destination_storage.shared_with, entity, component, component_type, true)
719
- remove_component_index_entry(storage.shared_with, entity, component, component_type)
720
-
721
- local component_added =
722
- get_component_index_entry(storage.changes.added_components, entity, component, component_type)
723
- if component_added then
724
- remove_component_index_entry(storage.changes.added_components, entity, component, component_type)
725
- set_component_index_entry(destination_storage.changes.added_components, entity, component, component_type, true)
726
- end
727
-
728
- local changes = storage.changes.changed[entity]
729
- if changes then
730
- local destination_changes = get_or_set_changed(destination_storage, entity)
731
- destination_changes.changed[component_type][component] = changes.changed[component_type][component]
732
- destination_changes.removed[component_type][component] = changes.removed[component_type][component]
733
-
734
- changes.changed[component_type][component] = nil
735
- changes.removed[component_type][component] = nil
736
- end
737
-
738
- return destination_storage
739
- end
740
-
741
- function masking_controller.bind_component_generator(
742
- masking: MaskingController,
743
- entity: Entity,
744
- component: Component,
745
- component_type: number,
746
- base_generator: MaskGenerator
747
- )
748
- local component_lookup, entity_lookup = masking:get_component_lookup(entity, component, component_type)
749
- local generator = mask_generator.create(nil, function()
750
- return entity_lookup.generator.result:band(base_generator.result)
751
- end)
752
-
753
- local function subscribed()
754
- if not component_lookup then
755
- component_lookup = entity_lookup.filtered_components[component_type][component]
756
- end
757
-
758
- local current_storage = component_lookup.storage_group
759
- local new_storage =
760
- masking:move_component_storage(entity, component, component_type, current_storage, generator.result)
761
-
762
- component_lookup.storage_group = new_storage
763
- end
764
-
765
- generator:track(base_generator)
766
- generator:track(masking.active_members_generator)
767
- generator.subscribed = subscribed
768
-
769
- return generator
770
- end
771
-
772
- function masking_controller.rebind_component_generators(masking: MaskingController, entity: Entity)
773
- local entity_lookup = masking.lookups.entities[entity]
774
- if entity_lookup then
775
- for component_type, lookups in entity_lookup.filtered_components do
776
- for component, lookup in lookups do
777
- lookup.band_generator:destroy()
778
-
779
- local binded_generator =
780
- masking:bind_component_generator(entity, component, component_type, lookup.generator)
781
- lookup.band_generator = binded_generator
782
- binded_generator:run_subscribed()
783
- end
784
- end
785
- end
786
- end
787
-
788
- function masking_controller.get_or_postpone_entity_lookup(
789
- masking: MaskingController,
790
- entity: Entity,
791
- component: Component,
792
- component_type: number,
793
- filter: MemberFilter?
794
- ): EntityLookup?
795
- local lookup = masking.lookups.entities[entity]
796
- if lookup then
797
- return lookup
798
- end
799
-
800
- if filter ~= nil then
801
- set_component_index_entry(masking.lookups.postponed, entity, component, component_type, { filter = filter })
802
- else
803
- set_component_index_entry(masking.lookups.postponed, entity, component, component_type, { filter = nil })
804
- end
805
-
806
- return nil
807
- end
808
-
809
- function masking_controller.update_entity_filter(
810
- masking: MaskingController,
811
- entity: Entity,
812
- filter: MemberFilter?
813
- ): MaskGenerator
814
- local generator: MaskGenerator
815
- if filter then
816
- generator = masking:create_generator_from_filter(filter)
817
- else
818
- generator = mask_generator.follow(masking.active_members_generator)
819
- end
820
-
821
- local lookup = masking.lookups.entities[entity]
822
-
823
- local function subscribed()
824
- if not lookup then
825
- lookup = masking.lookups.entities[entity]
826
- end
827
- local current_storage = lookup.storage_group
828
-
829
- local new_storage = masking:move_entity_storage(entity, current_storage, generator.result)
830
- lookup.storage_group = new_storage
831
- end
832
- generator.subscribed = subscribed
833
- return generator
834
- end
835
-
836
- function masking_controller.start_entity(masking: MaskingController, entity: Entity, given_filter: GivenFilter?)
837
- local filter = get_usable_filter(given_filter)
838
- local generator = masking:update_entity_filter(entity, filter)
839
-
840
- local storage_group = masking:get_or_create_storage_group(generator.result)
841
- local active = get_or_set_active(storage_group, entity)
842
- active.is_entity_mask = true
843
-
844
- local new_lookup: EntityLookup = {
845
- generator = generator,
846
- filter = filter,
847
- storage_group = storage_group,
848
- filtered_components = create_component_indexes() :: ComponentIndex<ComponentLookup>,
849
- components = create_component_indexes() :: ComponentIndex<true>,
850
- }
851
- masking.lookups.entities[entity] = new_lookup
852
-
853
- local postponed = masking.lookups.postponed[entity]
854
- if postponed then
855
- for component_type, components in postponed do
856
- for component, postponed_info in components do
857
- masking:start_component(entity, component, component_type, postponed_info.filter)
858
- end
859
- end
860
- masking.lookups.postponed[entity] = nil
861
- end
862
- end
863
-
864
- function masking_controller.set_entity(masking: MaskingController, entity: Entity, given_filter: GivenFilter?)
865
- local filter = get_usable_filter(given_filter)
866
- local lookup = masking.lookups.entities[entity]
867
- if not lookup then
868
- common.log_error "attempted to modify the filter of an unactive entity"
869
- end
870
- lookup.generator:destroy()
871
-
872
- local generator = masking:update_entity_filter(entity, filter)
873
-
874
- lookup.generator = generator
875
- lookup.filter = filter
876
-
877
- generator:run_subscribed()
878
- masking:rebind_component_generators(entity)
879
- end
880
-
881
- function masking_controller.stop_entity(masking: MaskingController, entity: Entity)
882
- local lookup = masking.lookups.entities[entity]
883
- if not lookup then
884
- common.log_error "attemped to stop an unactive entity"
885
- end
886
-
887
- local postponed = masking.lookups.postponed[entity]
888
-
889
- for component_type, lookups in lookup.filtered_components do
890
- for component, component_lookup in lookups do
891
- component_lookup.band_generator:destroy()
892
- component_lookup.generator:destroy()
893
- remove_component_active(component_lookup.storage_group, entity, component, component_type)
894
-
895
- local component_storage = component_lookup.storage_group
896
- component_storage.shared_with[entity] = nil
897
- component_storage.changes.added[entity] = nil
898
- component_storage.changes.changed[entity] = nil
899
- component_storage.changes.added_components[entity] = nil
900
-
901
- if postponed == nil then
902
- postponed = create_component_indexes() :: PostponedList
903
- masking.lookups.postponed[entity] = postponed
904
- end
905
- postponed[component_type][component] = { filter = component_lookup.filter }
906
- end
907
- end
908
- for component_type, components in lookup.components do
909
- for component in components do
910
- if postponed == nil then
911
- postponed = create_component_indexes() :: PostponedList
912
- masking.lookups.postponed[entity] = postponed
913
- end
914
- postponed[component_type][component] = { filter = nil :: MemberFilter? }
915
- end
916
- end
917
-
918
- lookup.generator:destroy()
919
- remove_active(lookup.storage_group, entity)
920
- lookup.storage_group.changes.added[entity] = nil
921
- lookup.storage_group.changes.changed[entity] = nil
922
- lookup.storage_group.changes.added_components[entity] = nil
923
-
924
- masking.lookups.entities[entity] = nil
925
- end
926
-
927
- function masking_controller.cleanup_entity(masking: MaskingController, entity: Entity)
928
- masking.lookups.entities[entity] = nil
929
- masking.lookups.postponed[entity] = nil
930
- masking.lookups.deletions.entities[entity] = nil
931
- masking.lookups.deletions.components[entity] = nil
932
- end
933
-
934
- function masking_controller.update_component_filter(
935
- masking: MaskingController,
936
- entity: Entity,
937
- component: Component,
938
- component_type: number,
939
- filter: MemberFilter
940
- )
941
- local generator = masking:create_generator_from_filter(filter)
942
- local band_generator = masking:bind_component_generator(entity, component, component_type, generator)
943
- return generator, band_generator
944
- end
945
-
946
- function masking_controller.start_component(
947
- masking: MaskingController,
948
- entity: Entity,
949
- component: Component,
950
- component_type: number,
951
- given_filter: GivenFilter?
952
- )
953
- local filter = get_usable_filter(given_filter)
954
- local lookup = masking:get_or_postpone_entity_lookup(entity, component, component_type, filter)
955
- if lookup == nil then
956
- return
957
- end
958
-
959
- if filter == nil then
960
- lookup.components[component_type][component] = true
961
- set_component_active(lookup.storage_group.active[entity], component, component_type)
962
- return
963
- end
964
-
965
- local generator, band_generator = masking:update_component_filter(entity, component, component_type, filter)
966
- local storage_group = masking:get_or_create_storage_group(band_generator.result)
967
- local active = get_or_set_active(storage_group, entity)
968
-
969
- set_component_active(active, component, component_type)
970
- set_component_index_entry(storage_group.shared_with, entity, component, component_type, true)
971
-
972
- local component_lookup: ComponentLookup = {
973
- generator = generator,
974
- band_generator = band_generator,
975
- filter = filter,
976
- storage_group = storage_group,
977
- }
978
- lookup.filtered_components[component_type][component] = component_lookup
979
- end
980
-
981
- function masking_controller.set_component(
982
- masking: MaskingController,
983
- entity: Entity,
984
- component: Component,
985
- component_type: number,
986
- given_filter: GivenFilter?
987
- )
988
- local filter = get_usable_filter(given_filter)
989
- local lookup = masking:get_or_postpone_entity_lookup(entity, component, component_type, filter)
990
- if lookup == nil then
991
- return
992
- end
993
- local component_lookup = lookup.filtered_components[component_type][component]
994
-
995
- if filter == nil then
996
- if component_lookup ~= nil then
997
- component_lookup.band_generator:destroy()
998
- component_lookup.generator:destroy()
999
-
1000
- masking:merge_component_filter(entity, component, component_type)
1001
- end
1002
- return
1003
- end
1004
-
1005
- local generator, band_generator = masking:update_component_filter(entity, component, component_type, filter)
1006
-
1007
- if component_lookup ~= nil then
1008
- component_lookup.band_generator:destroy()
1009
- component_lookup.generator:destroy()
1010
-
1011
- component_lookup.band_generator = band_generator
1012
- component_lookup.generator = generator
1013
- component_lookup.filter = filter
1014
-
1015
- band_generator:run_subscribed()
1016
- else
1017
- local desired_storage = masking:get_or_create_storage_group(band_generator.result)
1018
- local new_storage: StorageGroup
1019
-
1020
- if desired_storage and desired_storage == lookup.storage_group then
1021
- new_storage = lookup.storage_group
1022
- set_component_index_entry(desired_storage.shared_with, entity, component, component_type, true)
1023
- else
1024
- new_storage = masking:move_component_storage(
1025
- entity,
1026
- component,
1027
- component_type,
1028
- lookup.storage_group,
1029
- band_generator.result
1030
- )
1031
- end
1032
- local new_lookup: ComponentLookup = {
1033
- generator = generator,
1034
- band_generator = band_generator,
1035
- filter = filter :: MemberFilter?,
1036
- storage_group = new_storage,
1037
- }
1038
- lookup.filtered_components[component_type][component] = new_lookup
1039
- lookup.components[component_type][component] = nil
1040
- end
1041
- end
1042
-
1043
- function masking_controller.stop_component(
1044
- masking: MaskingController,
1045
- entity: Entity,
1046
- component: Component,
1047
- component_type: number
1048
- )
1049
- local component_lookup, entity_lookup = masking:get_component_lookup(entity, component, component_type)
1050
- if component_lookup ~= nil then
1051
- component_lookup.band_generator:destroy()
1052
- component_lookup.generator:destroy()
1053
-
1054
- remove_component_active(component_lookup.storage_group, entity, component, component_type)
1055
- remove_component_index_entry(component_lookup.storage_group.shared_with, entity, component, component_type)
1056
- entity_lookup.filtered_components[component_type][component] = nil
1057
- else
1058
- if entity_lookup then
1059
- remove_component_active(entity_lookup.storage_group, entity, component, component_type)
1060
- entity_lookup.components[component_type][component] = nil
1061
- else
1062
- remove_component_index_entry(masking.lookups.postponed, entity, component, component_type)
1063
- end
1064
- end
1065
- end
1066
-
1067
- function masking_controller.get_component_storage_group(
1068
- masking: MaskingController,
1069
- entity: Entity,
1070
- component: Component,
1071
- component_type: number
1072
- ): StorageGroup
1073
- local component_lookup, entity_lookup = masking:get_component_lookup(entity, component, component_type)
1074
-
1075
- if component_lookup ~= nil then
1076
- return component_lookup.storage_group
1077
- elseif entity_lookup then
1078
- return entity_lookup.storage_group
1079
- else
1080
- error "attempted to use an entity that is not active"
1081
- end
1082
- end
1083
-
1084
- function masking_controller.allocate_propagated_entity_start(masking: MaskingController, entity: Entity)
1085
- local entity_lookup = masking.lookups.entities[entity]
1086
- if entity_lookup then
1087
- entity_lookup.storage_group.changes.added[entity] = true
1088
-
1089
- for _, lookups in entity_lookup.filtered_components do
1090
- for _, lookup in lookups do
1091
- lookup.storage_group.changes.added[entity] = true
1092
- end
1093
- end
1094
- end
1095
- end
1096
-
1097
- function masking_controller.allocate_shared_entity_start(
1098
- masking: MaskingController,
1099
- entity: Entity,
1100
- component: Component,
1101
- component_type: number
1102
- )
1103
- local lookup = masking:get_component_lookup(entity, component, component_type)
1104
- if lookup ~= nil then
1105
- lookup.storage_group.changes.added[entity] = true
1106
- end
1107
- end
1108
-
1109
- function masking_controller.allocate_entity_stop(masking: MaskingController, entity: Entity)
1110
- local lookup = masking.lookups.entities[entity]
1111
- if not lookup then
1112
- return
1113
- end
1114
- local storage = lookup.storage_group
1115
-
1116
- if storage.deletions.entities[entity] then
1117
- return
1118
- end
1119
- storage.deletions.entities[entity] = true
1120
- end
1121
-
1122
- function masking_controller.allocate_component_start(
1123
- masking: MaskingController,
1124
- entity: Entity,
1125
- component: Component,
1126
- component_type: number
1127
- )
1128
- local storage = masking:get_component_storage_group(entity, component, component_type)
1129
- local additions = get_or_set_component_added(storage, entity)
1130
- additions[component_type][component] = true
1131
- end
1132
-
1133
- function masking_controller.allocate_component_stop(
1134
- masking: MaskingController,
1135
- entity: Entity,
1136
- component: Component,
1137
- component_type: number
1138
- )
1139
- local storage = masking:get_component_storage_group(entity, component, component_type) :: StorageGroup
1140
- if not storage then
1141
- return
1142
- end
1143
-
1144
- local deletions = storage.deletions.components[entity]
1145
- if deletions == nil then
1146
- deletions = create_component_indexes() :: ComponentIndex<boolean>
1147
- deletions[component_type][component] = true
1148
- storage.deletions.components[entity] = deletions
1149
- else
1150
- deletions[component_type][component] = true
1151
- end
1152
- end
1153
-
1154
- function masking_controller.deallocate_entity_stop(masking: MaskingController, entity: Entity)
1155
- local deletion_lookup = masking.lookups.deletions.entities[entity]
1156
- if not deletion_lookup then
1157
- return
1158
- end
1159
- local storage = deletion_lookup.storage_group
1160
-
1161
- if storage.deletions.entities[entity] then
1162
- storage.deletions.entities[entity] = nil
1163
- storage.deletions_count -= 1
1164
- end
1165
- end
1166
-
1167
- function masking_controller.deallocate_component_start(
1168
- masking: MaskingController,
1169
- entity: Entity,
1170
- component: Component,
1171
- component_type: number
1172
- )
1173
- local storage: StorageGroup = masking:get_component_storage_group(entity, component, component_type)
1174
- local additions = storage.changes.added_components[entity]
1175
- if additions then
1176
- additions[component_type][component] = nil
1177
- end
1178
- end
1179
-
1180
- function masking_controller.deallocate_component_stop(
1181
- masking: MaskingController,
1182
- entity: Entity,
1183
- component: Component,
1184
- component_type: number
1185
- )
1186
- local deletion_lookup =
1187
- get_component_index_entry(masking.lookups.deletions.components, entity, component, component_type)
1188
- if deletion_lookup == nil then
1189
- return
1190
- end
1191
- local storage = deletion_lookup.storage_group
1192
-
1193
- local deletions = storage.deletions.components[entity]
1194
- if deletions then
1195
- if deletions[component_type][component] then
1196
- deletions[component_type][component] = nil
1197
- end
1198
- end
1199
- end
1200
-
1201
- function masking_controller.allocate_tag_addition(masking: MaskingController, entity: Entity, tag: Component)
1202
- local storage = masking:get_component_storage_group(entity, tag, COMPONENT_TYPES.tag)
1203
- local changes = get_or_set_changed(storage, entity)
1204
-
1205
- changes.tag_added[tag] = true
1206
- changes.tag_removed[tag] = nil
1207
- end
1208
-
1209
- function masking_controller.allocate_component_change(
1210
- masking: MaskingController,
1211
- entity: Entity,
1212
- component: Component,
1213
- value: any
1214
- )
1215
- local storage = masking:get_component_storage_group(entity, component, COMPONENT_TYPES.component)
1216
- local changes = get_or_set_changed(storage, entity)
1217
-
1218
- changes.component_changed[component] = value
1219
- changes.component_removed[component] = nil
1220
- end
1221
-
1222
- function masking_controller.allocate_unreliable_addition(
1223
- masking: MaskingController,
1224
- entity: Entity,
1225
- component: Component
1226
- )
1227
- local storage = masking:get_component_storage_group(entity, component, COMPONENT_TYPES.unreliable)
1228
- local changes = get_or_set_changed(storage, entity)
1229
-
1230
- changes.unreliable_added[component] = true
1231
- changes.unreliable_removed[component] = nil
1232
- end
1233
-
1234
- function masking_controller.allocate_pair_tag_addition(masking: MaskingController, entity: Entity, id: Component)
1235
- local storage = masking:get_component_storage_group(entity, id, COMPONENT_TYPES.pair_tag)
1236
- local changes = get_or_set_changed(storage, entity)
1237
-
1238
- changes.pair_tag_added[id] = true
1239
- changes.pair_tag_removed[id] = nil
1240
- end
1241
-
1242
- function masking_controller.allocate_pair_component_change(
1243
- masking: MaskingController,
1244
- entity: Entity,
1245
- id: Component,
1246
- value: any
1247
- )
1248
- local storage = masking:get_component_storage_group(entity, id, COMPONENT_TYPES.pair_component)
1249
- local changes = get_or_set_changed(storage, entity)
1250
-
1251
- changes.pair_component_changed[id] = value
1252
- changes.pair_component_removed[id] = nil
1253
- end
1254
-
1255
- function masking_controller.allocate_relation_component_change(
1256
- masking: MaskingController,
1257
- entity: Entity,
1258
- relation: Component,
1259
- target: Entity,
1260
- value: any
1261
- )
1262
- local storage = masking:get_component_storage_group(entity, relation, COMPONENT_TYPES.relation_component)
1263
- local changes = get_or_set_changed(storage, entity)
1264
- local values = changes.relation_component_changed[relation]
1265
- if values == nil then
1266
- values = {}
1267
- changes.relation_component_changed[relation] = values
1268
- end
1269
- values[target] = value
1270
-
1271
- local removed = changes.relation_component_removed[relation]
1272
- if removed ~= nil then
1273
- removed[target] = nil
1274
- end
1275
- end
1276
-
1277
- function masking_controller.allocate_relation_tag_addition(
1278
- masking: MaskingController,
1279
- entity: Entity,
1280
- relation: Component,
1281
- target: Entity
1282
- )
1283
- local storage = masking:get_component_storage_group(entity, relation, COMPONENT_TYPES.relation)
1284
- local changes = get_or_set_changed(storage, entity)
1285
- local targets = changes.relation_tag_added[relation]
1286
- if targets == nil then
1287
- targets = {}
1288
- changes.relation_tag_added[relation] = targets
1289
- end
1290
- targets[target] = true
1291
-
1292
- local removed = changes.relation_tag_removed[relation]
1293
- if removed then
1294
- removed[target] = nil
1295
- end
1296
- end
1297
-
1298
- function masking_controller.allocate_tag_removal(masking: MaskingController, entity: Entity, tag: Component)
1299
- local storage = masking:get_component_storage_group(entity, tag, COMPONENT_TYPES.tag)
1300
- local changes = get_or_set_changed(storage, entity)
1301
-
1302
- changes.tag_added[tag] = nil
1303
- changes.tag_removed[tag] = true
1304
- end
1305
-
1306
- function masking_controller.allocate_component_removal(masking: MaskingController, entity: Entity, component: Component)
1307
- local storage = masking:get_component_storage_group(entity, component, COMPONENT_TYPES.component)
1308
- local changes = get_or_set_changed(storage, entity)
1309
-
1310
- changes.component_changed[component] = nil
1311
- changes.component_removed[component] = true
1312
- end
1313
-
1314
- function masking_controller.allocate_unreliable_removal(
1315
- masking: MaskingController,
1316
- entity: Entity,
1317
- component: Component
1318
- )
1319
- local storage = masking:get_component_storage_group(entity, component, COMPONENT_TYPES.unreliable)
1320
- local changes = get_or_set_changed(storage, entity)
1321
-
1322
- changes.unreliable_added[component] = nil
1323
- changes.unreliable_removed[component] = true
1324
- end
1325
-
1326
- function masking_controller.allocate_pair_tag_removal(masking: MaskingController, entity: Entity, id: Component)
1327
- local storage = masking:get_component_storage_group(entity, id, COMPONENT_TYPES.pair_tag)
1328
- local changes = get_or_set_changed(storage, entity)
1329
-
1330
- changes.pair_tag_added[id] = nil
1331
- changes.pair_tag_removed[id] = true
1332
- end
1333
-
1334
- function masking_controller.allocate_pair_component_removal(masking: MaskingController, entity: Entity, id: Component)
1335
- local storage = masking:get_component_storage_group(entity, id, COMPONENT_TYPES.pair_component)
1336
- local changes = get_or_set_changed(storage, entity)
1337
-
1338
- changes.pair_component_changed[id] = nil
1339
- changes.pair_component_removed[id] = true
1340
- end
1341
-
1342
- function masking_controller.allocate_relation_tag_removal(
1343
- masking: MaskingController,
1344
- entity: Entity,
1345
- relation: Component,
1346
- target: Entity
1347
- )
1348
- local storage = masking:get_component_storage_group(entity, relation, COMPONENT_TYPES.relation)
1349
- local changes = get_or_set_changed(storage, entity)
1350
- local targets = changes.relation_tag_removed[relation]
1351
- if targets == nil then
1352
- targets = {}
1353
- changes.relation_tag_removed[relation] = targets
1354
- end
1355
- targets[target] = true
1356
-
1357
- local added = changes.relation_tag_added[relation]
1358
- if added then
1359
- added[target] = nil
1360
- end
1361
- end
1362
-
1363
- function masking_controller.allocate_relation_component_removal(
1364
- masking: MaskingController,
1365
- entity: Entity,
1366
- relation: Component,
1367
- target: Entity
1368
- )
1369
- local storage = masking:get_component_storage_group(entity, relation, COMPONENT_TYPES.relation_component)
1370
- local changes = get_or_set_changed(storage, entity)
1371
- local targets = changes.relation_component_removed[relation]
1372
- if targets == nil then
1373
- targets = {}
1374
- changes.relation_component_removed[relation] = targets
1375
- end
1376
- targets[target] = true
1377
-
1378
- local values = changes.relation_component_changed[relation]
1379
- if values then
1380
- values[target] = nil
1381
- end
1382
- end
1383
-
1384
- local function remap_bitmask(
1385
- bitmask: Bitmask,
1386
- from: { [Member]: number },
1387
- target: { [Member]: number },
1388
- size: number?
1389
- ): Bitmask
1390
- local result = utils.bitmask.create(size)
1391
- for member, index in target do
1392
- local old_index = from[member]
1393
- if old_index then
1394
- local old_bit = bitmask:get(old_index)
1395
- if old_bit then
1396
- result:set(index, old_bit)
1397
- else
1398
- result:clear(index)
1399
- end
1400
- end
1401
- end
1402
- return result
1403
- end
1404
-
1405
- local function bitmask_from_set(masking: MaskingController, member_set: { [Member]: boolean }): utils.Bitmask
1406
- local new_bitmask = utils.bitmask.create(masking.member_count)
1407
- for member: Member in member_set do
1408
- local index = masking.client_indexes[member]
1409
- if not index then
1410
- local alias = masking.client_indexes[masking.client_aliases[member] ]
1411
- if alias then
1412
- if utils.is_client_valid(alias) then
1413
- index = alias
1414
- end
1415
- elseif utils.is_client_valid(member) then
1416
- masking_controller.register_client(masking, member)
1417
- index = masking.client_indexes[member]
1418
- end
1419
- end
1420
- if index then
1421
- new_bitmask:set(index)
1422
- end
1423
- end
1424
- return new_bitmask
1425
- end
1426
-
1427
- function masking_controller.merge_storages(
1428
- masking: MaskingController,
1429
- old_storage: StorageGroup,
1430
- new_storage: StorageGroup
1431
- )
1432
- if new_storage == old_storage then
1433
- return
1434
- end
1435
- for entity, active in old_storage.active do
1436
- local new_active = get_or_set_active(new_storage, entity)
1437
- merge_component_actives(active, new_active)
1438
-
1439
- if active.is_entity_mask then
1440
- local lookup = masking.lookups.entities[entity]
1441
- lookup.storage_group = new_storage
1442
- new_active.is_entity_mask = true
1443
- end
1444
- end
1445
- for entity, shared_components in old_storage.shared_with do
1446
- for component_type, components in shared_components do
1447
- for component in components do
1448
- set_component_index_entry(new_storage.shared_with, entity, component, component_type, true)
1449
-
1450
- local lookup = masking:get_component_lookup(entity, component, component_type)
1451
- if lookup ~= nil then
1452
- lookup.storage_group = new_storage
1453
- end
1454
- end
1455
- end
1456
- end
1457
- for entity, added_components in old_storage.changes.added_components do
1458
- local new_added_components = get_or_set_component_added(new_storage, entity)
1459
- merge_component_additions(new_added_components, added_components)
1460
- end
1461
- for entity, changes in old_storage.changes.changed do
1462
- local new_changes = get_or_set_changed(new_storage, entity)
1463
- merge_component_changes(new_changes, changes)
1464
- end
1465
- for entity in old_storage.changes.added do
1466
- new_storage.changes.added[entity] = true
1467
- end
1468
- for entity in old_storage.deletions.entities do
1469
- new_storage.deletions.entities[entity] = true
1470
- end
1471
- for entity, deleted_components in old_storage.deletions.components do
1472
- for component_type, components in deleted_components do
1473
- for component in components do
1474
- set_component_index_entry(new_storage.deletions.components, entity, component, component_type, true)
1475
- end
1476
- end
1477
- end
1478
- end
1479
-
1480
- function masking_controller.compact_members(masking: MaskingController)
1481
- -- we dont recompute as nothing should've changed
1482
- -- so this should be hopefully quite cheap
1483
- local old_indexes = masking.client_indexes
1484
- local new_indexes: { [Member]: number } = {}
1485
-
1486
- local new_count = 0
1487
- for member in old_indexes do
1488
- new_indexes[member] = new_count
1489
- new_count += 1
1490
- end
1491
- masking.client_indexes = new_indexes
1492
- masking.member_count = new_count
1493
-
1494
- for _, entity_lookup in masking.lookups.entities do
1495
- local entity_generator = entity_lookup.generator
1496
- local entity_bitmask = entity_generator.bitmask
1497
- if entity_bitmask then
1498
- entity_generator.bitmask = remap_bitmask(entity_bitmask, old_indexes, new_indexes, new_count)
1499
- end
1500
- entity_generator.result = remap_bitmask(entity_generator.result, old_indexes, new_indexes, new_count)
1501
-
1502
- for _, lookups in entity_lookup.filtered_components do
1503
- for _, component_lookup in lookups do
1504
- local component_generator = component_lookup.generator
1505
-
1506
- local component_bitmask = component_generator.bitmask
1507
- if component_bitmask then
1508
- component_generator.bitmask = remap_bitmask(component_bitmask, old_indexes, new_indexes, new_count)
1509
- end
1510
- component_generator.result = remap_bitmask(component_generator.result, old_indexes, new_indexes, new_count)
1511
-
1512
- local band_generator = component_lookup.band_generator
1513
- local band_bitmask = band_generator.bitmask
1514
- if band_bitmask then
1515
- band_generator.bitmask = remap_bitmask(band_bitmask, old_indexes, new_indexes, new_count)
1516
- end
1517
- band_generator.result = remap_bitmask(band_generator.result, old_indexes, new_indexes, new_count)
1518
- end
1519
- end
1520
- end
1521
-
1522
- local all = masking.all_members_generator
1523
- local unactive = masking.unactive_members_generator
1524
- local active = masking.active_members_generator
1525
-
1526
- all.bitmask = remap_bitmask(all.bitmask, old_indexes, new_indexes, new_count)
1527
- all.result = all.bitmask
1528
- unactive.bitmask = remap_bitmask(unactive.bitmask, old_indexes, new_indexes, new_count)
1529
- unactive.result = unactive.bitmask
1530
- active.result = remap_bitmask(active.result, old_indexes, new_indexes, new_count)
1531
-
1532
- local new_storages: Storages = {}
1533
-
1534
- for _, storage in masking.storages do
1535
- local new_bitmask = remap_bitmask(storage.mask.bitmask, old_indexes, new_indexes, new_count)
1536
- storage.mask.bitmask = new_bitmask
1537
- local new_hash = new_bitmask:tostring()
1538
- storage.mask.hash = new_hash
1539
- storage.mask.members = masking:get_clients_from_bitmask(new_bitmask)
1540
-
1541
- local existing = new_storages[new_hash]
1542
- if existing then
1543
- masking:merge_storages(storage, existing)
1544
- else
1545
- new_storages[new_hash] = storage
1546
- end
1547
- end
1548
- masking.storages = new_storages
1549
- end
1550
-
1551
- function masking_controller.create_generator_from_filter(
1552
- masking: MaskingController,
1553
- filter: MemberFilter
1554
- ): MaskGenerator
1555
- local is_include = is_include_filter(filter)
1556
- if is_include then
1557
- return masking:create_include_generator(filter) :: MaskGenerator
1558
- else
1559
- return masking:create_exclude_generator(filter) :: MaskGenerator
1560
- end
1561
- end
1562
-
1563
- function masking_controller.create_exclude_generator(masking: MaskingController, exclude: MemberFilter)
1564
- local bitmask = bitmask_from_set(masking, exclude)
1565
- local active_members = masking.active_members_generator
1566
-
1567
- local new_generator = mask_generator.create(bitmask, function(generator)
1568
- local current = generator.bitmask :: utils.Bitmask
1569
- return active_members.result:band(current:bnot())
1570
- end)
1571
- new_generator:track(active_members)
1572
-
1573
- return new_generator
1574
- end
1575
-
1576
- -- TODO: check for players existing and register them if they don't
1577
- function masking_controller.create_include_generator(masking: MaskingController, include: MemberFilter): MaskGenerator
1578
- local bitmask = bitmask_from_set(masking, include)
1579
- local active_members = masking.active_members_generator
1580
-
1581
- local new_generator = mask_generator.create(bitmask, function(generator)
1582
- local current = generator.bitmask :: utils.Bitmask
1583
- return current:band(active_members.result)
1584
- end)
1585
- new_generator:track(active_members)
1586
-
1587
- return new_generator
1588
- end
1589
-
1590
- function masking_controller.create_all_members_generator(masking: MaskingController)
1591
- local filter: MemberFilter = {}
1592
- for member in masking.client_indexes do
1593
- filter[member] = true
1594
- end
1595
- local bitmask = utils.bitmask.from_set(masking.client_indexes, filter, masking.member_count)
1596
- return mask_generator.create(bitmask) :: MaskGeneratorWithBitmask
1597
- end
1598
- function masking_controller.create_unactive_generator(masking: MaskingController)
1599
- local bitmask = utils.bitmask.from_set(masking.client_indexes, masking.unreplicated, masking.member_count)
1600
- return mask_generator.create(bitmask) :: MaskGeneratorWithBitmask
1601
- end
1602
- function masking_controller.create_active_generator(masking: MaskingController): MaskGenerator
1603
- local all = masking.all_members_generator
1604
- local unactive = masking.unactive_members_generator
1605
-
1606
- local new_generator = mask_generator.create(nil, function()
1607
- return all.result:band(unactive.result:bnot())
1608
- end)
1609
- new_generator:track(all)
1610
- new_generator:track(unactive)
1611
-
1612
- return new_generator
1613
- end
1614
-
1615
- --function masking_controller.register_mask_group(masking: MaskingController, group: Member) end
1616
-
1617
- --function masking_controller.unregister_mask_group(masking: MaskingController, group: Member) end
1618
-
1619
- function masking_controller.register_client(masking: MaskingController, member: Member)
1620
- if masking.client_indexes[member] then
1621
- return
1622
- end
1623
-
1624
- local current = masking.member_count
1625
- masking.client_indexes[member] = current
1626
- masking.member_count += 1
1627
-
1628
- masking.unreplicated[member] = true
1629
- masking.unactive_members_generator.bitmask:set(current)
1630
- masking.all_members_generator.bitmask:set(current)
1631
- masking.active_members_generator:compute()
1632
-
1633
- if masking.member_count >= masking.compact_count then
1634
- masking:compact_members()
1635
- end
1636
- end
1637
-
1638
- function masking_controller.unregister_client(masking: MaskingController, member: Member)
1639
- local index = masking.client_indexes[member]
1640
- if index == nil then
1641
- return
1642
- end
1643
- masking.client_indexes[member] = nil
1644
- masking.all_members_generator.bitmask:clear(index)
1645
- masking.active_members_generator:compute()
1646
- end
1647
-
1648
- function masking_controller.activate_client(masking: MaskingController, member: Member)
1649
- local index = masking.client_indexes[member]
1650
-
1651
- masking.unreplicated[member] = nil
1652
- masking.unactive_members_generator.bitmask:clear(index)
1653
- masking.active_members_generator:compute()
1654
- end
1655
-
1656
- function masking_controller.member_is_active(masking: MaskingController, member: Member): boolean
1657
- local index = masking.client_indexes[member]
1658
- if index == nil then
1659
- return false
1660
- end
1661
-
1662
- return masking.active_members_generator.result:get(index)
1663
- end
1664
-
1665
- local function create(): MaskingController
1666
- local self = {} :: MaskingController
1667
-
1668
- self.client_indexes = {}
1669
- self.group_indexes = {}
1670
- self.client_aliases = {}
1671
- self.member_count = 0
1672
- self.compact_count = 100
1673
- self.storages = {}
1674
- self.lookups = {
1675
- entities = {},
1676
- components = {},
1677
- deletions = {
1678
- entities = {},
1679
- components = {},
1680
- },
1681
- filter_deltas = {
1682
- entities = {},
1683
- components = {},
1684
- },
1685
- postponed = {},
1686
- }
1687
- self.unreplicated = {}
1688
- self.all_members_generator = masking_controller.create_all_members_generator(self)
1689
- self.unactive_members_generator = masking_controller.create_unactive_generator(self)
1690
- self.active_members_generator = masking_controller.create_active_generator(self)
1691
-
1692
- return setmetatable(self, masking_controller) :: any
1693
- end
1694
-
1695
- return { create = create, masking_controller = masking_controller, COMPONENT_TYPES = COMPONENT_TYPES }