@rbxts/replecs 0.0.1-rc.1 → 0.1.0-alpha2
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/LICENSE +21 -0
- package/out/replecs/client.luau +77 -40
- package/out/replecs/common.luau +2 -1
- package/out/replecs/index.d.ts +24 -15
- package/out/replecs/init.luau +88 -83
- package/out/replecs/masking/init.luau +258 -104
- package/out/replecs/masking/mask_generator.luau +8 -5
- package/out/replecs/server.luau +1065 -918
- package/out/replecs/utils.luau +66 -13
- package/package.json +1 -1
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
--!native
|
|
2
|
+
--!optimize 2
|
|
3
|
+
|
|
4
|
+
local jecs = require "../jecs"
|
|
5
|
+
local utils = require "./utils"
|
|
6
|
+
local mask_generator = require "@self/mask_generator"
|
|
4
7
|
|
|
5
8
|
type Entity<T = any> = jecs.Entity<T>
|
|
6
9
|
|
|
7
10
|
type Bitmask = utils.Bitmask
|
|
8
11
|
type MaskGenerator = mask_generator.MaskGenerator
|
|
9
12
|
|
|
13
|
+
type GivenFilter = MemberFilter | any
|
|
10
14
|
type MemberFilter = Set<Member>
|
|
11
15
|
type Member = any
|
|
12
16
|
type MaskHash = string
|
|
@@ -15,23 +19,30 @@ type Set<T> = { [T]: boolean }
|
|
|
15
19
|
type Map<K, V> = { [K]: V }
|
|
16
20
|
type Array<T> = { T }
|
|
17
21
|
|
|
18
|
-
type
|
|
22
|
+
export type FunctionFilter = (player: Player) -> boolean
|
|
23
|
+
|
|
24
|
+
export type ComponentIndex<T> = {
|
|
19
25
|
[number]: { [Entity]: T },
|
|
20
26
|
}
|
|
21
|
-
type EntityComponentIndex<T> = {
|
|
27
|
+
export type EntityComponentIndex<T> = {
|
|
22
28
|
[Entity]: ComponentIndex<T>,
|
|
23
29
|
}
|
|
24
30
|
|
|
25
31
|
type Lookup = {
|
|
26
32
|
generator: MaskGenerator,
|
|
27
|
-
-- filter in component lookups will never be nil
|
|
28
33
|
filter: MemberFilter?,
|
|
29
34
|
storage_group: StorageGroup,
|
|
30
35
|
}
|
|
36
|
+
|
|
31
37
|
type ComponentLookup = Lookup & {
|
|
32
38
|
band_generator: MaskGenerator,
|
|
33
39
|
}
|
|
34
40
|
|
|
41
|
+
type EntityLookup = Lookup & {
|
|
42
|
+
filtered_components: ComponentIndex<ComponentLookup>,
|
|
43
|
+
components: ComponentIndex<true>,
|
|
44
|
+
}
|
|
45
|
+
|
|
35
46
|
export type EntityChanges = {
|
|
36
47
|
tagged: { [Entity]: boolean },
|
|
37
48
|
component: { [Entity]: any },
|
|
@@ -39,16 +50,17 @@ export type EntityChanges = {
|
|
|
39
50
|
pairs: { [Entity]: Set<Entity> },
|
|
40
51
|
}
|
|
41
52
|
|
|
53
|
+
type PostponedList = ComponentIndex<{ filter: MemberFilter? }>
|
|
54
|
+
|
|
42
55
|
type LookupsList = {
|
|
43
|
-
entities: Map<Entity,
|
|
44
|
-
components: EntityComponentIndex<ComponentLookup>,
|
|
56
|
+
entities: Map<Entity, EntityLookup>,
|
|
45
57
|
|
|
46
58
|
deletions: {
|
|
47
59
|
entities: Map<Entity, Lookup>,
|
|
48
60
|
components: EntityComponentIndex<Lookup>,
|
|
49
61
|
},
|
|
50
62
|
|
|
51
|
-
|
|
63
|
+
postponed: { [Entity]: PostponedList },
|
|
52
64
|
}
|
|
53
65
|
|
|
54
66
|
export type ActiveEntity = {
|
|
@@ -90,6 +102,7 @@ type Storages = {
|
|
|
90
102
|
export type MaskingController = {
|
|
91
103
|
member_count: number,
|
|
92
104
|
member_indexes: { [Member]: number },
|
|
105
|
+
compact_count: number,
|
|
93
106
|
unreplicated: Set<Member>,
|
|
94
107
|
|
|
95
108
|
all_members_generator: MaskGenerator,
|
|
@@ -124,6 +137,7 @@ export type MaskingController = {
|
|
|
124
137
|
start_entity: (self: MaskingController, entity: Entity, filter: MemberFilter?) -> (),
|
|
125
138
|
set_entity: (self: MaskingController, entity: Entity, filter: MemberFilter?) -> (),
|
|
126
139
|
stop_entity: (self: MaskingController, entity: Entity) -> (),
|
|
140
|
+
cleanup_entity: (self: MaskingController, entity: Entity) -> (),
|
|
127
141
|
|
|
128
142
|
start_component: (
|
|
129
143
|
self: MaskingController,
|
|
@@ -179,8 +193,20 @@ function masking_controller.get_members_from_bitmask(controller: MaskingInternal
|
|
|
179
193
|
return members
|
|
180
194
|
end
|
|
181
195
|
|
|
196
|
+
local function get_usable_filter(filter: (MemberFilter | any)?): MemberFilter?
|
|
197
|
+
if filter then
|
|
198
|
+
if type(filter) == "table" then
|
|
199
|
+
return filter
|
|
200
|
+
else
|
|
201
|
+
return { [filter] = true }
|
|
202
|
+
end
|
|
203
|
+
else
|
|
204
|
+
return nil
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
182
208
|
local function create_component_indexes<T>()
|
|
183
|
-
return { {}, {}, {}, {} } :: ComponentIndex<
|
|
209
|
+
return { {}, {}, {}, {} } :: ComponentIndex<any>
|
|
184
210
|
end
|
|
185
211
|
|
|
186
212
|
local function create_entity_changes(): EntityChanges
|
|
@@ -234,7 +260,7 @@ function masking_controller.create_new_storage(
|
|
|
234
260
|
end
|
|
235
261
|
|
|
236
262
|
local function is_include_filter(filter: MemberFilter): boolean
|
|
237
|
-
for
|
|
263
|
+
for _, allow in filter do
|
|
238
264
|
if allow then
|
|
239
265
|
return true
|
|
240
266
|
else
|
|
@@ -260,17 +286,6 @@ local function create_new_changes(): EntityChanges
|
|
|
260
286
|
}
|
|
261
287
|
end
|
|
262
288
|
|
|
263
|
-
function masking_controller.get_or_create_storage_group(masking: MaskingInternal, bitmask: Bitmask): StorageGroup
|
|
264
|
-
local hash = bitmask:tostring()
|
|
265
|
-
local storage = masking.storages[hash]
|
|
266
|
-
|
|
267
|
-
if not storage then
|
|
268
|
-
storage = masking:create_new_storage(bitmask, hash)
|
|
269
|
-
masking.storages[hash] = storage
|
|
270
|
-
end
|
|
271
|
-
return storage
|
|
272
|
-
end
|
|
273
|
-
|
|
274
289
|
local function get_component_index_entry<T>(
|
|
275
290
|
index: EntityComponentIndex<T>,
|
|
276
291
|
entity: Entity,
|
|
@@ -373,6 +388,27 @@ local function remove_component_active(storage: StorageGroup, entity: Entity, co
|
|
|
373
388
|
end
|
|
374
389
|
end
|
|
375
390
|
|
|
391
|
+
function masking_controller.get_or_create_storage_group(masking: MaskingInternal, bitmask: Bitmask): StorageGroup
|
|
392
|
+
local hash = bitmask:tostring()
|
|
393
|
+
local storage = masking.storages[hash]
|
|
394
|
+
|
|
395
|
+
if not storage then
|
|
396
|
+
storage = masking:create_new_storage(bitmask, hash)
|
|
397
|
+
masking.storages[hash] = storage
|
|
398
|
+
end
|
|
399
|
+
return storage
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
function masking_controller.get_component_lookup(
|
|
403
|
+
masking: MaskingInternal,
|
|
404
|
+
entity: Entity,
|
|
405
|
+
component: Entity,
|
|
406
|
+
component_type: number
|
|
407
|
+
): (ComponentLookup, EntityLookup)
|
|
408
|
+
local entity_lookup = masking.lookups.entities[entity]
|
|
409
|
+
return entity_lookup.filtered_components[component_type][component], entity_lookup
|
|
410
|
+
end
|
|
411
|
+
|
|
376
412
|
local function dissect_component_actives(
|
|
377
413
|
storage: StorageGroup,
|
|
378
414
|
entity: Entity,
|
|
@@ -450,8 +486,7 @@ function masking_controller.merge_component_filter(
|
|
|
450
486
|
component: Entity,
|
|
451
487
|
component_type: number
|
|
452
488
|
)
|
|
453
|
-
local component_lookup =
|
|
454
|
-
local entity_lookup = masking.lookups.entities[entity]
|
|
489
|
+
local component_lookup, entity_lookup = masking:get_component_lookup(entity, component, component_type)
|
|
455
490
|
if not entity_lookup then
|
|
456
491
|
utils.logerror "attempted to merge a component filter to an unactive entity"
|
|
457
492
|
end
|
|
@@ -464,7 +499,7 @@ function masking_controller.merge_component_filter(
|
|
|
464
499
|
component_lookup.storage_group,
|
|
465
500
|
entity_lookup.generator.bitmask
|
|
466
501
|
)
|
|
467
|
-
|
|
502
|
+
entity_lookup.filtered_components[component_type][component] = nil
|
|
468
503
|
remove_component_index_entry(new_storage.shared_with, entity, component, component_type)
|
|
469
504
|
else
|
|
470
505
|
get_or_set_component_active(entity_lookup.storage_group.active[entity], component, component_type)
|
|
@@ -577,16 +612,14 @@ function masking_controller.bind_component_generator(
|
|
|
577
612
|
component_type: number,
|
|
578
613
|
base_generator: MaskGenerator
|
|
579
614
|
)
|
|
580
|
-
local entity_lookup = masking
|
|
581
|
-
local component_lookups = masking.lookups.components[entity]
|
|
582
|
-
local component_lookup = component_lookups and component_lookups[component_type][component]
|
|
615
|
+
local component_lookup, entity_lookup = masking:get_component_lookup(entity, component, component_type)
|
|
583
616
|
local generator = mask_generator.create(nil, function()
|
|
584
617
|
return entity_lookup.generator.bitmask:band(base_generator.bitmask)
|
|
585
618
|
end)
|
|
586
619
|
|
|
587
620
|
local function subscribed()
|
|
588
621
|
if not component_lookup then
|
|
589
|
-
component_lookup =
|
|
622
|
+
component_lookup = entity_lookup.filtered_components[component_type][component]
|
|
590
623
|
end
|
|
591
624
|
|
|
592
625
|
local current_storage = component_lookup.storage_group
|
|
@@ -604,9 +637,9 @@ function masking_controller.bind_component_generator(
|
|
|
604
637
|
end
|
|
605
638
|
|
|
606
639
|
function masking_controller.rebind_component_generators(masking: MaskingInternal, entity: Entity)
|
|
607
|
-
local
|
|
608
|
-
if
|
|
609
|
-
for component_type, lookups in
|
|
640
|
+
local entity_lookup = masking.lookups.entities[entity]
|
|
641
|
+
if entity_lookup then
|
|
642
|
+
for component_type, lookups in entity_lookup.filtered_components do
|
|
610
643
|
for component, lookup in lookups do
|
|
611
644
|
lookup.band_generator:destroy()
|
|
612
645
|
|
|
@@ -619,23 +652,24 @@ function masking_controller.rebind_component_generators(masking: MaskingInternal
|
|
|
619
652
|
end
|
|
620
653
|
end
|
|
621
654
|
|
|
622
|
-
function masking_controller.
|
|
655
|
+
function masking_controller.get_or_postpone_entity_lookup(
|
|
623
656
|
masking: MaskingInternal,
|
|
624
657
|
entity: Entity,
|
|
625
658
|
component: Entity,
|
|
626
659
|
component_type: number,
|
|
627
660
|
filter: MemberFilter?
|
|
628
|
-
):
|
|
661
|
+
): EntityLookup?
|
|
629
662
|
local lookup = masking.lookups.entities[entity]
|
|
630
663
|
if lookup then
|
|
631
664
|
return lookup
|
|
632
665
|
end
|
|
633
666
|
|
|
634
|
-
if filter
|
|
635
|
-
|
|
667
|
+
if filter ~= nil then
|
|
668
|
+
set_component_index_entry(masking.lookups.postponed, entity, component, component_type, { filter = filter })
|
|
669
|
+
else
|
|
670
|
+
set_component_index_entry(masking.lookups.postponed, entity, component, component_type, { filter = nil })
|
|
636
671
|
end
|
|
637
672
|
|
|
638
|
-
set_component_index_entry(masking.lookups.posponed, entity, component, component_type, filter)
|
|
639
673
|
return nil
|
|
640
674
|
end
|
|
641
675
|
|
|
@@ -711,12 +745,9 @@ function masking_controller.propagate_entity_addition(masking: MaskingInternal,
|
|
|
711
745
|
local entity_lookup = masking.lookups.entities[entity]
|
|
712
746
|
if entity_lookup then
|
|
713
747
|
entity_lookup.storage_group.changes.added[entity] = true
|
|
714
|
-
end
|
|
715
748
|
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
for component_type, lookups in component_lookups do
|
|
719
|
-
for component, lookup in lookups do
|
|
749
|
+
for _, lookups in entity_lookup.filtered_components do
|
|
750
|
+
for _, lookup in lookups do
|
|
720
751
|
lookup.storage_group.changes.added[entity] = true
|
|
721
752
|
end
|
|
722
753
|
end
|
|
@@ -745,32 +776,36 @@ function masking_controller.update_entity_filter(masking: MaskingInternal, entit
|
|
|
745
776
|
return generator
|
|
746
777
|
end
|
|
747
778
|
|
|
748
|
-
function masking_controller.start_entity(masking: MaskingInternal, entity: Entity,
|
|
779
|
+
function masking_controller.start_entity(masking: MaskingInternal, entity: Entity, given_filter: GivenFilter?)
|
|
780
|
+
local filter = get_usable_filter(given_filter)
|
|
749
781
|
local generator = masking:update_entity_filter(entity, filter)
|
|
750
782
|
|
|
751
783
|
local storage_group = masking:get_or_create_storage_group(generator.bitmask)
|
|
752
784
|
local active = get_or_set_active(storage_group, entity)
|
|
753
785
|
active.is_entity_mask = true
|
|
754
786
|
|
|
755
|
-
local new_lookup:
|
|
787
|
+
local new_lookup: EntityLookup = {
|
|
756
788
|
generator = generator,
|
|
757
789
|
filter = filter,
|
|
758
790
|
storage_group = storage_group,
|
|
791
|
+
filtered_components = create_component_indexes(),
|
|
792
|
+
components = create_component_indexes(),
|
|
759
793
|
}
|
|
760
794
|
masking.lookups.entities[entity] = new_lookup
|
|
761
795
|
|
|
762
|
-
local
|
|
763
|
-
if
|
|
764
|
-
for component_type, components in
|
|
765
|
-
for component,
|
|
766
|
-
masking:start_component(entity, component, component_type,
|
|
796
|
+
local postponed = masking.lookups.postponed[entity]
|
|
797
|
+
if postponed then
|
|
798
|
+
for component_type, components in postponed do
|
|
799
|
+
for component, postoned_info in components do
|
|
800
|
+
masking:start_component(entity, component, component_type, postoned_info.filter)
|
|
767
801
|
end
|
|
768
802
|
end
|
|
769
|
-
masking.lookups.
|
|
803
|
+
masking.lookups.postponed[entity] = nil
|
|
770
804
|
end
|
|
771
805
|
end
|
|
772
806
|
|
|
773
|
-
function masking_controller.set_entity(masking: MaskingInternal, entity: Entity,
|
|
807
|
+
function masking_controller.set_entity(masking: MaskingInternal, entity: Entity, given_filter: GivenFilter?)
|
|
808
|
+
local filter = get_usable_filter(given_filter)
|
|
774
809
|
local lookup = masking.lookups.entities[entity]
|
|
775
810
|
if not lookup then
|
|
776
811
|
utils.logerror "attempted to modify the filter of an unactive entity"
|
|
@@ -792,27 +827,24 @@ function masking_controller.stop_entity(masking: MaskingInternal, entity: Entity
|
|
|
792
827
|
utils.logerror "attemped to stop an unactive entity"
|
|
793
828
|
end
|
|
794
829
|
|
|
795
|
-
local
|
|
830
|
+
local postponed = masking.lookups.postponed[entity]
|
|
796
831
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
component_lookup.generator:destroy()
|
|
803
|
-
remove_component_active(component_lookup.storage_group, entity, component, component_type)
|
|
832
|
+
for component_type, lookups in lookup.filtered_components do
|
|
833
|
+
for component, component_lookup in lookups do
|
|
834
|
+
component_lookup.band_generator:destroy()
|
|
835
|
+
component_lookup.generator:destroy()
|
|
836
|
+
remove_component_active(component_lookup.storage_group, entity, component, component_type)
|
|
804
837
|
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
838
|
+
local component_storage = component_lookup.storage_group
|
|
839
|
+
component_storage.shared_with[entity] = nil
|
|
840
|
+
component_storage.changes.added[entity] = nil
|
|
841
|
+
component_storage.changes.changed[entity] = nil
|
|
809
842
|
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
end
|
|
814
|
-
posponed[component_type][component] = component_lookup.filter :: MemberFilter
|
|
843
|
+
if postponed == nil then
|
|
844
|
+
postponed = create_component_indexes() :: PostponedList
|
|
845
|
+
masking.lookups.postponed[entity] = postponed
|
|
815
846
|
end
|
|
847
|
+
postponed[component_type][component] = { filter = component_lookup.filter }
|
|
816
848
|
end
|
|
817
849
|
end
|
|
818
850
|
|
|
@@ -821,10 +853,16 @@ function masking_controller.stop_entity(masking: MaskingInternal, entity: Entity
|
|
|
821
853
|
lookup.storage_group.changes.added[entity] = nil
|
|
822
854
|
lookup.storage_group.changes.changed[entity] = nil
|
|
823
855
|
|
|
824
|
-
masking.lookups.components[entity] = nil
|
|
825
856
|
masking.lookups.entities[entity] = nil
|
|
826
857
|
end
|
|
827
858
|
|
|
859
|
+
function masking_controller.cleanup_entity(masking: MaskingInternal, entity: Entity)
|
|
860
|
+
masking.lookups.entities[entity] = nil
|
|
861
|
+
masking.lookups.postponed[entity] = nil
|
|
862
|
+
masking.lookups.deletions.entities[entity] = nil
|
|
863
|
+
masking.lookups.deletions.components[entity] = nil
|
|
864
|
+
end
|
|
865
|
+
|
|
828
866
|
function masking_controller.update_component_filter(
|
|
829
867
|
masking: MaskingInternal,
|
|
830
868
|
entity: Entity,
|
|
@@ -842,9 +880,10 @@ function masking_controller.start_component(
|
|
|
842
880
|
entity: Entity,
|
|
843
881
|
component: Entity,
|
|
844
882
|
component_type: number,
|
|
845
|
-
|
|
883
|
+
given_filter: GivenFilter?
|
|
846
884
|
)
|
|
847
|
-
local
|
|
885
|
+
local filter = get_usable_filter(given_filter)
|
|
886
|
+
local lookup = masking:get_or_postpone_entity_lookup(entity, component, component_type, filter)
|
|
848
887
|
if lookup == nil then
|
|
849
888
|
return
|
|
850
889
|
end
|
|
@@ -861,12 +900,13 @@ function masking_controller.start_component(
|
|
|
861
900
|
get_or_set_component_active(active, component, component_type)
|
|
862
901
|
set_component_index_entry(storage_group.shared_with, entity, component, component_type, true)
|
|
863
902
|
|
|
864
|
-
|
|
903
|
+
local component_lookup: ComponentLookup = {
|
|
865
904
|
generator = generator,
|
|
866
905
|
band_generator = band_generator,
|
|
867
|
-
filter = filter
|
|
906
|
+
filter = filter :: MemberFilter?, -- what
|
|
868
907
|
storage_group = storage_group,
|
|
869
|
-
}
|
|
908
|
+
}
|
|
909
|
+
lookup.filtered_components[component_type][component] = component_lookup
|
|
870
910
|
end
|
|
871
911
|
|
|
872
912
|
function masking_controller.set_component(
|
|
@@ -874,13 +914,14 @@ function masking_controller.set_component(
|
|
|
874
914
|
entity: Entity,
|
|
875
915
|
component: Entity,
|
|
876
916
|
component_type: number,
|
|
877
|
-
|
|
917
|
+
given_filter: GivenFilter?
|
|
878
918
|
)
|
|
879
|
-
local
|
|
919
|
+
local filter = get_usable_filter(given_filter)
|
|
920
|
+
local lookup = masking:get_or_postpone_entity_lookup(entity, component, component_type, filter)
|
|
880
921
|
if lookup == nil then
|
|
881
922
|
return
|
|
882
923
|
end
|
|
883
|
-
local component_lookup =
|
|
924
|
+
local component_lookup = lookup.filtered_components[component_type][component]
|
|
884
925
|
|
|
885
926
|
if filter == nil then
|
|
886
927
|
if component_lookup ~= nil then
|
|
@@ -919,13 +960,13 @@ function masking_controller.set_component(
|
|
|
919
960
|
band_generator.bitmask
|
|
920
961
|
)
|
|
921
962
|
end
|
|
922
|
-
|
|
923
|
-
set_component_index_entry(masking.lookups.components, entity, component, component_type, {
|
|
963
|
+
local new_lookup: ComponentLookup = {
|
|
924
964
|
generator = generator,
|
|
925
965
|
band_generator = band_generator,
|
|
926
|
-
filter = filter
|
|
966
|
+
filter = filter :: MemberFilter?,
|
|
927
967
|
storage_group = new_storage,
|
|
928
|
-
}
|
|
968
|
+
}
|
|
969
|
+
lookup.filtered_components[component_type][component] = new_lookup
|
|
929
970
|
end
|
|
930
971
|
end
|
|
931
972
|
|
|
@@ -935,16 +976,15 @@ function masking_controller.stop_component(
|
|
|
935
976
|
component: Entity,
|
|
936
977
|
component_type: number
|
|
937
978
|
)
|
|
938
|
-
local
|
|
939
|
-
if
|
|
940
|
-
|
|
941
|
-
|
|
979
|
+
local component_lookup, entity_lookup = masking:get_component_lookup(entity, component, component_type)
|
|
980
|
+
if component_lookup ~= nil then
|
|
981
|
+
component_lookup.band_generator:destroy()
|
|
982
|
+
component_lookup.generator:destroy()
|
|
942
983
|
|
|
943
|
-
remove_component_active(
|
|
944
|
-
remove_component_index_entry(
|
|
945
|
-
|
|
984
|
+
remove_component_active(component_lookup.storage_group, entity, component, component_type)
|
|
985
|
+
remove_component_index_entry(component_lookup.storage_group.shared_with, entity, component, component_type)
|
|
986
|
+
entity_lookup.filtered_components[component_type][component] = nil
|
|
946
987
|
else
|
|
947
|
-
local entity_lookup = masking.lookups.entities[entity]
|
|
948
988
|
if entity_lookup then
|
|
949
989
|
remove_component_active(entity_lookup.storage_group, entity, component, component_type)
|
|
950
990
|
end
|
|
@@ -957,20 +997,14 @@ function masking_controller.get_component_storage_group(
|
|
|
957
997
|
component: Entity,
|
|
958
998
|
component_type: number
|
|
959
999
|
): StorageGroup
|
|
960
|
-
local component_lookup =
|
|
961
|
-
|
|
962
|
-
entity,
|
|
963
|
-
component,
|
|
964
|
-
COMPONENT_TYPES.component
|
|
965
|
-
)
|
|
1000
|
+
local component_lookup, entity_lookup = masking:get_component_lookup(entity, component, component_type)
|
|
1001
|
+
|
|
966
1002
|
if component_lookup ~= nil then
|
|
967
1003
|
return component_lookup.storage_group
|
|
968
|
-
|
|
969
|
-
local entity_lookup = masking.lookups.entities[entity]
|
|
970
|
-
if not entity_lookup then
|
|
971
|
-
utils.logerror "attempted to use an entity that is not active"
|
|
972
|
-
end
|
|
1004
|
+
elseif entity_lookup then
|
|
973
1005
|
return entity_lookup.storage_group
|
|
1006
|
+
else
|
|
1007
|
+
error "attempted to use an entity that is not active"
|
|
974
1008
|
end
|
|
975
1009
|
end
|
|
976
1010
|
|
|
@@ -980,7 +1014,7 @@ function masking_controller.allocate_entity_addition(
|
|
|
980
1014
|
component: Entity,
|
|
981
1015
|
component_type: number
|
|
982
1016
|
)
|
|
983
|
-
local lookup =
|
|
1017
|
+
local lookup = masking:get_component_lookup(entity, component, component_type)
|
|
984
1018
|
if lookup ~= nil then
|
|
985
1019
|
lookup.storage_group.changes.added[entity] = true
|
|
986
1020
|
end
|
|
@@ -1055,8 +1089,123 @@ function masking_controller.allocate_pair_removal(
|
|
|
1055
1089
|
targets[target] = false
|
|
1056
1090
|
end
|
|
1057
1091
|
|
|
1058
|
-
function
|
|
1059
|
-
|
|
1092
|
+
local function remap_bitmask(
|
|
1093
|
+
bitmask: Bitmask,
|
|
1094
|
+
from: { [Member]: number },
|
|
1095
|
+
target: { [Member]: number },
|
|
1096
|
+
size: number?
|
|
1097
|
+
): Bitmask
|
|
1098
|
+
local result = utils.bitmask.create(size)
|
|
1099
|
+
for member, index in target do
|
|
1100
|
+
local old_index = from[member]
|
|
1101
|
+
if old_index then
|
|
1102
|
+
local old_bit = bitmask:get(old_index)
|
|
1103
|
+
if old_bit then
|
|
1104
|
+
result:set(index, old_bit)
|
|
1105
|
+
else
|
|
1106
|
+
result:clear(index)
|
|
1107
|
+
end
|
|
1108
|
+
end
|
|
1109
|
+
end
|
|
1110
|
+
return result
|
|
1111
|
+
end
|
|
1112
|
+
|
|
1113
|
+
function masking_controller.merge_storages(
|
|
1114
|
+
masking: MaskingInternal,
|
|
1115
|
+
old_storage: StorageGroup,
|
|
1116
|
+
new_storage: StorageGroup
|
|
1117
|
+
)
|
|
1118
|
+
for entity, active in old_storage.active do
|
|
1119
|
+
local new_active = get_or_set_active(new_storage, entity)
|
|
1120
|
+
merge_component_actives(new_active, active)
|
|
1121
|
+
|
|
1122
|
+
if active.is_entity_mask then
|
|
1123
|
+
local lookup = masking.lookups.entities[entity]
|
|
1124
|
+
lookup.storage_group = new_storage
|
|
1125
|
+
new_active.is_entity_mask = true
|
|
1126
|
+
end
|
|
1127
|
+
end
|
|
1128
|
+
for entity, shared_components in old_storage.shared_with do
|
|
1129
|
+
for component_type, components in shared_components do
|
|
1130
|
+
for component in components do
|
|
1131
|
+
set_component_index_entry(new_storage.shared_with, entity, component, component_type, true)
|
|
1132
|
+
|
|
1133
|
+
local lookup = masking:get_component_lookup(entity, component, component_type)
|
|
1134
|
+
if lookup ~= nil then
|
|
1135
|
+
lookup.storage_group = new_storage
|
|
1136
|
+
end
|
|
1137
|
+
end
|
|
1138
|
+
end
|
|
1139
|
+
end
|
|
1140
|
+
for entity, changes in old_storage.changes.changed do
|
|
1141
|
+
local new_changes = get_or_set_changes(new_storage, entity)
|
|
1142
|
+
merge_component_changes(new_changes, changes)
|
|
1143
|
+
end
|
|
1144
|
+
for entity in old_storage.deletions.entities do
|
|
1145
|
+
new_storage.deletions.entities[entity] = true
|
|
1146
|
+
end
|
|
1147
|
+
for entity, deleted_components in old_storage.deletions.components do
|
|
1148
|
+
for component_type, components in deleted_components do
|
|
1149
|
+
for component in components do
|
|
1150
|
+
set_component_index_entry(new_storage.deletions.components, entity, component, component_type, true)
|
|
1151
|
+
end
|
|
1152
|
+
end
|
|
1153
|
+
end
|
|
1154
|
+
end
|
|
1155
|
+
|
|
1156
|
+
function masking_controller.compact_members(masking: MaskingInternal)
|
|
1157
|
+
-- we dont recompute as nothing should've changed
|
|
1158
|
+
-- so this should be hopefully quite cheap
|
|
1159
|
+
local old_indexes = masking.member_indexes
|
|
1160
|
+
local new_indexes: { [Member]: number } = {}
|
|
1161
|
+
|
|
1162
|
+
local new_count = 0
|
|
1163
|
+
for member in old_indexes do
|
|
1164
|
+
new_indexes[member] = new_count
|
|
1165
|
+
new_count += 1
|
|
1166
|
+
end
|
|
1167
|
+
masking.member_indexes = new_indexes
|
|
1168
|
+
masking.member_count = new_count
|
|
1169
|
+
|
|
1170
|
+
for _, entity_lookup in masking.lookups.entities do
|
|
1171
|
+
local generator = entity_lookup.generator
|
|
1172
|
+
generator.bitmask = remap_bitmask(generator.bitmask, old_indexes, new_indexes, new_count)
|
|
1173
|
+
|
|
1174
|
+
for _, lookups in entity_lookup.filtered_components do
|
|
1175
|
+
for _, component_lookup in lookups do
|
|
1176
|
+
local component_generator = component_lookup.generator
|
|
1177
|
+
generator.bitmask = remap_bitmask(component_generator.bitmask, old_indexes, new_indexes, new_count)
|
|
1178
|
+
|
|
1179
|
+
local band_generator = component_lookup.band_generator
|
|
1180
|
+
band_generator.bitmask = remap_bitmask(band_generator.bitmask, old_indexes, new_indexes, new_count)
|
|
1181
|
+
end
|
|
1182
|
+
end
|
|
1183
|
+
end
|
|
1184
|
+
|
|
1185
|
+
local all = masking.all_members_generator
|
|
1186
|
+
local unactive = masking.unactive_members_generator
|
|
1187
|
+
local active = masking.active_members_generator
|
|
1188
|
+
|
|
1189
|
+
all.bitmask = remap_bitmask(all.bitmask, old_indexes, new_indexes, new_count)
|
|
1190
|
+
unactive.bitmask = remap_bitmask(unactive.bitmask, old_indexes, new_indexes, new_count)
|
|
1191
|
+
active.bitmask = remap_bitmask(active.bitmask, old_indexes, new_indexes, new_count)
|
|
1192
|
+
|
|
1193
|
+
local new_storages: Storages = {}
|
|
1194
|
+
|
|
1195
|
+
for _, storage in masking.storages do
|
|
1196
|
+
local new_bitmask = remap_bitmask(storage.mask.bitmask, old_indexes, new_indexes, new_count)
|
|
1197
|
+
storage.mask.bitmask = new_bitmask
|
|
1198
|
+
local new_hash = new_bitmask:tostring()
|
|
1199
|
+
storage.mask.hash = new_hash
|
|
1200
|
+
storage.mask.members = masking:get_members_from_bitmask(new_bitmask)
|
|
1201
|
+
|
|
1202
|
+
local existing = new_storages[new_hash]
|
|
1203
|
+
if existing then
|
|
1204
|
+
masking:merge_storages(storage, existing)
|
|
1205
|
+
else
|
|
1206
|
+
new_storages[new_hash] = storage
|
|
1207
|
+
end
|
|
1208
|
+
end
|
|
1060
1209
|
end
|
|
1061
1210
|
|
|
1062
1211
|
function masking_controller.create_generator_from_filter(masking: MaskingInternal, filter: MemberFilter): MaskGenerator
|
|
@@ -1131,6 +1280,10 @@ function masking_controller.register_member(masking: MaskingInternal, member: Me
|
|
|
1131
1280
|
masking.unactive_members_generator.bitmask:set(current)
|
|
1132
1281
|
masking.all_members_generator.bitmask:set(current)
|
|
1133
1282
|
masking.active_members_generator:compute()
|
|
1283
|
+
|
|
1284
|
+
if masking.member_count >= masking.compact_count then
|
|
1285
|
+
masking:compact_members()
|
|
1286
|
+
end
|
|
1134
1287
|
end
|
|
1135
1288
|
|
|
1136
1289
|
function masking_controller.unregister_member(masking: MaskingInternal, member: Member)
|
|
@@ -1170,6 +1323,7 @@ local function create(): MaskingController
|
|
|
1170
1323
|
|
|
1171
1324
|
self.member_indexes = {}
|
|
1172
1325
|
self.member_count = 0
|
|
1326
|
+
self.compact_count = 100
|
|
1173
1327
|
self.storages = {}
|
|
1174
1328
|
self.lookups = {
|
|
1175
1329
|
entities = {},
|
|
@@ -1178,7 +1332,7 @@ local function create(): MaskingController
|
|
|
1178
1332
|
entities = {},
|
|
1179
1333
|
components = {},
|
|
1180
1334
|
},
|
|
1181
|
-
|
|
1335
|
+
postponed = {},
|
|
1182
1336
|
}
|
|
1183
1337
|
self.unreplicated = {}
|
|
1184
1338
|
self.all_members_generator = masking_controller.create_all_members_generator(self)
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
--!native
|
|
2
|
+
--!optimize 2
|
|
3
|
+
|
|
4
|
+
local utils = require "../utils"
|
|
2
5
|
|
|
3
6
|
type ComputeCallback = (generator: MaskGenerator) -> utils.Bitmask
|
|
4
7
|
type SubscribeCallback = (generator: MaskGenerator) -> ()
|
|
@@ -40,7 +43,7 @@ function mask_generator.unmark_tracked(generator: GeneratorInternal, to_untrack:
|
|
|
40
43
|
|
|
41
44
|
if last and last ~= to_untrack then
|
|
42
45
|
generator.tracked_by[index] = last
|
|
43
|
-
generator.tracked_indexes[last] = index
|
|
46
|
+
generator.tracked_indexes[last :: GeneratorInternal] = index
|
|
44
47
|
end
|
|
45
48
|
|
|
46
49
|
generator.tracked_indexes[to_untrack] = nil
|
|
@@ -49,17 +52,17 @@ end
|
|
|
49
52
|
|
|
50
53
|
function mask_generator.run_subscribed(generator: GeneratorInternal)
|
|
51
54
|
if generator.subscribed then
|
|
52
|
-
generator.subscribed(generator)
|
|
55
|
+
generator.subscribed(generator :: GeneratorInternal)
|
|
53
56
|
end
|
|
54
57
|
end
|
|
55
58
|
|
|
56
59
|
function mask_generator.compute(generator: GeneratorInternal)
|
|
57
60
|
if generator.compute_callback then
|
|
58
|
-
local result = generator.compute_callback(generator)
|
|
61
|
+
local result = generator.compute_callback(generator :: GeneratorInternal)
|
|
59
62
|
generator.bitmask = result
|
|
60
63
|
end
|
|
61
64
|
if generator.subscribed then
|
|
62
|
-
generator.subscribed(generator)
|
|
65
|
+
generator.subscribed(generator :: GeneratorInternal)
|
|
63
66
|
end
|
|
64
67
|
|
|
65
68
|
for _, tracking in generator.tracked_by do
|