quad/src/mount.lua
2022-08-12 01:08:35 +09:00

93 lines
2.7 KiB
Lua

local module = {};
function module.init(shared)
local new = {};
local insert = table.insert;
local mountClass = {};
mountClass.__index = mountClass;
function mountClass:unmount()
local this = self.this
local typeThis = type(this);
if typeThis == "userdata" then
this:Destroy();
elseif typeThis == "table" then
pcall(function()
this.Parent = nil;
end);
local destroyThis = this.Destroy;
if destroyThis then
pcall(destroyThis,this);
end
--if sef.to when
-- todo for remove child on parent
end
end
function new.getHolder(item)
return (type(item) == "table") and (item._holder or item.holder or item.__holder) or item;
end
local getHolder = new.getHolder;
-- we should add plugin support
function new.mount(to,this,holder)
local thisObject = this;
if type(this) == "table" then
thisObject = rawget(this,"__object");
local parent = rawget(this,"__parent");
if type(parent) == "table" then
local parentChild = rawget(parent,"__child");
if parentChild then
for i,v in pairs(parentChild) do
if v == this then
parentChild[i] = nil;
end
end
end
end
rawset(this,"__parent",to);
end
if thisObject then
thisObject.Parent = holder or getHolder(to);
else
this.Parent = holder or getHolder(to);
end
if type(to) == "table" then
local child = rawget(to,"__child");
if not child then
child = {};
rawset(to,"__child",child);
end
insert(child,this);
end
return setmetatable({to = to,this = this},mountClass);
end
local mount = new.mount;
local pack = table.pack;
local mountsClass = {};
mountsClass.__index = mountsClass;
function mountsClass:unmount()
for _,v in ipairs(self) do
v:unmount();
end
end
setmetatable(new,{
__call = function (self,to,...)
if select("#",...) == 1 then
return new.mount(to,...);
end
local mounts = {};
local items = pack(...);
for _,item in ipairs(items) do
insert(mounts,mount(to,item));
end
setmetatable(mounts,mountsClass);
return mounts;
end;
});
return new;
end
return module;