mirror of
https://github.com/imezx/Warp.git
synced 2025-04-24 15:10:03 +00:00
v1.0.13
This commit is contained in:
parent
064075fbd9
commit
dbed984eea
16 changed files with 209 additions and 202 deletions
|
@ -1,5 +1,4 @@
|
|||
--!strict
|
||||
--!native
|
||||
--!optimize 2
|
||||
local Logger = {}
|
||||
local Logs: {
|
||||
|
@ -31,4 +30,8 @@ function Logger.read(Identifier: string)
|
|||
return Logs[Identifier]
|
||||
end
|
||||
|
||||
return Logger
|
||||
function Logger.clear(Identifier: string)
|
||||
Logs[Identifier] = nil
|
||||
end
|
||||
|
||||
return Logger :: typeof(Logger)
|
|
@ -122,6 +122,22 @@ function ClientProcess.add(Identifier: any, originId: string, conf: Type.ClientC
|
|||
end
|
||||
end
|
||||
|
||||
function ClientProcess.remove(Identifier: string)
|
||||
if not table.find(registeredIdentifier, Identifier) then return end
|
||||
table.remove(registeredIdentifier, table.find(registeredIdentifier, Identifier))
|
||||
clientQueue[Identifier] = nil
|
||||
unreliableClientQueue[Identifier] = nil
|
||||
clientRequestQueue[Identifier] = nil
|
||||
clientCallback[Identifier] = nil
|
||||
clientRatelimit[Identifier] = nil
|
||||
queueOutRequest[1][Identifier] = nil
|
||||
queueOutRequest[2][Identifier] = nil
|
||||
queueInRequest[1][Identifier] = nil
|
||||
queueInRequest[2][Identifier] = nil
|
||||
queueIn[Identifier] = nil
|
||||
Logger.clear(Identifier)
|
||||
end
|
||||
|
||||
function ClientProcess.logger(Identifier: string, store: boolean, log: boolean)
|
||||
logger[Identifier] = store
|
||||
Logger.write(Identifier, `state: change -> {log == true and "enabled" or "disabled"} logger.`, log)
|
||||
|
@ -147,12 +163,7 @@ end
|
|||
|
||||
function ClientProcess.start()
|
||||
debug.setmemorycategory("Warp")
|
||||
local clock_limit = 1/60
|
||||
local past_clock = os.clock()
|
||||
|
||||
RunService.PostSimulation:Connect(function()
|
||||
if (os.clock()-past_clock) >= (clock_limit - 0.006) then -- less potential to skip frames
|
||||
past_clock = os.clock()
|
||||
-- Unreliable
|
||||
for Identifier: string, data: any in unreliableClientQueue do
|
||||
if #data == 0 then continue end
|
||||
|
@ -194,7 +205,6 @@ function ClientProcess.start()
|
|||
end
|
||||
queueOutRequest[2][Identifier] = nil
|
||||
end
|
||||
end
|
||||
|
||||
for _, Identifier: string in registeredIdentifier do
|
||||
if clientRequestQueue[Identifier] then
|
||||
|
|
|
@ -13,16 +13,14 @@ local Assert = require(Util.Assert)
|
|||
local Key = require(Util.Key)
|
||||
local Serdes = require(Util.Serdes)
|
||||
local Buffer = require(Util.Buffer)
|
||||
local Middleware = require(Util.Middleware)
|
||||
|
||||
function Client.new(Identifier: string, conf: Type.ClientConf?)
|
||||
local self = setmetatable({}, Client)
|
||||
|
||||
self._buffer = Buffer.new()
|
||||
self._buffer:wu8(Serdes(Identifier, conf and conf.yieldWait))
|
||||
self._buffer:wu8(Serdes.increment(Identifier, conf and conf.yieldWait))
|
||||
self.id = Buffer.convert(self._buffer:build())
|
||||
self.fn = {}
|
||||
self.middleware = {}
|
||||
self._conf = table.freeze(conf or {})
|
||||
self.IsConnected = false
|
||||
|
||||
|
@ -45,39 +43,23 @@ function Client:Invoke(timeout: number, ...: any): any
|
|||
return ClientProcess.insertRequest(self.id, timeout, ...)
|
||||
end
|
||||
|
||||
function Client:Connect(callback: (args: any) -> ())
|
||||
function Client:Connect(callback: (args: any) -> ()): string
|
||||
local key = tostring(Key())
|
||||
local _middleware = Middleware(key)
|
||||
|
||||
table.insert(self.fn, key)
|
||||
self.middleware[key] = _middleware
|
||||
|
||||
self.IsConnected = #self.fn > 0
|
||||
ClientProcess.addCallback(self.id, key, function(...)
|
||||
if _middleware.bridge(...) then
|
||||
return callback(...)
|
||||
end
|
||||
return nil
|
||||
end)
|
||||
return _middleware
|
||||
ClientProcess.addCallback(self.id, key, callback)
|
||||
return key
|
||||
end
|
||||
|
||||
function Client:Once(callback: (args: any) -> ())
|
||||
function Client:Once(callback: (args: any) -> ()): string
|
||||
local key = tostring(Key())
|
||||
local _middleware = Middleware(key)
|
||||
|
||||
table.insert(self.fn, key)
|
||||
self.middleware[key] = _middleware
|
||||
|
||||
self.IsConnected = #self.fn > 0
|
||||
ClientProcess.addCallback(self.id, key, function(...)
|
||||
ClientProcess.addCallback(self.id, key, function(...: any?)
|
||||
self:Disconnect(key)
|
||||
if _middleware.bridge(...) then
|
||||
return callback(...)
|
||||
end
|
||||
return nil
|
||||
task.spawn(callback, ...)
|
||||
end)
|
||||
return _middleware
|
||||
return key
|
||||
end
|
||||
|
||||
function Client:Wait()
|
||||
|
@ -99,14 +81,14 @@ function Client:Disconnect(key: string)
|
|||
ClientProcess.removeCallback(self.id, key)
|
||||
table.remove(self.fn, table.find(self.fn, key))
|
||||
self.IsConnected = #self.fn > 0
|
||||
if self.middleware[key] then
|
||||
self.middleware[key]:destroy()
|
||||
self.middleware[key] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Client:Destroy()
|
||||
self:DisconnectAll()
|
||||
self._buffer:remove()
|
||||
ClientProcess.remove(self.id)
|
||||
Serdes.decrement()
|
||||
table.clear(self)
|
||||
setmetatable(self, nil)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
--!strict
|
||||
--!native
|
||||
--!optimize 2
|
||||
local RunService = game:GetService("RunService")
|
||||
local Type = require(script.Parent.Type)
|
||||
|
|
|
@ -13,16 +13,14 @@ local Assert = require(Util.Assert)
|
|||
local Key = require(Util.Key)
|
||||
local Serdes = require(Util.Serdes)
|
||||
local Buffer = require(Util.Buffer)
|
||||
local Middleware = require(Util.Middleware)
|
||||
|
||||
function Server.new(Identifier: string, conf: Type.ServerConf?)
|
||||
local self = setmetatable({}, Server)
|
||||
|
||||
self._buffer = Buffer.new()
|
||||
self._buffer:wu8(Serdes(Identifier))
|
||||
self._buffer:wu8(Serdes.increment(Identifier))
|
||||
self.id = Buffer.convert(self._buffer:build())
|
||||
self.fn = {}
|
||||
self.middleware = {}
|
||||
self._conf = table.freeze(conf or {})
|
||||
self.IsConnected = false
|
||||
|
||||
|
@ -65,39 +63,23 @@ function Server:Invoke(timeout: number, player: Player, ...: any): any
|
|||
return ServerProcess.insertRequest(self.id, timeout, player, ...)
|
||||
end
|
||||
|
||||
function Server:Connect(callback: (plyer: Player, args: any) -> ())
|
||||
function Server:Connect(callback: (plyer: Player, args: any) -> ()): string
|
||||
local key = tostring(Key())
|
||||
local _middleware = Middleware(key)
|
||||
|
||||
table.insert(self.fn, key)
|
||||
self.middleware[key] = _middleware
|
||||
|
||||
ServerProcess.addCallback(self.id, key, callback)
|
||||
self.IsConnected = #self.fn > 0
|
||||
ServerProcess.addCallback(self.id, key, function(...)
|
||||
if _middleware.bridge(...) then
|
||||
return callback(...)
|
||||
end
|
||||
return nil
|
||||
end)
|
||||
return _middleware
|
||||
return key
|
||||
end
|
||||
|
||||
function Server:Once(callback: (plyer: Player, args: any) -> ())
|
||||
function Server:Once(callback: (plyer: Player, args: any) -> ()): string
|
||||
local key = tostring(Key())
|
||||
local _middleware = Middleware(key)
|
||||
|
||||
table.insert(self.fn, key)
|
||||
self.middleware[key] = _middleware
|
||||
|
||||
self.IsConnected = #self.fn > 0
|
||||
ServerProcess.addCallback(self.id, key, function(...)
|
||||
ServerProcess.addCallback(self.id, key, function(player: Player, ...: any?)
|
||||
self:Disconnect(key)
|
||||
if _middleware.bridge(...) then
|
||||
return callback(...)
|
||||
end
|
||||
return nil
|
||||
task.spawn(callback, player, ...)
|
||||
end)
|
||||
return _middleware
|
||||
return key
|
||||
end
|
||||
|
||||
function Server:Wait()
|
||||
|
@ -119,15 +101,15 @@ function Server:Disconnect(key: string): boolean
|
|||
ServerProcess.removeCallback(self.id, key)
|
||||
table.remove(self.fn, table.find(self.fn, key))
|
||||
self.IsConnected = #self.fn > 0
|
||||
if self.middleware[key] then
|
||||
self.middleware[key]:destroy()
|
||||
self.middleware[key] = nil
|
||||
end
|
||||
return table.find(self.fn, key) == nil
|
||||
end
|
||||
|
||||
function Server:Destroy()
|
||||
self:DisconnectAll()
|
||||
self._buffer:remove()
|
||||
ServerProcess.remove(self.id)
|
||||
Serdes.decrement()
|
||||
table.clear(self)
|
||||
setmetatable(self, nil)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
--!strict
|
||||
--!native
|
||||
--!optimize 2
|
||||
local Logger = {}
|
||||
local Logs: {
|
||||
|
@ -31,4 +30,8 @@ function Logger.read(Identifier: string)
|
|||
return Logs[Identifier]
|
||||
end
|
||||
|
||||
return Logger
|
||||
function Logger.clear(Identifier: string)
|
||||
Logs[Identifier] = nil
|
||||
end
|
||||
|
||||
return Logger :: typeof(Logger)
|
|
@ -183,6 +183,21 @@ function ServerProcess.add(Identifier: string, originId: string, conf: Type.Serv
|
|||
end
|
||||
end
|
||||
|
||||
function ServerProcess.remove(Identifier: string)
|
||||
if not table.find(registeredIdentifier, Identifier) then return end
|
||||
table.remove(registeredIdentifier, table.find(registeredIdentifier, Identifier))
|
||||
serverQueue[Identifier] = nil
|
||||
serverRequestQueue[Identifier] = nil
|
||||
serverCallback[Identifier] = nil
|
||||
unreliableServerQueue[Identifier] = nil
|
||||
queueIn[Identifier] = nil
|
||||
queueInRequest[1][Identifier] = nil
|
||||
queueInRequest[2][Identifier] = nil
|
||||
queueOutRequest[1][Identifier] = nil
|
||||
queueOutRequest[2][Identifier] = nil
|
||||
Logger.clear(Identifier)
|
||||
end
|
||||
|
||||
function ServerProcess.logger(Identifier: string, store: boolean, log: boolean)
|
||||
logger[Identifier] = store
|
||||
Logger.write(Identifier, `state: change -> {log == true and "enabled" or "disabled"} logger.`, log)
|
||||
|
@ -208,12 +223,7 @@ end
|
|||
|
||||
function ServerProcess.start()
|
||||
debug.setmemorycategory("Warp")
|
||||
local clock_limit = 1/60
|
||||
local past_clock = os.clock()
|
||||
|
||||
RunService.PostSimulation:Connect(function()
|
||||
if (os.clock()-past_clock) >= (clock_limit - 0.006) then -- less potential to skip frames
|
||||
past_clock = os.clock()
|
||||
-- Unreliable
|
||||
for Identifier: string, players in unreliableServerQueue do
|
||||
for player: Player, content: any in players do
|
||||
|
@ -262,7 +272,6 @@ function ServerProcess.start()
|
|||
end
|
||||
queueOutRequest[2][Identifier] = nil
|
||||
end
|
||||
end
|
||||
|
||||
for _, Identifier: string in registeredIdentifier do
|
||||
if serverRequestQueue[Identifier] then
|
||||
|
|
|
@ -12,6 +12,7 @@ function Dedicated.new(signal: any, handler: (...any) -> ())
|
|||
end
|
||||
|
||||
function Dedicated:Disconnect()
|
||||
table.clear(self)
|
||||
setmetatable(self, nil)
|
||||
end
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
--!optimize 2
|
||||
local Signal = {}
|
||||
Signal.__index = Signal
|
||||
Signal.ClassName = "Signal"
|
||||
|
||||
local DedicatedSignal = require(script.Dedicated)
|
||||
|
||||
|
@ -22,15 +23,15 @@ function Signal.new(Identifier: string)
|
|||
return Signals[Identifier]
|
||||
end
|
||||
|
||||
function Signal:Connect(fn: (...any) -> ()): string
|
||||
local key = tostring(Key())
|
||||
function Signal:Connect(fn: (...any) -> (), optKey: string?): string
|
||||
local key: typeof(Signal) = optKey or tostring(Key()) :: any
|
||||
self[key] = DedicatedSignal(self, fn)
|
||||
return key
|
||||
return key :: any
|
||||
end
|
||||
|
||||
function Signal:Once(fn: (...any) -> ()): string
|
||||
local key: string
|
||||
key = self:Connect(function(...)
|
||||
key = self:Connect(function(...: any)
|
||||
self:Disconnect(key)
|
||||
task.spawn(fn, ...)
|
||||
end)
|
||||
|
@ -38,19 +39,17 @@ function Signal:Once(fn: (...any) -> ()): string
|
|||
end
|
||||
|
||||
function Signal:Disconnect(key: string)
|
||||
if not self[key] then return end
|
||||
self[key]:Disconnect()
|
||||
self[key] = nil
|
||||
end
|
||||
|
||||
function Signal:DisconnectAll(): ()
|
||||
for _, handle in self do
|
||||
handle:Disconnect()
|
||||
end
|
||||
table.clear(self)
|
||||
end
|
||||
|
||||
function Signal:Wait(): number
|
||||
local thread, t = coroutine.running(), os.clock()
|
||||
local t, thread = os.clock(), coroutine.running()
|
||||
self:Once(function()
|
||||
task.spawn(thread, os.clock()-t)
|
||||
end)
|
||||
|
@ -88,12 +87,6 @@ end
|
|||
|
||||
function Signal:Destroy(): ()
|
||||
self:DisconnectAll()
|
||||
for idx: string, signal in Signals do
|
||||
if self :: any == signal then
|
||||
Signals[idx] = nil
|
||||
break
|
||||
end
|
||||
end
|
||||
setmetatable(self, nil)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--!strict
|
||||
--!native
|
||||
--!optimize 2
|
||||
return function(condition: (any), errorMessage: string?): ()
|
||||
if not (condition) then error(`Warp: {errorMessage}`, 2) end
|
||||
return function(condition: (any), errorMessage: string, level: number?): ()
|
||||
if not (condition) then error(`Warp: {errorMessage}`, level or 2) end
|
||||
end
|
|
@ -128,7 +128,7 @@ function DedicatedBuffer.new()
|
|||
end
|
||||
|
||||
function DedicatedBuffer.remove(self: any)
|
||||
self:flush()
|
||||
table.clear(self)
|
||||
setmetatable(self, nil)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
--!strict
|
||||
--!native
|
||||
--!optimize 2
|
||||
return function(): number?
|
||||
return tonumber(string.sub(tostring(Random.new():NextNumber()), 3, 6)) -- 4 digits
|
||||
return tonumber(tostring(Random.new():NextNumber()):sub(3, 7)) -- 4-5 digits
|
||||
end
|
|
@ -1,5 +1,4 @@
|
|||
--!strict
|
||||
--!native
|
||||
--!optimize 2
|
||||
local RateLimit = {}
|
||||
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
--!strict
|
||||
--!native
|
||||
--!optimize 2
|
||||
local SerDes = {}
|
||||
local RunService = game:GetService("RunService")
|
||||
local SerInt = 0
|
||||
|
||||
local Event = require(script.Parent.Parent.Event).Reliable
|
||||
local Assert = require(script.Parent.Assert)
|
||||
|
||||
return function(Identifier: string, timeout: number?): number
|
||||
function SerDes.increment(Identifier: string, timeout: number?): number
|
||||
Assert(typeof(Identifier) == "string", "Identifier must be a string type.")
|
||||
Assert(SerInt < 255, "reached max 255 identifiers.")
|
||||
if RunService:IsServer() then
|
||||
Assert(SerInt < 255, "reached max 255 identifiers.")
|
||||
if not Event:GetAttribute(Identifier) then
|
||||
SerInt += 1
|
||||
Event:SetAttribute(`{SerInt}`, Identifier)
|
||||
Event:SetAttribute(Identifier, SerInt)
|
||||
--Event:SetAttribute(Identifier, string.pack("I1", SerInt)) -- I1 -> 255 max, I2 -> ~ 6.5e4 max. (SerInt), removed/disabled for buffer migration.
|
||||
end
|
||||
|
@ -20,11 +21,11 @@ return function(Identifier: string, timeout: number?): number
|
|||
local yieldThread: thread = coroutine.running()
|
||||
local cancel = task.delay(timeout or 10, function() -- yield cancelation (timerout)
|
||||
task.spawn(yieldThread, nil)
|
||||
error(`Serdes: {Identifier} is taking too long to retrieve, seems like not replicated on server.`, 2)
|
||||
error(`Serdes: {Identifier} is taking too long to retrieve, seems like it's not replicated on server.`, 2)
|
||||
end)
|
||||
task.spawn(function()
|
||||
while coroutine.status(cancel) ~= "dead" and task.wait(0.5) do -- let it loop for yields!
|
||||
if (Event:GetAttribute(Identifier)) then
|
||||
if Event:GetAttribute(Identifier) then
|
||||
task.cancel(cancel)
|
||||
task.spawn(yieldThread, Event:GetAttribute(Identifier))
|
||||
break
|
||||
|
@ -35,3 +36,15 @@ return function(Identifier: string, timeout: number?): number
|
|||
end
|
||||
return Event:GetAttribute(Identifier)
|
||||
end
|
||||
|
||||
function SerDes.decrement()
|
||||
if not RunService:IsServer() or SerInt <= 0 then return end
|
||||
local Identifier = Event:GetAttribute(`{SerInt}`)
|
||||
if not Identifier then return end
|
||||
Event:SetAttribute(`{Identifier}`, nil)
|
||||
Event:SetAttribute(`{SerInt}`, nil)
|
||||
SerInt -= 1
|
||||
Identifier = nil
|
||||
end
|
||||
|
||||
return SerDes :: typeof(SerDes)
|
|
@ -1,13 +1,20 @@
|
|||
--!native
|
||||
--!strict
|
||||
--!optimize 2
|
||||
local thread: thread? = nil
|
||||
local thread: thread?
|
||||
local threads: {
|
||||
thread
|
||||
} = {}
|
||||
|
||||
local function passer(fn, ...): ()
|
||||
local hold = thread
|
||||
local function passer<T...>(func: (T...) -> (), ...: T...): ()
|
||||
local HoldThread: thread = thread :: thread
|
||||
thread = nil
|
||||
fn(...)
|
||||
thread = hold
|
||||
func(...)
|
||||
if not thread then
|
||||
thread = HoldThread
|
||||
return
|
||||
end
|
||||
table.insert(threads, HoldThread)
|
||||
end
|
||||
|
||||
local function yield(): never
|
||||
|
@ -16,15 +23,22 @@ local function yield(): never
|
|||
end
|
||||
end
|
||||
|
||||
if not thread then
|
||||
thread = coroutine.create(yield)
|
||||
coroutine.resume(thread :: any, thread)
|
||||
local function createThread(): ()
|
||||
local newThread: thread = coroutine.create(yield)
|
||||
coroutine.resume(newThread, newThread)
|
||||
table.insert(threads, newThread)
|
||||
end
|
||||
|
||||
return function(fn: (...any) -> (...any?), ...: any): ()
|
||||
if not thread then
|
||||
thread = coroutine.create(yield)
|
||||
coroutine.resume(thread :: any, thread)
|
||||
end
|
||||
task.spawn(thread :: thread, fn, ...)
|
||||
for _=1,5 do
|
||||
createThread()
|
||||
end
|
||||
|
||||
return function<T...>(func: (T...) -> (), ...: T...): ()
|
||||
if not thread then
|
||||
if #threads == 0 then
|
||||
createThread()
|
||||
end
|
||||
thread = table.remove(threads, 1)
|
||||
end
|
||||
task.spawn(thread :: thread, func, ...)
|
||||
end
|
|
@ -1,5 +1,5 @@
|
|||
-- Warp Library (@Eternity_Devs)
|
||||
-- version 1.0.12
|
||||
-- version 1.0.13
|
||||
--!strict
|
||||
--!native
|
||||
--!optimize 2
|
||||
|
|
Loading…
Reference in a new issue