Game Development Community

returning objects and global versus local

by Tra · in Torque Game Engine · 02/11/2003 (8:50 pm) · 8 replies

I'm trying to construct a system similar to the World Editor/Inspector/Creator going, only with objects of my own. I'm using the GuiTreeViewCtrl do accomplish this, which requires creating my objects as SimSets, but it works and I've gotten basic Add/Remove functionaliy going on.

bork.hampshire.edu/~trahari/images/treeview2.gif

Whatever the currently selected object is stored in my TreeView object as currentObject. I added that field using the GUI editor's Dynamic Fields functionality. It looks like this:
new GuiTreeViewCtrl(DialogueTreeView) {
    profile = "GuiTreeViewProfile";
    horizSizing = "right";
    vertSizing = "bottom";
    position = "2 2";
    extent = "640 11";
    minExtent = "8 2";
    visible = "1";
    helpTag = "0";
    allowMultipleSelections = "0";
    recurseSets = "0";
    currentObject = "";
};
For those of you that care, it seems that onSelect is what you want when you wanna do something when something in your treeview is selected. The function for handling that looks like this:
function DialogueTreeView::onSelect( %this, %selectecObj)
{
    %this.currentObject = %selectecObj;
}

So, in order to add or remove nodes from whatever, I've gotta work with DialogueTreeView.currentObject directly. I've done this, and I don't really like this, from a design standpoint.

I'd rather provide access to currentObject through a DialogueTreeView::getCurrentObject function belonging to DialogueTreeView, so I can work in some error checking for the Remove button.

The trouble is, this function
function DialogueTreeView::getCurrentObject( %this)
{
    return %this.currentObject;
}
appears to behave unpredictably. Check out this console output:
==>echo( DialogueTreeView.getCurrentObject());
1211
==>%someThing = DialogueTreeView.getCurrentObject();
==>echo( %someThing);
Notice that last line there, that is blank? Yeah. That's the problem.

The funny thing is, a global fixes that right up:
==>$temp = DialogueTreeView.getCurrentObject();
==>echo( $temp);
1211

While writing this out, I just thought, "why not just keep one global that I reuse to store the result?" Still, that's a workaround, and I'd like to know if any of you have encountered anything like this, or know of a solution.

Thanks,
- Tra'Hari Vandaette

About the author

Recent Threads


#1
02/11/2003 (9:40 pm)
Well, I've discovered one piece of a workaround.

If I define functions addNode and removeNode, I can do something as simple as addNode( DialogueTreeView.getCurrentObject()), and that works.

The trouble is that my error checking in removeNode doesn't prevent a crash. Here's the code for removeNode:
function removeNode( %node)
{
    if( %node == DialogueRootNode )
    {
	// do nothing
    }
    else
    {
	%node.delete();
    }
}

If I do this at the console, it appears to work properly (or maybe not; I am very tired). Regardless, it still vomits. I'm looking into that.

In the meantime, I'm still curious as to whether or not any of you have discovered a neater way of doing things (i.e., more OO).

- Tra'Hari
#2
02/11/2003 (10:36 pm)
Not really sure, but the problem might be this:
function DialogueTreeView::getCurrentObject( %this)
{
    return %this.currentObject;
}
Usually, the %this var and first argument in any script object function is the datablock/class itself, and the second, usually named %obj is the current instance you are working with...
so maybe you should try this:
function DialogueTreeView::getCurrentObject(%this,%obj)
{
    return %obj.currentObject;
}
#3
02/12/2003 (7:36 am)
Huh.. I will definitely give that a try. :) I'll let you know if it works.

Thank you much!!
- Tra'Hari
#4
02/12/2003 (10:12 am)
Sadly, it did not work. As a matter of fact, the function never runs.

However, the information you provided me with was useful for future reference. I wonder if what you're talking about applies to the distinction between this syntax:
// the type is just an example
new ScriptObject( MyObject)
{
class = MyClass;
// stuff
};
...and this syntax:
%objectVar = new ScriptObject( AnotherObject)
{
class = AnotherClass;
// stuff
};

