View Single Post
08-05-05, 03:33 PM   #2
Littlejohn
A Warpwood Thunder Caller
AddOn Author - Click to view addons
Join Date: Jun 2005
Posts: 90
The code you have is really not bad. (Yeah, I know, glowing praise. Seriously though, unless the code is in a tight loop or OnUpdate it probably won't make much performance difference.)

The sort problem can be solved without making a table of keys -- just make another table from the contents of the keyed table. When you assign a table to a variable, Lua doesn't copy the table; it just shares the original table. If you know what a pointer is, what you want to do is create two tables that contain pointers to the same player info. One table is indexed by player name. The other table is sorted by index. Maybe this example will help:

Code:
local player = { }
player["foo"] = { name = "foo", total = 10, actual = 17 }
player["bar"] = { name = "bar", total = 7, actual = 47 }
player["goo"] = { name = "goo", total = 12, actual = 5 }

local sorted_player = { }
for k, v in player do
    table.insert(sorted_player, v)
end

table.sort(sorted_player, function(x, y)
			      return x.total > y.total
			  end)

for i=1,3 do
    print(sorted_player[i].name, sorted_player[i].total)
end
The HealTracker_GetActual can get you in a bit more trouble because you've got a couple loops that you will always run through even if you find the player name on the first pass. Lua lets you break out of loops with the "break" statement. If you add a cache and break out of the loops, I think this function works fine. (I would move the player name lookup into its own function of course. You'll probably want to use this code in other parts of your add-on.)

One thing you might think is ugly is my replacing your "partyN" loop with a numeric loop. Surprisingly the "party"..i does not generate garbage, but the { "party1", ... } does. Lua has shared (or interned) strings. This means that every time it builds a string, it looks up the string in a master dictionary to see if the string already exists. If it does, then the new string is thrown away and the old string is re-used. Lua doesn't do this for tables though. In your original code, the party table is re-created (and thrown away) every time.

Here's my implementation of HealTracker_GetActual:

Code:
local unit_name_to_id = { }

function HealTracker_GetActual(unit_name, amount)
    local unit_id = unit_name_to_id[unit_name]

    if not unit_id then
	if unit_name == "you" then
	    unit_id = "player"
	else
	    for i=1, 4 do
		local trialUnit = "party"..i
		if unit_name == UnitName(trialUnit) then
		    unit_id = trialUnit
		    break
		end
	    end

	    if not unit_id then
		for i=1, 40 do
		    local trialUnit = "raid"..i
		    if unit_name == UnitName(trialUnit) then
			unit_id = trialUnit
			break
		    end
		end
	    end
	end

	unit_name_to_id[unit_name] = unit_id
    end

    if not unit_id then
	return nil
    end

    local missinghp = UnitHealthMax(unit_id) - UnitHealth(unit_id)
    local healState = amount - missinghp

    if healState > 0 then
	return missinghp
    else
	return amount
    end
end
By the way, are you the Cladhaire that Vika has blessed with taking over WatchDog? I've got some patches for WatchDog if you are. I'm also curious about Vika and his disappearance. Can you fill us in with details? Think he's going to be back soon?
  Reply With Quote