@trioforge/crucible 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/client/package.json +4 -0
- package/emit/package.json +4 -0
- package/out/all.d.ts +7 -0
- package/out/all.luau +2 -0
- package/out/attribute.d.ts +7 -0
- package/out/attribute.luau +7 -0
- package/out/client/index.d.ts +10 -0
- package/out/client/init.luau +55 -0
- package/out/configs.d.ts +37 -0
- package/out/configs.luau +46 -0
- package/out/crucible-behaviour.d.ts +16 -0
- package/out/crucible-behaviour.luau +78 -0
- package/out/crucible-object.d.ts +10 -0
- package/out/crucible-object.luau +69 -0
- package/out/data.d.ts +224 -0
- package/out/data.luau +97 -0
- package/out/emit/configs.d.ts +4 -0
- package/out/emit/configs.luau +22 -0
- package/out/emit/data.d.ts +6 -0
- package/out/emit/data.luau +19 -0
- package/out/emit/index.d.ts +45 -0
- package/out/emit/init.luau +101 -0
- package/out/emit/network.d.ts +6 -0
- package/out/emit/network.luau +36 -0
- package/out/emit/replicated.d.ts +4 -0
- package/out/emit/replicated.luau +13 -0
- package/out/index.d.ts +20 -0
- package/out/init.luau +34 -0
- package/out/inject.d.ts +1 -0
- package/out/inject.luau +7 -0
- package/out/internal/binding.d.ts +1 -0
- package/out/internal/binding.luau +615 -0
- package/out/internal/boot.d.ts +1 -0
- package/out/internal/boot.luau +562 -0
- package/out/internal/configs/limits.d.ts +10 -0
- package/out/internal/configs/limits.luau +25 -0
- package/out/internal/configs/port.d.ts +29 -0
- package/out/internal/configs/port.luau +99 -0
- package/out/internal/configs/runtime.d.ts +21 -0
- package/out/internal/configs/runtime.luau +981 -0
- package/out/internal/construction-claim.d.ts +1 -0
- package/out/internal/construction-claim.luau +26 -0
- package/out/internal/data/admission.d.ts +1 -0
- package/out/internal/data/admission.luau +673 -0
- package/out/internal/data/declarations.d.ts +1 -0
- package/out/internal/data/declarations.luau +384 -0
- package/out/internal/data/envelope.d.ts +1 -0
- package/out/internal/data/envelope.luau +318 -0
- package/out/internal/data/handles.d.ts +1 -0
- package/out/internal/data/handles.luau +255 -0
- package/out/internal/data/inbox-transforms.d.ts +1 -0
- package/out/internal/data/inbox-transforms.luau +458 -0
- package/out/internal/data/inbox.d.ts +1 -0
- package/out/internal/data/inbox.luau +437 -0
- package/out/internal/data/lease.d.ts +1 -0
- package/out/internal/data/lease.luau +304 -0
- package/out/internal/data/limits.d.ts +1 -0
- package/out/internal/data/limits.luau +234 -0
- package/out/internal/data/messages.d.ts +1 -0
- package/out/internal/data/messages.luau +69 -0
- package/out/internal/data/operation-id.d.ts +1 -0
- package/out/internal/data/operation-id.luau +61 -0
- package/out/internal/data/paths.d.ts +2 -0
- package/out/internal/data/paths.luau +323 -0
- package/out/internal/data/port.d.ts +1 -0
- package/out/internal/data/port.luau +290 -0
- package/out/internal/data/profiles.d.ts +1 -0
- package/out/internal/data/profiles.luau +862 -0
- package/out/internal/data/receipts.d.ts +1 -0
- package/out/internal/data/receipts.luau +190 -0
- package/out/internal/data/record-bindings.d.ts +1 -0
- package/out/internal/data/record-bindings.luau +92 -0
- package/out/internal/data/record-declarations.d.ts +1 -0
- package/out/internal/data/record-declarations.luau +140 -0
- package/out/internal/data/records.d.ts +1 -0
- package/out/internal/data/records.luau +400 -0
- package/out/internal/data/runtime.d.ts +1 -0
- package/out/internal/data/runtime.luau +918 -0
- package/out/internal/data/scheduler.d.ts +1 -0
- package/out/internal/data/scheduler.luau +507 -0
- package/out/internal/data/session.d.ts +1 -0
- package/out/internal/data/session.luau +234 -0
- package/out/internal/data/shutdown.d.ts +1 -0
- package/out/internal/data/shutdown.luau +91 -0
- package/out/internal/data/waiters.d.ts +1 -0
- package/out/internal/data/waiters.luau +65 -0
- package/out/internal/dense-list.d.ts +1 -0
- package/out/internal/dense-list.luau +155 -0
- package/out/internal/diagnostics.d.ts +1 -0
- package/out/internal/diagnostics.luau +29 -0
- package/out/internal/hooks.d.ts +1 -0
- package/out/internal/hooks.luau +53 -0
- package/out/internal/implementers.d.ts +1 -0
- package/out/internal/implementers.luau +119 -0
- package/out/internal/lifecycle.d.ts +1 -0
- package/out/internal/lifecycle.luau +912 -0
- package/out/internal/log-output.d.ts +1 -0
- package/out/internal/log-output.luau +106 -0
- package/out/internal/network/catalog.d.ts +26 -0
- package/out/internal/network/catalog.luau +182 -0
- package/out/internal/network/claims.d.ts +1 -0
- package/out/internal/network/claims.luau +154 -0
- package/out/internal/network/client-session.d.ts +1 -0
- package/out/internal/network/client-session.luau +403 -0
- package/out/internal/network/codec.d.ts +63 -0
- package/out/internal/network/codec.luau +1183 -0
- package/out/internal/network/envelope.d.ts +1 -0
- package/out/internal/network/envelope.luau +247 -0
- package/out/internal/network/limits.d.ts +26 -0
- package/out/internal/network/limits.luau +55 -0
- package/out/internal/network/port.d.ts +1 -0
- package/out/internal/network/port.luau +19 -0
- package/out/internal/network/roblox-network-port.d.ts +1 -0
- package/out/internal/network/roblox-network-port.luau +105 -0
- package/out/internal/network/schema.d.ts +72 -0
- package/out/internal/network/schema.luau +386 -0
- package/out/internal/network/server-session.d.ts +1 -0
- package/out/internal/network/server-session.luau +393 -0
- package/out/internal/network/session.d.ts +1 -0
- package/out/internal/network/session.luau +266 -0
- package/out/internal/port.d.ts +1 -0
- package/out/internal/port.luau +12 -0
- package/out/internal/reactive/context.d.ts +1 -0
- package/out/internal/reactive/context.luau +149 -0
- package/out/internal/reactive/flush.d.ts +1 -0
- package/out/internal/reactive/flush.luau +355 -0
- package/out/internal/reactive/graph.d.ts +1 -0
- package/out/internal/reactive/graph.luau +626 -0
- package/out/internal/reactive/limits.d.ts +1 -0
- package/out/internal/reactive/limits.luau +54 -0
- package/out/internal/reactive/ownership.d.ts +1 -0
- package/out/internal/reactive/ownership.luau +626 -0
- package/out/internal/registry.d.ts +1 -0
- package/out/internal/registry.luau +455 -0
- package/out/internal/roblox-port.d.ts +1 -0
- package/out/internal/roblox-port.luau +117 -0
- package/out/internal/runner.d.ts +1 -0
- package/out/internal/runner.luau +86 -0
- package/out/internal/scheduler.d.ts +1 -0
- package/out/internal/scheduler.luau +207 -0
- package/out/internal/state.d.ts +1 -0
- package/out/internal/state.luau +41 -0
- package/out/internal/sync/client-sync.d.ts +1 -0
- package/out/internal/sync/client-sync.luau +157 -0
- package/out/internal/sync/declarations.d.ts +1 -0
- package/out/internal/sync/declarations.luau +276 -0
- package/out/internal/sync/frame.d.ts +1 -0
- package/out/internal/sync/frame.luau +91 -0
- package/out/internal/sync/server-sync.d.ts +1 -0
- package/out/internal/sync/server-sync.luau +502 -0
- package/out/internal/sync/values.d.ts +1 -0
- package/out/internal/sync/values.luau +930 -0
- package/out/log-level.d.ts +7 -0
- package/out/log-level.luau +21 -0
- package/out/logging.d.ts +34 -0
- package/out/logging.luau +233 -0
- package/out/network.d.ts +66 -0
- package/out/network.luau +24 -0
- package/out/reactive.d.ts +76 -0
- package/out/reactive.luau +136 -0
- package/out/replicated.d.ts +38 -0
- package/out/replicated.luau +45 -0
- package/out/server/data.d.ts +54 -0
- package/out/server/data.luau +44 -0
- package/out/server/index.d.ts +18 -0
- package/out/server/init.luau +62 -0
- package/out/server/publish.d.ts +20 -0
- package/out/server/publish.luau +24 -0
- package/out/subsystem.d.ts +4 -0
- package/out/subsystem.luau +30 -0
- package/out/vide/index.d.ts +7 -0
- package/out/vide/init.luau +50 -0
- package/package.json +52 -5
- package/server/package.json +4 -0
- package/transformer/data.cjs +72 -0
- package/transformer/declarations.cjs +153 -0
- package/transformer/diagnostics.cjs +19 -0
- package/transformer/index.js +741 -0
- package/transformer/network.cjs +961 -0
- package/transformer/type-id.cjs +80 -0
- package/vide/package.json +4 -0
- package/README.md +0 -3
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local bootClock = TS.import(script, script.Parent.Parent, "boot").bootClock
|
|
4
|
+
local _graph = TS.import(script, script.Parent.Parent, "reactive", "graph")
|
|
5
|
+
local createStateNode = _graph.createStateNode
|
|
6
|
+
local update = _graph.update
|
|
7
|
+
local call = TS.import(script, script.Parent.Parent, "runner").call
|
|
8
|
+
local admitWrite = TS.import(script, script.Parent, "admission").admitWrite
|
|
9
|
+
local jsonBytes = TS.import(script, script.Parent, "envelope").jsonBytes
|
|
10
|
+
local PAYLOAD_MAX_BYTES = TS.import(script, script.Parent, "limits").PAYLOAD_MAX_BYTES
|
|
11
|
+
--* @internal `confirmed` before any owned write with the session's token is confirmed (rule 37).
|
|
12
|
+
local NONE = -1
|
|
13
|
+
--[[
|
|
14
|
+
*
|
|
15
|
+
* @internal
|
|
16
|
+
* Loading --acquired, onLoad--> Active --leave / handoff / final phase / authority lost--> Sealed --release--> Ended
|
|
17
|
+
* Loading --failed, left or closed: abandon only--> Ended
|
|
18
|
+
|
|
19
|
+
]]
|
|
20
|
+
--* @internal
|
|
21
|
+
--* @internal How a release settled: its write committed, or it was fenced or gave up (rule 29).
|
|
22
|
+
local callbackThreads = {}
|
|
23
|
+
--* Data never writes this state: its `update` frame is what makes reactive reject a nested write (rule 13, K7).
|
|
24
|
+
local transaction = createStateNode(0)
|
|
25
|
+
local depth = 0
|
|
26
|
+
--[[
|
|
27
|
+
*
|
|
28
|
+
* @internal Runs a data callback on a no-yield worker whose thread may not write data, inside the `update` of a private
|
|
29
|
+
* reactive state so a state, publish or apply write throws (rule 13); a yield or throw is thrown here.
|
|
30
|
+
|
|
31
|
+
]]
|
|
32
|
+
local function dataCallback(work, a, b)
|
|
33
|
+
local worker
|
|
34
|
+
depth += 1
|
|
35
|
+
local status, value = call(function(x, y)
|
|
36
|
+
worker = coroutine.running()
|
|
37
|
+
local _worker = worker
|
|
38
|
+
callbackThreads[_worker] = true
|
|
39
|
+
local result
|
|
40
|
+
update(transaction, function(current)
|
|
41
|
+
result = work(x, y)
|
|
42
|
+
return current
|
|
43
|
+
end)
|
|
44
|
+
return result
|
|
45
|
+
end, a, b)
|
|
46
|
+
depth -= 1
|
|
47
|
+
if worker ~= nil then
|
|
48
|
+
local _worker = worker
|
|
49
|
+
callbackThreads[_worker] = nil
|
|
50
|
+
end
|
|
51
|
+
if status ~= 0 then
|
|
52
|
+
error(value, 0)
|
|
53
|
+
end
|
|
54
|
+
return value
|
|
55
|
+
end
|
|
56
|
+
--[[
|
|
57
|
+
*
|
|
58
|
+
* @internal True while any data callback runs. Callbacks never yield, so code running then was started inside one,
|
|
59
|
+
* on its thread or a thread it spawned (rule 123).
|
|
60
|
+
|
|
61
|
+
]]
|
|
62
|
+
local function insideDataCallback()
|
|
63
|
+
return depth > 0
|
|
64
|
+
end
|
|
65
|
+
--* @internal Rule 13: no data write on a data callback's own thread.
|
|
66
|
+
local function assertOutsideCallback()
|
|
67
|
+
local _arg0 = coroutine.running()
|
|
68
|
+
if callbackThreads[_arg0] ~= nil then
|
|
69
|
+
error("a write inside a data callback; return the data instead", 3)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
--* @internal One player's profile on this server, and the only writer of its data (rules 12 to 16).
|
|
73
|
+
local Session
|
|
74
|
+
do
|
|
75
|
+
Session = setmetatable({}, {
|
|
76
|
+
__tostring = function()
|
|
77
|
+
return "Session"
|
|
78
|
+
end,
|
|
79
|
+
})
|
|
80
|
+
Session.__index = Session
|
|
81
|
+
function Session.new(...)
|
|
82
|
+
local self = setmetatable({}, Session)
|
|
83
|
+
return self:constructor(...) or self
|
|
84
|
+
end
|
|
85
|
+
function Session:constructor(schema, player, userId, token, hooks)
|
|
86
|
+
self.schema = schema
|
|
87
|
+
self.player = player
|
|
88
|
+
self.userId = userId
|
|
89
|
+
self.token = token
|
|
90
|
+
self.hooks = hooks
|
|
91
|
+
self.phase = 0
|
|
92
|
+
self.abandoned = false
|
|
93
|
+
self.epoch = 0
|
|
94
|
+
self.safeUntil = 0
|
|
95
|
+
self.revision = 0
|
|
96
|
+
self.confirmed = NONE
|
|
97
|
+
self.op = 0
|
|
98
|
+
self.busy = false
|
|
99
|
+
self.receipts = {}
|
|
100
|
+
self.durable = {}
|
|
101
|
+
self.effects = {}
|
|
102
|
+
self.acks = {}
|
|
103
|
+
self.marks = {}
|
|
104
|
+
self.inbox = {}
|
|
105
|
+
self.retryAt = {}
|
|
106
|
+
self.carrying = NONE
|
|
107
|
+
self.lost = NONE
|
|
108
|
+
self.releaseWanted = false
|
|
109
|
+
self.releaseAmbiguous = false
|
|
110
|
+
self.renewAt = 0
|
|
111
|
+
end
|
|
112
|
+
function Session:writable()
|
|
113
|
+
return self.phase == 1 and bootClock() < self.safeUntil
|
|
114
|
+
end
|
|
115
|
+
function Session:snapshot()
|
|
116
|
+
local applied = {}
|
|
117
|
+
for id, revision in self.acks do
|
|
118
|
+
local _arg0 = { id, revision }
|
|
119
|
+
table.insert(applied, _arg0)
|
|
120
|
+
end
|
|
121
|
+
table.sort(applied, function(a, b)
|
|
122
|
+
return a[2] < b[2]
|
|
123
|
+
end)
|
|
124
|
+
-- ▼ ReadonlyArray.map ▼
|
|
125
|
+
local _newValue = table.create(#applied)
|
|
126
|
+
local _callback = function(_param)
|
|
127
|
+
local id = _param[1]
|
|
128
|
+
return id
|
|
129
|
+
end
|
|
130
|
+
for _k, _v in applied do
|
|
131
|
+
_newValue[_k] = _callback(_v, _k - 1, applied)
|
|
132
|
+
end
|
|
133
|
+
-- ▲ ReadonlyArray.map ▲
|
|
134
|
+
local acks = _newValue
|
|
135
|
+
local marks = {}
|
|
136
|
+
for _, mark in self.marks do
|
|
137
|
+
table.insert(marks, mark)
|
|
138
|
+
end
|
|
139
|
+
local _object = {
|
|
140
|
+
revision = self.revision,
|
|
141
|
+
schemaVersion = self.schema.version,
|
|
142
|
+
payload = self.value,
|
|
143
|
+
}
|
|
144
|
+
local _left = "receipts"
|
|
145
|
+
local _array = {}
|
|
146
|
+
local _length = #_array
|
|
147
|
+
local _array_1 = self.receipts
|
|
148
|
+
table.move(_array_1, 1, #_array_1, _length + 1, _array)
|
|
149
|
+
_object[_left] = _array
|
|
150
|
+
_object.acks = acks
|
|
151
|
+
_object.marks = marks
|
|
152
|
+
return _object
|
|
153
|
+
end
|
|
154
|
+
function Session:uncertain()
|
|
155
|
+
local ticket = self.writing
|
|
156
|
+
local _result = ticket
|
|
157
|
+
if _result ~= nil then
|
|
158
|
+
_result = _result.dispatched
|
|
159
|
+
end
|
|
160
|
+
local _condition = _result == true
|
|
161
|
+
if _condition then
|
|
162
|
+
_condition = (ticket.inFlight or ticket.ambiguous)
|
|
163
|
+
end
|
|
164
|
+
local pending = if _condition then self.carrying else NONE
|
|
165
|
+
return math.max(pending, self.lost)
|
|
166
|
+
end
|
|
167
|
+
function Session:assertIdle()
|
|
168
|
+
if self.busy then
|
|
169
|
+
error(`{self.schema.name}: {self.userId}'s profile is inside a data callback; return the data instead`, 3)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
function Session:transact(work)
|
|
173
|
+
self:assertIdle()
|
|
174
|
+
self.busy = true
|
|
175
|
+
local ok, result = pcall(work)
|
|
176
|
+
self.busy = false
|
|
177
|
+
self.hooks.changed()
|
|
178
|
+
if not ok then
|
|
179
|
+
error(result, 0)
|
|
180
|
+
end
|
|
181
|
+
return result
|
|
182
|
+
end
|
|
183
|
+
function Session:callback(work, a, b)
|
|
184
|
+
return dataCallback(work, a, b)
|
|
185
|
+
end
|
|
186
|
+
function Session:prepare(value)
|
|
187
|
+
local admitted = admitWrite(self.schema, value)
|
|
188
|
+
local bytes = jsonBytes(admitted)
|
|
189
|
+
if bytes > PAYLOAD_MAX_BYTES then
|
|
190
|
+
error(`{self.schema.name}: {self.userId}'s profile is {bytes} bytes, over {PAYLOAD_MAX_BYTES}`, 0)
|
|
191
|
+
end
|
|
192
|
+
local _result = self.schema.check
|
|
193
|
+
if _result ~= nil then
|
|
194
|
+
_result(admitted, self.value)
|
|
195
|
+
end
|
|
196
|
+
return admitted
|
|
197
|
+
end
|
|
198
|
+
function Session:commit(value, stage)
|
|
199
|
+
self.value = value
|
|
200
|
+
local _result = stage
|
|
201
|
+
if _result ~= nil then
|
|
202
|
+
_result()
|
|
203
|
+
end
|
|
204
|
+
self.revision += 1
|
|
205
|
+
end
|
|
206
|
+
function Session:write(change, stage)
|
|
207
|
+
return self:transact(function()
|
|
208
|
+
local current = self.value
|
|
209
|
+
local result = self:callback(change, current, nil)
|
|
210
|
+
if rawequal(result, current) and stage == nil then
|
|
211
|
+
return false
|
|
212
|
+
end
|
|
213
|
+
self:commit(self:prepare(result), stage)
|
|
214
|
+
self.hooks.publish(self.value)
|
|
215
|
+
return true
|
|
216
|
+
end)
|
|
217
|
+
end
|
|
218
|
+
function Session:stage(id)
|
|
219
|
+
local _receipts = self.receipts
|
|
220
|
+
local _id = id
|
|
221
|
+
if not (table.find(_receipts, _id) ~= nil) then
|
|
222
|
+
local _receipts_1 = self.receipts
|
|
223
|
+
local _id_1 = id
|
|
224
|
+
table.insert(_receipts_1, _id_1)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
return {
|
|
229
|
+
dataCallback = dataCallback,
|
|
230
|
+
insideDataCallback = insideDataCallback,
|
|
231
|
+
assertOutsideCallback = assertOutsideCallback,
|
|
232
|
+
NONE = NONE,
|
|
233
|
+
Session = Session,
|
|
234
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _boot = TS.import(script, script.Parent.Parent, "boot")
|
|
4
|
+
local bootClock = _boot.bootClock
|
|
5
|
+
local shutdownProgress = _boot.shutdownProgress
|
|
6
|
+
local _limits = TS.import(script, script.Parent, "limits")
|
|
7
|
+
local DISPATCH_CUTOFF_SECONDS = _limits.DISPATCH_CUTOFF_SECONDS
|
|
8
|
+
local FINAL_PHASE_SECONDS = _limits.FINAL_PHASE_SECONDS
|
|
9
|
+
local SETTLE_MARGIN_SECONDS = _limits.SETTLE_MARGIN_SECONDS
|
|
10
|
+
local SHUTDOWN_FALLBACK_SECONDS = _limits.SHUTDOWN_FALLBACK_SECONDS
|
|
11
|
+
local function pending(engine)
|
|
12
|
+
for _, runtime in engine.profiles do
|
|
13
|
+
for _1, session in runtime.sessions do
|
|
14
|
+
if session.phase ~= 3 then
|
|
15
|
+
return true
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
return false
|
|
20
|
+
end
|
|
21
|
+
--[[
|
|
22
|
+
*
|
|
23
|
+
* @internal DataRuntime's onShutdown (rules 50 to 56), against core's deadline through E-D1. `subsystem` is the hook's
|
|
24
|
+
* own Subsystem, excluded from `pending`; with no visible sweep the window is SHUTDOWN_FALLBACK_SECONDS.
|
|
25
|
+
|
|
26
|
+
]]
|
|
27
|
+
local function shutdownData(engine, subsystem)
|
|
28
|
+
local port = engine.port
|
|
29
|
+
local progress = if subsystem == nil then nil else shutdownProgress(subsystem)
|
|
30
|
+
local _result = progress
|
|
31
|
+
if _result ~= nil then
|
|
32
|
+
_result = _result.deadline
|
|
33
|
+
end
|
|
34
|
+
local _condition = _result
|
|
35
|
+
if _condition == nil then
|
|
36
|
+
_condition = bootClock() + SHUTDOWN_FALLBACK_SECONDS
|
|
37
|
+
end
|
|
38
|
+
local deadline = _condition
|
|
39
|
+
local finalAt = deadline - FINAL_PHASE_SECONDS
|
|
40
|
+
local cutoff = deadline - DISPATCH_CUTOFF_SECONDS
|
|
41
|
+
local settleAt = deadline - SETTLE_MARGIN_SECONDS
|
|
42
|
+
engine.scheduler:setDispatchCutoff(cutoff)
|
|
43
|
+
engine.closing = true
|
|
44
|
+
engine.receipts:close()
|
|
45
|
+
for _, runtime in engine.profiles do
|
|
46
|
+
for _1, session in runtime.sessions do
|
|
47
|
+
if session.phase == 0 then
|
|
48
|
+
session.abandoned = true
|
|
49
|
+
elseif session.phase == 1 and session.revision > session.confirmed then
|
|
50
|
+
runtime:flush(session)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
engine:wake()
|
|
55
|
+
local others = function()
|
|
56
|
+
local _result_1
|
|
57
|
+
if subsystem == nil then
|
|
58
|
+
_result_1 = 0
|
|
59
|
+
else
|
|
60
|
+
local _result_2 = shutdownProgress(subsystem)
|
|
61
|
+
if _result_2 ~= nil then
|
|
62
|
+
_result_2 = _result_2.pending
|
|
63
|
+
end
|
|
64
|
+
local _condition_1 = _result_2
|
|
65
|
+
if _condition_1 == nil then
|
|
66
|
+
_condition_1 = 0
|
|
67
|
+
end
|
|
68
|
+
_result_1 = _condition_1
|
|
69
|
+
end
|
|
70
|
+
return _result_1
|
|
71
|
+
end
|
|
72
|
+
while bootClock() < finalAt and others() > 0 do
|
|
73
|
+
port.wait(0)
|
|
74
|
+
end
|
|
75
|
+
engine.finalPhase = true
|
|
76
|
+
for _, runtime in engine.profiles do
|
|
77
|
+
for _1, session in runtime.sessions do
|
|
78
|
+
if session.phase == 1 then
|
|
79
|
+
runtime:release(session, "shutdown")
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
while bootClock() < settleAt and pending(engine) do
|
|
84
|
+
port.wait(0)
|
|
85
|
+
end
|
|
86
|
+
engine.settled = true
|
|
87
|
+
engine:wake()
|
|
88
|
+
end
|
|
89
|
+
return {
|
|
90
|
+
shutdownData = shutdownData,
|
|
91
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local bootClock = TS.import(script, script.Parent.Parent, "boot").bootClock
|
|
4
|
+
--[[
|
|
5
|
+
*
|
|
6
|
+
* @internal Threads parked until a wake or their deadline. Callers re-check their condition in a loop, so a spurious
|
|
7
|
+
* wake costs one check. A park id guards each resume, so a stale deadline timer never resumes a later park.
|
|
8
|
+
|
|
9
|
+
]]
|
|
10
|
+
local Waiters
|
|
11
|
+
do
|
|
12
|
+
Waiters = setmetatable({}, {
|
|
13
|
+
__tostring = function()
|
|
14
|
+
return "Waiters"
|
|
15
|
+
end,
|
|
16
|
+
})
|
|
17
|
+
Waiters.__index = Waiters
|
|
18
|
+
function Waiters.new(...)
|
|
19
|
+
local self = setmetatable({}, Waiters)
|
|
20
|
+
return self:constructor(...) or self
|
|
21
|
+
end
|
|
22
|
+
function Waiters:constructor(port)
|
|
23
|
+
self.port = port
|
|
24
|
+
self.parked = {}
|
|
25
|
+
self.sequence = 0
|
|
26
|
+
end
|
|
27
|
+
function Waiters:park(deadline)
|
|
28
|
+
local thread = coroutine.running()
|
|
29
|
+
self.sequence += 1
|
|
30
|
+
local id = self.sequence
|
|
31
|
+
self.parked[thread] = id
|
|
32
|
+
local fired = false
|
|
33
|
+
local timer = if deadline == nil then nil else self.port.delay(math.max(deadline - bootClock(), 0), function()
|
|
34
|
+
fired = true
|
|
35
|
+
if self.parked[thread] ~= id then
|
|
36
|
+
return nil
|
|
37
|
+
end
|
|
38
|
+
self.parked[thread] = nil
|
|
39
|
+
self.port.resume(thread)
|
|
40
|
+
end)
|
|
41
|
+
coroutine.yield()
|
|
42
|
+
self.parked[thread] = nil
|
|
43
|
+
if timer ~= nil and not fired then
|
|
44
|
+
self.port.cancel(timer)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
function Waiters:wake()
|
|
48
|
+
local threads = {}
|
|
49
|
+
for thread, id in self.parked do
|
|
50
|
+
local _arg0 = { thread, id }
|
|
51
|
+
table.insert(threads, _arg0)
|
|
52
|
+
end
|
|
53
|
+
table.clear(self.parked)
|
|
54
|
+
table.sort(threads, function(a, b)
|
|
55
|
+
return a[2] < b[2]
|
|
56
|
+
end)
|
|
57
|
+
for _, _binding in threads do
|
|
58
|
+
local thread = _binding[1]
|
|
59
|
+
self.port.resume(thread)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
return {
|
|
64
|
+
Waiters = Waiters,
|
|
65
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local function walk(items, stop, visit)
|
|
3
|
+
do
|
|
4
|
+
local i = 0
|
|
5
|
+
local _shouldIncrement = false
|
|
6
|
+
while true do
|
|
7
|
+
if _shouldIncrement then
|
|
8
|
+
i += 1
|
|
9
|
+
else
|
|
10
|
+
_shouldIncrement = true
|
|
11
|
+
end
|
|
12
|
+
if not (i < stop) then
|
|
13
|
+
break
|
|
14
|
+
end
|
|
15
|
+
local item = items[i + 1]
|
|
16
|
+
if item ~= nil then
|
|
17
|
+
visit(item)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
--[[
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
* Ordered list with O(1) append, O(1) removal by tombstone, and allocation-free iteration. Holes are
|
|
26
|
+
* `end - count`. An append always writes at `end`, so no slot is reused until compaction, which runs outside a
|
|
27
|
+
* walk once holes pass half the slots. Outside a walk `end <= 2 * count`, so a walk touches at most twice the
|
|
28
|
+
* members and compaction costs at most twice the removals. Iteration order is insertion order and survives any
|
|
29
|
+
* mutation from inside a visit. Items appended during `forEach` are visited by the next call, not this one.
|
|
30
|
+
|
|
31
|
+
]]
|
|
32
|
+
local DenseList
|
|
33
|
+
do
|
|
34
|
+
DenseList = setmetatable({}, {
|
|
35
|
+
__tostring = function()
|
|
36
|
+
return "DenseList"
|
|
37
|
+
end,
|
|
38
|
+
})
|
|
39
|
+
DenseList.__index = DenseList
|
|
40
|
+
function DenseList.new(...)
|
|
41
|
+
local self = setmetatable({}, DenseList)
|
|
42
|
+
return self:constructor(...) or self
|
|
43
|
+
end
|
|
44
|
+
function DenseList:constructor()
|
|
45
|
+
self.items = {}
|
|
46
|
+
self.slots = {}
|
|
47
|
+
self["end"] = 0
|
|
48
|
+
self.count = 0
|
|
49
|
+
self.depth = 0
|
|
50
|
+
end
|
|
51
|
+
function DenseList:size()
|
|
52
|
+
return self.count
|
|
53
|
+
end
|
|
54
|
+
function DenseList:has(item)
|
|
55
|
+
local _slots = self.slots
|
|
56
|
+
local _item = item
|
|
57
|
+
return _slots[_item] ~= nil
|
|
58
|
+
end
|
|
59
|
+
function DenseList:add(item)
|
|
60
|
+
local _slots = self.slots
|
|
61
|
+
local _item = item
|
|
62
|
+
if _slots[_item] ~= nil then
|
|
63
|
+
return false
|
|
64
|
+
end
|
|
65
|
+
self.items[self["end"] + 1] = item
|
|
66
|
+
local _slots_1 = self.slots
|
|
67
|
+
local _item_1 = item
|
|
68
|
+
local _arg1 = self["end"]
|
|
69
|
+
_slots_1[_item_1] = _arg1
|
|
70
|
+
self["end"] += 1
|
|
71
|
+
self.count += 1
|
|
72
|
+
return true
|
|
73
|
+
end
|
|
74
|
+
function DenseList:remove(item)
|
|
75
|
+
local _slots = self.slots
|
|
76
|
+
local _item = item
|
|
77
|
+
local slot = _slots[_item]
|
|
78
|
+
if slot == nil then
|
|
79
|
+
return false
|
|
80
|
+
end
|
|
81
|
+
self.items[slot + 1] = nil
|
|
82
|
+
local _slots_1 = self.slots
|
|
83
|
+
local _item_1 = item
|
|
84
|
+
_slots_1[_item_1] = nil
|
|
85
|
+
self.count -= 1
|
|
86
|
+
self:compactIfSparse()
|
|
87
|
+
return true
|
|
88
|
+
end
|
|
89
|
+
function DenseList:forEach(visit)
|
|
90
|
+
self.depth += 1
|
|
91
|
+
local ok, err = pcall(walk, self.items, self["end"], visit)
|
|
92
|
+
self.depth -= 1
|
|
93
|
+
self:compactIfSparse()
|
|
94
|
+
if not ok then
|
|
95
|
+
error(err, 0)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
function DenseList:first()
|
|
99
|
+
do
|
|
100
|
+
local i = 0
|
|
101
|
+
local _shouldIncrement = false
|
|
102
|
+
while true do
|
|
103
|
+
if _shouldIncrement then
|
|
104
|
+
i += 1
|
|
105
|
+
else
|
|
106
|
+
_shouldIncrement = true
|
|
107
|
+
end
|
|
108
|
+
if not (i < self["end"]) then
|
|
109
|
+
break
|
|
110
|
+
end
|
|
111
|
+
local item = self.items[i + 1]
|
|
112
|
+
if item ~= nil then
|
|
113
|
+
return item
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
return nil
|
|
118
|
+
end
|
|
119
|
+
function DenseList:compactIfSparse()
|
|
120
|
+
if self.depth > 0 or self["end"] - self.count <= self["end"] / 2 then
|
|
121
|
+
return nil
|
|
122
|
+
end
|
|
123
|
+
local write = 0
|
|
124
|
+
do
|
|
125
|
+
local read = 0
|
|
126
|
+
local _shouldIncrement = false
|
|
127
|
+
while true do
|
|
128
|
+
if _shouldIncrement then
|
|
129
|
+
read += 1
|
|
130
|
+
else
|
|
131
|
+
_shouldIncrement = true
|
|
132
|
+
end
|
|
133
|
+
if not (read < self["end"]) then
|
|
134
|
+
break
|
|
135
|
+
end
|
|
136
|
+
local item = self.items[read + 1]
|
|
137
|
+
if item == nil then
|
|
138
|
+
continue
|
|
139
|
+
end
|
|
140
|
+
if read ~= write then
|
|
141
|
+
self.items[write + 1] = item
|
|
142
|
+
self.items[read + 1] = nil
|
|
143
|
+
local _slots = self.slots
|
|
144
|
+
local _write = write
|
|
145
|
+
_slots[item] = _write
|
|
146
|
+
end
|
|
147
|
+
write += 1
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
self["end"] = write
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
return {
|
|
154
|
+
DenseList = DenseList,
|
|
155
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local loggingPort = TS.import(script, script.Parent, "log-output").loggingPort
|
|
4
|
+
local emitting = false
|
|
5
|
+
local terminal = false
|
|
6
|
+
--* @internal
|
|
7
|
+
local function runtimeDiagnostic(level, message)
|
|
8
|
+
if not emitting then
|
|
9
|
+
emitting = true
|
|
10
|
+
local ok = pcall(function()
|
|
11
|
+
return loggingPort().writeInternal(level, message)
|
|
12
|
+
end)
|
|
13
|
+
emitting = false
|
|
14
|
+
if ok then
|
|
15
|
+
return nil
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
if terminal then
|
|
19
|
+
return nil
|
|
20
|
+
end
|
|
21
|
+
terminal = true
|
|
22
|
+
pcall(function()
|
|
23
|
+
return warn(`[Crucible] {message}`)
|
|
24
|
+
end)
|
|
25
|
+
terminal = false
|
|
26
|
+
end
|
|
27
|
+
return {
|
|
28
|
+
runtimeDiagnostic = runtimeDiagnostic,
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
--* @internal
|
|
3
|
+
--* @internal
|
|
4
|
+
--* @internal
|
|
5
|
+
local FRAME_HOOK_NAMES = { "preRender", "fixedUpdate", "update", "lateUpdate" }
|
|
6
|
+
--* @internal
|
|
7
|
+
local OBJECT_HOOK_NAMES = { "awake", "start", "fixedUpdate", "update", "lateUpdate", "preRender" }
|
|
8
|
+
--* @internal
|
|
9
|
+
local BEHAVIOUR_HOOK_NAMES = { "onEnable", "onDisable", "onDestroy" }
|
|
10
|
+
--* @internal
|
|
11
|
+
--* @internal
|
|
12
|
+
--* @internal
|
|
13
|
+
local SUBSYSTEM_HOOK_NAMES = { "onShutdown" }
|
|
14
|
+
--* @internal
|
|
15
|
+
local subsystemHooks
|
|
16
|
+
--* @internal
|
|
17
|
+
local function installSubsystemHooks(value)
|
|
18
|
+
subsystemHooks = value
|
|
19
|
+
end
|
|
20
|
+
--* @internal
|
|
21
|
+
local function shutdownHooks()
|
|
22
|
+
return subsystemHooks or error("Subsystem hooks not installed")
|
|
23
|
+
end
|
|
24
|
+
local objectHooks
|
|
25
|
+
local behaviourHooks
|
|
26
|
+
--* @internal
|
|
27
|
+
local function installObjectHooks(hooks)
|
|
28
|
+
objectHooks = hooks
|
|
29
|
+
end
|
|
30
|
+
--* @internal
|
|
31
|
+
local function installBehaviourHooks(hooks)
|
|
32
|
+
behaviourHooks = hooks
|
|
33
|
+
end
|
|
34
|
+
--* @internal
|
|
35
|
+
local function hooks()
|
|
36
|
+
return objectHooks or error("Crucible hooks used before CrucibleObject loaded")
|
|
37
|
+
end
|
|
38
|
+
--* @internal
|
|
39
|
+
local function lifecycleHooks()
|
|
40
|
+
return behaviourHooks or error("Crucible hooks used before CrucibleObject loaded")
|
|
41
|
+
end
|
|
42
|
+
return {
|
|
43
|
+
installSubsystemHooks = installSubsystemHooks,
|
|
44
|
+
shutdownHooks = shutdownHooks,
|
|
45
|
+
installObjectHooks = installObjectHooks,
|
|
46
|
+
installBehaviourHooks = installBehaviourHooks,
|
|
47
|
+
hooks = hooks,
|
|
48
|
+
lifecycleHooks = lifecycleHooks,
|
|
49
|
+
FRAME_HOOK_NAMES = FRAME_HOOK_NAMES,
|
|
50
|
+
OBJECT_HOOK_NAMES = OBJECT_HOOK_NAMES,
|
|
51
|
+
BEHAVIOUR_HOOK_NAMES = BEHAVIOUR_HOOK_NAMES,
|
|
52
|
+
SUBSYSTEM_HOOK_NAMES = SUBSYSTEM_HOOK_NAMES,
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|