Thread Tools Display Modes
04-21-09, 10:42 AM   #1
Luzzifus
A Warpwood Thunder Caller
 
Luzzifus's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2007
Posts: 94
Reliably referencing the player frame

Hi,

this is an issue I've run into a few times now, so the code I'm posting here is only an example. So as an example, in my layouts config I am building some dynamic option frames to adjust the unit names for different units. That looks something like this:

Code:
local optUnitNames = function(order, unit)
	return {	
		type = 'group', name = "Unit Name Settings", order = order, dialogHidden = true, dialogInline = true, 
		args = {
			playerPos	= {
				type = 'select',
				order = 8,
				name = unit,
				width = "half",
				values = { ["Top"] = "Top", ["Bottom"] = "Bottom", },
				get = function(info) return 
					nivcfgDB.names[unit].pos 
				end,
				set = function(info, value)	
					nivcfgDB.names[unit].pos = value
					oUF_Nivaya:UpdateNamePos(oUF.units[unit], unit)
				end, },
			
			...
		},
	}
end

function oUF_Nivaya:UpdateNamePos(self, unit)
	...
end
The important line is the red one. This function needs the stated parameters in order to apply the given settings to a specific frame. That architecture perfectly works as long as I am not in a party or a raid.

In a party or a raid, my layout also shows the player as a unit button in the raidframes. When the above update function is now called for the player frame, I'm getting an error about unit being nil in UpdateNamePos(). For some reason, oUF references the unit button in the raidframes instead of the actual player frame via oUF.units['player'].

I managed to work around that via adding global references to the spawned frames, like this:
Code:
oUF_Nivaya:UpdateNamePos(oUF_player, 'player')
Nedless to say that I need to call that for every unit everytime since I cannot restrict the call to a specific unit via the unit parameter. As a result this is destroying my dynamic architecture of the options table.

So, is there a way to reliably reference the player frame via a units parameter and without using a global reference?

Thanks in advance,
Luzzifus.

Last edited by Luzzifus : 04-21-09 at 10:47 AM.
  Reply With Quote
04-21-09, 11:06 AM   #2
haste
Featured Artist
 
haste's Avatar
Premium Member
Featured
Join Date: Dec 2005
Posts: 1,027
You could always iterate over oUF.objects and check if the unit is player, and run your code if it is. oUF.units is really just meant for quick unreliable indexing.
  Reply With Quote
04-21-09, 11:19 AM   #3
Luzzifus
A Warpwood Thunder Caller
 
Luzzifus's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2007
Posts: 94
Iterating through all units for every call doesn't look too efficient, does it?

There's something else crossing my mind given my global reference, how about this:

Code:
local v = _G['oUF_'..unit]
if v then oUF_Nivaya:UpdateNamePos(v, unit) end
It's still global but it would at least allow me to use the unit parameter.

**edit:
Btw. what's the exact difference between oUF.units, oUF.objects and oUF.elements?

Last edited by Luzzifus : 04-21-09 at 11:22 AM.
  Reply With Quote
04-21-09, 12:05 PM   #4
haste
Featured Artist
 
haste's Avatar
Premium Member
Featured
Join Date: Dec 2005
Posts: 1,027
The iterators in Lua aren't exactly slow, and you are most likely not calling them all the time anyway. You can ofc. use a global, it's all up to you really .

oUF.objects - Contains every frame touched by oUF.
oUF.units - Contains all the units that oUF knows about. The list is created by watching what gets sent to :SetAttribute('unit', ...).
oUF.elements - Doesn't exist. You might be thinking of the __elements table that exists on oUF objets however. This table just contains all the active elements on a frame.
  Reply With Quote
04-21-09, 02:29 PM   #5
Luzzifus
A Warpwood Thunder Caller
 
Luzzifus's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2007
Posts: 94
Thanks alot, that will help.
  Reply With Quote
04-21-09, 07:59 PM   #6
jadakren
A Flamescale Wyrmkin
 
jadakren's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2007
Posts: 103
Post

i got around this by creating a units table on my addon object.
http://github.com/airtonix/oufsmee2/...e.lua#L966-988

oUF_Smee2.units is a table built off my settings table. This way i can interate over the exact frames i create.

I do the same thing in my raid layout :
Code:
	local raidSettings = db.frames.raid
	local raidFrame = CreateFrame('Frame', 'oufraid', UIParent)
				raidFrame.groups = {}
				raidFrame:SetBackdrop(db.textures.backdrop)
				raidFrame:SetBackdropColor(unpack(db.colors.backdropColors))
			 	raidFrame:EnableMouse(true)


	self.units.raid = raidFrame
	self.units.raid.groups={}
	for index,data in pairs(raidSettings.group) do
		if(data.visible) then 
			local group = oUF:Spawn('header', 'oufraid'..index)
			group:SetManyAttributes(
			"template",			"oUF_Smee2_Groups_Raid",
			"groupFilter",		index,
			"showRaid",		true,
			"showPlayer", 		true,
			"yOffSet",			raidSettings.unit.yOffSet,
			"xOffSet", 			raidSettings.unit.xOffSet,
			"point", 			raidSettings.unit.anchorFromPoint,
			"initial-height",  		raidSettings.unit.height,
			"initial-width",		raidSettings.unit.width,
			"showPlayer", 		true)

			
			group.groupType = 'raid'
			group:SetPoint(data.anchorFromPoint,
					self.units.raid.groups[data.anchorTo] or self.units.raid,
					data.anchorToPoint,
					data.anchorX,
					data.columnSpacing)			
			group:SetFrameLevel(0)
			group:SetParent(raidFrame)
			self.units.raid.groups[index] = group
		end
	end
	raidFrame:SetFrameLevel(1)
	raidFrame:SetPoint(
		raidSettings.anchorFromPoint,
		UIParent,
		raidSettings.anchorToPoint,
		raidSettings.anchorX,
		raidSettings.anchorY)

Last edited by jadakren : 04-21-09 at 08:28 PM.
  Reply With Quote

WoWInterface » Featured Projects » oUF (Otravi Unit Frames) » Reliably referencing the player frame


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off