local Signal = require("Signal");
local chunk_to_script_map = {};
local script_to_unload_signal = {};
local function connectUnload(callback)
local i = 1;
while true do
local info = debug.getinfo(i);
if info == nil then break; end;
local script_name = chunk_to_script_map[info.func];
if script_name then
script_to_unload_signal[script_name]:Connect(callback);
end;
i = i + 1;
end;
end;
_G.juju = {
connectUnload = connectUnload
}
local prepend = "local juju = _G.juju;\n";
local function loadScript(name)
local file = io.open(name);
local contents = file:read("*a");
file:close();
script_to_unload_signal[name] = Signal:new();
local chunk = loadstring(prepend .. contents);
chunk_to_script_map[chunk] = name;
chunk();
end;
local function unloadScript(name)
script_to_unload_signal[name]:Fire();
script_to_unload_signal[name] = nil;
end;
loadScript("hi.lua");
loadScript("bye.lua");
unloadScript("hi.lua");
unloadScript("bye.lua");
juju.connectUnload(function()
print"cleanup from hi"
end);
local Connection = {};Connection.__index = Connection;
function Connection.new(signal, callback)
return signal:_add(setmetatable({
_signal = signal,
_callback = callback
}, Connection));
end;
function Connection:Disconnect()
self._signal:remove(self);
end;
local Signal = {};Signal.__index = Signal;
function Signal.new()
return setmetatable({
_connections = {}
}, Signal);
end;
function Signal:_add(con)
self._connections[con] = true;
return con;
end;
function Signal:_remove(con)
self._connections[con] = false;
end;
function Signal:Connect(callback)
return Connection.new(self, callback);
end;
function Signal:Fire(...)
local args = {...};
for connection in next, self._connections do
connection._callback(unpack(args));
end;
end;
return Signal;
juju.connectUnload(function()
print"cleanup from bye"
end)