mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-20 12:45:05 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73c6b5a08c | ||
|
|
1f5a686570 | ||
|
|
6fc497f95e | ||
|
|
52eea667a7 | ||
|
|
c2f7e268ff | ||
|
|
31e5c558ab | ||
|
|
7a7ac9550d | ||
|
|
4d0fdf0dfd | ||
|
|
b448e8007e | ||
|
|
bad0e67266 | ||
|
|
3dee3dd627 |
12
CHANGES.md
12
CHANGES.md
@@ -3,6 +3,18 @@
|
|||||||
## Current Master
|
## Current Master
|
||||||
*No changes*
|
*No changes*
|
||||||
|
|
||||||
|
## 0.4.4 (April 7, 2018)
|
||||||
|
* Fix small regression introduced in 0.4.3
|
||||||
|
|
||||||
|
## 0.4.3 (April 7, 2018)
|
||||||
|
* Plugin now automatically selects `HttpService` if it determines that HTTP isn't enabled ([#58](https://github.com/LPGhatguy/rojo/pull/58))
|
||||||
|
* Plugin now has much more robust handling and will wipe all state when the server changes.
|
||||||
|
* This should fix issues that would otherwise be solved by restarting Roblox Studio.
|
||||||
|
|
||||||
|
## 0.4.2 (April 4, 2018)
|
||||||
|
* Fixed final case of duplicated instance insertion, caused by reconciled instances not being inserted into `RouteMap`.
|
||||||
|
* The reconciler is still not a perfect solution, especially if script instances get moved around without being destroyed. I don't think this can be fixed before a big refactor.
|
||||||
|
|
||||||
## 0.4.1 (April 1, 2018)
|
## 0.4.1 (April 1, 2018)
|
||||||
* Merged plugin repository into main Rojo repository for easier tracking.
|
* Merged plugin repository into main Rojo repository for easier tracking.
|
||||||
* Improved `RouteMap` object tracking; this should fix some cases of duplicated instances being synced into the tree.
|
* Improved `RouteMap` object tracking; this should fix some cases of duplicated instances being synced into the tree.
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
<div> </div>
|
<div> </div>
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<a href="https://travis-ci.org/LPGhatguy/rojo">
|
<a href="https://travis-ci.org/LPGhatguy/rojo">
|
||||||
<img src="https://api.travis-ci.org/LPGhatguy/rojo.svg?branch=master" alt="Travis-CI Build Status" />
|
<img src="https://api.travis-ci.org/LPGhatguy/rojo.svg?branch=master" alt="Travis-CI Build Status" />
|
||||||
</a>
|
</a>
|
||||||
<img src="https://img.shields.io/badge/latest_version-0.4.1-brightgreen.svg" alt="Current server version" />
|
<img src="https://img.shields.io/badge/latest_version-0.4.4-brightgreen.svg" alt="Current server version" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|||||||
@@ -4,32 +4,43 @@ local Config = require(script.Parent.Config)
|
|||||||
local Promise = require(script.Parent.Promise)
|
local Promise = require(script.Parent.Promise)
|
||||||
local Version = require(script.Parent.Version)
|
local Version = require(script.Parent.Version)
|
||||||
|
|
||||||
local Server = {}
|
local Api = {}
|
||||||
Server.__index = Server
|
Api.__index = Api
|
||||||
|
|
||||||
|
Api.Error = {
|
||||||
|
ServerIdMismatch = "ServerIdMismatch",
|
||||||
|
}
|
||||||
|
|
||||||
|
setmetatable(Api.Error, {
|
||||||
|
__index = function(_, key)
|
||||||
|
error("Invalid API.Error name " .. key, 2)
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
Create a new Server using the given HTTP implementation and replacer.
|
Api.connect(Http) -> Promise<Api>
|
||||||
|
|
||||||
If the context becomes invalid, `replacer` will be invoked with a new
|
Create a new Api using the given HTTP implementation.
|
||||||
context that should be suitable to replace this one.
|
|
||||||
|
|
||||||
Attempting to invoke methods on an invalid conext will throw errors!
|
Attempting to invoke methods on an invalid conext will throw errors!
|
||||||
]]
|
]]
|
||||||
function Server.connect(http)
|
function Api.connect(http)
|
||||||
local context = {
|
local context = {
|
||||||
http = http,
|
http = http,
|
||||||
serverId = nil,
|
serverId = nil,
|
||||||
currentTime = 0,
|
currentTime = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
setmetatable(context, Server)
|
setmetatable(context, Api)
|
||||||
|
|
||||||
return context:_start()
|
return context:_start()
|
||||||
end
|
end
|
||||||
|
|
||||||
function Server:_start()
|
function Api:_start()
|
||||||
return self:getInfo()
|
return self.http:get("/")
|
||||||
:andThen(function(response)
|
:andThen(function(response)
|
||||||
|
response = response:json()
|
||||||
|
|
||||||
if response.protocolVersion ~= Config.protocolVersion then
|
if response.protocolVersion ~= Config.protocolVersion then
|
||||||
local message = (
|
local message = (
|
||||||
"Found a Rojo dev server, but it's using a different protocol version, and is incompatible." ..
|
"Found a Rojo dev server, but it's using a different protocol version, and is incompatible." ..
|
||||||
@@ -39,7 +50,7 @@ function Server:_start()
|
|||||||
"\n\nGo to https://github.com/LPGhatguy/rojo for more details."
|
"\n\nGo to https://github.com/LPGhatguy/rojo for more details."
|
||||||
):format(
|
):format(
|
||||||
Version.display(Config.version), Config.protocolVersion,
|
Version.display(Config.version), Config.protocolVersion,
|
||||||
Config.expectedServerVersionString,
|
Config.expectedApiVersionString,
|
||||||
response.serverVersion, response.protocolVersion
|
response.serverVersion, response.protocolVersion
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -53,37 +64,49 @@ function Server:_start()
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Server:getInfo()
|
function Api:getInfo()
|
||||||
return self.http:get("/")
|
return self.http:get("/")
|
||||||
:andThen(function(response)
|
:andThen(function(response)
|
||||||
response = response:json()
|
response = response:json()
|
||||||
|
|
||||||
|
if response.serverId ~= self.serverId then
|
||||||
|
return Promise.reject(Api.Error.ServerIdMismatch)
|
||||||
|
end
|
||||||
|
|
||||||
return response
|
return response
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Server:read(paths)
|
function Api:read(paths)
|
||||||
local body = HttpService:JSONEncode(paths)
|
local body = HttpService:JSONEncode(paths)
|
||||||
|
|
||||||
return self.http:post("/read", body)
|
return self.http:post("/read", body)
|
||||||
:andThen(function(response)
|
:andThen(function(response)
|
||||||
response = response:json()
|
response = response:json()
|
||||||
|
|
||||||
|
if response.serverId ~= self.serverId then
|
||||||
|
return Promise.reject(Api.Error.ServerIdMismatch)
|
||||||
|
end
|
||||||
|
|
||||||
return response.items
|
return response.items
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Server:getChanges()
|
function Api:getChanges()
|
||||||
local url = ("/changes/%f"):format(self.currentTime)
|
local url = ("/changes/%f"):format(self.currentTime)
|
||||||
|
|
||||||
return self.http:get(url)
|
return self.http:get(url)
|
||||||
:andThen(function(response)
|
:andThen(function(response)
|
||||||
response = response:json()
|
response = response:json()
|
||||||
|
|
||||||
|
if response.serverId ~= self.serverId then
|
||||||
|
return Promise.reject(Api.Error.ServerIdMismatch)
|
||||||
|
end
|
||||||
|
|
||||||
self.currentTime = response.currentTime
|
self.currentTime = response.currentTime
|
||||||
|
|
||||||
return response.changes
|
return response.changes
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
return Server
|
return Api
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
return {
|
return {
|
||||||
pollingRate = 0.2,
|
pollingRate = 0.2,
|
||||||
version = {0, 4, 1},
|
version = {0, 4, 4},
|
||||||
expectedServerVersionString = "0.4.x",
|
expectedServerVersionString = "0.4.x",
|
||||||
protocolVersion = 1,
|
protocolVersion = 1,
|
||||||
dev = false,
|
dev = false,
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ end
|
|||||||
|
|
||||||
function HttpError:report()
|
function HttpError:report()
|
||||||
warn(self.message)
|
warn(self.message)
|
||||||
|
if self.type == HttpError.Error.HttpNotEnabled then
|
||||||
|
game:GetService("Selection"):Set{game:GetService("HttpService")}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return HttpError
|
return HttpError
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ local Version = require(script.Parent.Version)
|
|||||||
are, show them a reminder to make sure they check their server version.
|
are, show them a reminder to make sure they check their server version.
|
||||||
]]
|
]]
|
||||||
local function checkUpgrade()
|
local function checkUpgrade()
|
||||||
|
-- When developing Rojo, there's no use in doing version checks
|
||||||
|
if Config.dev then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local lastVersion = plugin:GetSetting("LastRojoVersion")
|
local lastVersion = plugin:GetSetting("LastRojoVersion")
|
||||||
|
|
||||||
if lastVersion then
|
if lastVersion then
|
||||||
@@ -30,10 +35,7 @@ local function checkUpgrade()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- When developing Rojo, there's no use in storing that version number.
|
plugin:SetSetting("LastRojoVersion", Config.version)
|
||||||
if not Config.dev then
|
|
||||||
plugin:SetSetting("LastRojoVersion", Config.version)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function main()
|
local function main()
|
||||||
@@ -67,12 +69,10 @@ local function main()
|
|||||||
.Click:Connect(function()
|
.Click:Connect(function()
|
||||||
checkUpgrade()
|
checkUpgrade()
|
||||||
|
|
||||||
spawn(function()
|
pluginInstance:togglePolling()
|
||||||
pluginInstance:togglePolling()
|
:catch(function(err)
|
||||||
:catch(function(err)
|
warn(err)
|
||||||
warn(err)
|
end)
|
||||||
end)
|
|
||||||
end)
|
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
local Config = require(script.Parent.Config)
|
local Config = require(script.Parent.Config)
|
||||||
local Http = require(script.Parent.Http)
|
local Http = require(script.Parent.Http)
|
||||||
local Server = require(script.Parent.Server)
|
local Api = require(script.Parent.Api)
|
||||||
local Promise = require(script.Parent.Promise)
|
local Promise = require(script.Parent.Promise)
|
||||||
local Reconciler = require(script.Parent.Reconciler)
|
local Reconciler = require(script.Parent.Reconciler)
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ function Plugin.new()
|
|||||||
local self = {
|
local self = {
|
||||||
_http = Http.new(remote),
|
_http = Http.new(remote),
|
||||||
_reconciler = Reconciler.new(),
|
_reconciler = Reconciler.new(),
|
||||||
_server = nil,
|
_api = nil,
|
||||||
_polling = false,
|
_polling = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,37 +57,58 @@ function Plugin.new()
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function Plugin:server()
|
--[[
|
||||||
if not self._server then
|
Clears all state and issues a notice to the user that the plugin has
|
||||||
self._server = Server.connect(self._http)
|
restarted.
|
||||||
|
]]
|
||||||
|
function Plugin:restart()
|
||||||
|
warn("The server has changed since the last request, reloading plugin...")
|
||||||
|
|
||||||
|
self._reconciler:clear()
|
||||||
|
self._api = nil
|
||||||
|
self._polling = false
|
||||||
|
end
|
||||||
|
|
||||||
|
function Plugin:api()
|
||||||
|
if not self._api then
|
||||||
|
self._api = Api.connect(self._http)
|
||||||
:catch(function(err)
|
:catch(function(err)
|
||||||
self._server = nil
|
self._api = nil
|
||||||
return Promise.reject(err)
|
return Promise.reject(err)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
return self._server
|
return self._api
|
||||||
end
|
end
|
||||||
|
|
||||||
function Plugin:connect()
|
function Plugin:connect()
|
||||||
print("Testing connection...")
|
print("Testing connection...")
|
||||||
|
|
||||||
return self:server()
|
return self:api()
|
||||||
:andThen(function(server)
|
:andThen(function(api)
|
||||||
return server:getInfo()
|
local ok, info = api:getInfo():await()
|
||||||
end)
|
|
||||||
:andThen(function(result)
|
if not ok then
|
||||||
|
return Promise.reject(info)
|
||||||
|
end
|
||||||
|
|
||||||
print("Server found!")
|
print("Server found!")
|
||||||
print("Protocol version:", result.protocolVersion)
|
print("Protocol version:", info.protocolVersion)
|
||||||
print("Server version:", result.serverVersion)
|
print("Server version:", info.serverVersion)
|
||||||
|
end)
|
||||||
|
:catch(function(err)
|
||||||
|
if err == Api.Error.ServerIdMismatch then
|
||||||
|
self:restart()
|
||||||
|
return self:connect()
|
||||||
|
else
|
||||||
|
return Promise.reject(err)
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Plugin:togglePolling()
|
function Plugin:togglePolling()
|
||||||
if self._polling then
|
if self._polling then
|
||||||
self:stopPolling()
|
return self:stopPolling()
|
||||||
|
|
||||||
return Promise.resolve(nil)
|
|
||||||
else
|
else
|
||||||
return self:startPolling()
|
return self:startPolling()
|
||||||
end
|
end
|
||||||
@@ -95,48 +116,51 @@ end
|
|||||||
|
|
||||||
function Plugin:stopPolling()
|
function Plugin:stopPolling()
|
||||||
if not self._polling then
|
if not self._polling then
|
||||||
return
|
return Promise.resolve(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
print("Stopped polling.")
|
print("Stopped polling.")
|
||||||
|
|
||||||
self._polling = false
|
self._polling = false
|
||||||
self._label.Enabled = false
|
self._label.Enabled = false
|
||||||
|
|
||||||
|
return Promise.resolve(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Plugin:_pull(server, project, routes)
|
function Plugin:_pull(api, project, routes)
|
||||||
local items = server:read(routes):await()
|
return api:read(routes)
|
||||||
|
:andThen(function(items)
|
||||||
|
for index = 1, #routes do
|
||||||
|
local itemRoute = routes[index]
|
||||||
|
local partitionName = itemRoute[1]
|
||||||
|
local partition = project.partitions[partitionName]
|
||||||
|
local item = items[index]
|
||||||
|
|
||||||
for index = 1, #routes do
|
local partitionRoute = collectMatch(partition.target, "[^.]+")
|
||||||
local itemRoute = routes[index]
|
|
||||||
local partitionName = itemRoute[1]
|
|
||||||
local partition = project.partitions[partitionName]
|
|
||||||
local item = items[index]
|
|
||||||
|
|
||||||
local partitionRoute = collectMatch(partition.target, "[^.]+")
|
-- If the item route's length was 1, we need to rename the instance to
|
||||||
|
-- line up with the partition's root object name.
|
||||||
|
--
|
||||||
|
-- This is a HACK!
|
||||||
|
if #itemRoute == 1 then
|
||||||
|
if item then
|
||||||
|
local objectName = partition.target:match("[^.]+$")
|
||||||
|
item.Name = objectName
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- If the item route's length was 1, we need to rename the instance to
|
local fullRoute = {}
|
||||||
-- line up with the partition's root object name.
|
for _, piece in ipairs(partitionRoute) do
|
||||||
--
|
table.insert(fullRoute, piece)
|
||||||
-- This is a HACK!
|
end
|
||||||
if #itemRoute == 1 then
|
|
||||||
if item then
|
for i = 2, #itemRoute do
|
||||||
local objectName = partition.target:match("[^.]+$")
|
table.insert(fullRoute, itemRoute[i])
|
||||||
item.Name = objectName
|
end
|
||||||
|
|
||||||
|
self._reconciler:reconcileRoute(fullRoute, item, itemRoute)
|
||||||
end
|
end
|
||||||
end
|
end)
|
||||||
|
|
||||||
local fullRoute = {}
|
|
||||||
for _, piece in ipairs(partitionRoute) do
|
|
||||||
table.insert(fullRoute, piece)
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 2, #itemRoute do
|
|
||||||
table.insert(fullRoute, itemRoute[i])
|
|
||||||
end
|
|
||||||
|
|
||||||
self._reconciler:reconcileRoute(fullRoute, item, itemRoute)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Plugin:startPolling()
|
function Plugin:startPolling()
|
||||||
@@ -149,14 +173,26 @@ function Plugin:startPolling()
|
|||||||
self._polling = true
|
self._polling = true
|
||||||
self._label.Enabled = true
|
self._label.Enabled = true
|
||||||
|
|
||||||
return self:server()
|
return self:api()
|
||||||
:andThen(function(server)
|
:andThen(function(api)
|
||||||
self:syncIn():await()
|
local syncOk, result = self:syncIn():await()
|
||||||
|
|
||||||
local project = server:getInfo():await().project
|
if not syncOk then
|
||||||
|
return Promise.reject(result)
|
||||||
|
end
|
||||||
|
|
||||||
|
local infoOk, info = api:getInfo():await()
|
||||||
|
|
||||||
|
if not infoOk then
|
||||||
|
return Promise.reject(info)
|
||||||
|
end
|
||||||
|
|
||||||
while self._polling do
|
while self._polling do
|
||||||
local changes = server:getChanges():await()
|
local changesOk, changes = api:getChanges():await()
|
||||||
|
|
||||||
|
if not changesOk then
|
||||||
|
return Promise.reject(changes)
|
||||||
|
end
|
||||||
|
|
||||||
if #changes > 0 then
|
if #changes > 0 then
|
||||||
local routes = {}
|
local routes = {}
|
||||||
@@ -165,34 +201,57 @@ function Plugin:startPolling()
|
|||||||
table.insert(routes, change.route)
|
table.insert(routes, change.route)
|
||||||
end
|
end
|
||||||
|
|
||||||
self:_pull(server, project, routes)
|
local pullOk, pullResult = self:_pull(api, info.project, routes):await()
|
||||||
|
|
||||||
|
if not pullOk then
|
||||||
|
return Promise.reject(pullResult)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
wait(Config.pollingRate)
|
wait(Config.pollingRate)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
:catch(function()
|
:catch(function(err)
|
||||||
self:stopPolling()
|
self:stopPolling()
|
||||||
|
|
||||||
|
if err == Api.Error.ServerIdMismatch then
|
||||||
|
self:restart()
|
||||||
|
return self:startPolling()
|
||||||
|
else
|
||||||
|
return Promise.reject(err)
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Plugin:syncIn()
|
function Plugin:syncIn()
|
||||||
print("Syncing from server...")
|
print("Syncing from server...")
|
||||||
|
|
||||||
return self:server()
|
return self:api()
|
||||||
:andThen(function(server)
|
:andThen(function(api)
|
||||||
local project = server:getInfo():await().project
|
local ok, info = api:getInfo():await()
|
||||||
|
|
||||||
|
if not ok then
|
||||||
|
return Promise.reject(info)
|
||||||
|
end
|
||||||
|
|
||||||
local routes = {}
|
local routes = {}
|
||||||
|
|
||||||
for name in pairs(project.partitions) do
|
for name in pairs(info.project.partitions) do
|
||||||
table.insert(routes, {name})
|
table.insert(routes, {name})
|
||||||
end
|
end
|
||||||
|
|
||||||
self:_pull(server, project, routes)
|
self:_pull(api, info.project, routes)
|
||||||
|
|
||||||
print("Sync successful!")
|
print("Sync successful!")
|
||||||
end)
|
end)
|
||||||
|
:catch(function(err)
|
||||||
|
if err == Api.Error.ServerIdMismatch then
|
||||||
|
self:restart()
|
||||||
|
return self:syncIn()
|
||||||
|
else
|
||||||
|
return Promise.reject(err)
|
||||||
|
end
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
return Plugin
|
return Plugin
|
||||||
|
|||||||
@@ -221,15 +221,11 @@ function Promise:await()
|
|||||||
local ok = bindable.Event:Wait()
|
local ok = bindable.Event:Wait()
|
||||||
bindable:Destroy()
|
bindable:Destroy()
|
||||||
|
|
||||||
if not ok then
|
return ok, unpack(result)
|
||||||
error(tostring(result[1]), 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
return unpack(result)
|
|
||||||
elseif self._status == Promise.Status.Resolved then
|
elseif self._status == Promise.Status.Resolved then
|
||||||
return unpack(self._value)
|
return true, unpack(self._value)
|
||||||
elseif self._status == Promise.Status.Rejected then
|
elseif self._status == Promise.Status.Rejected then
|
||||||
error(tostring(self._value[1]), 2)
|
return false, unpack(self._value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,13 @@ function Reconciler:_reify(item)
|
|||||||
return rbx
|
return rbx
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Clears any state that the Reconciler has, effectively restarting it.
|
||||||
|
]]
|
||||||
|
function Reconciler:clear()
|
||||||
|
self._routeMap:clear()
|
||||||
|
end
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
Apply the changes represented by the given item to a Roblox object that's a
|
Apply the changes represented by the given item to a Roblox object that's a
|
||||||
child of the given instance.
|
child of the given instance.
|
||||||
@@ -161,6 +168,10 @@ function Reconciler:reconcile(rbx, item)
|
|||||||
-- Use a dumb algorithm for reconciling children
|
-- Use a dumb algorithm for reconciling children
|
||||||
self:_reconcileChildren(rbx, item)
|
self:_reconcileChildren(rbx, item)
|
||||||
|
|
||||||
|
if item.Route then
|
||||||
|
self._routeMap:insert(item.Route, rbx)
|
||||||
|
end
|
||||||
|
|
||||||
return rbx
|
return rbx
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ function RouteMap:clear()
|
|||||||
self._map = {}
|
self._map = {}
|
||||||
self._reverseMap = {}
|
self._reverseMap = {}
|
||||||
|
|
||||||
for object in pairs(self._connectionsByRbx) do
|
for _, connection in pairs(self._connectionsByRbx) do
|
||||||
object:Disconnect()
|
connection:Disconnect()
|
||||||
end
|
end
|
||||||
|
|
||||||
self._connectionsByRbx = {}
|
self._connectionsByRbx = {}
|
||||||
|
|||||||
2
server/Cargo.lock
generated
2
server/Cargo.lock
generated
@@ -597,7 +597,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rojo"
|
name = "rojo"
|
||||||
version = "0.4.1"
|
version = "0.4.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rojo"
|
name = "rojo"
|
||||||
version = "0.4.1"
|
version = "0.4.4"
|
||||||
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
|
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
|
||||||
description = "A tool to create robust Roblox projects"
|
description = "A tool to create robust Roblox projects"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
Reference in New Issue
Block a user