perf: sync atomic changes to keys

This commit is contained in:
Richard 2024-10-31 20:57:27 -07:00
parent 13e06dd44c
commit ecf808c706
13 changed files with 368 additions and 402 deletions

View file

@ -5,7 +5,6 @@ local atom = Charm.atom
local CharmSync = require(ReplicatedStorage.DevPackages.CharmSync)
type SyncPayload = CharmSync.SyncPayload
local server = CharmSync.server
local patch = require(ReplicatedStorage.DevPackages.CharmSync.patch)
return function()
local target: Player = {} :: any
@ -22,14 +21,14 @@ return function()
server:hydrate(target)
expect(player).to.equal(target)
expect(payload.type).to.equal("init")
assert(payload.type == "init", "payload.type is not 'init'")
expect(payload.data.a).to.equal(1)
disconnect()
end)
it("sends state patches", function()
local a = atom({ b = 1, c = 2 } :: { [string]: number? })
local a = atom({ 1, 2 })
local server = server({ atoms = { a = a }, interval = -1 })
local player: Player, payload: SyncPayload
@ -37,20 +36,27 @@ return function()
player, payload = ...
end)
a({ b = 1, c = 5 })
a({ 1, 5 })
server:_sendPatch(target)
expect(player).to.equal(target)
expect(payload.type).to.equal("patch")
expect(payload.data.a.b).to.never.be.ok()
expect(payload.data.a.c).to.equal(5)
assert(payload.type == "patch", "payload.type is not 'patch'")
expect(#payload.data).to.equal(1)
a({ b = 1, d = 1 })
expect(table.concat(payload.data[1].path, "/")).to.equal("a/2")
expect(payload.data[1].data).to.equal(5)
a({ 1, nil :: any, 1 })
server:_sendPatch(target)
expect(payload.data.a.b).to.never.be.ok()
expect(payload.data.a.c).to.equal(patch.None)
expect(payload.data.a.d).to.equal(1)
assert(payload.type == "patch", "payload.type is not 'patch'")
expect(#payload.data).to.equal(2)
expect(table.concat(payload.data[1].path, "/")).to.equal("a/2")
expect(payload.data[1].data).to.never.be.ok()
expect(table.concat(payload.data[2].path, "/")).to.equal("a/3")
expect(payload.data[2].data).to.equal(1)
disconnect()
end)
@ -75,9 +81,16 @@ return function()
server:_sendPatch(target)
expect(#payloads).to.equal(1)
expect(payloads[1].type).to.equal("patch")
expect(payloads[1].data.a).to.equal(2)
expect(payloads[1].data.b).to.equal(2)
assert(payloads[1].type == "patch", "payload 1 type is not 'patch'")
expect(#payloads[1].data).to.equal(2)
-- a(2)
expect(table.concat(payloads[1].data[1].path, "/")).to.equal("a")
expect(payloads[1].data[1].data).to.equal(2)
-- b(2)
expect(table.concat(payloads[1].data[2].path, "/")).to.equal("b")
expect(payloads[1].data[2].data).to.equal(2)
a(3)
a(4)
@ -85,12 +98,24 @@ return function()
server:_sendPatch(target)
expect(#payloads).to.equal(2)
expect(payloads[1].type).to.equal("patch")
expect(payloads[1].data.a).to.equal(3)
expect(payloads[1].data.b).to.never.be.ok()
expect(payloads[2].type).to.equal("patch")
expect(payloads[2].data.a).to.equal(4)
expect(payloads[2].data.b).to.equal(3)
assert(payloads[1].type == "patch", "payload 1 type is not 'patch'")
expect(#payloads[1].data).to.equal(1)
-- a(3)
expect(table.concat(payloads[1].data[1].path, "/")).to.equal("a")
expect(payloads[1].data[1].data).to.equal(3)
-- second a() call cannot be collapsed, so it is added to a new payload
assert(payloads[2].type == "patch", "payload 2 type is not 'patch'")
expect(#payloads[2].data).to.equal(2)
-- a(4)
expect(table.concat(payloads[2].data[1].path, "/")).to.equal("a")
expect(payloads[2].data[1].data).to.equal(4)
-- b(3)
expect(table.concat(payloads[2].data[2].path, "/")).to.equal("b")
expect(payloads[2].data[2].data).to.equal(3)
disconnect()
end)