Thread Tools Display Modes
06-26-13, 08:47 PM   #1
Clamsoda
A Frostmaul Preserver
Join Date: Nov 2011
Posts: 269
Questions About Manipulating SetPoint()

Good evening,

I wanted to start by making an inquiry:

Is it considered acceptable practice to destroy an object's SetPoint() function, similar to:

Lua Code:
  1. someProperlyNamedFrame.SetPoint = function() end

I have a strange feeling that this is a good way to taint the UI or some such.

I have also tried to safely manipulate SetPoint as such:

Lua Code:
  1. hooksecurefunc(someProperlyNamedFrame, "SetPoint", function(self)
  2.     self:SetPoint(stuff here obviously)
  3. end)
This actually worked, but BugSack reports a C stack overflow, whatever that is.

Any insight about such processes would be much appreciated.

Thanks!

Last edited by Clamsoda : 06-26-13 at 08:49 PM.
  Reply With Quote
06-26-13, 08:57 PM   #2
Dridzt
A Pyroguard Emberseer
 
Dridzt's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2005
Posts: 1,360
Second example is a circular reference, since every :SetPoint() run on that frame re-triggers the securehook ad-infinitum
  Reply With Quote
06-26-13, 09:01 PM   #3
Clamsoda
A Frostmaul Preserver
Join Date: Nov 2011
Posts: 269
Oh, that makes sense. Thank you.
  Reply With Quote
06-26-13, 09:02 PM   #4
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
Originally Posted by Clamsoda View Post
Is it considered acceptable practice to destroy an object's SetPoint() function, similar to:

Lua Code:
  1. someProperlyNamedFrame.SetPoint = function() end

I have a strange feeling that this is a good way to taint the UI or some such.
It does cause taint. How bad the results of said taint will depend on the frame you used it on. Someone with more taint knowledge may be able to weigh in on this better.


I have also tried to safely manipulate SetPoint as such:

Lua Code:
  1. hooksecurefunc(someProperlyNamedFrame, "SetPoint", function(self)
  2.     self:SetPoint(stuff here obviously)
  3. end)
As mentioned below, this is a circular doohicky. Can be prevented like so:

Lua Code:
  1. local PointGettingSet
  2. hooksecurefunc(someProperlyNamedFrame, "SetPoint", function(self)
  3.     if PointGettingSet then return end
  4.     PointGettingSet = true
  5.     -- do stuff here
  6.     self:SetPoint(stuff here obviously)
  7.     PointGettingSet = false
  8. end)
  Reply With Quote
06-26-13, 09:05 PM   #5
Clamsoda
A Frostmaul Preserver
Join Date: Nov 2011
Posts: 269
Lua Code:
  1. local PointGettingSet
  2. hooksecurefunc(someProperlyNamedFrame, "SetPoint", function(self)
  3.     if PointGettingSet then return end
  4.     PointGettingSet = true
  5.     -- do stuff here
  6.     self:SetPoint(stuff here obviously)
  7.     PointGettingSet = false
  8. end)

Oh, that is neat. I thought it would still trigger the secure hook over and over, but I am seeing now that it would only respond to the SetPoint calls.

Last edited by Clamsoda : 06-26-13 at 09:09 PM.
  Reply With Quote
06-26-13, 10:09 PM   #6
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Actually all you have to do is create a separate reference to the frame's SetPoint function and call that instead of what you hooked.
Lua Code:
  1. local oSetPoint = f.SetPoint
  2. hooksecurefunc(f, 'SetPoint', function(self)
  3.     self:ClearAllPoints()
  4.     oSetPoint(self, 'CENTER')
  5. end)
You will also need to clear its previous points or you could run into unexpected behavior.
  Reply With Quote
06-26-13, 10:20 PM   #7
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
Originally Posted by semlar View Post
Actually all you have to do is create a separate reference to the frame's SetPoint function and call that instead of what you hooked.
Lua Code:
  1. local oSetPoint = f.SetPoint
  2. hooksecurefunc(f, 'SetPoint', function(self)
  3.     self:ClearAllPoints()
  4.     oSetPoint(self, 'CENTER')
  5. end)
Ohh, clever
  Reply With Quote
06-27-13, 08:30 AM   #8
Clamsoda
A Frostmaul Preserver
Join Date: Nov 2011
Posts: 269
Originally Posted by semlar View Post
Actually all you have to do is create a separate reference to the frame's SetPoint function and call that instead of what you hooked.
Lua Code:
  1. local oSetPoint = f.SetPoint
  2. hooksecurefunc(f, 'SetPoint', function(self)
  3.     self:ClearAllPoints()
  4.     oSetPoint(self, 'CENTER')
  5. end)
Fantastic =]. Working perfectly! Thank you very much for the response.
  Reply With Quote
06-27-13, 10:09 AM   #9
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,327
Originally Posted by semlar View Post
Lua Code:
  1. local oSetPoint = f.SetPoint
  2. hooksecurefunc(f, 'SetPoint', function(self)
  3.     self:ClearAllPoints()
  4.     oSetPoint(self, 'CENTER')
  5. end)
You will also need to clear its previous points or you could run into unexpected behavior.
Ideally, this should be done before the call that runs the hook. Otherwise, you break the ability to have a frame dynamically resize via 2 or more points.

