|
02-09-12, 10:15 PM | #1 |
Mass confusion, loading process
OKay so I have always had some funny intermitent problems with my saved variables and it has always had to do with the way it clears default keys out... but i may have just noticed part of the problem... umm when is it that PLAYER_LOGIN fires? because the following code should not even work but yet its the only way i can get it to work properly... Notice there is a register for ADDON_LOADED in a PLAYER_LOGIN event so technically that addon loaded part should never run right? but it does!
Code:
addon.RegisterEvent("MoveFrames-Initialize", 'PLAYER_LOGIN', function(self, event) addon.UnregisterEvent(self, event) if addon.settings.movedFrames then movedFrames = addon.settings.movedFrames end if type(movedFrames) ~= 'table' then movedFrames = { } addon.settings.movedFrames = movedFrames end local function HookFrames(self, event) addon:DefaultMoveableFrames() VerCheckUpdate() moveableframes = CopyTable(GMoveableFrames) for name, parent in pairs(moveableframes) do if HookFrame(name, parent) then moveableframes[name] = nil end end if next(moveableframes) then return end addon.UnregisterEvent(self, event) end addon.RegisterEvent("MoveFrames-Hook", 'ADDON_LOADED', HookFrames) HookFrames("MoveFrames-Hook", 'ADDON_LOADED') end) |
|
02-09-12, 11:14 PM | #2 |
yea thinking about it and looking at whats going on and how the game is responding my tweaks to what vrul originally wrote has created some bizarre and what one would think is impossible behavior. Ive been struggling with this for years now heh. Always come back to the same problem or rather set of problems. My frame mover system needs to load up during the addon loaded event to avoid taint bugs and just because frame positioning should be done right after the variables are available. Or so they say... Im constantly having issues with it not being able to return a value out of the saved variables. Possibly because i still em confused by the saved variables and tables and their working in conjunction, the prime example of this issue is in the frame mover system all the way around... as you can see i had to do all kinds of funny business to get the LOD config panels listings to function with the frame movers moveable frame table and oh my... it just gets out of control or rather just becomes a lot to wrap your brain around or at least for me to wrap mine around... The following code chunks are my "settings" setup, the small chunk in the core that deals with the event registering just incase and then the whole of the frame mover system. I should be able to change the frame mover event to have everything in the hookframes function in an addon loaded event along with the stuff at the top of that, with some minor changes well i made all proper changes and it loads with no errors but its not hooking the frames somthing is happening. Or rather not... Any thoughts on any of this? any recomendations even if its not addressing what appears to be the issue? as far as how is it an addon loaded fires after a player login? whats going on here?
Core - Code:
local addonName, addon = ... _G[addonName] = addon --[[----------------------------------------------------------------------------- Event handling - Use one frame to process multiple individual OnEvent needs -------------------------------------------------------------------------------]] do local frame, select, next, events = CreateFrame('Frame'), select, pairs({ }) local register, unregister = frame.RegisterEvent, frame.UnregisterEvent frame:Hide() frame:SetScript('OnEvent', function(self, event, ...) for reference, func in next, events[event], nil do func(reference, event, ...) end end) function addon.RegisterEvent(reference, event, func, ...) if not events[event] then events[event] = { } register(frame, event) end events[event][reference] = func end function addon.RegisterEvents(reference, func, ...) local event for index = 1, select('#', ...) do event = select(index, ...) if not events[event] then events[event] = { } register(frame, event) end events[event][reference] = func end end function addon.UnregisterEvent(reference, event) if events[event] then events[event][reference] = nil if not next(events[event]) then events[event] = nil unregister(frame, event) end end end function addon.UnregisterAllEvents(reference) for event, registry in next, events, nil do registry[reference] = nil if not next(registry) then events[event] = nil unregister(frame, event) end end end end --[[----------------------------------------------------------------------------- SafeCall - Queue a method of addon to run once combat ends if needed -------------------------------------------------------------------------------]] do local combatLockdown, queue = InCombatLockdown(), { } addon.RegisterEvent("Core-SafeCall-EnterCombat", 'PLAYER_REGEN_DISABLED', function(self) combatLockdown = true end) addon.RegisterEvent("Core-SafeCall-LeaveCombat", 'PLAYER_REGEN_ENABLED', function(self) combatLockdown = nil for method, arg in pairs(queue) do addon[method](addon, arg) queue[method] = nil end end) function addon:SafeCall(method, arg) if combatLockdown then queue[method] = arg or false else addon[method](addon, arg) end end end --[[----------------------------------------------------------------------------- Localized class name to file class name look up table -------------------------------------------------------------------------------]] local CLASS = { } for fileName, localName in pairs(LOCALIZED_CLASS_NAMES_MALE) do CLASS[localName] = fileName end for fileName, localName in pairs(LOCALIZED_CLASS_NAMES_FEMALE) do CLASS[localName] = fileName end addon.CLASS = CLASS Code:
local addonName, addon = ... local defaults = { class = true } --[[----------------------------------------------------------------------------- RegisterDefaultSetting - Allow modules to set their defaults -------------------------------------------------------------------------------]] function addon:RegisterDefaultSetting(key, value) -- Use caution if using this after ADDON_LOADED defaults[key] = value end --[[----------------------------------------------------------------------------- Load settings, apply version conversions as needed, and link to defaults -------------------------------------------------------------------------------]] addon.RegisterEvent("Settings-Load", 'ADDON_LOADED', function(self, event, name) if name ~= addonName then return end addon.UnregisterEvent(self, event) local name, class = UnitClass('player') name = UnitName('player') local realm = GetRealmName() local settings = _G[addonName .. "Settings"] if type(settings) ~= 'table' then settings = { } _G[addonName .. "Settings"] = settings end if type(settings[realm]) ~= 'table' then settings[realm] = { } end if type(settings[realm][name]) ~= 'table' then settings[realm][name] = { class = class } end settings.version = nil -- Reset value on logout (so can iterate over data without issue) addon.settings = setmetatable(settings[realm][name], { __index = defaults }) return settings end) --[[----------------------------------------------------------------------------- Character Specific WTF Reset. -------------------------------------------------------------------------------]] function addon:ResetWTF() local name, class = UnitClass('player') name = UnitName('player') local realm = GetRealmName() local settings = _G[addonName .. "Settings"] if type(settings[realm][name]) == 'table' then settings[realm][name] = { class = class } end settings.version = nil -- Reset value on logout return settings end --[[----------------------------------------------------------------------------- Remove unused settings or settings that are the same as defaults -------------------------------------------------------------------------------]] addon.RegisterEvent("Settings-Unload", 'PLAYER_LOGOUT', function() local settings = addon.settings for key, value in pairs(settings) do if value == defaults[key] or defaults[key] == nil then settings[key] = nil end end _G[addonName .. "Settings"].version = GetAddOnMetadata(addonName, 'Version') _G[addonName .. "Settings"].lastVersion = GetAddOnMetadata(addonName, 'Version') end) --[[----------------------------------------------------------------------------- LOD Configuration -------------------------------------------------------------------------------]] -- options local LOA = LibStub and LibStub('LibOptionsAssist-1.0', true) if not (LOA and select(2, GetAddOnInfo(addonName .. "_Config"))) then return end -- Make sure config support exists addon.configPanel = LOA:AddEntry(addonName, nil, addonName .. "_Config") _G['SLASH_' .. addonName .. 1] = '/' .. addonName _G['SLASH_' .. addonName .. 2] = '/' .. addonName:lower() _G['SLASH_' .. addonName .. 3] = '/' .. addonName:upper() _G['SLASH_' .. addonName .. 4] = '/gui' SlashCmdList[addonName] = addon.configPanel InterfaceOptionsFrame:SetFrameStrata('HIGH') InterfaceOptionsFrame.SetFrameStrata = addon.DoNothing --[[----------------------------------------------------------------------------- GrimUI Options Frame Logo -------------------------------------------------------------------------------]] local GUI_Logo = CreateFrame('Frame', "GUI_Logo", InterfaceOptionsFrame) GUI_Logo:SetHeight(256) GUI_Logo:SetWidth(256) GUI_Logo:SetPoint('BOTTOM', InterfaceOptionsFrame, 'TOP', 0, -75) GUI_Logo:SetBackdrop({ bgFile = [[Interface\AddOns\GrimUI\Media\GrimUILogo]], edgeFile = nil, edgeSize = 0, tile = false, insets = { left = 0, right = 0, top = 0, bottom = 0 } }) GUI_Logo:Hide() --[[----------------------------------------------------------------------------- In Game Help System Setup -------------------------------------------------------------------------------]] function addon:LoadGUIHelp() addon.configPanel() GUI_HelpInitiate() end local GUI_HelpButton = CreateFrame('Button', "GUI_HelpButton", InterfaceOptionsFrame) GUI_HelpButton:SetHeight(40) GUI_HelpButton:SetWidth(25) GUI_HelpButton:SetPoint('TOP', InterfaceOptionsFrame, 'TOP', 190, -37) GUI_HelpButton:RegisterForClicks("AnyUp") GUI_HelpButton:SetFrameStrata("DIALOG") GUI_HelpButton:SetNormalTexture([[Interface\BUTTONS\UI-MicroButton-Help-Up]]) GUI_HelpButton:SetHighlightTexture([[Interface\BUTTONS\UI-MicroButton-Hilight]]) GUI_HelpButton:SetPushedTexture([[Interface\BUTTONS\UI-MicroButton-Help-Down]]) local HelpText = GUI_HelpButton:CreateFontString(nil, 'DIALOG') HelpText:SetFont([[Fonts\FRIZQT__.TTF]], 14) HelpText:SetText("Help") HelpText:SetPoint("RIGHT", GUI_HelpButton, "LEFT", 0, -5) HelpText:SetTextColor(1, .10, .10, 1) GUI_HelpButton:SetScript('OnClick', function(self) if button == 'LeftButton' then GUI_HelpInitiate() else GUI_HelpInitiate() end end) GUI_HelpButton:Hide() -- Auto load help on first use. addon.RegisterEvent("Settings-Help", 'PLAYER_ENTERING_WORLD', function(self, event, name) addon.UnregisterEvent(self, event) if not addon.settings.HelpViewed or addon.settings.HelpViewed == false then addon:LoadGUIHelp() end if IsAddOnLoadOnDemand("GrimUI_DevTools") then if addon.settings.loadDevTools == true then LoadAddOn("GrimUI_DevTools") end end end) --[[------------------------------------------------------------------------------- Config Panel Show/Hide Scripts - Put all config panel adjustment functions here! ---------------------------------------------------------------------------------]] addon.configPanel:SetScript('OnHide', function() GUI_Logo:Hide() GUI_HelpButton:Hide() end) addon.configPanel:SetScript('OnShow', function() GUI_Logo:Show() GUI_HelpButton:Show() end) --[[------------------------------------------------------------------------------- Default WTF Settings - Try them here to stop nextto error and other errors. ---------------------------------------------------------------------------------]] --Settings.lua settings addon:RegisterDefaultSetting("HelpViewed", false) --DevTools.lua settings addon:RegisterDefaultSetting("loadDevTools", false) addon:RegisterDefaultSetting("showDevBar", true) --HideFrames.lua --Skins.lua settings addon:RegisterDefaultSetting("useViewPort", false) addon:RegisterDefaultSetting("VPLeftPos", 0) addon:RegisterDefaultSetting("VPRightPos", 0) addon:RegisterDefaultSetting("VPTopPos", 0) addon:RegisterDefaultSetting("VPBottomPos", 90) addon:RegisterDefaultSetting("artSetPoint", 0) addon:RegisterDefaultSetting("artSetAlpha", 1) addon:RegisterDefaultSetting("ShowAggroArt", true) addon:RegisterDefaultSetting("resolution", false) addon:RegisterDefaultSetting("uiSkin", [[Interface\AddOns\]] .. addonName .. [[\Skins\]] .. UnitFactionGroup('player')) --Anchors.lua settings addon:RegisterDefaultSetting("LootGrowDirection", true) --FrameMover.lua --addon:RegisterDefaultSetting("movedFrames", true) addon:RegisterDefaultSetting("lockFrames", false) --ChatFrames.lua settings addon:RegisterDefaultSetting("chatInitialized", false) addon:RegisterDefaultSetting("showCombatLog", true) addon:RegisterDefaultSetting("showInfoLog", true) addon:RegisterDefaultSetting("showChatTabs", false) addon:RegisterDefaultSetting("useGrimChat", true) --MiniMap.lua settings addon:RegisterDefaultSetting("NotSoMinimap", false) addon:RegisterDefaultSetting("ShowMiniMap", true) addon:RegisterDefaultSetting("MapArt", true) addon:RegisterDefaultSetting("MapButStyle", 1) addon:RegisterDefaultSetting("GmapMask", "Interface\\BUTTONS\\WHITE8X8") addon:RegisterDefaultSetting("NSmapMask", "Interface\\BUTTONS\\WHITE8X8") addon:RegisterDefaultSetting("GmapAlpha", 1) addon:RegisterDefaultSetting("NSmapAlpha", 1) addon:RegisterDefaultSetting("NSmapScale", 1.5) Code:
local addonName, addon = ... --[[----------------------------------------------------------------------------- Frames to allow moving and saving -------------------------------------------------------------------------------]] --["FrameName"] = false - move the frame --true - move the frame's parent instead --string - move the named frame instead DefGMoveableFrames = { ['MiniMapLFGFrame'] = false, ['ShardBarFrame'] = false, ['SpellBookFrame'] = false, ['QuestLogFrame'] = false, ['FriendsFrame'] = false, ['LFDParentFrame'] = false, ['KnowledgeBaseFrame'] = true, ['MerchantFrame'] = false, ['MailFrame'] = false, ['DressUpFrame'] = false, ['TaxiFrame'] = false, ['QuestLogFrame'] = false, ['PaperDollFrame'] = true, ['PVPFrame'] = false, ['WatchFrameHeader'] = true, ['InspectFrame'] = false, ['PlayerTalentFrame'] = false, ['AchievementFrame'] = false, ['AchievementFrameHeader'] = true, ['AchievementFrameCategoriesContainer'] = 'AchievementFrame', ['GlyphFrame'] = 'PlayerTalentFrame', ['CalendarFrame'] = false, ['ContainerFrame1'] = false, ['ContainerFrame2'] = false, ['ContainerFrame3'] = false, ['ContainerFrame4'] = false, ['ContainerFrame5'] = false, ['Minimap'] = false, --GrimUI Frames ['GrimUIPlayerFrame'] = false, ['GrimUIPartyFrame1'] = false, ['GrimUIPartyFrame2'] = false, ['GrimUIPartyFrame3'] = false, ['GrimUIPartyFrame4'] = false, ['GrimExpBar'] = false, ['GrimRepBar'] = false, ['GUI_DevBar'] = false, ['Audio_UI_Control'] = true, ['GUI_AnchorPoint1'] = false, ['GUI_AnchorPoint2'] = false, ['GUI_AnchorPoint3'] = false, ['GUI_AnchorPoint4'] = false, ['GUI_AnchorPoint5'] = false, ['GUI_AnchorPoint6'] = false, ['GUI_AnchorPoint7'] = false, ['GUI_AnchorPoint8'] = false, ['GUI_AnchorPoint9'] = false, ['GUI_AnchorPoint10'] = false, ['GUI_AnchorPoint11'] = false, } function addon:DefaultMoveableFrames() if not GMoveableFrames then GMoveableFrames = GMoveableFrames or DefGMoveableFrames end end --[[----------------------------------------------------------------------------- Frame hooking -------------------------------------------------------------------------------]] local hookedFrame, parentFrame, movedFrames, oldPoint, oldX, oldY = { }, { } local function GetRelativePosition(frame) local _, _, uiWidth, uiHeight = UIParent:GetRect() local left, bottom, width, height = frame:GetRect() if bottom + height / 2 >= uiHeight / 2 then if left + width / 2 >= uiWidth / 2 then return 'TOPRIGHT', left + width - uiWidth - 1, bottom + height - uiHeight - 1 else return 'TOPLEFT', left, bottom + height - uiHeight - 1 end elseif left + width / 2 >= uiWidth / 2 then return 'BOTTOMRIGHT', left + width - uiWidth - 1, bottom end return 'BOTTOMLEFT', left, bottom end local function OnShow(self) local frame = parentFrame[self] or self if self == Minimap then if addon.settings.NotSoMinimap == true then self = _G["NSMiniMapAnchor"] -- needed for extra minimap functions frame = _G["NSMiniMapAnchor"] else self = _G["GMiniMapAnchor"] frame = _G["GMiniMapAnchor"] end end local position = movedFrames[self:GetName()] if position then addon:UnlockFrame(frame) frame:ClearAllPoints() frame:SetPoint(unpack(position)) addon:LockFrame(frame) end end local function OnMouseDown(self, button) if button ~= 'LeftButton' or addon.settings.lockFrames then return end if IsControlKeyDown() and button == 'LeftButton' then local frame = parentFrame[self] or self if self == Minimap then if addon.settings.NotSoMinimap == true then self = _G["NSMiniMapAnchor"] -- needed for extra minimap functions frame = _G["NSMiniMapAnchor"] else self = _G["GMiniMapAnchor"] frame = _G["GMiniMapAnchor"] end end oldPoint, oldX, oldY = GetRelativePosition(frame) addon:UnlockFrame(frame) frame:StartMoving() end end local function OnMouseUp(self, button) if button ~= 'LeftButton' or not oldPoint then return end local frame = parentFrame[self] or self if self == Minimap then if addon.settings.NotSoMinimap == true then self = _G["NSMiniMapAnchor"] -- needed for extra minimap functions frame = _G["NSMiniMapAnchor"] else self = _G["GMiniMapAnchor"] frame = _G["GMiniMapAnchor"] end end frame:StopMovingOrSizing() addon:LockFrame(frame) local point, x, y = GetRelativePosition(frame) if point ~= oldPoint or x ~= oldX or y ~= oldY then movedFrames[frame:GetName()] = { point, 'UIParent', x, y } end oldPoint, oldX, oldY = nil, nil, nil end function HookFrame(name, parent) if hookedFrame[name] then return true end local frame = _G[name] if not frame then return end if parent then if type(parent) == 'string' then parent = _G[parent] else if frame:GetParent() ~= UIParent then parent = frame:GetParent() else parent = frame end end if not parent then return end HookFrame(parent:GetName()) while(parentFrame[parent]) do parent = parentFrame[parent] end parentFrame[frame] = parent elseif not name:match("^" .. addonName) then frame:HookScript('OnShow', OnShow) end frame:EnableMouse(true) frame:EnableKeyboard(true) frame:SetMovable(true) frame:SetClampedToScreen(false) frame:HookScript('OnMouseDown', OnMouseDown) frame:HookScript('OnMouseUp', OnMouseUp) hookedFrame[name] = true if movedFrames[name] and frame:IsShown() then OnShow(frame) end return true end --[[----------------------------------------------------------------------------- Initialize -------------------------------------------------------------------------------]] local moveableframes = {} local function VerCheckUpdate() local CurVer = GetAddOnMetadata(addonName, 'Version') local LastVer = _G[addonName .. "Settings"].lastVersion if LastVer then if CurVer > LastVer then for gname, gparent in pairs(DefGMoveableFrames) do local TabCont = tContains( GMoveableFrames, gname ) if TabCont == nil then GMoveableFrames[gname] = gparent end end end _G[addonName .. "Settings"].lastVersion = nil end end addon.RegisterEvent("MoveFrames-Initialize", 'PLAYER_LOGIN', function(self, event) addon.UnregisterEvent(self, event) movedFrames = addon.settings.movedFrames if type(movedFrames) ~= 'table' then movedFrames = { } addon.settings.movedFrames = movedFrames end addon:RegisterDefaultSetting("movedFrames", true) -- Prevent it from being removed on PLAYER_LOGOUT local function HookFrames(self, event) addon:DefaultMoveableFrames() VerCheckUpdate() moveableframes = CopyTable(GMoveableFrames) for name, parent in pairs(moveableframes) do if HookFrame(name, parent) then moveableframes[name] = nil end end if next(moveableframes) then return end addon.UnregisterEvent(self, event) end addon.RegisterEvent("MoveFrames-Hook", 'ADDON_LOADED', HookFrames) HookFrames("MoveFrames-Hook", 'ADDON_LOADED') end) --[[----------------------------------------------------------------------------- in game add remove functions -------------------------------------------------------------------------------]] function addon:AddMoveableFrame(name, parvar) if parvar then if parvar == string then parvar = _G[parvar] end GMoveableFrames[name] = parvar HookFrame(name, parvar) elseif not parvar or parvar == "" or parvar == nil then parvar = false GMoveableFrames[name] = parvar HookFrame(name, parvar) end end function addon:RemMoveableFrame(name) GMoveableFrames[name] = nil end SlashCmdList["GADDMOVE_SHORTHAND"] = function(cmd) local name, parvar = strsplit(" ", cmd) if parvar then if parvar == "true" then parvar = true elseif parvar == "false" then parvar = false end end if not parvar then parvar = false end addon:AddMoveableFrame(name, parvar) end SLASH_GADDMOVE_SHORTHAND1 = "/gaddmove" SlashCmdList["GREMMOVE_SHORTHAND"] = function(cmd) addon:RemMoveableFrame(cmd) end SLASH_GREMMOVE_SHORTHAND1 = "/gremmove" |
|
02-10-12, 02:06 AM | #3 |
ADDON_LOADED fires every time any addon (including the Blizzard ones) finishes loading. The first argument passed with the event is the name of the addon that finished loading. When it fires for an addon, that means that:
PLAYER_LOGIN fires at approximately the same time that the initial loading screen disappears and the game world becomes visible. Generally, this event means that all non-LoD addons have finished loading. Most addons listen for this event, and perform additional start-up tasks like creating visible UI objects (eg. action buttons or unit frames) and registering for general events (eg. UNIT_HEALTH or PLAYER_REGEN_ENABLED). Since the user cannot see or interact with the UI prior to this event firing, there is no reason to perform these tasks earlier. If you are writing an addon that modifies another addon's configuration, you will usually want to listen for the other addon's ADDON_LOADED event, and make your changes when it fires. However, depending on the other addon's design, and the nature of the changes you wish to make, you may need to listen for the PLAYER_LOGIN event instead (though I have never found this useful), or temporarily pre-hook one of the addon's functions when its ADDON_LOADED event fires and make your changes when that function is run: Lua Code:
For a more complex example that handles modifying multiple addons, see the attached file. It's what I use to apply custom borders to a number of addons. You'll notice that in some cases, I need to permanently hook one or more of the addon's functions, so that I can overwrite changes the addon makes during gameplay, long after the initial loading process. |
|
02-10-12, 02:17 AM | #4 |
So h ow is it that my above code functions? if i have addonloaded events fireing after a player login event registration?
and whats the proper means of going down the saved variables table? SavedvairableName[firstlvl][2ndlvl]? Last edited by Grimsin : 02-10-12 at 02:19 AM. |
|
02-10-12, 02:42 AM | #5 | |
The wowpedia loading process description is pretty accurate in its description. me and scott changed our addon loading process after I figured that VAIABLES_LOADED and PLAYER_ENTERING_WORLD sometimes loaded in different order and wasn't consistent enough to guarantee using just one of them for the same code segment.
http://www.wowpedia.org/AddOn_loading_process
__________________
All Level 70 Characters: Demon Warlock Resto Druid Disc Priest Resto Shaman Survival Hunter Augment Evoker Frost Mage Vengence Demon Hunter Rogue ( was subtlety ) Brewmaster Monk (TR) Prot Paladin (TR) Blood Death Knight ( TR) As you can see I am missing a warrior And .. I don't have all the allied races covered. Time Runner time when it happens again |
||
02-10-12, 02:44 AM | #6 |
Im not used variables loaded though im getting ADDON_LOADED after PLAYER_LOGIN....
|
|
02-10-12, 03:51 PM | #7 |
time during loading accuracy.
Okay so i had an idea... it may be a bad one maybe not. I need some details first. So how accurate can time delays be? could you delay something into 100ths and 1000's of a second? does wow understand a time delay of 0.001? i know it understands 0.01 as a 1/10th of a second. Why is this important you may be thinking. Well my next question is how accurate are these timers, how reliable? are they at all effected by lag? My thinking is since now i have an issue of even if a file is listed first in the toc the addon settings are still in an addon loaded event and even though its listed before other files if i use addon loaded in other files it has no guaranty it loads first in fact i cant get it to load first no mater how many times i reload. So my thinking is what if, where i need things to fire after that settings code but still in an addon loaded event from another file, I use a timer of 0.001 or the like to stall that code. Would that insure it fires prior to player_login? the big reason to load as much as possible prior to player login and player entering world is it helps alleviate tainting especially when you reload or relog while in combat, prime example is if your dc'd during a boss fight. Ive noticed that combat lockdown and the secure environment do not invoke until player_login or later.
|
|
02-10-12, 10:48 PM | #8 | ||||
Grim, your posts would be 100x more readable if you used paragraphs instead of typing everything in one giant block.
Code:
local t = {} local f = CreateFrame("Frame") f:RegisterEvent("ADDON_LOADED") f:RegisterEvent("PLAYER_ALIVE") f:RegisterEvent("PLAYER_ENTERING_WORLD") f:RegisterEvent("PLAYER_LOGIN") f:SetScript("OnEvent", function(f, e, ...) local m = string.join(", ", e, ...) table.insert(t, m) print(m) end) InterfaceLoadingLog = t Code:
/run for i,v in ipairs(InterfaceLoadingLog) do print(i..". "..v) end
If you are having trouble initializing default settings for your addon, and are not using a library like AceDB-3.0 to handle this, here is a simple method for handling defaults: Code:
local db local MyAddon = CreateFrame("Frame") MyAddon:RegisterEvent("ADDON_LOADED") MyAddon:SetScript("OnEvent", function(self, event, addon) if addon ~= "MyAddon" then return end -- Define a table containing a complete configuration -- for your addon, with the default values: local defaultsTable = { blah = "blah", etc = "something", num = 5, height = 200, width = 600, color = { r = 1, g = 1, b = 0, a = 0.5, magic = true, } } -- This function goes through your defaults table -- and copies to the real settings table any values -- that are the wrong type (eg. nil vs string, or -- number vs boolean). -- It is recursive, so it will go through sub-tables -- as well, up to any depth: local function copyDefaults(a, b) if type(a) ~= "table" then return {} end if type(b) ~= "table" then b = {} end for k, v in pairs(a) do if type(v) == "table" then b[k] = copyDefaults(v, b[k]) elseif type(v) ~= type(b[k]) then b[k] = v end end return b end -- Now call the function, supplying your defaults table -- as the source, and your addon's saved variable table -- as the destination: db = copyDefaults(defaultsTable, MyAddonDB) -- Finally, make sure your addon's saved variable points -- to the table, in case it did not already exist: MyAddonDB = db -- Now you can use "db.blah" or "db.color.magic" to get -- the current settings. There is no need for any metatables. end) |
|||||
02-10-12, 10:59 PM | #9 | ||
It sounds like you are simply doing things wrong. If you need multiple files to be aware of when your addon finishes loading, and run setup functions, here is a simple method of handling that that does not require multiple frames handling ADDON_LOADED, or convoluted timer solutions. In your main file (the one that's loaded first), handle ADDON_LOADED and initializing your saved variables. Near the top of that file, add: Code:
MyAddon.loadFunctions = {} Code:
for _, methodName in ipairs(MyAddon.loadFunctions) do MyAddon[methodName](MyAddon) end Code:
function MyAddon:DoSomething() -- Do stuff. end table.insert(MyAddon.loadFunctions, "DoSomething")
I think you're thinking of secure frames, and the actions that can only be performed on them outside of combat. In this case, you can still delay performing these actions until PLAYER_LOGIN fires; the UI is not locked down until some time after the PLAYER_REGEN_DISABLED event fires to indicate that the player has been flagged for combat, and you can always check to see if the UI is locked down by calling InCombatLockdown(). It might be more helpful if you are more specific about what code you are trying to run that you think needs to be called before PLAYER_LOGIN. |
|||
02-11-12, 03:02 PM | #10 |
your right secure frames is what im thinking. So your saying the regen disabled happens after player login? because i know it happens before player entering world or at least last time i tried it it did... a few places i have this issue is in party frames, the focus frame, the vehicle action bar and the boss target frame.
As for data collection, two places i can think of right off the top of my head is the guild information and the calendar information Actually I think this may be true for any of the bliz LOD stuff, anything thats in the addons directory created by bliz. My UI allows the user to set the xp bar to show guild xp, in order for this to be available when they log in and display correct i have to load the guild stuff, same goes for the calendar in order for the highlighting on the clock that lets players know they have pending events to display proper it has to be able to check for events and the events dont load until the calendar loads... I may go about alleviating the calendar issue the same way i did the mail issue by hooking blizzards own notification highlight to my clock. I did this for the mail since the mail had the same issue and i could not get the information i needed at the times needed to make the mail notifications function right so i made it so blizzards stuff just highlighted my frames. Did the same for hooking blizzards mail tooltip to my frame since i could not get the same function any other way. There is no way around the guild xp bar requiring the guild information be loaded. And yes many people have informed me that i write exactly as i would speak. i tried to break it up some... and use more "," also im using Vrul's LibOptionsAssist to handle options and the config panel. along with aceGUI and other ace config panel libs. |
|
02-11-12, 03:19 PM | #11 | ||
It should, yes. Use the code in my last post to check. You can use the same code to check the order of any events you want.
If you are trying to create/modify secure frames when PLAYER_LOGIN fires, and are having problems, post the code. There's only so much anyone can tell you without seeing the actual code you are working with.
Again, though, there's only so much I can tell you without seeing your code. Again, this information should be available through the appropriate API regardless of whether any addon is loaded. The default UI's clock can show pending calendar invites before the Blizzard_CalendarUI is loaded, so your addon's clock can do the same. If you aren't sure how to do it, look at the Blizzard UI code. |
|||
02-11-12, 04:19 PM | #12 |
Yea i will look at the code and then just alter and hook the bliz highlight but what im saying is the bliz highlight as able to access the information without the calendar LOD being loaded... we how ever can not. at least thats how it looks when i messed with it before ill be back to poking at it here in a minute. you have to open the calendar to get numpendinginvite information.
|
|
WoWInterface » Developer Discussions » Lua/XML Help » Mass confusion, loading process |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Switch to Linear Mode |
Hybrid Mode |
Switch to Threaded Mode |
|
|