I'll test this in a minute to see if I'm totally off my nut, but maybe your suggestion applies in the latter case? There does appear to be an important distinction between %objectVar and AnotherObject, as AnotherObject is what it gets called in the hierarchy, regardless of what you put in for the "class" field.

One thing that came up in my research of GuiTreeViewCtrl was that if you tell it to open an empty object or variable name, you'll see a hierarchy of a bunch of SimSets, starting with a RootGroup SimGroup with an ID of -1. Kind of bizarre that it defaults to that. :)

For the purposes of nice syntax, I wrap the creation of my Node class (a SimSet class) in a newDialogueNode() function. That way, I can declare the class bits however I want without having to worry about adding the fields every single time. When I use that to create a new class and add it to another Node class via add(), there are _two_ DialogueNodes added to the list. One of them appears wherever it should in the hierarchy, and the other one appears in the list outside of any hierarchy aside from belonging to RootGroup. They have the same ID, though, which is kind of interesting.
#5
02/12/2003 (12:07 pm)
I might be wrong but it seems from looking at your test data that you have attempted to do this in the console...

==>%someThing = DialogueTreeView.getCurrentObject();
==>echo( %someThing);

If you did this in the console this would always return a null value for %someThing as %someThing does not exist.

Variables starting with % are local variables and only "live" for as long as the function is running. As it is not in a function, it dies as soon as it is created.

Try testing with a global variable and you should get predictable results.

eg.
==>$someThing = DialogueTreeView.getCurrentObject();
==>echo( $someThing);


If that still does not work. Try something like..
function DialogueTreeView::bla(%this)
{
    %this.lastSelected = %this.getCurrentObject();
}
This would store the last Selected value in the object which is safer than using a global variable as it is "cleaned up" when the object is destroyed.
#6
02/12/2003 (3:30 pm)
Daniel:
Aha. You know, I thought about that briefly, but I guess it just didn't sink in. Makes sense, though. In any event, you are correct that I was trying to do that at the console, and I thank you for pointing that out.

It doesn't quite solve my current problem, but I'm still working on it so I can't quite articulate where I am at the moment. I'm _trying_ to make everything a member of the DialogueTreeView object just for simplicity's sake, but I'm running into problems with the details. :)
#7
02/12/2003 (11:58 pm)
Not sure where you are going with the getCurrentObject function, seems to me you're creating an unnecessary wrapper around something that you could access easily in an OO method by simply using:

DialogueTreeView.currentObject

So you would be using:

addNode(DialogueTreeView.currentObject);

As for the removeNode problem, I haven't looked yet. But I'd recommend using nameToID instead of trying to compare the %Node to the named DialogueRootNode

function removeNode(%node)
{
	if ( %node $= "")
	{
		// No Node
	}
	else if ( %node == nameToID(DialogueRootNode) )
   {
   	// do nothing
   }
   else
   {   
   	%node.delete();
   }
}


As to the other question about %this = new scriptobject(Test) vs just newscriptobject(test)...

They are functionally identical. Except that with the %this = new scriptobject you do not need to name the object. You can for example use:

%objectVar = new ScriptObject()
{
	class = AnotherClass;
	// stuff
};

This will give you an object that can only be referenced by the %ObjectVar which you must keep track of.
#8
02/13/2003 (8:44 am)
@LabRat:

I use DialogueTreeView.getCurrentObject() because to me, it's cleaner. If public and private were in TorqueScript, I'd be using them. :) So, I'm just going what I do in Python, which also lacks public and private.

As for the rest, that is very interesting. I didn't have to do the nameToID() but I managed to fix the crashing problem somehow. I'm not exactly sure what I did differently from before, except maybe being a little more awake throughout the whole process.

Now I'm just attempting to consolidate my .gui, *Gui.cs, and .cs files in a way similar to the way the Editor does it. It seems to involve some fanciness, so I might just leave it the way it is, but we'll see. If anyone is interested, I'll post whatever solution I come up with, but chances are, I'll be looking at some other people's mods for inspiration. :)

In the meantime, I'd like to thank everyone for their help. I really appreciate it!

- Tra'Hari