Additionally, you're not necessarily destroying the original function. All methods of a frame reside in a metatable shared amongst all other frames of the same type. If for whatever reason, you want to restore the frame to its original functionality, you can just set the entry in the table back to nil. Understanding metatables can get tricky, but they are powerful if you know how they work.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
06-27-13, 01:37 PM   #10
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Originally Posted by SDPhantom View Post
Ideally, this should be done before the call that runs the hook. Otherwise, you break the ability to have a frame dynamically resize via 2 or more points.
You can set however many points you need to after clearing them.
Lua Code:
  1. local oSetPoint = f.SetPoint
  2. hooksecurefunc(f, 'SetPoint', function(self)
  3.     self:ClearAllPoints()
  4.     oSetPoint(self, 'TOPLEFT', -4, 4)
  5.     oSetPoint(self, 'BOTTOMRIGHT', 4, -4)
  6. end)
  Reply With Quote
07-01-13, 03:24 AM   #11
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,327
It just seems like a waste of CPU power to not only block normal calls to frame:SetPoint(), which should be enough by itself, but to clear and redefine the frame's points. What I would suggest is setting the frame's points before disabling the frame:SetPoint() metamethod on said frame.

Code:
frame:SetPoint(<<Frame Point Data>>);
frame.SetPoint=function() end;--	Usually a nil value in the frame's table itself
Remember, when you try to access a table field that has a nil value, Lua falls back to the __index field of its metatable if one exists.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
07-01-13, 03:39 AM   #12
Clamsoda
A Frostmaul Preserver
Join Date: Nov 2011
Posts: 269
Well, that is what I was doing, SDPhantom. My inquiry was to how detrimental it is to void a frame's SetPoint function; and if there was a healthier alternative.

If there is no downside to the practice, then that is what I would continue to use.
  Reply With Quote
07-01-13, 09:26 AM   #13
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Replacing the SetPoint function of a frame will taint it, so if that matters for what you're doing, don't do it.

I don't know if the taint log has been fixed, but previously it would cause actual lua errors (or even crashed the game) if it detected certain execution paths had been tainted and logging had been enabled.

If this is not for a blizzard frame, then there's no downside to replacing the function, otherwise it's generally best practice to avoid tainting the execution path because it can easily cause unforeseen consequences.

Depending on what you're trying to accomplish it's sometimes possible to avoid calling the function in the first place (and still avoiding taint) by unregistering the events that trigger it and reproducing some of the code yourself.

Last edited by semlar : 07-01-13 at 09:29 AM.
  Reply With Quote
07-01-13, 01:14 PM   #14
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,327
Originally Posted by Clamsoda View Post
Well, that is what I was doing, SDPhantom. My inquiry was to how detrimental it is to void a frame's SetPoint function; and if there was a healthier alternative.

If there is no downside to the practice, then that is what I would continue to use.
As far as taint, sure, the dummy function will taint the execution path for any code that runs it. There is no other problem with diverting the calls to your dummy function. As I've explained before, you're not necessarily wiping out the original function entirely. You're just adding a function into the frame's table in such a way it'll use that function rather than indexing its metatable. Anyone can still access the original function by going through the metatable. For example, getmetatable(frame).__index.SetPoint() will access the original function regardless of what you did to the frame's table. Note you'll have to add in the frame itself as the first argument since it's a different way of calling the function than most are used to, but it'll still work.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
07-01-13, 05:27 PM   #15
Clamsoda
A Frostmaul Preserver
Join Date: Nov 2011
Posts: 269
Originally Posted by semlar View Post
Replacing the SetPoint function of a frame will taint it, so if that matters for what you're doing, don't do it.
Well, I guess it will take some time to see how large of an impact my meddling will have.

Originally Posted by semlar View Post
If this is not for a blizzard frame, then there's no downside to replacing the function, otherwise it's generally best practice to avoid tainting the execution path because it can easily cause unforeseen consequences.
Well, it is for a LOT of Blizzard frames, specifically the ContainerFrame#Slot# frames.

Originally Posted by SDPhantom View Post
As far as taint, sure, the dummy function will taint the execution path for any code that runs it. There is no other problem with diverting the calls to your dummy function. As I've explained before, you're not necessarily wiping out the original function entirely. You're just adding a function into the frame's table in such a way it'll use that function rather than indexing its metatable. Anyone can still access the original function by going through the metatable. For example, getmetatable(frame).__index.SetPoint() will access the original function regardless of what you did to the frame's table. Note you'll have to add in the frame itself as the first argument since it's a different way of calling the function than most are used to, but it'll still work.
Well, in light of such a comprehensive post, I think that I will stick to the dummy function method for now, and see what sort of impact is has down the line. I have been playing while using this method for a while now, and it hasn't produced any headache.

Thanks for all of the insight and explanations, especially regarding meta....stuff
  Reply With Quote
07-02-13, 01:46 AM   #16
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
Try the dummy function in combat first. If it fails (aka spits out a taint) stop right there. It will get you nothing.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)
  Reply With Quote
07-02-13, 02:15 AM   #17
Clamsoda
A Frostmaul Preserver
Join Date: Nov 2011
Posts: 269
Originally Posted by zork View Post
Try the dummy function in combat first. If it fails (aka spits out a taint) stop right there. It will get you nothing.
Well, it has made it past that! Thanks for the reply Zork!
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Questions About Manipulating SetPoint()


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