WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   AddOn Help/Support (https://www.wowinterface.com/forums/forumdisplay.php?f=3)
-   -   about a Create functions and new instances of objects (https://www.wowinterface.com/forums/showthread.php?t=43282)

Wildbreath 04-18-12 11:12 AM

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

Seerah 04-18-12 01:00 PM

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. :confused:

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...

SDPhantom 04-18-12 03:18 PM

Quote:

Originally Posted by Seerah (Post 255590)
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.





Quote:

Originally Posted by Wildbreath (Post 255588)
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.

Wildbreath 04-18-12 03:39 PM

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 :(

Phanx 04-18-12 05:23 PM

Quote:

Originally Posted by Wildbreath (Post 255596)
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.

Ketho 04-18-12 08:58 PM

Quote:

Originally Posted by Phanx (Post 255602)
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!")


Torhal 04-18-12 11:00 PM

Quote:

Originally Posted by Ketho (Post 255610)
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.

Wildbreath 04-19-12 03:15 AM

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.

Phanx 04-19-12 01:00 PM

Quote:

Originally Posted by Ketho (Post 255610)
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.

Ketho 04-19-12 08:59 PM

Quote:

Originally Posted by Phanx (Post 255633)
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 >.<

SDPhantom 04-19-12 09:07 PM

Quote:

Originally Posted by Ketho (Post 255663)
Quote:

Originally Posted by Phanx (Post 255633)
Quote:

Originally Posted by Ketho (Post 255610)
Quote:

Originally Posted by Phanx (Post 255602)
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.

Phanx 04-20-12 01:10 AM

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. :rolleyes:

Ketho 04-20-12 01:21 AM

Quote:

Originally Posted by Torhal (Post 255615)
No: Read the OP's code.

Quote:

Originally Posted by SDPhantom (Post 255664)
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.

Quote:

Originally Posted by Phanx (Post 255678)
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. :rolleyes:

I now finally realize this. Sorry for derailing, and not properly reading the OP's post (=.o)\


All times are GMT -6. The time now is 09:27 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI