diff --git a/components/disenchant.lua b/components/disenchant.lua index 38b15b8..7c21b73 100644 --- a/components/disenchant.lua +++ b/components/disenchant.lua @@ -41,7 +41,7 @@ do end function m.LOAD() - armor = hashset( + armor = set( 'INVTYPE_HEAD', 'INVTYPE_NECK', 'INVTYPE_SHOULDER', @@ -59,7 +59,7 @@ function m.LOAD() 'INVTYPE_HOLDABLE' ) - weapon = hashset( + weapon = set( 'INVTYPE_2HWEAPON' , 'INVTYPE_WEAPONMAINHAND', 'INVTYPE_WEAPON', diff --git a/core.lua b/core.lua index 2f55488..fd6de90 100644 --- a/core.lua +++ b/core.lua @@ -8,33 +8,23 @@ tabs = {} function public.tab(index, name) local module_env = getfenv(2) local tab = {name=name, env=module_env} - module_env.public.ACTIVE = function() - return tab == active_tab - end - for _, handler in {'OPEN', 'CLOSE', 'CLICK_LINK', 'USE_ITEM'} do - module_env.mutable[handler] = nil - end + module_env.public.ACTIVE = function() return tab == active_tab end + for handler in temp-set{'OPEN', 'CLOSE', 'CLICK_LINK', 'USE_ITEM'} do module_env.mutable[handler] = nil end tabs[index] = tab end do local active_tab_index - function accessor.active_tab() - return tabs[active_tab_index] - end + function accessor.active_tab() return tabs[active_tab_index] end function on_tab_click(index) - if active_tab_index then - call(active_tab.env.CLOSE) - end + call(active_tab_index and active_tab.env.CLOSE) active_tab_index = index - if active_tab_index then - call(active_tab.env.OPEN) - end + call(active_tab_index and active_tab.env.OPEN) end end -function VARIABLES_LOADED() +function LOAD() do - local frame = CreateFrame('Frame', aux.gui.name, UIParent) + local frame = CreateFrame('Frame', gui.name, UIParent) tinsert(UISpecialFrames, 'aux_frame1') gui.set_window_style(frame) frame:SetWidth(768) @@ -45,19 +35,10 @@ function VARIABLES_LOADED() frame:EnableMouse(true) frame:SetClampedToScreen(true) frame:RegisterForDrag 'LeftButton' - frame:SetScript('OnDragStart', function() - this:StartMoving() - end) - frame:SetScript('OnDragStop', function() - this:StopMovingOrSizing() - end) - frame:SetScript('OnShow', function() - PlaySound 'AuctionWindowOpen' - end) - frame:SetScript('OnHide', function() - PlaySound 'AuctionWindowClose' - CloseAuctionHouse() - end) + frame:SetScript('OnDragStart', function() this:StartMoving() end) + frame:SetScript('OnDragStop', function() this:StopMovingOrSizing() end) + frame:SetScript('OnShow', function() PlaySound 'AuctionWindowOpen' end) + frame:SetScript('OnHide', function() PlaySound 'AuctionWindowClose' CloseAuctionHouse() end) frame.content = CreateFrame('Frame', nil, frame) frame.content:SetPoint('TOPLEFT', 4, -80) frame.content:SetPoint('BOTTOMRIGHT', -4, 35) @@ -67,12 +48,8 @@ function VARIABLES_LOADED() do local tabs = gui.tabs(frame, 'DOWN') tabs._on_select = on_tab_click - for _, tab in m.tabs do - tabs:create_tab(tab.name) - end - function public.set_tab(id) - tabs:select(id) - end + for _, tab in m.tabs do tabs:create_tab(tab.name) end + function public.set_tab(id) tabs:select(id) end end do local btn = gui.button(frame, 16) @@ -90,11 +67,7 @@ function VARIABLES_LOADED() btn:SetHeight(24) btn:SetText 'Default UI' btn:SetScript('OnClick',function() - if AuctionFrame:IsVisible() then - HideUIPanel(AuctionFrame) - else - ShowUIPanel(AuctionFrame) - end + if AuctionFrame:IsVisible() then HideUIPanel(AuctionFrame) else ShowUIPanel(AuctionFrame) end end) end end @@ -124,16 +97,12 @@ function AUCTION_OWNED_LIST_UPDATE() end function ADDON_LOADED.Blizzard_AuctionUI() - AuctionFrame:UnregisterEvent('AUCTION_HOUSE_SHOW') + AuctionFrame:UnregisterEvent 'AUCTION_HOUSE_SHOW' AuctionFrame:SetScript('OnHide', nil) - hook('ShowUIPanel', function(...) - if arg[1] == AuctionFrame then - return AuctionFrame:Show() - end + if arg[1] == AuctionFrame then return AuctionFrame:Show() end return orig.ShowUIPanel(unpack(arg)) end) - hook('GetOwnerAuctionItems', GetOwnerAuctionItems) hook('SetItemRef', SetItemRef) hook('UseContainerItem', UseContainerItem) @@ -147,14 +116,11 @@ do label = label..LIGHTYELLOW_FONT_COLOR_CODE..')'..FONT_COLOR_CODE_CLOSE return label end - function ADDON_LOADED.Blizzard_CraftUI() hook('CraftFrame_SetSelection', function(...) local results = {orig.CraftFrame_SetSelection(unpack(arg))} - local id = GetCraftSelectionIndex() local reagent_count = GetCraftNumReagents(id) - local total_cost = 0 for i=1,reagent_count do local link = GetCraftReagentItemLink(id, i) @@ -173,20 +139,15 @@ do total_cost = total_cost + value * count end end - CraftReagentLabel:SetText(SPELL_REAGENTS..' '..cost_label(total_cost)) - return unpack(results) end) end - function ADDON_LOADED.Blizzard_TradeSkillUI() hook('TradeSkillFrame_SetSelection', function(...) local results = {orig.TradeSkillFrame_SetSelection(unpack(arg))} - local id = GetTradeSkillSelectionIndex() local reagent_count = GetTradeSkillNumReagents(id) - local total_cost = 0 for i=1,reagent_count do local link = GetTradeSkillReagentItemLink(id, i) @@ -205,9 +166,7 @@ do total_cost = total_cost + value * count end end - TradeSkillReagentLabel:SetText(SPELL_REAGENTS..' '..cost_label(total_cost)) - return unpack(results) end) end @@ -223,9 +182,7 @@ function public.hook(name, handler, object) object = g orig = m.orig end - if orig[name] then - error('"'..name..'" is already hooked.') - end + assert(not orig[name], '"'..name..'" is already hooked.') orig[name] = object[name] object[name] = handler end @@ -246,7 +203,7 @@ function SetItemRef(...) if arg[3] ~= 'RightButton' or not index(active_tab, 'env', 'CLICK_LINK') or not strfind(arg[1], '^item:%d+') then return orig.SetItemRef(unpack(arg)) end - for item_info in present(info.item(tonumber(({strfind(arg[1], '^item:(%d+)')})[3]))) do + for item_info in present(info.item(tonumber(select(3, strfind(arg[1], '^item:(%d+)'))))) do return active_tab.env.CLICK_LINK(item_info) end end @@ -262,9 +219,7 @@ end do local locked - function public.bid_in_progress() - return locked - end + function public.bid_in_progress() return locked end function public.place_bid(type, index, amount, on_success) if locked then return @@ -286,9 +241,7 @@ end do local locked - function public.cancel_in_progress() - return locked - end + function public.cancel_in_progress() return locked end function public.cancel_auction(index, on_success) if locked then return diff --git a/init.lua b/init.lua index 9db1943..a665920 100644 --- a/init.lua +++ b/init.lua @@ -1,85 +1,79 @@ -setglobal('aux', aux_module 'core') +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 public.version = '5.0.0' -local temp +local temp, recycle do - local setn, tinsert, tremove = g.table.setn, g.tinsert, g.tremove local table_pool, locked = {}, {} local function wipe(t) -- like with a cloth or something for k in t do t[k] = nil end setn(t, 0) return t end - local function release(t) + function recycle(t) locked[t] = nil tinsert(table_pool, t) - aux.log(getn(table_pool)) - end - function temp() - local t = tremove(table_pool) - t = t and wipe(t) or {} - locked[t] = true + log(getn(table_pool)) end + public.recycle = recycle + temp = setmetatable({}, { + __call = function() + local t = tremove(table_pool) + t = t and wipe(t) or {} + locked[t] = true + end, + __sub = function(_, t) locked[t] = true return t end, + }) public.temp = temp - function public.static() - local t = tremove(table_pool) - t = t and wipe(t) or {} - locked[t] = true - end - function public.array(...) locked[arg] = true end - function public.set(...) - local set = temp() - for i=1,arg.n do set[arg[i]] = true end - release(arg) - return set - end end do - local aux_module, getfenv, setfenv, gfind = g.aux_module, g.getfenv, g.setfenv, g.string.gfind - aux_module 'modules' function public.module(path) - local parts, name, env - parts, name = gfind(path, '[%a_][%w_]*'), 'modules' + local env, parts, parent, name + parts, parent, name = gfind(path, '[%a_][%w_]*'), aux_module 'modules', '' for part in parts do - env.public[part], env = (function() return aux_module(name), getfenv() end)() - env.import('modules', 'core', 'util') name = name..'/'..part + env, parent.public[part] = aux_module(name) + env.import('modules', 'core', 'util') + parent = env end setfenv(2, env) end end local event_frame = CreateFrame 'Frame' -for _, event in {'VARIABLES_LOADED', 'ADDON_LOADED', 'AUCTION_HOUSE_SHOW', 'AUCTION_HOUSE_CLOSED', 'AUCTION_BIDDER_LIST_UPDATE', 'AUCTION_OWNED_LIST_UPDATE'} do +for event in temp-set{'VARIABLES_LOADED', 'ADDON_LOADED', 'AUCTION_HOUSE_SHOW', 'AUCTION_HOUSE_CLOSED', 'AUCTION_BIDDER_LIST_UPDATE', 'AUCTION_OWNED_LIST_UPDATE'} do event_frame:RegisterEvent(event) end -LOADED, LOADED2, ADDON_LOADED = {}, {}, {} -function public.accessor.LOAD(f) tinsert(LOAD, f) end -event_frame:SetScript('OnEvent', function() - if event == 'ADDON_LOADED' then - if ADDON_LOADED[arg1] then - ADDON_LOADED[arg1]() +ADDON_LOADED = {} +do + local variables_loaded_hooks, player_login_hooks = {}, {} + function public.accessor.LOAD(f) tinsert(variables_loaded_hooks, f) end + function public.accessor.LOAD2(f) tinsert(player_login_hooks, f) end + event_frame:SetScript('OnEvent', function() + if event == 'ADDON_LOADED' then + if ADDON_LOADED[arg1] then ADDON_LOADED[arg1]() end + else + m[event]() + if event == 'VARIABLES_LOADED' then + for _, f in variables_loaded_hooks do f() end + end + if event == 'PLAYER_LOGIN' then + for _, f in player_login_hooks do f() end + log('v'..version..' loaded.') + end end - else - m[event]() - if event == 'VARIABLES_LOADED' then --- for _, env in module_envs do --- if env.LOAD then --- env.LOAD() --- end --- end - log('v'..version..' loaded.') - end - end -end) + end) +end function public.log(...) local msg = '[aux]' - for i=1,arg.n do - msg = msg..' '..tostring(arg[i]) - end + for i=1,arg.n do msg = msg..' '..tostring(arg[i]) end DEFAULT_CHAT_FRAME:AddMessage(LIGHTYELLOW_FONT_COLOR_CODE..msg) end diff --git a/module.lua b/module.lua index 25c81fc..01f6da2 100644 --- a/module.lua +++ b/module.lua @@ -1,91 +1,91 @@ -local rawget, setmetatable, mask, add, g = rawget, setmetatable, bit.band, bit.bor, getfenv(0) -local DECLARED, ACCESSOR, MUTABLE, PUBLIC = 1, 2, 4, 8 -local IMPORTER_KEY, ACCESSOR_KEY, MUTABLE_KEY, PUBLIC_KEY = 'import', 'accessor', 'mutable', 'public' -local PROPERTY = {[ACCESSOR_KEY]=ACCESSOR, [MUTABLE_KEY]=MUTABLE, [PUBLIC_KEY]=PUBLIC} -local _modules, _data, _metadata, _modifiers, _modifier_properties, _imports = {}, {}, {}, {}, {}, {} -local metadata_mt, modifier_mt, env_mt, interface_mt, importer_mt -local modifier_accessor, accessor_modifier_accessor, mutable_modifier_accessor, public_modifier_accessor -local error, locked +local setmetatable, unpack, mask, add, g = setmetatable, unpack, bit.band, bit.bor, getfenv(0) +local DECLARED, PUBLIC, MUTABLE, ACCESSOR, MUTATOR = 1, 2, 4, 8, 16 +local MODIFIER = {public=PUBLIC, mutable=MUTABLE, accessor=ACCESSOR, mutator=MUTATOR} +local _10, _01, tf, ft = {[true]=1, [false]=0}, {[true]=0, [false]=1}, {true, false}, {false, true} +local importer_mt, modifier_mt, env_mt, interface_mt, lock_mt +local define_property, declarator_accessor, public_accessor, mutable_accessor, accessor_accessor, mutator_accessor, index, error +local _modules, _metadata, _data, _accessors, _mutators, _imports, _declarators, _declarator_state = setmetatable({}, lock_mt), {}, {}, {}, {}, {}, {}, {} function error(message, ...) g.error(format(message, unpack(arg))..'\n'..debugstack(3, 5, 0), 3) end -metadata_mt = {__index=function() return 0 end } +importer_mt = {__metatable=false} function importer_mt.__call(self, ...) local imports = _imports[self] - for i = 1, arg.n do imports[arg[i]] = true end + for i=1,arg.n do imports[arg[i]] = true end end -function modifier_accessor(property) - return function(modifier) return function() _modifier_properties[modifier] = DECLARED+property return modifier end end +function declarator_accessor(modifier) + return function(declarator) return function() _declarator_state[declarator] = DECLARED+modifier return declarator end end +end +public_accessor, mutable_accessor, accessor_accessor, mutator_accessor = declarator_accessor(PUBLIC), declarator_accessor(MUTABLE), declarator_accessor(ACCESSOR), declarator_accessor(MUTATOR) +function define_property(self, key, t) + local accessor, mutator = t.get, t.set + _declarator_state[self] = add(_01[not accessor]*ACCESSOR, _01[not mutator]*MUTATOR, _declarator_state[self]) + _accessors[self][key], _mutators[self][key] = accessor, mutator end -accessor_modifier_accessor, mutable_modifier_accessor, public_modifier_accessor = modifier_accessor(ACCESSOR), modifier_accessor(MUTABLE), modifier_accessor(PUBLIC) modifier_mt = {__metatable=false} function modifier_mt.__index(self, key) - local property = PROPERTY[key] - if not property then error('Unknown modifier "%s".', key) end - _modifier_properties[self] = add(property, _modifier_properties[self]) + local modifier = MODIFIER[key] + if not modifier then return function(t) define_property(self, key, t) end end + _declarator_state[self] = add(modifier, _declarator_state[self]) return self end function modifier_mt.__newindex(self, key, value) - if rawget(_metadata[self], key) then error('Field "%s" already exists.', key) end - _metadata[self][key], _data[self][key] = _modifier_properties[self], 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 end -env_mt = {__metatable=false} -function env_mt.__index(self, key) - local value, properties = _data[self][key], _metadata[self][key] - if mask(DECLARED + ACCESSOR, properties) == DECLARED then - return value - elseif mask(ACCESSOR, properties) == ACCESSOR then - return value(key) - else - return g[key] or error('No field "%s".', key) +function index(access, default) + return function(self, key) + local modifiers = _metadata[self][key] or 0 + if mask(access+ACCESSOR, modifiers) == access then + return _data[self][key] + elseif mask(access, modifiers) ~= 0 then + return _accessors[self]() + else + return default[key] or error('No field "%s".', key) + end end end +env_mt = {__metatable=false, __index=index(DECLARED, g)} function env_mt.__newindex(self, key, value) - if not rawget(_metadata[self], key) then + if not _metadata[self][key] then _metadata[self][key] = DECLARED elseif mask(MUTABLE, _metadata[self][key]) == 0 then error('Field "%s" is immutable.', key) end _data[self][key] = value end -interface_mt = {__metatable=false} -function interface_mt.__index(self, key) - local value, properties = _data[self][key], _metadata[self][key] - if mask(ACCESSOR + PUBLIC, properties) == PUBLIC then - return value - elseif mask(PUBLIC, properties) ~= 0 or error('No field "%s".', key) then - return value(key) - end -end +interface_mt = {__metatable=false, __index=index(PUBLIC, {})} function interface_mt.__newindex(self, key, value) self[key](value) end -importer_mt = {__metatable=false} +lock_mt = {} function g.aux_module(name) if not _modules[name] then - local metadata, data, imports, importer, modifier, env, interface - imports, importer, modifier, env, interface = {}, setmetatable({}, importer_mt), setmetatable({}, modifier_mt), setmetatable({}, env_mt), setmetatable({}, interface_mt) - metadata = setmetatable({g=DECLARED, m=DECLARED, [IMPORTER_KEY]=DECLARED, [ACCESSOR_KEY]=ACCESSOR, [MUTABLE_KEY]=ACCESSOR, [PUBLIC_KEY]=ACCESSOR}, metadata_mt) - data = {g=g, m=env, [IMPORTER_KEY]=importer, [ACCESSOR_KEY]=accessor_modifier_accessor(modifier), [MUTABLE_KEY]=mutable_modifier_accessor(modifier), [PUBLIC_KEY]=public_modifier_accessor(modifier)} - _metadata[name], _metadata[modifier], _metadata[env], _metadata[interface] = metadata, metadata, metadata, metadata - _data[name], _data[modifier], _data[env], _data[interface] = data, data, data, data + local metadata, data, accessors, mutators, imports, importer, declarator, env, interface + imports, importer, declarator, env, interface = {}, setmetatable({}, importer_mt), setmetatable({}, modifier_mt), setmetatable({}, env_mt), setmetatable({}, interface_mt) + metadata = setmetatable({g=DECLARED, m=DECLARED, import=DECLARED, public=ACCESSOR, mutable=ACCESSOR, accessor=ACCESSOR, mutator=ACCESSOR}, lock_mt) + data = {g=g, m=env, import=importer, public=public_accessor(declarator), mutable=mutable_accessor(declarator), accessor=accessor_accessor(declarator), mutator=mutator_accessor(declarator)} + _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 _imports[name], _imports[importer] = imports, imports - _modifiers[name] = modifier + _declarators[name] = declarator _modules[name] = {env, interface} end - return _modules[name] + return unpack(_modules[name]) end local frame = CreateFrame 'Frame' frame:RegisterEvent 'PLAYER_LOGIN' frame:SetScript('OnEvent', function() - locked = true + lock_mt.__newindex = function() error 'Cannot change modules after the loading phase.' end local count = 0 local t0 = GetTime() for name in _modules do - local modifier = _modifiers[name] + local declarator = _declarators[name] for import_name in _imports[name] do if not _modules[import_name] then error('Invalid import %s in %s.', import_name, name) end local data = _data[import_name] - for key, properties in _metadata[import_name] do - if mask(PUBLIC, properties) ~= 0 then - _modifier_properties[modifier] = properties - modifier[key] = data[key] + for key, modifiers in _metadata[import_name] do + if mask(PUBLIC, modifiers) ~= 0 then + _declarator_state[declarator] = modifiers + declarator[key] = data[key] end end end diff --git a/util/core.lua b/util/core.lua index cf17304..e665a58 100644 --- a/util/core.lua +++ b/util/core.lua @@ -1,6 +1,6 @@ aux.module 'util' -local temp, getn = g.aux.temp, g.getn +local temp, recycle, getn = temp, recycle, g.getn function public.copy(t) local copy = {} @@ -205,9 +205,10 @@ end do local mt = {__call = function(self, key) return self[key] end} - function public.hashset(...) -- TODO rename/remove? + function public.set(t) local self = {} - for i=1,arg.n do self[arg[i]] = true end + for i=1,getn(t) do self[t[i]] = true end + recycle(t) return setmetatable(self, mt) end end diff --git a/util/money.lua b/util/money.lua index 7abaf3a..1a9e05f 100644 --- a/util/money.lua +++ b/util/money.lua @@ -58,7 +58,7 @@ end --function public.to_string(params) -- TODO -- local gold, silver, copper = to_gsc(params.copper or 0 + ) --- local settings = hashset(unpack(arg)) +-- local settings = set(unpack(arg)) --end function public.to_string(money, pad, trim, decimal_points, color, no_color)