Quantcast
about a Create functions and new instances of objects - WoWInterface
Thread Tools Display Modes
04-18-12, 11:12 AM   #1
Wildbreath
A Cyclonian
 
Wildbreath's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 46
about a Create functions and new instances of objects

For example:
frame1 = CreateFrame("frame","frame1",UIParent)
frame2 = CreateFrame("frame","frame1",UIParent)

frame1 == frame2 ?
or frame2 is new widget object?

If second is right then i have a new snippet for optimize all addons
lua Code:
  1. local oldCreateFrame = CreateFrame
  2. CreateFrame = function(ftype, name, ...)
  3.     local frame, texture, fontstring, animation, animationg
  4.    
  5.     if name ~= nil and name:find('map') then return oldCreateFrame(ftype, name, ...) end
  6.     if _G[name] ~= nil then
  7.         frame = _G[name]
  8.     else
  9.         frame = oldCreateFrame(ftype, name, ...)
  10.     end
  11.    
  12.     local oldCreateTexture = frame.CreateTexture
  13.     frame.CreateTexture = function(name, ...)
  14.         if _G[name] ~= nil then
  15.             texture = _G[name]
  16.         else
  17.             texture = oldCreateTexture(name, ...)
  18.         end
  19.         return texture
  20.     end
  21.    
  22.     local oldCreateFontString = frame.CreateFontString
  23.     frame.CreateFontString = function(name, ...)
  24.         if _G[name] ~= nil then
  25.             fontstring = _G[name]
  26.         else
  27.             fontstring = oldCreateFontString(name, ...)
  28.         end
  29.         return fontstring
  30.     end
  31.    
  32.     local oldCreateAnimationGroup = frame.CreateAnimationGroup
  33.     frame.CreateAnimationGroup = function(name, ...)
  34.         if _G[name] ~= nil then
  35.             animationg = _G[name]
  36.         else
  37.             animationg = oldCreateAnimationGroup(name, ...)
  38.         end
  39.         return animationg
  40.     end
  41.  
  42.  
  43.     local oldCreateAnimation = frame.CreateAnimation
  44.     frame.CreateAnimation = function(atype, name, ...)
  45.         if _G[name] ~= nil then
  46.             animation = _G[name]
  47.         else
  48.             animation = oldCreateAnimation(atype, name, ...)
  49.         end
  50.         return animation
  51.     end
  52.    
  53.     return frame
  54. end
  Reply With Quote
04-18-12, 01:00 PM   #2
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,747
Lua Code:
  1. frame1 = CreateFrame("frame","frame1",UIParent)
  2. frame2 = CreateFrame("frame","frame1",UIParent)
This creates 2 frames. The first is referenced by the global variable frame1 while the second is referenced by two global variables, frame1 and frame2. While the second frame's frame1 reference overwrites the first frame's reference, that does not mean that the second frame replaces the first. They both still exist.

That said, this snippet is not found in your code block.



Lua Code:
  1. if _G[name] ~= nil then
  2.         frame = _G[name]
  3.     else
  4.         frame = oldCreateFrame(ftype, name, ...)
  5.     end
This just says that if the variable name we want to call our frame already exists in the gobal table (which most frames should not be named globally anyway) then assign this frame to the variable frame and... just pass it through the function, replacing some of its methods. The replaced methods do the exact same thing. If there was no frame (or widget) with that global name before, then... just create it as normal. Nothing is changed, except you're replacing the functions with copies of what they originally were.

I have no idea what you are trying to accomplish with this, though. Either I am missing something or your code does nothing that the default UI doesn't already do, except you are adding another complicated layer on top of it... Well, other than not creating any frames if that name already existed...
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh


Last edited by Seerah : 04-18-12 at 01:02 PM.
  Reply With Quote
04-18-12, 03:18 PM   #3
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 1,934
Originally Posted by Seerah View Post
Lua Code:
  1. frame1 = CreateFrame("frame","frame1",UIParent)
  2. frame2 = CreateFrame("frame","frame1",UIParent)
This creates 2 frames. The first is referenced by the global variable frame1 while the second is referenced by two global variables, frame1 and frame2. While the second frame's frame1 reference overwrites the first frame's reference, that does not mean that the second frame replaces the first. They both still exist.
Actually, this is incorrect. Two frames are indeed created, but the setting of the global variable from the frame name is more complex. To demonstrate, we'll run the following code.
Code:
f1=CreateFrame("Frame","f0");
f2=CreateFrame("Frame","f0");
print(f0,f1,f2);
Notice both frames are created with the name "f0", yet only the first one is stored in that global. This is confirmed by the first 2 pointers printed out being equal. This is because there's an internal check when a frame is created that restricts it to only set the frame name global if it doesn't exist.





Originally Posted by Wildbreath View Post
For example:
frame1 = CreateFrame("frame","frame1",UIParent)
frame2 = CreateFrame("frame","frame1",UIParent)

frame1 == frame2 ?
or frame2 is new widget object?

