LoTROInterface

LoTROInterface (https://www.lotrointerface.com/forums/index.php)
-   Lua Programming Help (L) (https://www.lotrointerface.com/forums/forumdisplay.php?f=50)
-   -   Nested Classes issue (https://www.lotrointerface.com/forums/showthread.php?t=1662)

SanDBoX 10-21-2011 11:11 PM

Nested Classes issue
 
anyone have any pointers for dealing with nested windows? basicly what I am trying to do is get a window to create a new copy of itself then be able to share information with the child. I tried creating a holding place in the class but the parents data doesnt seam to update with the childs...

so:
window1 creates window2
window2 creates window3
change information in window3
window3 updates information for window2
then window2 updates window1

I have most of it togeather and figured out but I cant get them to recursivly update...


here is my window sorry it is a little long, figured all information is better then not enough:
Code:



import "SandBox.Crafters"

AddItemWindow = class( Turbine.UI.Window )

function AddItemWindow:Constructor()
        Turbine.UI.Lotro.Window.Constructor( self )
        self:SetText("Add item to recipe")
        self:SetPosition( 530, 150 )
        self:SetSize(300, 300)
        self:SetVisible(false)
       
        self.uppernode = nil
       
        namelabel = Turbine.UI.Label()
        namelabel:SetText("Subcombine Name: ")
        namelabel:SetPosition(25, 45)
        namelabel:SetSize(115, 20)
        namelabel:SetParent(self)
        namelabel:SetForeColor(Turbine.UI.Color( 1, .8, .6 ))
       
        self.namebox = Turbine.UI.Lotro.TextBox()
        self.namebox:SetSize(120, 20 )
        self.namebox:SetPosition(140, 40)
        self.namebox:SetParent(self)
        self.namebox:SetText("New Item")
        self.namebox:SetFont( Turbine.UI.Lotro.Font.Verdana12 )
       
        inglabel = Turbine.UI.Label()
        inglabel:SetText("Ingredients:")
        inglabel:SetSize(115, 20)
        inglabel:SetPosition(25, 60)
        inglabel:SetParent(self)
        inglabel:SetForeColor(Turbine.UI.Color( 1, .8, .6 ))
       
        ingtreeview = Turbine.UI.TreeView()
        ingtreeview:SetParent(self)
        ingtreeview:SetSize(250, 100)
        ingtreeview:SetPosition(25, 150)
        ingtreeview:SetIndentationWidth( 15 )
        ingtreeview:SetBackColor( Turbine.UI.Color(.1,.1,.1))

        treescroll = Turbine.UI.Lotro.ScrollBar()
        treescroll:SetOrientation( Turbine.UI.Orientation.Vertical )
        treescroll:SetParent( self )
        treescroll:SetPosition( 275, 150 )
        treescroll:SetSize( 10, 120 )
       
        ingtreeview:SetVerticalScrollBar(treescroll)
       
        self.nodes = ingtreeview:GetNodes()
       
        addrecbut = Turbine.UI.Lotro.Button()
        addrecbut:SetParent(self)
        addrecbut:SetSize(125, 20)
        addrecbut:SetPosition(25, 80)
        addrecbut:SetText("Add Recipe")
       
        addrecbut.Click = function(sender, args)
            Turbine.Shell.WriteLine("Clicked Add Recipe Button")
            self:spawnrec(self.nodes)
        end

        clrbut = Turbine.UI.Lotro.Button()
        clrbut:SetPosition(155, 250)
        clrbut:SetSize(120, 20)
        clrbut:SetParent(self)
        clrbut:SetText("Cancel")
       
        clrbut.Click = function(Sender, args)
          Turbine.Shell.WriteLine("Clicked Cancel Button")
          self:Clear()
        end
               
        self.ingtext = Turbine.UI.Lotro.TextBox()
        self.ingtext:SetParent(self)
        self.ingtext:SetSize(150, 20)
        self.ingtext:SetPosition(25,100)
        self.ingtext:SetFont( Turbine.UI.Lotro.Font.Verdana12 )
        self.ingtext:SetText("Ingredient")

        self.ingqty = Turbine.UI.Lotro.TextBox()
        self.ingqty:SetParent(self)
        self.ingqty:SetSize(50, 20)
        self.ingqty:SetPosition(175,100)
        self.ingqty:SetFont( Turbine.UI.Lotro.Font.Verdana12 )
        self.ingqty:SetText("Qty")
       
        additembut = Turbine.UI.Lotro.Button()
        additembut:SetParent(self)
        additembut:SetSize( 50, 20 )
        additembut:SetPosition(225,100)
        additembut:SetText("Add")
       
        additembut.Click = function(sender, args)
          Turbine.Shell.WriteLine("Clicked Add Item Button")
          self:spawnitem()
          self.ingtext:SetText("Ingredient")
          self.ingqty:SetText("Qty")
        end
       
        treeheadering = Turbine.UI.Label()
        treeheadering:SetParent(self)
        treeheadering:SetSize(220,20)
        treeheadering:SetPosition(25, 130)
        treeheadering:SetFont( Turbine.UI.Lotro.Font.Verdana12 )
        treeheadering:SetForeColor(Turbine.UI.Color( 1, .8, .6 ))
        treeheadering:SetBackColor( Turbine.UI.Color(.1,.1,.1))
        treeheadering:SetText("Ingredient")
       
        treeheaderqty = Turbine.UI.Label()
        treeheaderqty:SetParent(self)
        treeheaderqty:SetSize(25,20)
        treeheaderqty:SetPosition(250,130)
        treeheaderqty:SetFont( Turbine.UI.Lotro.Font.Verdana12 )
        treeheaderqty:SetForeColor(Turbine.UI.Color( 1, .8, .6 ))
        treeheaderqty:SetBackColor( Turbine.UI.Color(.1,.1,.1))
        treeheaderqty:SetText("Qty")

        self.okbutton = Turbine.UI.Lotro.Button()
        self.okbutton:SetParent(self)
        self.okbutton:SetSize(125,20)
        self.okbutton:SetPosition(25,250)
        self.okbutton:SetText("Okay")
       


end

--I creates new window and populates the container for parent data
function AddItemWindow:spawnrec()
        Turbine.Shell.WriteLine("Spawning new add window")
        nestwin = AddItemWindow()
        nestwin:SetVisible(true)
        nestwin.uppernode = self.nodes
        ox,oy = self:GetPosition()
        nx = ox + 15
        ny = oy + 15
        nestwin:SetPosition(nx,ny)
        Turbine.Shell.WriteLine(type(nestwin.uppernode))
       
        nestwin.okbutton.Click = function(sender, args)
          Turbine.Shell.WriteLine("AddItemWindow.okbutton.Click: Clicked ok button")
          self.nodes:Add(nestwin:elevate())
          nestwin:Clear()
        end
end

--I packages inputed data into node and displays in current window
function AddItemWindow:spawnitem()
        ingredant = self.ingtext:GetText()
        quantity = self.ingqty:GetText()
       
        node = Turbine.UI.TreeNode()
        node:SetSize(250,20)
       
        list = Turbine.UI.ListBox()
        list:SetSize(200, 20)
        list:SetParent(node)
        list:SetOrientation( Turbine.UI.Orientation.Horizontal )

        inglabel = Turbine.UI.Label()
        inglabel:SetSize(100, 20)
        inglabel:SetText(ingredant)
        list:AddItem(inglabel)
       
        qtylabel = Turbine.UI.Label()
        qtylabel:SetSize(50, 20)
        qtylabel:SetText(quantity)
        list:AddItem(qtylabel)
       
        self.nodes:Add(node)
end

--I Packages data into tree node for parent window
function AddItemWindow:elevate()
        tempnode = Turbine.UI.TreeNode()
        tempname = Turbine.UI.Label()
        tempname:SetParent(tempnode)
        tempname:SetText(self.ingtext:GetText())
       
        tempqty = Turbine.UI.Label()
        tempqty:SetParent(tempnode)
        tempqty:SetPosition(0,100)
        tempqty:SetText(self.ingqty:GetText())
       
        tempnodes = tempnode:GetChildNodes()
        tempnodes:Add(self.nodes)
        return tempnodes

end

--I Clears and hides window
function AddItemWindow:Clear()
        Turbine.Shell.WriteLine("AddItemWindow.Clear: Clearing Add Item Window" )
        self.nodes = nil
        self:SetVisible(false)
end

idealy the window/window functions should be self contained in order to have a near unlimited number of steps.

I also havent built in any error control and still needs some clean up but just wanted to get the idea working first.

at first I figured the tree nodes were not updating correctly so that is when I rebuilt the "spawnrec" and "elevate" functions to interact with the child directly...

any pointers would be awesome, I am not a very good programmer but I am persistant and good and finding work arounds but this one has me stumped...

lunarwtr 10-22-2011 10:44 AM

Without looking into it too far, my first guess is you might be having namespace collision with multiple copies of the same class. I notice in your constructor & some of the method you define some variables like..

Code:

nestwin = AddItemWindow()
I would encourage you to put the keyword "local " before the variable name or if you want to later reference it, assign it to a private datamember of your object reference.

Essentially what I'm getting at is perhaps the copy of "nextwin" in your click event function isn't referring to what you think its referring to when the code gets ran (but rather the last one to be defined.

SanDBoX 10-22-2011 11:41 AM

perhaps, but I was under the impression that in lua anything declared in a function was local to the function by default, but worth a shot.

Garan 10-22-2011 01:14 PM

Quote:

Originally Posted by SanDBoX (Post 7296)
perhaps, but I was under the impression that in lua anything declared in a function was local to the function by default, but worth a shot.

Lunarwtr is definately correct about the scoping. If you declare a function with a variable inside it, call the function and then reference the variable outside the function you will see that the variable is scoped outside the function (unless you declare it with "local").

You can do this interactively using the debug.lua class from the Cards plugin:
Start the Cards plugin. Start a game of "Ring". Enter the command "/ringgame debug" to start the interactive debugger. It is usually a good idea to select "Plugin Environment" at the top of the debug window but it's not necessary for this example.
Create a function "testfunc" by entering
Code:

testfunc=function() abcdef="hello" end
and click Execute. Then run the function by entering
Code:

testfunc()
and click Execute. At this point, we are no longer in the scope of the function, but if you enter
Code:

return abcdef
and click Execute, it displays "hello" in the standard chat.
You can see where the testfunc and abcdef exist in the object viewer at the bottom. If you selected "Global Environment" they will be defined just inside the "_G" global object. If you chose "Plugin Environment" you will have to expand the "GaranStuff" object, then the "Cards" object.


The recursive filling of the object viewer list in debug.lua may give you some insight into how to resolve your problem.

itsallhype820 10-22-2011 11:53 PM

garan is right about the data scope. i think it would be a better idea to do what you are trying to do by, making a class that contains your top level info. so say you want an array of a certain window. a class holding this info could be like (im doing this off the top of my head so bare with me.

cont = class()
function cont:Cunstructor()

self.winList = {}
end
function cont:addWindow(winObj, nameOf)

self.winList[nameOf] = winObj
end
function cont:getWindow(nameOf)
return self.winList[nameOf]
end
this is just a very simple example.. of how to maintain a collection of objects. nameOf can be a string like "title window" or you can make it interger base where it is 1 2 3 4 etc.

so to use just do , myContainer = cont()
--my window is a window class that you have made just make a new instance of it then pass it
myContainer:addWindow(myWindow, "Main")

to set data or grab position etc use
local tempWindow = myContainer:getWindow("Main")
local x, y = tempWindow:GetPosition()

hope this makes some sense. ideally you would use your container class with self.mainWin = yourWindow in the constructor to save it in the class for future reference

SanDBoX 10-23-2011 12:33 AM

my idea was just to collect the data then let the window get garbage collected that was why i was trying to create a tree node, then have the children add the info into the parents tree node. and after setting some of the information local and passing the "tempnode" instead of the "tempnodes" up the tree it seams to almost work. the windows are more reliable and they are passing some of the information not all of their child nodes (as in depth 1 would work but depth 3 would not pass all the way back to 1)

on the point of keeping a list of windows, does anyone know how well the garbage collection works in lotro/lua? how many windows would it take to start slowing the client if I record each and every one of them? and how would I tell the client to kill a window other then setting it to not-visible?

Garan 10-23-2011 01:41 AM

Quote:

Originally Posted by SanDBoX (Post 7302)
on the point of keeping a list of windows, does anyone know how well the garbage collection works in lotro/lua? how many windows would it take to start slowing the client if I record each and every one of them? and how would I tell the client to kill a window other then setting it to not-visible?

Garbage collection usually works fine but if you find the need to force a garbage collection cycle (I found an issue in the Card game that required me to manually force a collection cycle) you can with the collectgarbage("collect") command. As to killing a window, setting it to non-visible does not release the window to be collected, you must set all references to it to nil. So when you instantiate a window with: newWindow=SomeWindow() you would then need to use newWindow=nil to allow the garbage collection to remove the window. It is a good idea to set the window to non-visible first so that the graphics are hidden until the garbage collection gets around to actually removing it but until all references are set to nil the window won't get collected.

SanDBoX 10-27-2011 10:30 AM

ok, I can get the node to pass correctly but it is not passing the child nodes at all from what i can tell, even when i pass the children directly, which brings up another question can you add all child nodes at once or do you have to do it one by one?

as in:

nodes = node:GetChildNode()

parentnodes:Add(nodes)


All times are GMT -5. The time now is 03:00 PM.

vBulletin® - Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
© MMOUI