-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathloader.server.lua
More file actions
145 lines (129 loc) · 3.19 KB
/
loader.server.lua
File metadata and controls
145 lines (129 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
local DEVELOPMENT = false
-- When not in development, just directly run the plugin
if not DEVELOPMENT then
require(script.Parent.Src.main)(plugin)
return
end
-- Otherwise, mock the plugin to allow reloading...
local Signal = require(script.Parent.Packages.Signal)
local Maid = require(script.Parent.Packages.Maid)
local MockToolbars = {}
local function makeMockToolbar(name)
local mockToolbar = setmetatable({
_instance = plugin:CreateToolbar(name),
Buttons = {},
CreateButton = function(self, id, tooltip, icon, text)
local button = self.Buttons[id]
if not button then
button = self._instance:CreateButton(id, tooltip, icon, text)
self.Buttons[id] = button
end
return button
end,
}, {
__index = function(self, key)
return self._instance[key]
end,
__newindex = function(self, key, value)
self._instance[key] = value
end,
})
return mockToolbar
end
local MockPlugin = setmetatable({
_instance = plugin,
Unloading = Signal.new(),
CreateToolbar = function(self, name)
local mockToolbar = MockToolbars[name]
if not mockToolbar then
mockToolbar = makeMockToolbar(name)
MockToolbars[name] = mockToolbar
end
return mockToolbar
end,
GetMouse = function(self)
return plugin:GetMouse()
end,
}, {
__index = function(self, key)
return plugin[key]
end,
__newindex = function(self, key, value)
plugin[key] = value
end,
})
local originalSrc = script.Parent.Src
local originalPackages = script.Parent.Packages
local currentContainer;
local loading = false
local function unload()
loading = true
if currentContainer then
MockPlugin.Unloading:Fire()
currentContainer:Destroy()
currentContainer = nil
end
loading = false
end
local function load()
loading = true
currentContainer = Instance.new("Folder")
currentContainer.Name = "MockPlugin"
currentContainer.Archivable = false
originalSrc:Clone().Parent = currentContainer
originalPackages:Clone().Parent = currentContainer
require(currentContainer.Src.main)(MockPlugin)
loading = false
end
local function reload()
print("Reload...")
unload()
load()
end
local unloadingMaid = Maid.new()
unloadingMaid:GiveTask(unload)
-- Deferred reloading task
local reloadTask;
local function queueReload()
if not reloadTask then
reloadTask = task.delay(0.5, function()
reloadTask = nil
reload()
end)
end
end
unloadingMaid:GiveTask(script.Parent.DescendantRemoving:Connect(function(desc)
if reloadTask then
task.cancel(reloadTask)
end
end))
-- Listen for any descendants being added / removed / changing
for _, desc in script.Parent:GetDescendants() do
unloadingMaid:GiveTask(desc.Changed:Connect(function()
if not loading then
queueReload()
end
end))
end
script.Parent.DescendantAdded:Connect(function(desc)
if not loading then
queueReload()
unloadingMaid:GiveTask(desc.Changed:Connect(function()
if not loading then
queueReload()
end
end))
end
end)
script.Parent.DescendantRemoving:Connect(function(desc)
if not loading then
queueReload()
end
end)
plugin.Unloading:Connect(function()
unloadingMaid:Destroy()
end)
local ReloadToolbar = plugin:CreateToolbar("Reload")
local ReloadButton = ReloadToolbar:CreateButton("Reload", "Reload", "", "Reload")
ReloadButton.Click:Connect(reload)
load()