If second is right then i have a new snippet for optimize all addons
As most authors use locals and table keys rather than globals for performance improvements, this method is practically useless.
__________________
ESOUI AddOns | 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)

Last edited by SDPhantom : 04-18-12 at 03:35 PM.
  Reply With Quote
04-18-12, 03:39 PM   #4
Wildbreath
A Cyclonian
 
Wildbreath's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 46
but when i create frames as local - creates one widget or two and stores first in global table and rewtiting by second CreateFrame?

local frame1 = CreateFrame("frame","frame1",UIParent)
local frame2 = CreateFrame("frame","frame1",UIParent)

my snippet should return frame if that existed in _G and return new frame if not exist (by name)
upd. exept secured frames

Last edited by Wildbreath : 04-18-12 at 03:41 PM.
  Reply With Quote
04-18-12, 05:23 PM   #5
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by Wildbreath View Post
but when i create frames as local - creates one widget or two and stores first in global table and rewtiting by second CreateFrame?

local frame1 = CreateFrame("frame","frame1",UIParent)
local frame2 = CreateFrame("frame","frame1",UIParent)
You are still creating two separate frame objects.

Code:
print(frame1 == frame2)
==> false
-- They are two separate objects, not the same object.

print(frame2 == _G["frame1"])
==> true
-- The global name "frame1" was most recently assigned to the frame
-- assigned to the frame2 variable.

print(frame1 == _G["frame1"])
==> false
-- The global name "frame1" was assigned to the frame2 object
-- after it was assigned to the frame1 object. The later assignment
-- takes priority, so the global name no longer points to the original object.
Frames are (basically) tables. Like all tables in Lua, they are passed by reference, not by value.

Code:
t1 = {}
t2 = {}
-- Creates two new table objects.

print(t1 == t2) ==> false
-- Despite having identical contents, they are not the same object.

t2 = t1
-- Point the t2 variable to the table originally assigned to the t1 variable.
-- The table originally assigned to the t2 variable still exists,
-- but no references to it remain, so it cannot be accessed, and will
-- eventually be garbage-collected.

t1.x = 5

print(t2.x) ==> 5
-- Since both variables now point to the same table, any changes to that table
-- are accessible through either variable.
Frames are exactly the same, except that they do not get garbage-collected because they have special properties (eg. userdata).

Also, your code is a terrible idea. If a frame already exists named "MyTestFrame" and I run this code:

Code:
local frame = CreateFrame("Frame", "MyTestFrame")
I want a new frame object, not some random frame object from another addon that happens to have the same global name.

Also, your code does not take into account that global variables can contain any type of data. For example, if I try to create a frame whose global name is "ABANDON_QUEST":

Code:
local frame = CreateFrame("Button", "ABANDON_QUEST", UIParent, "UIPanelButtonTemplate")
frame:SetPoint("CENTER")
frame:SetSize(100, 100)
frame:SetText("Abandon Quest!")
... your code would set the contents of my frame variable to the string that the Blizzard UI originally assigned to the global variable ABANDON_QUEST, and the rest of my code would fail, because a string does not have :SetPoint, :SetSize, or :SetText methods.

Your code does not optimize anything. It adds complexity, adds overhead, and would make it much more difficult to identify the cause of any naming conflicts.

Last edited by Phanx : 04-18-12 at 05:31 PM.
  Reply With Quote
04-18-12, 08:58 PM   #6
Ketho
A Molten Giant
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 931
Originally Posted by Phanx View Post
Also, your code does not take into account that global variables can contain any type of data. For example, if I try to create a frame whose global name is "ABANDON_QUEST":

Code:
local frame = CreateFrame("Button", "ABANDON_QUEST", UIParent, "UIPanelButtonTemplate")
frame:SetPoint("CENTER")
frame:SetSize(100, 100)
frame:SetText("Abandon Quest!")
... your code would set the contents of my frame variable to the string that the Blizzard UI originally assigned to the global variable ABANDON_QUEST, and the rest of my code would fail, because a string does not have :SetPoint, :SetSize, or :SetText methods.

The above code actually works. Did you instead mean this, Phanx?
Code:
local frame = CreateFrame("Button", "ABANDON_QUEST", UIParent, "UIPanelButtonTemplate")
ABANDON_QUEST:SetPoint("CENTER")
ABANDON_QUEST:SetSize(100, 100)
ABANDON_QUEST:SetText("Abandon Quest!")
  Reply With Quote
04-18-12, 11:00 PM   #7
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Originally Posted by Ketho View Post
The above code actually works. Did you instead mean this, Phanx?
Code:
local frame = CreateFrame("Button", "ABANDON_QUEST", UIParent, "UIPanelButtonTemplate")
ABANDON_QUEST:SetPoint("CENTER")
ABANDON_QUEST:SetSize(100, 100)
ABANDON_QUEST:SetText("Abandon Quest!")
No: Read the OP's code.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
04-19-12, 03:15 AM   #8
Wildbreath
A Cyclonian
 
