@rbxts/replecs 0.0.1-rc.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.
@@ -0,0 +1,97 @@
1
+ local utils = require(script.Parent.Parent.utils)
2
+
3
+ type ComputeCallback = (generator: MaskGenerator) -> utils.Bitmask
4
+ type SubscribeCallback = (generator: MaskGenerator) -> ()
5
+
6
+ export type MaskGenerator = {
7
+ compute_callback: ComputeCallback?,
8
+ subscribed: SubscribeCallback?,
9
+ bitmask: utils.Bitmask,
10
+
11
+ tracking: { GeneratorInternal },
12
+ tracked_by: { GeneratorInternal },
13
+ tracked_indexes: { [GeneratorInternal]: number },
14
+
15
+ compute: (self: MaskGenerator) -> (),
16
+ run_subscribed: (self: MaskGenerator) -> (),
17
+ track: (self: MaskGenerator, tracking: MaskGenerator) -> (),
18
+ destroy: (self: MaskGenerator) -> (),
19
+ }
20
+
21
+ local mask_generator = {}
22
+ mask_generator.__index = mask_generator
23
+
24
+ type GeneratorInternal = MaskGenerator & typeof(mask_generator)
25
+
26
+ function mask_generator.track(generator: GeneratorInternal, tracking: GeneratorInternal)
27
+ table.insert(generator.tracking, tracking)
28
+ tracking:mark_as_tracked(generator)
29
+ end
30
+
31
+ function mask_generator.mark_as_tracked(generator: GeneratorInternal, tracked_by: GeneratorInternal)
32
+ table.insert(generator.tracked_by, tracked_by)
33
+ generator.tracked_indexes[tracked_by] = #generator.tracked_by
34
+ end
35
+
36
+ function mask_generator.unmark_tracked(generator: GeneratorInternal, to_untrack: GeneratorInternal)
37
+ local index = generator.tracked_indexes[to_untrack]
38
+ if index then
39
+ local last = table.remove(generator.tracked_by)
40
+
41
+ if last and last ~= to_untrack then
42
+ generator.tracked_by[index] = last
43
+ generator.tracked_indexes[last] = index
44
+ end
45
+
46
+ generator.tracked_indexes[to_untrack] = nil
47
+ end
48
+ end
49
+
50
+ function mask_generator.run_subscribed(generator: GeneratorInternal)
51
+ if generator.subscribed then
52
+ generator.subscribed(generator)
53
+ end
54
+ end
55
+
56
+ function mask_generator.compute(generator: GeneratorInternal)
57
+ if generator.compute_callback then
58
+ local result = generator.compute_callback(generator)
59
+ generator.bitmask = result
60
+ end
61
+ if generator.subscribed then
62
+ generator.subscribed(generator)
63
+ end
64
+
65
+ for _, tracking in generator.tracked_by do
66
+ tracking:compute()
67
+ end
68
+ end
69
+
70
+ function mask_generator.destroy(generator: GeneratorInternal)
71
+ for _, tracking in generator.tracking do
72
+ tracking:unmark_tracked(generator :: GeneratorInternal)
73
+ end
74
+ end
75
+
76
+ function create(bitmask: utils.Bitmask?, compute: ComputeCallback?): MaskGenerator
77
+ local self = {} :: MaskGenerator
78
+
79
+ self.bitmask = bitmask or (compute :: ComputeCallback)(self)
80
+ self.compute_callback = compute
81
+ self.subscribed = nil
82
+ self.tracking = {}
83
+ self.tracked_by = {}
84
+ self.tracked_indexes = {}
85
+
86
+ return setmetatable(self, mask_generator) :: any
87
+ end
88
+
89
+ function follow(leading: MaskGenerator): MaskGenerator
90
+ local created = create(nil, function()
91
+ return leading.bitmask
92
+ end)
93
+ created:track(leading)
94
+ return created
95
+ end
96
+
97
+ return { create = create, follow = follow }