From bece337d797e16542a8645394c3560bf14886966 Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Mon, 25 Jun 2018 17:58:30 -0700 Subject: [PATCH] Implement rudimentary reifer against new APIs --- plugin/src/ApiContext.lua | 14 ++++---- plugin/src/HttpError.lua | 2 +- plugin/src/Session.lua | 73 ++++++++++++++++++++++----------------- 3 files changed, 51 insertions(+), 38 deletions(-) diff --git a/plugin/src/ApiContext.lua b/plugin/src/ApiContext.lua index 999f8cb7..5bfcc6b8 100644 --- a/plugin/src/ApiContext.lua +++ b/plugin/src/ApiContext.lua @@ -29,6 +29,7 @@ function ApiContext.new(url, onMessage) serverId = nil, connected = false, messageCursor = -1, + partitionRoutes = nil, } setmetatable(context, ApiContext) @@ -37,7 +38,7 @@ function ApiContext.new(url, onMessage) end function ApiContext:connect() - return Http.get(self.url) + return Http.get(self.url .. "/api/rojo") :andThen(function(response) local body = response:json() @@ -59,6 +60,7 @@ function ApiContext:connect() self.serverId = body.serverId self.connected = true + self.partitionRoutes = body.partitions end) end @@ -67,17 +69,17 @@ function ApiContext:readAll() return Promise.reject() end - return Http.get(self.url .. "/read_all") + return Http.get(self.url .. "/api/read_all") :andThen(function(response) local body = response:json() if body.serverId ~= self.serverId then - return Promise.reject("server changed ID") + return Promise.reject("Server changed ID") end self.messageCursor = body.messageCursor - return body.instances + return body end, function(err) self.connected = false @@ -90,12 +92,12 @@ function ApiContext:retrieveMessages() return Promise.reject() end - return Http.get(self.url .. "/subscribe/" .. self.messageCursor) + return Http.get(self.url .. "/api/subscribe/" .. self.messageCursor) :andThen(function(response) local body = response:json() if body.serverId ~= self.serverId then - return Promise.reject("server changed ID") + return Promise.reject("Server changed ID") end for _, message in ipairs(body.messages) do diff --git a/plugin/src/HttpError.lua b/plugin/src/HttpError.lua index ca624037..ed611356 100644 --- a/plugin/src/HttpError.lua +++ b/plugin/src/HttpError.lua @@ -8,7 +8,7 @@ HttpError.Error = { }, ConnectFailed = { message = "Rojo plugin couldn't connect to the Rojo server.\n" .. - "Make sure the server is running -- use 'Rojo serve' to run it!", + "Make sure the server is running -- use 'rojo serve' to run it!", }, Timeout = { message = "Rojo timed out during a request.", diff --git a/plugin/src/Session.lua b/plugin/src/Session.lua index 1d0e6d30..e209f3f9 100644 --- a/plugin/src/Session.lua +++ b/plugin/src/Session.lua @@ -12,45 +12,56 @@ function Session.new() setmetatable(self, Session) -- TODO: Rewrite all instance tracking logic and implement a real reconciler - local created = {} - created["0"] = game:GetService("ReplicatedFirst") + local instancesById = {} + + local function createFoldersUntil(location, route) + for i = 1, #route - 1 do + local piece = route[i] + + local child = location:FindFirstChild(piece) + + if child == nil then + child = Instance.new("Folder") + child.Name = piece + child.Parent = location + end + + location = child + end + + return location + end + + local function reify(instancesById, id) + local object = instancesById[tostring(id)] + local instance = Instance.new(object.className) + instance.Name = object.name + + for key, property in pairs(object.properties) do + instance[key] = property.value + end + + for _, childId in ipairs(object.children) do + reify(instancesById, childId).Parent = instance + end + + return instance + end local api local function readAll() print("Reading all...") return api:readAll() - :andThen(function(instances) - local visited = {} - for id, instance in pairs(instances) do - visited[id] = true - if id ~= "0" then - local existing = created[id] - if existing ~= nil then - pcall(existing.Destroy, existing) - end + :andThen(function(response) + for partitionName, partitionRoute in pairs(api.partitionRoutes) do + local parent = createFoldersUntil(game, partitionRoute) - local real = Instance.new(instance.className) - real.Name = instance.name + local rootInstanceId = response.partitionInstances[partitionName] - for key, value in pairs(instance.properties) do - real[key] = value - end + print("Root for", partitionName, "is", rootInstanceId) - created[id] = real - end - end - - for id, instance in pairs(instances) do - if id ~= "0" then - created[id].Parent = created[tostring(instance.parent)] - end - end - - for id, object in pairs(created) do - if not visited[id] then - object:Destroy() - end + reify(response.instances, rootInstanceId).Parent = parent end end) end @@ -58,7 +69,7 @@ function Session.new() api = ApiContext.new(REMOTE_URL, function(message) if message.type == "InstanceChanged" then print("Instance", message.id, "changed!") - readAll() + -- readAll() else warn("Unknown message type " .. message.type) end