Wildbreath's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 46
That's sad
We really need garbage collector, came across this quite often, for example in addon kCore
But it was the first attempt. At least we can determine the type of data and etc.
  Reply With Quote
04-19-12, 01:00 PM   #9
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by Ketho View Post
The above code actually works. Did you instead mean this, Phanx?
Code:
local frame = CreateFrame("Button", "ABANDON_QUEST", UIParent, "UIPanelButtonTemplate")
ABANDON_QUEST:SetPoint("CENTER")
ABANDON_QUEST:SetSize(100, 100)
ABANDON_QUEST:SetText("Abandon Quest!")
No, but that would also fail, for the same reason. Re-read the OP's code. Once a global is set, it cannot be overwritten by creating a new UI object with the same name, so even through you pass "ABANDON_QUEST" as the global name in the CreateFrame call, the OP's code would see that there is already a global named "ABANDON_QUEST", and simply return that (a string) instead of actually creating a new frame. Either way, the global "ABANDON_QUEST" still points to the original string, and the frame variable is given that string as its value.
  Reply With Quote
04-19-12, 08:59 PM   #10
Ketho
A Molten Giant
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 931
Originally Posted by Phanx View Post
No, but that would also fail, for the same reason. Re-read the OP's code. Once a global is set, it cannot be overwritten by creating a new UI object with the same name, so even through you pass "ABANDON_QUEST" as the global name in the CreateFrame call, the OP's code would see that there is already a global named "ABANDON_QUEST", and simply return that (a string) instead of actually creating a new frame. Either way, the global "ABANDON_QUEST" still points to the original string, and the frame variable is given that string as its value.
I mean ..
that the "above" code which I quoted from you (local frame) actually works,
that the "below" code which I posted myself (ABANDON_QUEST) doesn't work. not the other way round

I can't reread the OP's posts. It just isn't legible imo >.<
  Reply With Quote
04-19-12, 09:07 PM   #11
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 1,934
Originally Posted by Ketho View Post
Originally Posted by Phanx View Post
Originally Posted by Ketho View Post
Originally Posted by Phanx View Post
Also, your code does not take into account that global variables can contain any type of data. For example, if I try to create a frame whose global name is "ABANDON_QUEST":

Code:
local frame = CreateFrame("Button", "ABANDON_QUEST", UIParent, "UIPanelButtonTemplate")
frame:SetPoint("CENTER")
frame:SetSize(100, 100)
frame:SetText("Abandon Quest!")
The above code actually works. Did you instead mean this, Phanx?
Code:
local frame = CreateFrame("Button", "ABANDON_QUEST", UIParent, "UIPanelButtonTemplate")
ABANDON_QUEST:SetPoint("CENTER")
ABANDON_QUEST:SetSize(100, 100)
ABANDON_QUEST:SetText("Abandon Quest!")
No, but that would also fail, for the same reason. Re-read the OP's code. Once a global is set, it cannot be overwritten by creating a new UI object with the same name, so even through you pass "ABANDON_QUEST" as the global name in the CreateFrame call, the OP's code would see that there is already a global named "ABANDON_QUEST", and simply return that (a string) instead of actually creating a new frame. Either way, the global "ABANDON_QUEST" still points to the original string, and the frame variable is given that string as its value.
I mean ..
that the "above" code which I quoted from you (local frame) actually works,
that the "below" code which I posted myself (ABANDON_QUEST) doesn't work. not the other way round

I can't reread the OP's posts. It just isn't legible imo >.<
The explanation was that the code normally should work on an unmodified CreateFrame() and modifying that function to work as the OP had specified would break it. This is because the modification takes the frame's name and causes it to return the global variable contained there instead of the new frame it should've created.
__________________
ESOUI AddOns | 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)

Last edited by SDPhantom : 04-19-12 at 09:15 PM.
  Reply With Quote
04-20-12, 01:10 AM   #12
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Yes, if you're not reading the OP's code, then probably nothing else in this thread is going to make any sense to you. Everything in my post was about what would happen if the OP's code were in use.
  Reply With Quote
04-20-12, 01:21 AM   #13
Ketho
A Molten Giant
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 931
Originally Posted by Torhal View Post
No: Read the OP's code.
Originally Posted by SDPhantom View Post
The explanation was that the code normally should work on an unmodified CreateFrame() and modifying that function to work as the OP had specified would break it. This is because the modification takes the frame's name and causes it to return the global variable contained there instead of the new frame it should've created.
Originally Posted by Phanx View Post
Yes, if you're not reading the OP's code, then probably nothing else in this thread is going to make any sense to you. Everything in my post was about what would happen if the OP's code were in use.
I now finally realize this. Sorry for derailing, and not properly reading the OP's post (=.o)\

Last edited by Ketho : 04-20-12 at 01:25 AM.
  Reply With Quote

WoWInterface » AddOns, Compilations, Macros » AddOn Help/Support » about a Create functions and new instances of objects

Thread Tools
Display Modes

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