• 0

    posted a message on uh... first add on and I am not sure what I am doing wrong
    Quote from Bam »

    Error messages are your friends. Post the exact error message and post the line where the error occurs including any relevant context to that line.

    I agree with Bam.

    I recommend installing an addon like BugSack/!Buggrabber. This addon helped me a lot in detecting/finding errors on my script.

    Unfortunately, it won't tell you the error of in your logic. :D



    Posted in: Lua Code Discussion
  • 0

    posted a message on Limitations of the WoW Client
    Quote from tekkub »

    Good god, I hate this "quote reply quote reply quote reply quote reply quote reply quote reply quote reply" shit... I just skipped the last 8 or so replies... ugh...


    Sorry, tekkub. Just like JaedxRapture said, it is the easiest way for me to understand.


    Sure, the advantage is slight, but cutting out the function call (getglobal) and the global lookup (local _G = _G) are a good thing to do if you are using getglobal on the scale Blizzy does. However, if you only make a small handful of calls, I'd just use _G directly without making a local copy.

    I see. I do try to eliminate the getglobal() function call and replace it with _G[] instead (literally speaking). However, nowhere in my code I have the single line:
    local _G = _G

    I'm sure that will cause a hand-slap-on-the-face. :)

    Should this line always be at the top of the file if the file has a _G[] reference within it, then?

    Or, can it be in the first file that gets loaded?

    I'm assuming that it has to be at the top of each file as to me, that symbolizes that the variable is local to all of the functions within that file.

    I always define local variables within functions and files, such as:
    local myDataTable = {}
    
    function myAddOn:CreateWindow()
    
      local myWindow = CreateFrame("Frame","MainFrame",UIParent)
      local xmlDefinedFrame = MyFrameInXMLFile
      .. do other stuff..
    
      myDataTable = self.db.servers.characters
    
      local key
    
      for key,_ in pairs(myDataTable)
      do
        self:Print("Character: " .. key)
      end
    
      self:DoMe()
    
    end
    
    function myAddOn:DoMe()
    
      local i 
      local currentCharacter = myDataTable[UnitName("player")]
    
      for i = 1, #currentCharacter, 1
      do
        self:Print("Table entry " .. i .. ": " .. myDataTable[i])
      end
    
    end



    In any case, thank you very much for responding this thread. Until next question...


    Rin

    Posted in: Lua Code Discussion
  • 0

    posted a message on Limitations of the WoW Client
    Quote from JaedxRapture »

    No, this assigns self.frames[num] to the return of the function CreateFrame (being a frame). So your table becomes this:

    myAddon = {
     frames = {
       [1] = someFrame,
       ...
     }
     ...
    }




    No. This just grabs the frame created at self.frames[num] into a local varaible (making repeated access faster).


    Oh, I see.


    You're defining a handler 'OnClick' to the frame and having it call self:OnFrameClick (which is the same as myAddon:OnFrameClick(), since 'self' represents myAddon when calling/listing functions from within a table with a colon). And here 'this' is the frame, yes.

    I believe this is a mistake anyway. As far as I know, frames of the type 'Frame' don't have an 'OnClick' handler.


    Yes, there is no OnClick for a frame, it would have to be a button. :) But, it was just an example. :D


    Yes. (But remember 'OnEnable' isn't going to be automatically called. You have to call it.)

    Hmm... I had assumed that OnEnable would be called automatically much like how the Ace2 tutorial mentioned. Now, OrionShock didn't define myAddon using the Ace2 framework so I could be comparing apples and oranges here.



    When you list functions from within a table with a colon (function myAddon:someFunc()), they assume a hidden argument 'self' to be used inside that function. When calling with that same colon (myAddon:someFunc()) Lua assumes a hidden 'self' once again and passes it (which is just the addon table). When calling functions listed with the colon without it (myAddon.someFunc()), you need to pass 'myAddon' to avoid having that hidden first argument 'self' appear empty (or have it inherit the wrong argument).

    But here there's a mistake, because in the line:

    self.Actions[1] = function () end


    he didn't list 'self'. So why he's passing it I don't know.

    You lost me here.

    Posted in: Lua Code Discussion
  • 0

    posted a message on Limitations of the WoW Client
    Let me see if understood what you posted, OrionShock.

    local myAddon = {}
    myAddon.frames = {}
    myAddon.Actions = {}


    Define a local table that represents myAddon. Then define two other tables (which will be local also) .frames and .Actions

    function myAddon:OnEnable()
     self:CreateNewButton(1)
     self.Actions[1] = function () end
    end

    When the myAddon is enabled, call the CreateNewButton function and pass 1 as a parameter. You used a colon here because the function is a global function(??).

    function MyAddon:CreateNewButton(num)
     self.frames[num] = CreateFrame("Frame","AddOnMainFrame",UIParent)
     local frame = self.frames[num]
     frame.num = num
     frame:SetWidth(128)
     frame:SetHeight(128)
     frame:SetPoint("CENTER")
     frame:SetTexture("Can't_Forget_To_Set_A_Texture.blp")
     frame.num = num
     frame:SetScript("OnClick", function() self:OnFrameClick(this) end )
     frame:Show()
    end

    The first line, self.frames[num] = CreateFrame("Frame","AddOnMainFrame",UIParent), assigns a function (CreateFrame) into frame[1]. This could also had been myAddon.frames, right?

    The 2nd line, local frame = self.frames[num] is the same as local frame = CreateFrame("Frame","AddOnMainFrame",UIParent). And it also creates a frame named "AddOnMainFrame" with a UIParent parent.

    The 3rd line, frame.num = num, you assign 1 (the parameter) to frame.num variable. I'm guessing this could have also been frame:SetID(num) and GetID() will be used in the click function.

    Lines 4 thru 7, defines the actual frame width, height, anchor and texture.

    Line 8, I don't know why you had this the same as line 3.

    Line 9, you defined a OnClick handler to the frame called OnFrameClick which will pass the frame into it. I would have used myAddon:OnFrameClick(this), but tekkub corrected me to use self: instead of myAddon:.

    Line 10, the frame is shown in the center of the UI.

    Code execution jumps back to the OnEnable and executes...
    self.Actions[1] = function () end

    ... which defines Actions[1] as a function. An empty function.

    When the user clicks on the frame, execution will jump into myAddon:OnFrameClick function.

    function myAddon:OnFrameClick(this)
     if type(self.Actions[this.num]) == 'function' then
      self.Actions[this.num](self)
     end
    end


    Let's see. "this" would represent the frame that was clicked. It will grab the .num which will be 1. Then it will grab the first entry in self.Actions table. It will then check if that is a function (which it is).

    If the :SetID(num) was used above, then the line could have been...
    if type(self.Actions[this:GetID()]) == 'function' then


    I don't understand:
    self.Actions[this.num](self)


    You are passing the myAddon (table) into the empty function in Actions[1]?
    Posted in: Lua Code Discussion
  • 0

    posted a message on Limitations of the WoW Client
    Quote from tekkub »

    I think I'm going to stab you.

    -- If you need 'self' for MyAddOn:
    AddOnMainFrame:SetScript("OnClick", function(f) self:MainFrame_OnClick(f) end )
    
    -- If you don't... don't define MainFrame_OnClick with a colon... or better yet define it as a local function
    AddOnMainFrame:SetScript("OnClick", MyAddOn.MainFrame_OnClick )
    AddOnMainFrame:SetScript("OnClick", MyLocalMainFrame_OnClick )
    
    -- Or if you only use the function in this one place...
    AddOnMainFrame:SetScript("OnClick", function(f)
    	-- Do shit here...
    end)



    Hehehe... my apologies. As a newbie to WoW AddOn programming, I've seen the colon definition in some AddOns that I looked into.

    I do sometimes use:
    AddOnMainFrame:SetScript("OnClick", function(f)
    	-- Do shit here...
    end)


    But, I think I prefer:
    AddOnMainFrame:SetScript("OnClick", MyAddOn.MainFrame_OnClick )


    Posted in: Lua Code Discussion
  • 0

    posted a message on Limitations of the WoW Client
    Quote from tekkub »

    -- In terms of functionality, this code
    CreateFrame('Frame', 'MyFrameName')
    
    -- is identical to this code
    MyFrameName = CreateFrame('Frame')


    Wrong. The "name" is not just the global scope variable name, but it's also passed back from frame:GetName()... which Blizzy loves to use.


    I see your point here too.

    The third example in my above post would return "nil" if I did AddOnMainFrame:GetName().


    The whole point here is, as with the quasi-OO design, to avoid polluting the global namespace. every Blizzard frame and function out there is in the global namespace, but you don't have to be. Your addon object should, ideally, be the only global you declare. If a frame needs some external access, you can just add it into that table.

    Besides that, learning to use locals is the first big step in improving your addon's performance. Blizzy's super heavy use of getglobal() makes me a sad panda.

    It's not really that Blizzy wants to keep their frames from being destroyed... it's that the process of destroying a frame, and potentially all it's children, and figuring out what to do with frames anchored to the frame... well isn't exactly a simple process. Frames aren't something that need to be dynamically destroyed and remade, as the UI layout is fairly static after creation.


    You said tekkub, "the UI layout is fairly static after creation".

    In the past, I've been quite liberal with getglobal(). In a different thread, I learned that getglobal() is nothing but a wrapper function that does _G[ <blah blah> ].

    Posted in: Lua Code Discussion
  • 0

    posted a message on Limitations of the WoW Client
    Quote from egingell »

    Also, don't create a frame unless you need to. If you're not listening for an event and not executing code every n seconds, then there's no practical need for a frame.

    -- In terms of functionality, this code
    CreateFrame('Frame', 'MyFrameName')
    
    -- is identical to this code
    MyFrameName = CreateFrame('Frame')


    Hmm... I see what you mean.

    I find myself doing this:
    function MyAddOn:CreateWindow()
     local myMainFrame = CreateFrame("Frame","AddOnMainFrame",UIParent)
     myMainFrame:SetWidth(128)
     myMainFrame:SetHeight(128)
     myMainFrame:SetPoint("CENTER")
     myMainFrame:SetScript("OnClick", function() MyAddOn:MainFrame_OnClick(this) end )
     myMainFrame:Show()
    end


    Based on what you said, the above function could have been:
    function MyAddOn:CreateWindow()
     CreateFrame("Frame","AddOnMainFrame",UIParent)
     AddOnMainFrame:SetWidth(128)
     AddOnMainFrame:SetHeight(128)
     AddOnMainFrame:SetPoint("CENTER")
     AddOnMainFrame:SetScript("OnClick", function() MyAddOn:MainFrame_OnClick(this) end )
     AddOnMainFrame:Show()
    end


    And if I understood Bam correctly, the above 2 function can also be:
    function MyAddOn:CreateWindow()
     AddOnMainFrame = CreateFrame("Frame")
     AddOnMainFrame:SetWidth(128)
     AddOnMainFrame:SetHeight(128)
     AddOnMainFrame:SetPoint("CENTER")
     AddOnMainFrame:SetScript("OnClick", function() MyAddOn:MainFrame_OnClick(this) end )
     AddOnMainFrame:Show()
    end

    All of the above functions will have "AddOnMainFrame" as a global "variable" that points to a Frame.

    "More than one way to skin a cat"
    Posted in: Lua Code Discussion
  • 0

    posted a message on Limitations of the WoW Client
    Quote from Bam »

    Of course you can. Just assign the reference to a variable or field that is accessible from the other places in your code where you need it. That's basic Lua programming. In this respect a frame reference is no different from any other value (strings, tables, numbers, etc.) that you create in one place and use in another.


    Oh, I see. Didn't think of it that way. As long as the said reference(variable) points to the nameless frame, it is still accessible.


    Not really sure what you mean. Named frames don't offer any additional functionality by themselves. But as I mentioned above, there are a few API functions that require a name rather than a frame reference. But that's merely a sad limitation of those functions.

    Well, the name itself and the global variable associated with it will take up a small amount of memory. But that's so small, it's not worth mentioning really.

    I know what you mean. I've been discovering those as I plow through the WoW API.


    Indeed. But frames can't be destroyed ever. No matter how you created them. That's simply a feature Blizzard has not implemented. There are probably some difficulties doing that. But they are not Lua related.

    I guess Blizzard doesn't want their OWN frames to be destroyed by an AddOn. :D

    There actually is one situation where I sometimes do use named frames even though it's not stricly needed. That's when I want to debug visible frame layout. A tool like Iriel's DevTools will show the name of a frame when you hover over it. This can be quite useful sometimes.


    Ahh... I'll hunt down that DevTool by Iriel. :)
    Posted in: Lua Code Discussion
  • 0

    posted a message on Limitations of the WoW Client
    Quote from Bam »

    For frames created in Lua, you can easily get a reference to it upon creation:

    local frame = CreateFrame("Frame")



    I understand that I can create the frame like the code above, but, once the function is over, I don't think I can refer to that particular frame again without a name.

    I guess "child objects" could be nameless more as hiding the parent object would also hide the children.

    Also, if names have no impact on memory, then does that mean that a nameless frame will take (theoretically) the same memory space as a named frame.

    I really wish there are ways to "destroy" manually created frames (frames created by the CreateFrame function).

    Anyways, something to think about when coding. I guess the rule of thumb is if the frame won't be referred to again after the initial creation, then it could be nameless.

    Posted in: Lua Code Discussion
  • 0

    posted a message on Limitations of the WoW Client
    Quote from tekkub »

    Don't name frames unless you have to (you're using a Blizzy template).

    What are the cases when I won't need any names on the frames?

    I've always thought that giving a frame a name would allow me to reference to it.

    Would that also mean that 5 frames with names will take up more memory space than 5 nameless frames?

    Posted in: Lua Code Discussion
  • 0

    posted a message on Limitations of the WoW Client
    I know the title is quite general, but, I have been wondering:

    1) What is the limit of the number of objects (Frames, Buttons, Sliders, ScrollFrames, etc) of the WoW Client? As I try to keep up on the number of addons I'd like to make, I'm noticing that I've been creating various frames, buttons (objects). Would the WoW Client say: "Hey, you can't make any more objects!"?


    2) As I continue to make the above objects, I try to make them as unique as possible when it comes to names. With using the "$parent" option, the name of the deepest "child" can be very long. What is the limit of the object name in terms of length?


    3) I'm guessing here... if an object (Frame, Button, etc) is NOT visible on the UI, then that object is not using any memory. Is this correct? Or, if I define/create the object (via Lua or XML), that object will continue to use memory even though it is not visible? I'm sure it would use a bit of memory for the definition of the object, but, I'm banking that that is minimal.


    Posted in: Lua Code Discussion
  • 0

    posted a message on TargetUnit(UnitName("player"))
    Quote from Pastamancer »

    Yes, "John Burnside" is not a valid unitid. Find out more here: http://www.wowwiki.com/UnitId


    Ahh, I had assumed that since I can do /target John Burnside, then it would be the same as TargetUnit("John Burnside"). I misread:


    "name"
    This must be spelled exactly and will be invalid if the named player is not a part of your party or raid.


    Posted in: Lua Code Discussion
  • 0

    posted a message on Help with an error I am getting in an addon I am writing
    Quote from flamewalker »

    This is the error for the life of me I don't know why I am getting this. What would be the usual cause of this kind of error with show?

    attempt to call method 'show' (a nil value)


    If you are showing a frame, then the frame might not be defined hence it is nil.

    Or, the method 'show' is not a defined function.
    Posted in: Lua Code Discussion
  • 0

    posted a message on TargetUnit(UnitName("player"))
    Bam:

    Thanks very much for the macro option you mentioned.

    If I had:
    button:SetAttribute("unit", "John Burnside")
    button:SetAttribute("type", "target")


    It doesn't work and fails silently.

    But,
    button:SetAttribute("type", "macro")
    button:SetAttribute("macrotext", "/target John Burnside")


    Works great! My target frame will have John Burnside as targeted.

    Is there a web-site/tutorial that lists all of the possible "SetAttribute" arguments?

    Posted in: Lua Code Discussion
  • 0

    posted a message on LoadOnDemand issue
    Quote from Fwip »

    You have addon 1 set up as "Load-on-demand." The game sees this, and doesn't load it. Then it gets to addon 2, and sees that addon 2 demands addon 1 in order to load. Therefore, the game loads addon 1, and then addon 2.


    So, both "master" addon (Addon1) and the "slave/child" (Addon2) MUST have a LoadOnDemand set for the behavior to work like what JaedxRapture showed in the code?

    Kunda's TOC in Addon2 doesn't specify the LoadOnDemand, so Addon2 is forcing the load of Addon1 as it is a dependency which bypasses the LoadOnDemand in Addon1's TOC. Would Blizzard_AuctionUI also load then since it is in the LoadWith of Addon1?

    Posted in: Lua Code Discussion
  • To post a comment, please or register a new account.