@axpecter/lync 1.5.2 → 2.1.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/README.md +499 -357
- package/package.json +2 -2
- package/src/Types.luau +69 -27
- package/src/api/Group.luau +101 -106
- package/src/api/Packet.luau +191 -157
- package/src/api/Query.luau +223 -282
- package/src/api/Scope.luau +46 -57
- package/src/api/Signal.luau +104 -137
- package/src/codec/Base.luau +69 -20
- package/src/codec/composite/Array.luau +189 -201
- package/src/codec/composite/Map.luau +97 -341
- package/src/codec/composite/Optional.luau +27 -23
- package/src/codec/composite/Shared.luau +96 -65
- package/src/codec/composite/Struct.luau +201 -339
- package/src/codec/composite/Tagged.luau +64 -178
- package/src/codec/composite/Tuple.luau +81 -95
- package/src/codec/datatype/Buffer.luau +49 -21
- package/src/codec/datatype/CFrame.luau +207 -30
- package/src/codec/datatype/Color.luau +21 -11
- package/src/codec/datatype/Instance.luau +29 -19
- package/src/codec/datatype/IntVector.luau +33 -21
- package/src/codec/datatype/NumberRange.luau +19 -10
- package/src/codec/datatype/Ray.luau +26 -22
- package/src/codec/datatype/Rect.luau +20 -16
- package/src/codec/datatype/Region.luau +51 -45
- package/src/codec/datatype/Sequence.luau +64 -56
- package/src/codec/datatype/String.luau +89 -56
- package/src/codec/datatype/UDim.luau +40 -22
- package/src/codec/datatype/Vector.luau +181 -17
- package/src/codec/meta/Auto.luau +295 -253
- package/src/codec/meta/Bitfield.luau +104 -148
- package/src/codec/meta/Custom.luau +8 -4
- package/src/codec/meta/Enum.luau +29 -57
- package/src/codec/meta/Float.luau +64 -0
- package/src/codec/meta/Nothing.luau +9 -5
- package/src/codec/meta/Unknown.luau +44 -35
- package/src/codec/primitive/Bool.luau +16 -26
- package/src/codec/primitive/Float16.luau +58 -64
- package/src/codec/primitive/Int.luau +68 -0
- package/src/codec/primitive/Number.luau +21 -43
- package/src/codec/primitive/Varint.luau +67 -46
- package/src/index.d.ts +249 -306
- package/src/init.luau +332 -173
- package/src/internal/Baseline.luau +29 -24
- package/src/internal/Channel.luau +346 -161
- package/src/internal/Middleware.luau +60 -85
- package/src/internal/Pool.luau +19 -30
- package/src/internal/Registry.luau +61 -101
- package/src/transport/Bridge.luau +64 -43
- package/src/transport/Client.luau +60 -117
- package/src/transport/Gate.luau +282 -133
- package/src/transport/Reader.luau +159 -100
- package/src/transport/Server.luau +147 -292
- package/src/api/Namespace.luau +0 -251
- package/src/codec/meta/Quantized.luau +0 -174
package/src/api/Scope.luau
CHANGED
|
@@ -4,84 +4,73 @@
|
|
|
4
4
|
|
|
5
5
|
local Types = require(script.Parent.Parent.Types)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
-- Public --------------------------------------------------------------
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
local Scope = {}
|
|
10
10
|
|
|
11
|
-
type
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
export type ScopeHandle = {
|
|
12
|
+
on: (self: ScopeHandle, source: any, fn: (...any) -> ()) -> Types.Connection,
|
|
13
|
+
once: (self: ScopeHandle, source: any, fn: (...any) -> ()) -> Types.Connection,
|
|
14
|
+
add: (self: ScopeHandle, connection: any) -> (),
|
|
15
|
+
destroy: (self: ScopeHandle) -> (),
|
|
14
16
|
}
|
|
15
17
|
|
|
16
|
-
local
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export type Scope = typeof(setmetatable({} :: ScopeFields, ScopeImpl))
|
|
20
|
-
|
|
21
|
-
function ScopeImpl.add(self: Scope, conn: any): ()
|
|
22
|
-
if not conn then
|
|
23
|
-
return
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
local entries = self._entries
|
|
27
|
-
local count = self._count + 1
|
|
28
|
-
self._count = count
|
|
29
|
-
entries[count] = conn
|
|
30
|
-
end
|
|
18
|
+
local ScopeMeta = {}
|
|
19
|
+
ScopeMeta.__index = ScopeMeta
|
|
31
20
|
|
|
32
|
-
function
|
|
33
|
-
local conn = source:
|
|
34
|
-
local
|
|
35
|
-
local
|
|
36
|
-
self._count =
|
|
37
|
-
|
|
21
|
+
function ScopeMeta.on(self: any, source: any, fn: (...any) -> ()): Types.Connection
|
|
22
|
+
local conn = source:on(fn)
|
|
23
|
+
local conns = self._connections
|
|
24
|
+
local idx = self._count + 1
|
|
25
|
+
self._count = idx
|
|
26
|
+
conns[idx] = conn
|
|
27
|
+
return conn
|
|
38
28
|
end
|
|
39
29
|
|
|
40
|
-
function
|
|
41
|
-
local conn = source:once(
|
|
42
|
-
local
|
|
43
|
-
local
|
|
44
|
-
self._count =
|
|
45
|
-
|
|
30
|
+
function ScopeMeta.once(self: any, source: any, fn: (...any) -> ()): Types.Connection
|
|
31
|
+
local conn = source:once(fn)
|
|
32
|
+
local conns = self._connections
|
|
33
|
+
local idx = self._count + 1
|
|
34
|
+
self._count = idx
|
|
35
|
+
conns[idx] = conn
|
|
36
|
+
return conn
|
|
46
37
|
end
|
|
47
38
|
|
|
48
|
-
function
|
|
49
|
-
local
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
self._count = count
|
|
53
|
-
entries[count] = conn
|
|
39
|
+
function ScopeMeta.add(self: any, connection: any): ()
|
|
40
|
+
local idx = self._count + 1
|
|
41
|
+
self._count = idx
|
|
42
|
+
self._connections[idx] = connection
|
|
54
43
|
end
|
|
55
44
|
|
|
56
|
-
function
|
|
57
|
-
local
|
|
45
|
+
function ScopeMeta.destroy(self: any): ()
|
|
46
|
+
local conns = self._connections
|
|
58
47
|
local count = self._count
|
|
59
48
|
|
|
60
49
|
for i = 1, count do
|
|
61
|
-
local conn =
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
conn:
|
|
66
|
-
|
|
67
|
-
|
|
50
|
+
local conn = conns[i]
|
|
51
|
+
conns[i] = nil :: any
|
|
52
|
+
|
|
53
|
+
--[[
|
|
54
|
+
Support both Lync Connection (conn:disconnect())
|
|
55
|
+
and RBXScriptConnection (conn:Disconnect()).
|
|
56
|
+
]]
|
|
57
|
+
if typeof(conn) == "table" then
|
|
58
|
+
if conn.disconnect then
|
|
59
|
+
conn:disconnect()
|
|
60
|
+
end
|
|
61
|
+
elseif typeof(conn) == "RBXScriptConnection" then
|
|
62
|
+
(conn :: RBXScriptConnection):Disconnect()
|
|
68
63
|
end
|
|
69
64
|
end
|
|
70
65
|
|
|
71
66
|
self._count = 0
|
|
72
67
|
end
|
|
73
68
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
-- Public --------------------------------------------------------------
|
|
77
|
-
|
|
78
|
-
local ScopeModule = {}
|
|
79
|
-
|
|
80
|
-
function ScopeModule.create(): Scope
|
|
69
|
+
function Scope.create(): ScopeHandle
|
|
81
70
|
return setmetatable({
|
|
82
|
-
|
|
71
|
+
_connections = {},
|
|
83
72
|
_count = 0,
|
|
84
|
-
},
|
|
73
|
+
}, ScopeMeta) :: any
|
|
85
74
|
end
|
|
86
75
|
|
|
87
|
-
return table.freeze(
|
|
76
|
+
return table.freeze(Scope)
|
package/src/api/Signal.luau
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
--!strict
|
|
2
2
|
--!optimize 2
|
|
3
|
-
-- O(1) disconnect
|
|
3
|
+
-- O(1) disconnect signal system with thread reuse.
|
|
4
4
|
|
|
5
5
|
local Types = require(script.Parent.Parent.Types)
|
|
6
6
|
|
|
7
|
-
type Connection = Types.Connection
|
|
8
|
-
|
|
9
7
|
-- Constants -----------------------------------------------------------
|
|
10
8
|
|
|
11
9
|
local STATE_DISCONNECTED = 0
|
|
12
10
|
local STATE_CONNECTED = 1
|
|
13
11
|
local STATE_ONCE = 2
|
|
14
12
|
|
|
15
|
-
--
|
|
13
|
+
-- State ---------------------------------------------------------------
|
|
16
14
|
|
|
17
15
|
local _freeThread: thread? = nil
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
-- Private -------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
local function passer(fn: (...any) -> (), ...): ()
|
|
20
|
+
local thread = _freeThread
|
|
21
21
|
_freeThread = nil
|
|
22
22
|
fn(...)
|
|
23
|
-
_freeThread =
|
|
23
|
+
_freeThread = thread
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
local function yielder(): ()
|
|
@@ -29,7 +29,7 @@ local function yielder(): ()
|
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
local function
|
|
32
|
+
local function spawnCallback(fn: (...any) -> (), ...: any): ()
|
|
33
33
|
if not _freeThread then
|
|
34
34
|
_freeThread = coroutine.create(yielder)
|
|
35
35
|
coroutine.resume(_freeThread :: thread)
|
|
@@ -37,29 +37,21 @@ local function spawn(fn: (...any) -> (), ...: any): ()
|
|
|
37
37
|
task.spawn(_freeThread :: thread, fn, ...)
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
--
|
|
41
|
-
|
|
42
|
-
-- Luau resolves the cycle at type-check time.
|
|
43
|
-
type EntryFields = {
|
|
40
|
+
-- Entry type
|
|
41
|
+
type Entry = {
|
|
44
42
|
fn: (...any) -> (),
|
|
45
43
|
_state: number,
|
|
46
44
|
connected: boolean,
|
|
47
|
-
|
|
45
|
+
_signalEntries: { Entry },
|
|
46
|
+
_signalCount: { number },
|
|
48
47
|
_index: number,
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
_entries: { EntryFields },
|
|
53
|
-
_count: number,
|
|
54
|
-
_snapshot: { EntryFields },
|
|
55
|
-
}
|
|
56
|
-
|
|
50
|
+
-- EntryImpl metatable
|
|
57
51
|
local EntryImpl = {}
|
|
58
52
|
EntryImpl.__index = EntryImpl
|
|
59
53
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
function EntryImpl.disconnect(self: EntrySelf): ()
|
|
54
|
+
function EntryImpl.disconnect(self: Entry): ()
|
|
63
55
|
if self._state == STATE_DISCONNECTED then
|
|
64
56
|
return
|
|
65
57
|
end
|
|
@@ -67,136 +59,137 @@ function EntryImpl.disconnect(self: EntrySelf): ()
|
|
|
67
59
|
self._state = STATE_DISCONNECTED
|
|
68
60
|
self.connected = false
|
|
69
61
|
|
|
70
|
-
local entries = self.
|
|
71
|
-
local
|
|
72
|
-
local
|
|
62
|
+
local entries = self._signalEntries
|
|
63
|
+
local countRef = self._signalCount
|
|
64
|
+
local idx = self._index
|
|
65
|
+
local last = countRef[1]
|
|
73
66
|
|
|
74
|
-
if
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
local last = entries[count]
|
|
80
|
-
entries[index] = last
|
|
81
|
-
last._index = index
|
|
67
|
+
if idx < last then
|
|
68
|
+
-- Swap-remove: move last entry to this slot
|
|
69
|
+
local moved = entries[last]
|
|
70
|
+
entries[idx] = moved
|
|
71
|
+
moved._index = idx
|
|
82
72
|
end
|
|
83
73
|
|
|
84
|
-
entries[
|
|
85
|
-
|
|
74
|
+
entries[last] = nil :: any
|
|
75
|
+
countRef[1] = last - 1
|
|
86
76
|
end
|
|
87
77
|
|
|
88
|
-
|
|
89
|
-
SignalImpl.__index = SignalImpl
|
|
78
|
+
table.freeze(EntryImpl)
|
|
90
79
|
|
|
91
|
-
|
|
80
|
+
-- Public --------------------------------------------------------------
|
|
92
81
|
|
|
93
|
-
local
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
82
|
+
local SignalModule = {}
|
|
83
|
+
|
|
84
|
+
type SignalFields = {
|
|
85
|
+
_entries: { Entry },
|
|
86
|
+
_count: { number },
|
|
87
|
+
_snapshot: { Entry },
|
|
88
|
+
}
|
|
97
89
|
|
|
98
|
-
|
|
99
|
-
|
|
90
|
+
local SignalImpl = {}
|
|
91
|
+
SignalImpl.__index = SignalImpl
|
|
100
92
|
|
|
101
|
-
|
|
93
|
+
function SignalImpl.connect(self: SignalFields, callback: (...any) -> ()): Types.Connection
|
|
94
|
+
local countRef = self._count
|
|
95
|
+
local idx = countRef[1] + 1
|
|
96
|
+
countRef[1] = idx
|
|
97
|
+
|
|
98
|
+
local entry: Entry = setmetatable({
|
|
102
99
|
fn = callback,
|
|
103
|
-
_state =
|
|
100
|
+
_state = STATE_CONNECTED,
|
|
104
101
|
connected = true,
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
_signalEntries = self._entries,
|
|
103
|
+
_signalCount = countRef,
|
|
104
|
+
_index = idx,
|
|
105
|
+
}, EntryImpl) :: any
|
|
108
106
|
|
|
109
|
-
self._entries[
|
|
107
|
+
self._entries[idx] = entry
|
|
110
108
|
return entry :: any
|
|
111
109
|
end
|
|
112
110
|
|
|
113
|
-
function SignalImpl.
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
function SignalImpl.once(self: SignalFields, callback: (...any) -> ()): Types.Connection
|
|
112
|
+
local countRef = self._count
|
|
113
|
+
local idx = countRef[1] + 1
|
|
114
|
+
countRef[1] = idx
|
|
116
115
|
|
|
117
|
-
|
|
118
|
-
|
|
116
|
+
local entry: Entry = setmetatable({
|
|
117
|
+
fn = callback,
|
|
118
|
+
_state = STATE_ONCE,
|
|
119
|
+
connected = true,
|
|
120
|
+
_signalEntries = self._entries,
|
|
121
|
+
_signalCount = countRef,
|
|
122
|
+
_index = idx,
|
|
123
|
+
}, EntryImpl) :: any
|
|
124
|
+
|
|
125
|
+
self._entries[idx] = entry
|
|
126
|
+
return entry :: any
|
|
119
127
|
end
|
|
120
128
|
|
|
121
|
-
function SignalImpl.wait(self:
|
|
122
|
-
local
|
|
123
|
-
local
|
|
129
|
+
function SignalImpl.wait(self: SignalFields): ...any
|
|
130
|
+
local running = coroutine.running()
|
|
131
|
+
local conn: Types.Connection
|
|
124
132
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
task.spawn(
|
|
128
|
-
end
|
|
133
|
+
conn = SignalImpl.connect(self, function(...: any)
|
|
134
|
+
conn:disconnect()
|
|
135
|
+
task.spawn(running, ...)
|
|
136
|
+
end)
|
|
129
137
|
|
|
130
138
|
return coroutine.yield()
|
|
131
139
|
end
|
|
132
140
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
local entries = self._entries
|
|
136
|
-
local count = self._count
|
|
141
|
+
function SignalImpl.fire(self: SignalFields, ...: any): ()
|
|
142
|
+
local count = self._count[1]
|
|
137
143
|
if count == 0 then
|
|
138
144
|
return
|
|
139
145
|
end
|
|
140
146
|
|
|
147
|
+
local entries = self._entries
|
|
148
|
+
|
|
149
|
+
-- Single-listener fast path
|
|
141
150
|
if count == 1 then
|
|
142
151
|
local entry = entries[1]
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
spawn(entry.fn, ...)
|
|
149
|
-
|
|
150
|
-
if state == STATE_ONCE then
|
|
151
|
-
(entry :: any):disconnect()
|
|
152
|
+
if entry._state == STATE_ONCE then
|
|
153
|
+
EntryImpl.disconnect(entry)
|
|
154
|
+
spawnCallback(entry.fn, ...)
|
|
155
|
+
elseif entry._state == STATE_CONNECTED then
|
|
156
|
+
spawnCallback(entry.fn, ...)
|
|
152
157
|
end
|
|
153
158
|
return
|
|
154
159
|
end
|
|
155
160
|
|
|
161
|
+
-- Multi-listener: snapshot to handle mid-fire disconnects
|
|
156
162
|
local snapshot = self._snapshot
|
|
157
163
|
table.move(entries, 1, count, 1, snapshot)
|
|
158
164
|
|
|
159
|
-
local tail = count + 1
|
|
160
|
-
if snapshot[tail] ~= nil then
|
|
161
|
-
snapshot[tail] = nil :: any
|
|
162
|
-
end
|
|
163
|
-
|
|
164
165
|
for i = 1, count do
|
|
165
166
|
local entry = snapshot[i]
|
|
166
167
|
snapshot[i] = nil :: any
|
|
167
168
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
spawn(entry.fn, ...)
|
|
174
|
-
|
|
175
|
-
if state == STATE_ONCE then
|
|
176
|
-
(entry :: any):disconnect()
|
|
169
|
+
if entry._state == STATE_ONCE then
|
|
170
|
+
EntryImpl.disconnect(entry)
|
|
171
|
+
spawnCallback(entry.fn, ...)
|
|
172
|
+
elseif entry._state == STATE_CONNECTED then
|
|
173
|
+
spawnCallback(entry.fn, ...)
|
|
177
174
|
end
|
|
178
175
|
end
|
|
179
176
|
end
|
|
180
177
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
local entries = self._entries
|
|
184
|
-
local count = self._count
|
|
178
|
+
function SignalImpl.fireSync(self: SignalFields, ...: any): ()
|
|
179
|
+
local count = self._count[1]
|
|
185
180
|
if count == 0 then
|
|
186
181
|
return
|
|
187
182
|
end
|
|
188
183
|
|
|
184
|
+
local entries = self._entries
|
|
185
|
+
|
|
189
186
|
if count == 1 then
|
|
190
187
|
local entry = entries[1]
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
entry.fn(...)
|
|
197
|
-
|
|
198
|
-
if state == STATE_ONCE then
|
|
199
|
-
(entry :: any):disconnect()
|
|
188
|
+
if entry._state == STATE_ONCE then
|
|
189
|
+
EntryImpl.disconnect(entry)
|
|
190
|
+
entry.fn(...)
|
|
191
|
+
elseif entry._state == STATE_CONNECTED then
|
|
192
|
+
entry.fn(...)
|
|
200
193
|
end
|
|
201
194
|
return
|
|
202
195
|
end
|
|
@@ -204,52 +197,26 @@ function SignalImpl.fireSync(self: Signal, ...: any): ()
|
|
|
204
197
|
local snapshot = self._snapshot
|
|
205
198
|
table.move(entries, 1, count, 1, snapshot)
|
|
206
199
|
|
|
207
|
-
local tail = count + 1
|
|
208
|
-
if snapshot[tail] ~= nil then
|
|
209
|
-
snapshot[tail] = nil :: any
|
|
210
|
-
end
|
|
211
|
-
|
|
212
200
|
for i = 1, count do
|
|
213
201
|
local entry = snapshot[i]
|
|
214
202
|
snapshot[i] = nil :: any
|
|
215
203
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
entry.fn(...)
|
|
222
|
-
|
|
223
|
-
if state == STATE_ONCE then
|
|
224
|
-
(entry :: any):disconnect()
|
|
204
|
+
if entry._state == STATE_ONCE then
|
|
205
|
+
EntryImpl.disconnect(entry)
|
|
206
|
+
entry.fn(...)
|
|
207
|
+
elseif entry._state == STATE_CONNECTED then
|
|
208
|
+
entry.fn(...)
|
|
225
209
|
end
|
|
226
210
|
end
|
|
227
211
|
end
|
|
228
212
|
|
|
229
|
-
function SignalImpl.disconnectAll(self: Signal): ()
|
|
230
|
-
local entries = self._entries
|
|
231
|
-
|
|
232
|
-
for i = 1, self._count do
|
|
233
|
-
entries[i]._state = STATE_DISCONNECTED
|
|
234
|
-
entries[i].connected = false
|
|
235
|
-
entries[i] = nil :: any
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
self._count = 0
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
table.freeze(EntryImpl)
|
|
242
213
|
table.freeze(SignalImpl)
|
|
243
214
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
local SignalModule = {}
|
|
247
|
-
|
|
248
|
-
function SignalModule.create(): Signal
|
|
215
|
+
function SignalModule.create(): any
|
|
249
216
|
return setmetatable({
|
|
250
|
-
_entries = {}
|
|
251
|
-
_count = 0,
|
|
252
|
-
_snapshot = {}
|
|
217
|
+
_entries = {},
|
|
218
|
+
_count = { 0 },
|
|
219
|
+
_snapshot = {},
|
|
253
220
|
}, SignalImpl)
|
|
254
221
|
end
|
|
255
222
|
|
package/src/codec/Base.luau
CHANGED
|
@@ -1,53 +1,102 @@
|
|
|
1
1
|
--!strict
|
|
2
|
-
--!
|
|
3
|
-
-- Fixed-size codec factory
|
|
2
|
+
--!optimize 2
|
|
3
|
+
-- Fixed-size codec factory with buffer allocation.
|
|
4
4
|
|
|
5
|
-
local Channel = require(script.Parent.Parent.internal.Channel)
|
|
6
5
|
local Types = require(script.Parent.Parent.Types)
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
-- Constants -----------------------------------------------------------
|
|
9
8
|
|
|
10
|
-
local
|
|
9
|
+
local DEFAULT_MAX = 262144
|
|
10
|
+
|
|
11
|
+
-- State ---------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
local _maxSize = DEFAULT_MAX
|
|
14
|
+
|
|
15
|
+
-- Private -------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
local countlz = bit32.countlz
|
|
18
|
+
local lshift = bit32.lshift
|
|
19
|
+
|
|
20
|
+
local function alloc(ch: Types.ChannelState, bytes: number): ()
|
|
21
|
+
local needed = ch.cursor + bytes
|
|
22
|
+
if needed <= ch.size then
|
|
23
|
+
return
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if needed > _maxSize then
|
|
27
|
+
local name = ch.currentPacket
|
|
28
|
+
error(
|
|
29
|
+
if name
|
|
30
|
+
then `[Lync] Channel: buffer overflow ({needed}B, max {_maxSize}B) in "{name}"`
|
|
31
|
+
else `[Lync] Channel: buffer overflow ({needed}B, max {_maxSize}B)`
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
local newSize = lshift(1, 32 - countlz(needed - 1))
|
|
36
|
+
local newBuff = buffer.create(newSize)
|
|
37
|
+
buffer.copy(newBuff, 0, ch.buff, 0, ch.cursor)
|
|
38
|
+
ch.buff = newBuff
|
|
39
|
+
ch.size = newSize
|
|
40
|
+
end
|
|
11
41
|
|
|
12
42
|
-- Public --------------------------------------------------------------
|
|
13
43
|
|
|
14
44
|
local Base = {}
|
|
15
45
|
|
|
46
|
+
function Base.alloc(ch: Types.ChannelState, bytes: number): ()
|
|
47
|
+
alloc(ch, bytes)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
function Base.setMaxSize(bytes: number): ()
|
|
51
|
+
_maxSize = bytes
|
|
52
|
+
end
|
|
53
|
+
|
|
16
54
|
function Base.define<T>(
|
|
17
55
|
size: number,
|
|
18
56
|
directWrite: (b: buffer, offset: number, value: T) -> (),
|
|
19
|
-
directRead: (b: buffer, offset: number) -> T
|
|
20
|
-
|
|
21
|
-
|
|
57
|
+
directRead: (b: buffer, offset: number) -> T,
|
|
58
|
+
meta: { [string]: any }?
|
|
59
|
+
): Types.InternalCodec<T>
|
|
60
|
+
local codec: any = {
|
|
22
61
|
_size = size,
|
|
23
62
|
_directWrite = directWrite,
|
|
24
63
|
_directRead = directRead,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
64
|
+
|
|
65
|
+
write = function(ch: Types.ChannelState, value: T): ()
|
|
66
|
+
local cursor = ch.cursor
|
|
67
|
+
if cursor + size > ch.size then
|
|
28
68
|
alloc(ch, size)
|
|
29
69
|
end
|
|
30
|
-
directWrite(ch.buff,
|
|
31
|
-
ch.cursor =
|
|
70
|
+
directWrite(ch.buff, cursor, value)
|
|
71
|
+
ch.cursor = cursor + size
|
|
32
72
|
end,
|
|
73
|
+
|
|
33
74
|
read = function(src: buffer, pos: number, _refs: { Instance }?): (T, number)
|
|
34
75
|
return directRead(src, pos), size
|
|
35
76
|
end,
|
|
36
|
-
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if meta then
|
|
80
|
+
for key, val in meta do
|
|
81
|
+
codec[key] = val
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
return table.freeze(codec)
|
|
37
86
|
end
|
|
38
87
|
|
|
39
|
-
function Base.zero():
|
|
88
|
+
function Base.zero(): Types.InternalCodec<nil>
|
|
40
89
|
return table.freeze({
|
|
41
90
|
_size = 0,
|
|
42
|
-
_directWrite = function(_b: buffer,
|
|
43
|
-
_directRead = function(_b: buffer,
|
|
91
|
+
_directWrite = function(_b: buffer, _off: number, _v: nil): () end,
|
|
92
|
+
_directRead = function(_b: buffer, _off: number): nil
|
|
44
93
|
return nil
|
|
45
94
|
end,
|
|
46
|
-
write = function(_ch: ChannelState,
|
|
47
|
-
read = function(_src: buffer, _pos: number, _refs: { Instance }?): (
|
|
95
|
+
write = function(_ch: Types.ChannelState, _v: nil): () end,
|
|
96
|
+
read = function(_src: buffer, _pos: number, _refs: { Instance }?): (nil, number)
|
|
48
97
|
return nil, 0
|
|
49
98
|
end,
|
|
50
|
-
})
|
|
99
|
+
} :: any)
|
|
51
100
|
end
|
|
52
101
|
|
|
53
102
|
return table.freeze(Base)
|