Compare commits

..

No commits in common. "master" and "1.1.0-pre4" have entirely different histories.

4 changed files with 453 additions and 407 deletions

View file

@ -10,11 +10,7 @@ local Client = Warp.Client()
## `.awaitReady` <Badge type="warning" text="yield" /> ## `.awaitReady` <Badge type="warning" text="yield" />
Yields the current thread until the client has successfully initialized and synchronized with the server's replication data (identifier). Yields the current thread until the client has successfully initialized and synchronized with the server's replication data (identifier). Its optionally, but highly recommended to call this before firing or connecting to any events to ensure the network is fully ready.
::: info
Its optionally, but highly recommended to call this before firing or connecting to any events to ensure the network is fully ready.
:::
::: code-group ::: code-group
```luau [Variable] ```luau [Variable]

View file

@ -37,7 +37,7 @@ Client.awaitReady = Replication.wait_for_ready
--@schema Buffer.SchemaType --@schema Buffer.SchemaType
-- Define a schema for strict data packing on a specific event. -- Define a schema for strict data packing on a specific event.
Client.useSchema = function(remoteName: string, schema: Buffer.SchemaType) Client.useSchema = function(remoteName: string, schema: Buffer.SchemaType)
local id = Replication.get_id[remoteName] local id = Replication.get_id(remoteName)
if not id then if not id then
warn(`[Warp]: ".useSchema"::"{remoteName}" does not exist, likely its not registered on the server yet.`) warn(`[Warp]: ".useSchema"::"{remoteName}" does not exist, likely its not registered on the server yet.`)
return return
@ -49,7 +49,7 @@ end
--@fn function --@fn function
-- Connect to an event to receive incoming data from the server. -- Connect to an event to receive incoming data from the server.
Client.Connect = function(remoteName: string, fn: (Player, ...any?) -> ...any?): Connection Client.Connect = function(remoteName: string, fn: (Player, ...any?) -> ...any?): Connection
local id = Replication.get_id[remoteName] local id = Replication.get_id(remoteName)
if not id then if not id then
warn(`[Warp]: ".Connect"::"{remoteName}" does not exist, likely its not registered on the server yet.`) warn(`[Warp]: ".Connect"::"{remoteName}" does not exist, likely its not registered on the server yet.`)
return { Connected = false, Disconnect = function() return end } :: Connection return { Connected = false, Disconnect = function() return end } :: Connection
@ -101,7 +101,7 @@ end
--@remoteName string --@remoteName string
-- Disconnect all connections for a specific event. -- Disconnect all connections for a specific event.
Client.DisconnectAll = function(remoteName: string) Client.DisconnectAll = function(remoteName: string)
local id = Replication.get_id[remoteName] local id = Replication.get_id(remoteName)
if not id then if not id then
return return
end end
@ -120,10 +120,10 @@ Client.Destroy = Client.DisconnectAll
--@reliable boolean --@reliable boolean
-- Fire an event to the server. -- Fire an event to the server.
Client.Fire = function(remoteName: string, reliable: boolean, ...: any?) Client.Fire = function(remoteName: string, reliable: boolean, ...: any?)
local id = Replication.get_id[remoteName] local id = Replication.get_id(remoteName)
if id then if id then
table.insert(reliable and queueEvent or queueUnreliableEvent, { table.insert(reliable and queueEvent or queueUnreliableEvent, {
Replication.get_id[remoteName], Replication.get_id(remoteName),
{ ... } :: any, { ... } :: any,
}) })
end end
@ -133,7 +133,7 @@ end
--@timeout number? --@timeout number?
-- Invoke the server with timeout support. Yields the current thread. Returns nil if timeout occurs. -- Invoke the server with timeout support. Yields the current thread. Returns nil if timeout occurs.
Client.Invoke = function(remoteName: string, timeout: number?, ...: any?): ...any? Client.Invoke = function(remoteName: string, timeout: number?, ...: any?): ...any?
local id = Replication.get_id[remoteName] local id = Replication.get_id(remoteName)
if not id then if not id then
return nil return nil
end end

View file

@ -23,7 +23,7 @@ if RunService:IsClient() or RunService:IsRunMode() then
local contents = Buffer.readRepl(b, identifiers_schema) local contents = Buffer.readRepl(b, identifiers_schema)
if #contents == 0 then return end if #contents == 0 then return end
for _, content in contents do for _, content in contents do
local id: number, remote: string = content[1], content[2] local id, remote = content[1], content[2]
warp_identifier_registry.cache[remote] = id warp_identifier_registry.cache[remote] = id
warp_identifier_registry.name[id] = remote warp_identifier_registry.name[id] = remote
@ -61,8 +61,60 @@ if RunService:IsClient() or RunService:IsRunMode() then
coroutine.yield() coroutine.yield()
end end
Replication.get_id = warp_identifier_registry.cache --@name string
Replication.get_name = warp_identifier_registry.name --@timeout number (default: 0)
Replication.get_id = function(name: string, timeout: number?): number
local cached = warp_identifier_registry.cache[name]
if cached or type(timeout) ~= "number" then return cached end
local thread = coroutine.running()
if not pending_id_yields[name] then pending_id_yields[name] = {} end
table.insert(pending_id_yields[name], thread)
task.delay(timeout, function()
if pending_id_yields[name] then
local idx = table.find(pending_id_yields[name], thread)
if idx then
table.remove(pending_id_yields[name], idx)
task.spawn(thread, nil)
end
end
end)
local obj: number = coroutine.yield()
if not obj then
warn(`[Replication] timeout: could not find identifier '{name}' after {timeout}s.`)
end
return obj
end
--@name string
--@timeout number (default: 0)
Replication.get_name = function(id: number, timeout: number?): string
local cached = warp_identifier_registry.name[id]
if cached or type(timeout) ~= "number" then return cached end
local thread = coroutine.running()
if not pending_name_yields[id] then pending_name_yields[id] = {} end
table.insert(pending_name_yields[id], thread)
task.delay(timeout, function()
if pending_name_yields[id] then
local idx = table.find(pending_name_yields[id], thread)
if idx then
table.remove(pending_name_yields[id], idx)
task.spawn(thread, nil)
end
end
end)
local obj: string = coroutine.yield()
if not id then
warn(`[Replication] timeout: could not find identifier '{id}' after {timeout}s.`)
end
return obj
end
else else
local replication_ready: { Player }, pending_replications = {}, {} local replication_ready: { Player }, pending_replications = {}, {}
local writer: Buffer.Writer = Buffer.createWriter() local writer: Buffer.Writer = Buffer.createWriter()

View file

@ -186,11 +186,9 @@ if RunService:IsServer() then
if type(b) ~= "buffer" then if type(b) ~= "buffer" then
return return
end end
if not RunService:IsStudio() then
local bytes: number = (player_bytes[player] or 0) + math.max(buffer.len(b), 800) local bytes: number = (player_bytes[player] or 0) + math.max(buffer.len(b), 800)
if bytes > 8e3 then return end if bytes > 8e3 then return end
player_bytes[player] = bytes player_bytes[player] = bytes
end
local contents = Buffer.readEvents(b, ref, eventSchemas) local contents = Buffer.readEvents(b, ref, eventSchemas)
for _, content in contents do for _, content in contents do