• 0

    posted a message on Table with keys and sorting
    Quote from Mokhtar
    Personnally I do it like this :
    local function pairsByKey (t, f)
        local a = {}
        for n in pairs(t) do table.insert(a, n) end
        table.sort(a, f)
        local i = 0      -- iterator variable
        local iter = function ()   -- iterator function
            i = i + 1
            if a[i] == nil then return nil
            else return a[i], t[a[i]]
            end
        end
        return iter
    end
     
    ...
     
    function foo()
        local bar = {
            ["key1"]="value1",
            ["key2"]="value2",
            ["key3"]="value3",
        }
        for k, v in pairsByKey(bar) do
            dostuffwith(k, v)
        end
    end


    I have no idea if what I do leads to a lot of garbage or not

    It creates a table and a function everytime it's called, depending on how you use it, it could produce some quite a bit of garbage. Something like this will only create the required iteration function and sorted array when required.
    [SIZE=2]
    [SIZE=2]local pairsByKeys; do[/SIZE]
    [SIZE=2]local sortedtbl, iter[/SIZE]
    [SIZE=2]function pairsByKeys(tbl, f)[/SIZE]
    [SIZE=2] if sortedtbl then[/SIZE]
    [SIZE=2]  wipe(sortedtbl)[/SIZE]
    [SIZE=2] else[/SIZE]
    [SIZE=2]  sortedtbl = {}[/SIZE]
    [SIZE=2]  function iter(tbl, i)[/SIZE]
    [SIZE=2]   i = i + 1[/SIZE]
    [SIZE=2]   if sortedtbl[i] == nil then[/SIZE]
    [SIZE=2]    return nil, nil, nil[/SIZE]
    [SIZE=2]   else[/SIZE]
    [SIZE=2]    return i, sortedtbl[i], tbl[sortedtbl[i]][/SIZE]
    [SIZE=2]   end[/SIZE]
    [SIZE=2]  end[/SIZE]
    [SIZE=2] end[/SIZE]
    [SIZE=2] for k, v in pairs(tbl) do[/SIZE]
    [SIZE=2]  table.insert(sortedtbl, k)[/SIZE]
    [SIZE=2] end[/SIZE]
    [SIZE=2] table.sort(sortedtbl, f)[/SIZE]
    [SIZE=2] return iter, tbl, 0[/SIZE]
    [SIZE=2]end[/SIZE]
    [SIZE=2]end[/SIZE]
    [SIZE=2]local tbl = {[/SIZE]
    [SIZE=2]key1 = "val1",[/SIZE]
    [SIZE=2]key2 = "val2",[/SIZE]
    [SIZE=2]key3 = "val3",[/SIZE]
    [SIZE=2]key4 = "val4",[/SIZE]
    [SIZE=2]key5 = "val5",[/SIZE]
    [SIZE=2]key6 = "val6",[/SIZE]
    [SIZE=2]}[/SIZE]
    [SIZE=2]for i, k, v in pairsByKeys(tbl) do[/SIZE]
    [SIZE=2]print(k, v)[/SIZE]
    [SIZE=2]end[/SIZE]
     
    [/SIZE]
    Posted in: Lua Code Discussion
  • 0

    posted a message on RealID reading and broadcasting
    Quote from kunda
    Culprit: SendAddonMessage

    There is exactly one WoW API function that can send messages to other players: SendAddonMessage.

    It's nice for me to say this again: (and again and again)

    DO NOT TRUST ADDONS THAT USE SendAddonMessage!

    Any addon with SendAddonMessage _can_ send any global (and even everything locally available within it's own code) variable data from any addon to any player without userinteraction, and hey get this: all SavedVariables data is global; accessible and available for all other addons!
    Big potential for misuse.


    If you want to use an addon:
    1) search the complete source code (incl. libs) for 'SendAddonMessage'
    2) if you find 'SendAddonMessage' read the code and try to understand what this addon is sending
    3) if you do not know (by source code) what this addon is sending: DO NOT USE IT!

    Simple and radical solution.


    If a mod was doing something truly dodgy they would probably obfuscate the reference i.e.
    local f = _G[string.char(83, 101, 110, 100, 65, 100, 100, 111, 110, 77, 101, 115, 115, 97, 103, 101)]


    So your best option is probably StopAddonMessage
    Posted in: General Chat
  • 0

    posted a message on help with logical tests
    Quote from Elsia


    It's not clear to my why OnUpdate is involved in all of this, but that's a separate question. And if you do need OnUpdate, why not attach scripts to active frames individually? I think you should tell us what actual goal you have, beyond the specifics, because the right answer very much depends upon what you ultimately try to achieve.


    Having one OnUpdate is more efficient than many, thus why Ace_Timer-3.0 exists.
    Posted in: Lua Code Discussion
  • 0

    posted a message on Timer sync problem
    Quote from airscape
    The above code doesn't work, it prints out the numbers from 10 to 0 within 1 sec.



    Works for me, just tested in WoWLua, if your on about starting the timer then minimising WoW waiting 10 seconds and then having it print numbers 10 to 0 within 1 sec then this is to be expected, as the timer has to catch up.
    Posted in: Lua Code Discussion
  • 0

    posted a message on Timer sync problem
    Quote from Tekkub
    Windowed fullscreen, the only mode you should *ever* use.


    Why? I thought you get an FPS boost when not using windowed mode?

    Anyway when alt-tabbed out WoW doesn't run the OnUpdate handlers while in fullscreen mode so instead of telling the time relative to each OnUpdate you would want to get the fixed time using time() or GetTime().
    e.g.
    	local startTime = GetTime()
    	local counter = 10
    	CreateFrame("Frame"):SetScript("OnUpdate", function(f)
    		local currentTime = GetTime()
    		if currentTime - 1 > startTime then
    			for i = counter, counter - math.floor((currentTime - 1) - startTime), -1 do
    				if i > 0 then
    					print("countdown: " .. i)
    					startTime = GetTime()
    					counter = counter - 1
    				else
    					print("reached 0")
    					f:SetScript("OnUpdate", nil)
    				end
    			end
    		end
    	end)
    Posted in: Lua Code Discussion
  • 0

    posted a message on Timer sync problem
    local starttime = time() + <how many seconds you want your timer to run for>
    
    frame:SetScript("OnUpdate", function(frame)
    	if time() > starttime then
    		frame:SetScript("OnUpdate", nil)
    		
    		--stuff to run when the timer finishes
    	end
    end)


    Something like that, or you could just use AceTimer.
    Posted in: Lua Code Discussion
  • 0

    posted a message on Timer sync problem
    Use time() to gauge elapsed time instead of the second argument from OnUpdate.
    Posted in: Lua Code Discussion
  • 0

    posted a message on Can't UnregisterEvent in event handler?
    Quote from jerry
    Coming a bit late in the discussion. Be careful the name you choose because, although the function is called CollapseSkillHeaderPreHook, it's code is executed AFTER the hooked function has returned.


    Yup your right, edited my previous code to avoid confusion.
    Posted in: Lua Code Discussion
  • 0

    posted a message on Can't UnregisterEvent in event handler?
    A safe posthook without using a table:

    local OldCollapseSkillHeader = CollapseSkillHeader
    local function CollapseSkillHeaderPostHook(arg1, arg2, ...)
    	-- do stuff with arg1 and arg2
            --arg1 and arg2 are the arguments sent to CollapseSkillHeader, while ... is the return from CollapseSkillHeader
    	return ...
    end
    
    function CollapseSkillHeader(arg1, arg2, ...)
    	return CollapseSkillHeaderPostHook(arg1, arg2, OldCollapseSkillHeader(...))
    end
    Posted in: Lua Code Discussion
  • 0

    posted a message on Working with AceConsole-3.0
    Have you included embeds.xml in your toc, and is it above the main lua file?
    Posted in: Lua Code Discussion
  • 0

    posted a message on Question on Hooks coming unhooked.
    Heres something which should help finding out whats changing the function.

    local mt = getmetatable(_G)
    
    local function newnewindex(t, key, val)
    	if key == "HandleModifiedItemClick" then
    		print(debugstack(2))
    	end
    	t[key] = val
    end
    
    if mt then
    	if mt.__newindex then
    		local _mtnewindex = mt.__newindex
    		--pre hook newindex
    		function mt.__newindex(t, key, ...)
    			if key == "HandleModifiedItemClick" then
    				print(debugstack(2))
    			end
    			return _mtnewindex(t, key, ...)
    		end
    	else
    		mt.__newindex = newnewindex
    	end
    else
    	setmetatable(_G, {__newindex = newnewindex})
    end
    
    Posted in: Lua Code Discussion
  • 0

    posted a message on IconHell
    local addon = CreateFrame("Frame")
    
    local t = 0
    local partypos = 0
    local iconpos = 0
    local units = {"player", "party1", "party2", "party3", "party4"}
    
    addon:SetScript("OnUpdate", function(self, el)
    	if t > 1 then --update icons after a sec
    		local unit
    		if partypos == 5 then
    			partypos = 0
    		end
    		partypos = partypos + 1
    		
    		if iconpos == 8 then
    			iconpos = 0
    		end
    		iconpos = iconpos + 1
    		SetRaidTarget(units[partypos], iconpos)
    		t = 0
    	end
    	t = t + el
    end)
    addon:Hide()
    
    local function y()
    	addon:Show()
    end
    
    local function n()
    	addon:Hide()
    	for i = 1, 5 do
    		SetRaidTarget(units[i], 0)
    	end
    end
    
    local function toggle()
    	if addon:IsShown() then
    		n()
    	else y()
    	end
    end
    	
    local cmds = setmetatable({
    	-- enable
    	on = y,
    	enable = y,
    	go = y,
    	["true"] = y,
    	y = y,
    	--disable
    	off = n,
    	disable = n,
    	stop = n,
    	["false"] = n,
    	n = n
    }, {__index = toggle})
    	
    SlashCmdList["ICONHELL"] = function(msg)
    	local a = msg:match("(%S+)")
    	if a then
    		cmds[a:lower()]()
    	else
    		toggle()
    	end
    end
    
    
    SLASH_ICONHELL1 = "/iconhell"
    SLASH_ICONHELL2 = "/ihell"


    Does this work (I don't have a wow account so I can't test.
    Posted in: Addon Ideas
  • 0

    posted a message on IconHell
    local addon = CreateFrame("Frame")
    
    local t = 0
    local partypos = 0
    local iconpos = 0
    local units = {"player", "party1", "party2", "party3", "party4"}
    
    f:SetScript("OnUpdate", function(self, el)
    	if t > 1 then --update icons after a sec
    		local unit
    		if partypos == 5 then
    			partypos = 0
    		end
    		partypos = partypos + 1
    		
    		if iconpos == 8 then
    			iconpos = 0
    		end
    		iconpos = iconpos + 1
    		SetRaidTarget(units[partypos], iconpos)
    		t = 0
    	end
    	t = t + el
    end)
    f:Hide()
    
    local y = function()
    	addon:Show()
    end
    
    local n = function()
    	addon:Hide()
    	for i = 1, 5 do
    		SetRaidTarget(units[i], 0)
    	end
    end
    		
    local cmds = setmetatable({
    	-- enable
    	on = y,
    	enable = y,
    	go = y,
    	["true"] = y,
    	y = y,
    	--disable
    	off = n,
    	disable = n,
    	stop = n,
    	["false"] = n,
    	n = n
    }, {__index = function()
    	if addon:IsShown() then
    		n()
    	else y()
    	end
    end})
    	
    SlashCmdList["ICONHELL"] = function(msg)
    	local a = msg:match("(%S+)")
    	if a then
    		cmds[a:lower()]()
    	end
    end
    
    
    SLASH_ICONHELL1 = "/iconhell"
    SLASH_ICONHELL2 = "/ihell"


    make an addon file stick in the code, then type /ihell .

    quick warning, it's a 100% drycoded, but might work properly on first go.
    Posted in: Addon Ideas
  • 0

    posted a message on InterfaceOptionsFrame_OpenToCategory opens to wrong panel sometimes
    Quote from myrroddin
    Sorry to hijack the thread, but a related question. During testing/updating/etc of SmartRes2, if I use my slash commands (/sr and /smartres) sometimes they open right to the SmartRes2 panel, and sometimes they open to Interface.. Addons, and you have to scroll down to the SR2 entry. It isn't consistent, and I did notice an addon on curse.com that "fixes" this, but I do not have it installed.

    Any ideas why the inconsistency? Furthermore, if it does not open right the panel on first slash use, it will every time after I use a slash after. It is the first time that sometimes it works, sometimes it doesn't.


    iirc it's because of weirdness when using InterfaceOptionsFrame_OpenToCategory with too many categories, you might be noticing this discrepancy because you don't have a panels sub panels expanded.
    Posted in: Lua Code Discussion
  • To post a comment, please or register a new account.