From 2b9a63fe8c15e47831698c5a5fb66f6410c6b24f Mon Sep 17 00:00:00 2001 From: Manuel Simon Hirsig Date: Sun, 21 Aug 2016 14:10:48 +0200 Subject: [PATCH] big refactoring --- init.lua | 5 ++-- module.lua | 70 ++++++++++++++++++++++++------------------------------ 2 files changed, 33 insertions(+), 42 deletions(-) diff --git a/init.lua b/init.lua index 272fb0b..94f97ec 100644 --- a/init.lua +++ b/init.lua @@ -1,4 +1,4 @@ -local aux_module, getn, setn, tinsert, tremove, getfenv, setfenv, gfind = aux_module, getn, table.setn, tinsert, tremove, getfenv, setfenv, string.gfind +local aux_module, getn, setn, tinsert, tremove, setfenv = aux_module, getn, table.setn, tinsert, tremove, setfenv aux = aux_module 'core' public.version = '5.0.0' @@ -25,9 +25,8 @@ end do local modules = {} - local function module_env(name) aux_module(name) return m end function public.module(name) - local env = module_env(name) + local env = aux_module(name).env if not modules[name] then env.import(temp-{['']='modules', ['']='core', ['']='util'}) end setfenv(2, env) modules[name] = true diff --git a/module.lua b/module.lua index 16c6092..6acbda5 100644 --- a/module.lua +++ b/module.lua @@ -2,19 +2,18 @@ local type, setmetatable, setfenv, unpack, mask, g = type, setmetatable, setfenv local PRIVATE, PUBLIC, MUTABLE, PROPERTY = 0, 1, 2, 4 local MODIFIER = {private=PRIVATE, public=PUBLIC, mutable=MUTABLE, property=PROPERTY} local MODIFIER_MASK, PROPERTY_MASK = {private=MUTABLE+PROPERTY, public=MUTABLE+PROPERTY, mutable=PRIVATE+PUBLIC}, PRIVATE+PUBLIC -local import, error, lock_mt, env_mt, interface_mt, declarator_mt +local error, import, define_property, lock_mt, env_mt, interface_mt, declarator_mt local _state, _modules = {}, {} -function error(message, ...) g.error(format(message, unpack(arg))..'\n'..debugstack(3, 5, 0), 3) end +function error(message, level, ...) g.error(format(message, unpack(arg))..'\n'..debugstack(3, 5, 0), (level or 1) + 1) end function import(imports, t) for k, v in t do imports[type(k) == 'number' and v or k] = v end end declarator_mt = {__metatable=false} -function declarator_mt.__call(self, t) - local state = _state[self]; local key = state.property - if not key then return end +function define_property(self, key, t) + local state = _state[self] for k, v in t do if k == 'get' then - state.getters[key] = type(v) == 'function' and v or error('Getter must be function.') - elseif k == 'set' or error('Malformed property definition.') then - state.setters[key] = type(v) == 'function' and v or error('Setter must be function.') + state.getters[key] = type(v) == 'function' and v or error('Getter must be function.', 3) + elseif k == 'set' or error 'Malformed declaration.' then + state.setters[key] = type(v) == 'function' and v or error('Setter must be function.', 3) end end end @@ -23,32 +22,25 @@ function declarator_mt.__index(self, key) if modifier then state.modifiers = modifier + mask(MODIFIER_MASK[key], state.modifiers) return self - else + elseif not state.metadata[key] or error('Field "%s" already exists.', 2, key) then state.modifiers = PROPERTY + mask(PROPERTY_MASK, state.modifiers) - state.property = key - return self + return function(t) define_property(self, key, t) end end end function declarator_mt.__newindex(self, key, value) - local state, modifiers; local state = _state[self] - modifiers, state.modifiers = state.modifiers, PRIVATE - if modifiers then error('Field "%s" already exists.', key) end - state.metadata[key] = modifiers - if mask(PROPERTY, modifiers) == 0 then - state.data[self][key] = value - elseif type(value) == 'function' or error('Getters/setters must be functions.') then - state.getters[key], state.setters[key] = value, value - end + local state = _state[self] + if state.metadata[key] then error('Field "%s" already exists.', 2, key) end + state.metadata[key], state.data[key], state.modifiers = state.modifiers, value, PRIVATE end do local function index(access, default) return function(self, key) - local state = _state[self]; local modifiers = state.modifiers + local state = _state[self]; local modifiers = state.metadata[key] if mask(access+PROPERTY, modifiers) == access then return state.data[key] else local getter = state.getters[key] - if getter then return getter() else return default[key] or error('No field "%s".', key) end + if getter then return getter() else return default[key] or error('No field "%s".', 2, key) end end end end @@ -60,16 +52,16 @@ do else local setter = state.setters[key] if setter then return setter(value) end - if mask(MUTABLE, state.metadata[key]) == 0 then error('Field "%s" is immutable.', key) end + if mask(MUTABLE, state.metadata[key]) == 0 then error('Field "%s" is immutable.', 2, key) end end state.data[key] = value end interface_mt = {__metatable=false, __index=index(PUBLIC, {})} function interface_mt.__newindex(self, key, value) - local state = _state[self] - if mask(PUBLIC+PROPERTY, state.metadata[key]) == PUBLIC+PROPERTY then - return state.setters[key](value) - elseif mask(PUBLIC+MUTABLE, state.metadata[key]) == PUBLIC+MUTABLE or error('Field "%s" is immutable.', key) then + local state = _state[self]; local setter = state.setters[key] + if mask(PUBLIC+PROPERTY, state.metadata[key]) == PUBLIC+PROPERTY and setter then + return setter(value) + elseif mask(PUBLIC, state.metadata[key]) == PUBLIC or error('Field "%s" is immutable.', 2, key) then state.data[key] = value end end @@ -87,25 +79,25 @@ function g.aux_module(name) } _modules[name], _state[env], _state[interface], _state[declarator] = state, state, state, state end - local state = (_state[name]) - setfenv(2, state.env) - return state + local module = _modules[name] + setfenv(2, module.env) + return module end local frame = CreateFrame 'Frame' frame:RegisterEvent 'PLAYER_LOGIN' frame:SetScript('OnEvent', function() - lock_mt.__newindex = function() error 'Cannot change modules after the loading phase.' end + lock_mt.__newindex = function() error 'Modules are frozen after the loading phase.' end local count = 0 local t0 = GetTime() - for _, state in _state do - local metadata, data, getters, setters = state.metadata, state.data, state.getters, state.setters - for alias, name in state.imports do - local state = _state[name] - if not state then error('Import failed. No module "%s".', name) end - local import_data, import_getters, import_setters = state.data, state.getters, state.setters + for _, module in _modules do + local metadata, data, getters, setters = module.metadata, module.data, module.getters, module.setters + for alias, name in module.imports do + local import = _modules[name] + if not import then error('Import failed. No module "%s".', 1, name) end + local import_data, import_getters, import_setters = import.data, import.getters, import.setters if alias == '' then for key, modifiers in import.metadata do - if metadata[key] then error('') end + if metadata[key] then error('Import of "%s" failed. Conflict with "%s"', 1, name, key) end count = count + 1 metadata[key], data[key], getters[key], setters[key] = modifiers, import_data[key], import_getters[key], import_setters[key] end @@ -115,5 +107,5 @@ frame:SetScript('OnEvent', function() end end end - log('imported: '..count..' in '..(GetTime()-t0)) + g.aux.log('imported: '..count..' in '..(GetTime()-t0)) end) \ No newline at end of file