From 8026ae4b91e27275251c5f1b092270fde34b1909 Mon Sep 17 00:00:00 2001 From: Manuel Simon Hirsig Date: Sun, 21 Aug 2016 08:06:22 +0200 Subject: [PATCH] big refactoring --- core.lua | 18 +++++---------- init.lua | 35 ++++++++++++++--------------- module.lua | 61 ++++++++++++++++++++++++++++----------------------- util/core.lua | 14 +++++++----- 4 files changed, 65 insertions(+), 63 deletions(-) diff --git a/core.lua b/core.lua index 0316bb6..ea1fcb5 100644 --- a/core.lua +++ b/core.lua @@ -77,19 +77,13 @@ do end end -public.orig = {} +public.orig = setmetatable({}, {__index=function(self, key) return self[g][key] end}) function public.hook(name, handler, object) - local orig - if object then - m.orig[object] = m.orig[object] or {} - orig = m.orig[object] - else - object = g - orig = m.orig - end - assert(not orig[name], '"'..name..'" is already hooked.') - orig[name] = object[name] - object[name] = handler + handler = handler or getfenv(2)[name] + object = object or g + orig[object] = orig[object] or {} + assert(not orig[object][name] '"'..name..'" is already hooked into.') + orig[object][name], object[name] = object[name], handler end do diff --git a/init.lua b/init.lua index 64bac50..d9f7a92 100644 --- a/init.lua +++ b/init.lua @@ -1,14 +1,9 @@ -local aux_module, getn, setn, tinsert, tremove, setfenv, gfind = aux_module, getn, table.setn, tinsert, tremove, setfenv, string.gfind -do - local env, interface = aux_module '/core' - setfenv(1, env) - g.aux = interface -end +local aux_module, getn, setn, tinsert, tremove, getfenv, setfenv, gfind = aux_module, getn, table.setn, tinsert, tremove, getfenv, setfenv, string.gfind +setfenv(1, aux_module '/core') public.version = '5.0.0' do - local recycle_frame = CreateFrame 'Frame' local table_pool, auto_recycle = {}, {} local function wipe(t) -- like with a cloth or something for k in t do t[k] = nil end @@ -20,28 +15,32 @@ do tinsert(table_pool, wipe(t)) log(getn(table_pool)) end - public.accessor.temp = setmetatable({}, {__sub = function(_, t) auto_recycle[t] = true return t end}) + public.temp = setmetatable({}, {__sub = function(_, t) auto_recycle[t] = true return t end}) function public.accessor.t() return tremove(table_pool) or {} end + CreateFrame('Frame'):SetScript('OnUpdate', function() + for t in auto_recycle do recycle(t) end + recycle(auto_recycle) + auto_recycle = t + end) end do - local module_envs = t + local envs = t + envs['/core'], envs['/modules'] = getfenv(), aux_module '/modules' function public.module(path) local env, parts, parent, name - parts, parent, name = gfind(path, '[%a_][%w_]*'), aux_module '/modules', '' + parts, parent, name = gfind(path, '[%a_][%w_]*'), envs.modules, '' for part in parts do name = name..'/'..part - if not module_envs[name] then - env, parent.public[part] = aux_module(name) - env.import(temp-{'modules', 'core', 'util'}) - module_envs[name] = env - else - env = module_envs[name] + if not envs[name] then + envs[name], parent.public[part] = aux_module(name) + envs[name].import(temp-{'modules', 'core', 'util'}) end - parent = env + parent = envs[name] end - setfenv(2, env) + setfenv(2, parent) end + g.aux = module 'core' end local event_frame = CreateFrame 'Frame' diff --git a/module.lua b/module.lua index 8b440b2..36255c8 100644 --- a/module.lua +++ b/module.lua @@ -1,25 +1,25 @@ -local setmetatable, unpack, mask, g = setmetatable, unpack, bit.band, getfenv(0) -local PRIVATE, PUBLIC, MUTABLE, ACCESSOR, MUTATOR = 1, 2, 4, 8, 16 -local MODIFIER = {private=PRIVATE, public=PUBLIC, mutable=MUTABLE, accessor=ACCESSOR, mutator=MUTATOR} -local MASK = {private=PUBLIC+MUTABLE+ACCESSOR+MUTATOR, public=PRIVATE+MUTABLE+ACCESSOR+MUTATOR, mutable=PRIVATE+PUBLIC, accessor=PRIVATE+PUBLIC+MUTATOR, mutator=PRIVATE+PUBLIC+ACCESSOR} -local _10, _01, tf, ft = {[true]=1, [false]=0}, {[true]=0, [false]=1}, {true, false}, {false, true} +local type, setmetatable, unpack, mask, g = type, setmetatable, unpack, bit.band, getfenv(0) +local PRIVATE, PUBLIC, MUTABLE, GETTER, SETTER = 1, 2, 4, 8, 16 +local MODIFIER = {private=PRIVATE, public=PUBLIC, mutable=MUTABLE, getter=GETTER, setter=SETTER} +local MASK = {private=PUBLIC+MUTABLE+GETTER+SETTER, public=PRIVATE+MUTABLE+GETTER+SETTER, mutable=PRIVATE+PUBLIC, getter=PRIVATE+PUBLIC+SETTER, setter=PRIVATE+PUBLIC+GETTER} +local t1f0, t0f1 = {[true]=1, [false]=0}, {[true]=0, [false]=1} local importer_mt, declarator_mt, env_mt, interface_mt, lock_mt -local define_property, declarator_accessor, private_accessor, public_accessor, mutable_accessor, accessor_accessor, mutator_accessor, index, error -local _modules, _metadata, _data, _accessors, _mutators, _imports, _declarators, _declarator_state = setmetatable({}, lock_mt), {}, {}, {}, {}, {}, {}, {} +local define_property, declarator_getter, private_getter, public_getter, mutable_getter, accessor_getter, mutator_getter, index, error +local _modules, _metadata, _data, _getters, _setters, _imports, _declarators, _declarator_state = setmetatable({}, lock_mt), {}, {}, {}, {}, {}, {}, {} function error(message, ...) g.error(format(message, unpack(arg))..'\n'..debugstack(3, 5, 0), 3) end importer_mt = {__metatable=false} function importer_mt.__call(self, t) local imports = _imports[self] for _, name in t do imports[name] = true end end -function declarator_accessor(modifier) +function declarator_getter(modifier) return function(declarator) return function() _declarator_state[declarator] = PRIVATE+modifier return declarator end end end -private_accessor, public_accessor, mutable_accessor, accessor_accessor, mutator_accessor = declarator_accessor(0), declarator_accessor(PUBLIC), declarator_accessor(MUTABLE), declarator_accessor(ACCESSOR), declarator_accessor(MUTATOR) +private_getter, public_getter, mutable_getter, accessor_getter, mutator_getter = declarator_getter(0), declarator_getter(PUBLIC), declarator_getter(MUTABLE), declarator_getter(GETTER), declarator_getter(SETTER) function define_property(self, key, t) - local accessor, mutator = t.get, t.set - _declarator_state[self] = _01[not accessor]*ACCESSOR + _01[not mutator]*MUTATOR + mask(PRIVATE+PUBLIC, _declarator_state[self]) - _accessors[self][key], _mutators[self][key] = accessor, mutator + local getter, setter = t.get, t.set + _declarator_state[self] = t0f1[not getter]*GETTER + t0f1[not setter]*SETTER + mask(PRIVATE+PUBLIC, _declarator_state[self]) + _getters[self][key], _setters[self][key] = getter, setter end declarator_mt = {__metatable=false} function declarator_mt.__index(self, key) @@ -29,17 +29,22 @@ function declarator_mt.__index(self, key) return self end function declarator_mt.__newindex(self, key, value) - if _metadata[self][key] then error('Field "%s" already exists.', key) end - _metadata[self][key], _data[self][key], _accessors[self][key], _mutators[self][key] = _declarator_state[self], value, value, value + local modifiers = _declarator_state[self] + if modifiers then error('Field "%s" already exists.', key) end + _metadata[self][key] = modifiers + if mask(GETTER+SETTER, modifiers) == 0 then + _data[self][key] = value + elseif type(value) == 'function' or error('Getters/setters must be functions.') then + _getters[self][key], _setters[self][key] = value, value + end end function index(access, default) return function(self, key) local modifiers = _metadata[self][key] or 0 - if mask(access+ACCESSOR+MUTATOR, modifiers) == access then --- DEFAULT_CHAT_FRAME:AddMessage(access) + if mask(access+GETTER+SETTER, modifiers) == access then return _data[self][key] - elseif mask(access+ACCESSOR, modifiers) == access+ACCESSOR then - return _accessors[self][key]() + elseif mask(access+GETTER, modifiers) == access+GETTER then + return _getters[self][key]() else return default[key] or error('No field "%s".', key) end @@ -49,8 +54,8 @@ env_mt = {__metatable=false, __index=index(PRIVATE, g)} function env_mt.__newindex(self, key, value) if not _metadata[self][key] then _metadata[self][key] = PRIVATE - elseif mask(MUTATOR, _metadata[self][key]) ~= 0 then - return _mutators[self][key](value) + elseif mask(SETTER, _metadata[self][key]) ~= 0 then + return _setters[self][key](value) elseif mask(MUTABLE, _metadata[self][key]) == 0 then error('Field "%s" is immutable.', key) end @@ -58,8 +63,8 @@ function env_mt.__newindex(self, key, value) end interface_mt = {__metatable=false, __index=index(PUBLIC, {})} function interface_mt.__newindex(self, key, value) - if mask(PUBLIC+MUTATOR, _metadata[self][key]) == PUBLIC+MUTATOR then - return _mutators[self][key](value) + if mask(PUBLIC+SETTER, _metadata[self][key]) == PUBLIC+SETTER then + return _setters[self][key](value) elseif mask(PUBLIC+MUTABLE, _metadata[self][key]) == PUBLIC+MUTABLE or error('Field "%s" is immutable.', key) then _data[self][key] = value end @@ -67,16 +72,16 @@ end lock_mt = {} function g.aux_module(name) if _modules[name] then error('Module %s already exists.', name) end - local metadata, data, accessors, mutators, imports, importer, declarator, env, interface + local metadata, data, getters, setters, imports, importer, declarator, env, interface imports, importer, declarator, env, interface = {}, setmetatable({}, importer_mt), setmetatable({}, declarator_mt), setmetatable({}, env_mt), setmetatable({}, interface_mt) - metadata = setmetatable({g=PRIVATE, m=PRIVATE, import=PRIVATE, private=PRIVATE+ACCESSOR, public=PRIVATE+ACCESSOR, mutable=PRIVATE+ACCESSOR, accessor=PRIVATE+ACCESSOR, mutator=PRIVATE+ACCESSOR}, lock_mt) + metadata = setmetatable({g=PRIVATE, m=PRIVATE, import=PRIVATE, private=PRIVATE+GETTER, public=PRIVATE+GETTER, mutable=PRIVATE+GETTER, getter=PRIVATE+GETTER, setter=PRIVATE+GETTER}, lock_mt) data = {g=g, m=env, import=importer} - accessors = {private=private_accessor(declarator), public=public_accessor(declarator), mutable=mutable_accessor(declarator), accessor=accessor_accessor(declarator), mutator=mutator_accessor(declarator)} - mutators = {} + getters = {private=private_getter(declarator), public=public_getter(declarator), mutable=mutable_getter(declarator), getter=accessor_getter(declarator), setter=mutator_getter(declarator)} + setters = {} _metadata[name], _metadata[declarator], _metadata[env], _metadata[interface] = metadata, metadata, metadata, metadata _data[name], _data[declarator], _data[env], _data[interface] = data, data, data, data - _accessors[name], _accessors[declarator], _accessors[env], _accessors[interface] = accessors, accessors, accessors, accessors - _mutators[name], _mutators[declarator], _mutators[env], _mutators[interface] = mutators, mutators, mutators, mutators + _getters[name], _getters[declarator], _getters[env], _getters[interface] = getters, getters, getters, getters + _setters[name], _setters[declarator], _setters[env], _setters[interface] = setters, setters, setters, setters _imports[name], _imports[importer] = imports, imports _declarators[name] = declarator _modules[name] = true diff --git a/util/core.lua b/util/core.lua index c6f8ddd..f42cab8 100644 --- a/util/core.lua +++ b/util/core.lua @@ -63,12 +63,16 @@ do end return f(unpack(params)) end - function public.L(f, ...) - if type(f) == 'function' then + local a1b2 = {a=1, b=2} + function public.L(body, ...) + if type(body) == 'function' then local arg1 = arg - return function(...) return helper(f, arg1, arg) end + return function(...) return helper(body, arg1, arg) end else - return loadstring 'function(_1,_2,_3,_4,_5,_6,_7,_8,_9)' + body = gsub(body, '_([ab])', function(char) return '_'..a1b2[char] end) + local lambda = loadstring 'return function(_1,_2,_3,_4,_5,_6,_7,_8,_9)'..f..' end' + setfenv(lambda, getfenv(2)) + return lambda end end end @@ -105,7 +109,7 @@ do local __index = function(self, key) return _state[self].handler({public=self, private=_state[self].state}, key) end - function public.index_function(state, handler) + function public.index_function(state, handler) -- TODO rename table-accessor, use predicate to stop local state, self = {handler=handler, state=state}, {} _state[self] = state return setmetatable(self, {__metatable=false, __index=__index, state=state})