@rbxts/planck 0.2.5 → 0.3.0-alpha.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.
package/package.json CHANGED
@@ -1,51 +1,40 @@
1
- {
2
- "name": "@rbxts/planck",
3
- "version": "0.2.5",
4
- "description": "An agnostic scheduler for ECS",
5
- "main": "out/init.lua",
6
- "repository": {
7
- "type": "git",
8
- "url": "https://github.com/yetanotherclown/planck"
9
- },
10
- "homepage": "https://yetanotherclown.github.io/planck",
11
- "keywords": [
12
- "ECS",
13
- "Entity Component System",
14
- "Scheduler",
15
- "@rbxts",
16
- "Roblox",
17
- "Roblox-TS",
18
- "roblox ts",
19
- "roblox-ts"
20
- ],
21
- "author": "YetAnotherClown",
22
- "license": "MIT",
23
- "types": "out/index.d.ts",
24
- "files": [
25
- "out",
26
- "!**/*.tsbuildinfo",
27
- "!out/__tests__",
28
- "!out/__tests__/**/*",
29
- "!out/jest.config.luau"
30
- ],
31
- "publishConfig": {
32
- "access": "public"
33
- },
34
- "devDependencies": {
35
- "@rbxts/compiler-types": "3.0.0-types.0",
36
- "@rbxts/types": "^1.0.813",
37
- "@typescript-eslint/eslint-plugin": "^8.19.0",
38
- "@typescript-eslint/parser": "^8.19.0",
39
- "eslint": "^9.17.0",
40
- "eslint-config-prettier": "^9.1.0",
41
- "eslint-plugin-prettier": "^5.2.1",
42
- "eslint-plugin-roblox-ts": "^0.0.36",
43
- "prettier": "^3.4.2",
44
- "roblox-ts": "^3.0.0",
45
- "typescript": "^5.7.2"
46
- },
47
- "scripts": {
48
- "build": "rbxtsc",
49
- "watch": "rbxtsc -w"
50
- }
51
- }
1
+ {
2
+ "name": "@rbxts/planck",
3
+ "version": "0.3.0-alpha.2",
4
+ "description": "An Agnostic Scheduler for ECS",
5
+ "main": "src",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/YetAnotherClown/planck.git"
9
+ },
10
+ "keywords": [],
11
+ "author": "YetAnotherClown",
12
+ "contributors": [
13
+ "YetAnotherClown",
14
+ "MajestikButter"
15
+ ],
16
+ "homepage": "https://github.com/YetAnotherClown/planck",
17
+ "license": "MIT",
18
+ "types": "src/index.d.ts",
19
+ "files": [
20
+ "src",
21
+ "LICENSE.md",
22
+ "README.md"
23
+ ],
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "devDependencies": {
28
+ "@rbxts/compiler-types": "^2.3.0-types.1",
29
+ "@rbxts/types": "^1.0.781",
30
+ "@typescript-eslint/eslint-plugin": "^5.8.0",
31
+ "@typescript-eslint/parser": "^5.8.0",
32
+ "eslint": "^8.5.0",
33
+ "eslint-config-prettier": "^8.3.0",
34
+ "eslint-plugin-prettier": "^4.0.0",
35
+ "eslint-plugin-roblox-ts": "^0.0.32",
36
+ "prettier": "^2.5.1",
37
+ "roblox-ts": "^3.0.0",
38
+ "typescript": "^5.4.2"
39
+ }
40
+ }
@@ -1,180 +1,220 @@
1
- local AdjacencyMatrix = {}
2
- AdjacencyMatrix.__index = AdjacencyMatrix
3
-
4
- function AdjacencyMatrix:__tostring()
5
- local s = "\n"
6
-
7
- for i = 1, self.length do
8
- if i == 1 then
9
- s ..= "\n"
10
- end
11
-
12
- local sub = ""
13
- for j = 1, self.width do
14
- if j == self.width then
15
- sub ..= `{self.matrix[i][j]}`
16
- continue
17
- end
18
-
19
- sub ..= `{self.matrix[i][j]}, `
20
- end
21
-
22
- sub ..= "\n"
23
- s ..= sub
24
- end
25
-
26
- return s
27
- end
28
-
29
- function AdjacencyMatrix:extend()
30
- self.length = (self.length :: number) + 1
31
- self.width = (self.length :: number) + 1
32
-
33
- self.matrix[self.length] = {}
34
- for j = 1, self.width do
35
- self.matrix[self.length][j] = 0
36
- end
37
-
38
- for i = 1, self.length do
39
- self.matrix[i][self.width] = 0
40
- end
41
- end
42
-
43
- function AdjacencyMatrix:setEdge(i, j, val)
44
- self.matrix[i][j] = val
45
- end
46
-
47
- function AdjacencyMatrix:toAdjacencyList()
48
- local list = {}
49
-
50
- for i = 1, self.length do
51
- list[i] = {}
52
- for j = 1, self.width do
53
- if self.matrix[i][j] ~= 0 then
54
- table.insert(list[i], j)
55
- end
56
- end
57
- end
58
-
59
- return list
60
- end
61
-
62
- function AdjacencyMatrix:topologicalSort(): { number }?
63
- local adjacencyList = self:toAdjacencyList()
64
-
65
- local result = {}
66
- local inDegrees = table.create(self.length, 0)
67
-
68
- for i = 1, self.length do
69
- for _, j in adjacencyList[i] do
70
- inDegrees[j] += 1
71
- end
72
- end
73
-
74
- local queue = {}
75
- for i = 1, self.length do
76
- if inDegrees[i] == 0 then
77
- table.insert(queue, i)
78
- end
79
- end
80
-
81
- while #queue ~= 0 do
82
- local i = table.remove(queue, 1) :: number
83
- table.insert(result, i)
84
-
85
- for _, j in adjacencyList[i] do
86
- inDegrees[j] -= 1
87
- if inDegrees[j] == 0 then
88
- table.insert(queue, j)
89
- end
90
- end
91
- end
92
-
93
- if #result ~= self.length then
94
- return nil
95
- end
96
-
97
- return result
98
- end
99
-
100
- function AdjacencyMatrix.new()
101
- return setmetatable({
102
- matrix = {},
103
- length = 0,
104
- width = 0,
105
- }, AdjacencyMatrix)
106
- end
107
-
108
- local DependencyGraph = {}
109
- DependencyGraph.__index = DependencyGraph
110
-
111
- function DependencyGraph:getOrderedList(): { any }?
112
- local orderedList = {}
113
-
114
- local topologicalSort = self.matrix:topologicalSort()
115
- if not topologicalSort then
116
- return nil
117
- end
118
-
119
- for _, i in topologicalSort do
120
- table.insert(orderedList, self.nodes[i])
121
- end
122
-
123
- return orderedList
124
- end
125
-
126
- function DependencyGraph:insertBefore(node, beforeNode)
127
- if not table.find(self.nodes, beforeNode) then
128
- error("Node not found in DependencyGraph:insertBefore(_, unknown)")
129
- end
130
-
131
- table.insert(self.nodes, node)
132
- local j = #self.nodes
133
- local i = table.find(self.nodes, beforeNode)
134
-
135
- self.matrix:extend()
136
- self.matrix:setEdge(j, i, 1)
137
-
138
- return self
139
- end
140
-
141
- function DependencyGraph:insertAfter(node, afterNode)
142
- if not table.find(self.nodes, afterNode) then
143
- error("Node not found in DependencyGraph:insertAfter(_, unknown)")
144
- end
145
-
146
- table.insert(self.nodes, node)
147
-
148
- local j = #self.nodes
149
- local i = table.find(self.nodes, afterNode)
150
-
151
- self.matrix:extend()
152
- self.matrix:setEdge(i, j, 1)
153
-
154
- return self
155
- end
156
-
157
- function DependencyGraph:insert(node)
158
- local i = #self.nodes
159
- table.insert(self.nodes, node)
160
- local j = #self.nodes
161
-
162
- self.matrix:extend()
163
-
164
- if i ~= 0 then
165
- self.matrix:setEdge(i, j, 1)
166
- end
167
-
168
- return self
169
- end
170
-
171
- function DependencyGraph.new()
172
- return setmetatable({
173
- nodes = {},
174
- matrix = AdjacencyMatrix.new(),
175
- length = 0,
176
- width = 0,
177
- }, DependencyGraph)
178
- end
179
-
180
- return DependencyGraph
1
+ local AdjacencyMatrix = {}
2
+ AdjacencyMatrix.__index = AdjacencyMatrix
3
+
4
+ export type AdjacencyMatrix = {
5
+ matrix: { { number } },
6
+ length: number,
7
+ width: number,
8
+
9
+ extend: (self: AdjacencyMatrix) -> (),
10
+ setEdge: (self: AdjacencyMatrix, i: number, j: number, v: number) -> (),
11
+ toAdjacencyList: (self: AdjacencyMatrix) -> { { number } },
12
+ topologicalSort: (self: AdjacencyMatrix) -> { number }?,
13
+ new: () -> AdjacencyMatrix,
14
+ }
15
+
16
+ function AdjacencyMatrix:__tostring()
17
+ local s = "\n"
18
+
19
+ for i = 1, self.length do
20
+ if i == 1 then
21
+ s ..= "\n"
22
+ end
23
+
24
+ local sub = ""
25
+ for j = 1, self.width do
26
+ if j == self.width then
27
+ sub ..= `{self.matrix[i][j]}`
28
+ continue
29
+ end
30
+
31
+ sub ..= `{self.matrix[i][j]}, `
32
+ end
33
+
34
+ sub ..= "\n"
35
+ s ..= sub
36
+ end
37
+
38
+ return s
39
+ end
40
+
41
+ function AdjacencyMatrix:extend()
42
+ self.length = (self.length :: number) + 1
43
+ self.width = (self.length :: number) + 1
44
+
45
+ self.matrix[self.length] = {}
46
+ for j = 1, self.width do
47
+ self.matrix[self.length][j] = 0
48
+ end
49
+
50
+ for i = 1, self.length do
51
+ self.matrix[i][self.width] = 0
52
+ end
53
+ end
54
+
55
+ function AdjacencyMatrix:setEdge(i, j, val)
56
+ self.matrix[i][j] = val
57
+ end
58
+
59
+ function AdjacencyMatrix:toAdjacencyList()
60
+ local list = {}
61
+
62
+ for i = 1, self.length do
63
+ list[i] = {}
64
+ for j = 1, self.width do
65
+ if self.matrix[i][j] ~= 0 then
66
+ table.insert(list[i], j)
67
+ end
68
+ end
69
+ end
70
+
71
+ return list
72
+ end
73
+
74
+ function AdjacencyMatrix:topologicalSort(): { number }?
75
+ local adjacencyList = self:toAdjacencyList()
76
+
77
+ local result = {}
78
+ local inDegrees = table.create(self.length, 0)
79
+
80
+ for i = 1, self.length do
81
+ for _, j in adjacencyList[i] do
82
+ inDegrees[j] += 1
83
+ end
84
+ end
85
+
86
+ local queue = {}
87
+ for i = 1, self.length do
88
+ if inDegrees[i] == 0 then
89
+ table.insert(queue, i)
90
+ end
91
+ end
92
+
93
+ while #queue ~= 0 do
94
+ local i = table.remove(queue, 1) :: number
95
+ table.insert(result, i)
96
+
97
+ for _, j in adjacencyList[i] do
98
+ inDegrees[j] -= 1
99
+ if inDegrees[j] == 0 then
100
+ table.insert(queue, j)
101
+ end
102
+ end
103
+ end
104
+
105
+ if #result ~= self.length then
106
+ return nil
107
+ end
108
+
109
+ return result
110
+ end
111
+
112
+ function AdjacencyMatrix.new(): AdjacencyMatrix
113
+ return setmetatable({
114
+ matrix = {},
115
+ length = 0,
116
+ width = 0,
117
+ }, AdjacencyMatrix) :: any
118
+ end
119
+
120
+ export type DependencyGraph<T> = {
121
+ nodes: { T },
122
+ matrix: AdjacencyMatrix,
123
+ length: number,
124
+ width: number,
125
+
126
+ getOrderedList: (self: DependencyGraph<T>) -> { T }?,
127
+ insert: (self: DependencyGraph<T>, node: T) -> DependencyGraph<T>,
128
+ insertAfter: (
129
+ self: DependencyGraph<T>,
130
+ node: T,
131
+ afterNode: T
132
+ ) -> DependencyGraph<T>,
133
+ insertBefore: (
134
+ self: DependencyGraph<T>,
135
+ node: T,
136
+ beforeNode: T
137
+ ) -> DependencyGraph<T>,
138
+ new: () -> DependencyGraph<T>,
139
+ }
140
+
141
+ local DependencyGraph = {}
142
+ DependencyGraph.__index = DependencyGraph
143
+
144
+ function DependencyGraph:getOrderedList(): { any }?
145
+ local orderedList = {}
146
+
147
+ local topologicalSort = self.matrix:topologicalSort()
148
+ if not topologicalSort then
149
+ return nil
150
+ end
151
+
152
+ for _, i in topologicalSort do
153
+ table.insert(orderedList, self.nodes[i])
154
+ end
155
+
156
+ return orderedList
157
+ end
158
+
159
+ function DependencyGraph:insertBefore(node, beforeNode)
160
+ if not table.find(self.nodes, beforeNode) then
161
+ error("Node not found in DependencyGraph:insertBefore(_, unknown)")
162
+ end
163
+
164
+ local j = table.find(self.nodes, node)
165
+ if not j then
166
+ table.insert(self.nodes, node)
167
+ j = #self.nodes
168
+ end
169
+
170
+ local i = table.find(self.nodes, beforeNode)
171
+
172
+ self.matrix:extend()
173
+ self.matrix:setEdge(j, i, 1)
174
+
175
+ return self
176
+ end
177
+
178
+ function DependencyGraph:insertAfter(node, afterNode)
179
+ if not table.find(self.nodes, afterNode) then
180
+ error("Node not found in DependencyGraph:insertAfter(_, unknown)")
181
+ end
182
+
183
+ local j = table.find(self.nodes, node)
184
+ if not j then
185
+ table.insert(self.nodes, node)
186
+ j = #self.nodes
187
+ end
188
+
189
+ local i = table.find(self.nodes, afterNode)
190
+
191
+ self.matrix:extend()
192
+ self.matrix:setEdge(i, j, 1)
193
+
194
+ return self
195
+ end
196
+
197
+ function DependencyGraph:insert(node)
198
+ local i = #self.nodes
199
+ table.insert(self.nodes, node)
200
+ local j = #self.nodes
201
+
202
+ self.matrix:extend()
203
+
204
+ if i ~= 0 then
205
+ self.matrix:setEdge(i, j, 1)
206
+ end
207
+
208
+ return self
209
+ end
210
+
211
+ function DependencyGraph.new<T>(): DependencyGraph<T>
212
+ return setmetatable({
213
+ nodes = {},
214
+ matrix = AdjacencyMatrix.new(),
215
+ length = 0,
216
+ width = 0,
217
+ }, DependencyGraph) :: any
218
+ end
219
+
220
+ return DependencyGraph
package/src/Phase.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Phases represent tags that tell the scheduler when to
3
+ * schedule a set of systems.
4
+ */
5
+ export class Phase {
6
+ /** Runs before the `Startup` Phase. */
7
+ static PreStartup: Phase;
8
+ /**
9
+ * This Phase will run once, the first time the Scheduler is ran,
10
+ * before any other Phases are ran.
11
+ */
12
+ static Startup: Phase;
13
+ /** Runs after the `Startup` phase. */
14
+ static PostStartup: Phase;
15
+
16
+ private _type: "phase";
17
+
18
+ /**
19
+ * Creates a new Phase, with an optional name to use for debugging.
20
+ * When no name is provided, the script and line number will be used.
21
+ */
22
+ constructor(name?: string);
23
+ }
@@ -1,41 +1,41 @@
1
- --- @class Phase
2
- ---
3
- --- Phases represent tags that tell the scheduler when to
4
- --- schedule a set of systems.
5
- local Phase = {}
6
- Phase.__index = Phase
7
-
8
- function Phase:__tostring()
9
- return self._name
10
- end
11
-
12
- --- @within Phase
13
- ---
14
- --- Creates a new Phase, with an optional name to use for debugging.
15
- --- When no name is provided, the script and line number will be used.
16
- function Phase.new(name: string?)
17
- name = name or debug.info(2, "sl")
18
- return setmetatable({
19
- _name = name,
20
- _type = "phase",
21
- }, Phase)
22
- end
23
-
24
- --- @prop PreStartup Phase
25
- --- @within Phase
26
- --- Runs before the `Startup` Phase.
27
-
28
- --- @prop Startup Phase
29
- --- @within Phase
30
- --- This Phase will run once, the first time the Scheduler is ran,
31
- --- before any other Phases are ran.
32
-
33
- --- @prop PostStartup Phase
34
- --- @within Phase
35
- --- Runs after the `Startup` phase.
36
-
37
- Phase.PreStartup = Phase.new("PreStartup")
38
- Phase.Startup = Phase.new("Startup")
39
- Phase.PostStartup = Phase.new("PostStartup")
40
-
41
- return Phase
1
+ --- @class Phase
2
+ ---
3
+ --- Phases represent tags that tell the scheduler when to
4
+ --- schedule a set of systems.
5
+ local Phase = {}
6
+ Phase.__index = Phase
7
+
8
+ function Phase:__tostring()
9
+ return self._name
10
+ end
11
+
12
+ --- @within Phase
13
+ ---
14
+ --- Creates a new Phase, with an optional name to use for debugging.
15
+ --- When no name is provided, the script and line number will be used.
16
+ function Phase.new(name: string?)
17
+ name = name or debug.info(2, "sl")
18
+ return setmetatable({
19
+ _name = name,
20
+ _type = "phase",
21
+ }, Phase)
22
+ end
23
+
24
+ --- @prop PreStartup Phase
25
+ --- @within Phase
26
+ --- Runs before the `Startup` Phase.
27
+
28
+ --- @prop Startup Phase
29
+ --- @within Phase
30
+ --- This Phase will run once, the first time the Scheduler is ran,
31
+ --- before any other Phases are ran.
32
+
33
+ --- @prop PostStartup Phase
34
+ --- @within Phase
35
+ --- Runs after the `Startup` phase.
36
+
37
+ Phase.PreStartup = Phase.new("PreStartup")
38
+ Phase.Startup = Phase.new("Startup")
39
+ Phase.PostStartup = Phase.new("PostStartup")
40
+
41
+ return Phase
@@ -0,0 +1,26 @@
1
+ import { Phase } from "./Phase";
2
+
3
+ /**
4
+ * Pipelines represent a set of ordered Phases. Systems cannot be
5
+ * assigned to Pipelines themselves, but rather to Phases within
6
+ * those Pipelines.
7
+ */
8
+ export class Pipeline {
9
+ /** A Pipeline containing the `PreStartup`, `Startup`, and `PostStartup` phases. */
10
+ static Startup: Pipeline;
11
+
12
+ private _type: "pipeline";
13
+
14
+ /**
15
+ * Creates a new Pipeline, with an optional name to use for debugging.
16
+ * When no name is provided, the script and line number will be used.
17
+ */
18
+ constructor(name?: string);
19
+
20
+ /** Adds a Phase to the Pipeline, ordering it implicitly. */
21
+ insert(phase: Phase): this;
22
+ /** Adds a Phase to the Pipeline after another Phase, ordering it explicitly. */
23
+ insertAfter(phase: Phase, after: Phase): this;
24
+ /** Adds a Phase to the Pipeline before another Phase, ordering it explicitly. */
25
+ insertBefore(phase: Phase, before: Phase): this;
26
+ }