Dynamically adding methods from behaviors
by Thomas Petersen · in Torque Game Builder · 05/02/2008 (4:10 am) · 3 replies
I would like to know if there is a 'best practice' when adding a method to a behavior.owner ?
For instance, the fade-behavior defines the function:
I am examining how behaviors can use other behaviors attached to a given object, for instance my button-behavior wants to change visibility to 0 for an object once the button is pressed. However if the object is equipped with a fade-behavior then this fade-behavior should be used instead. This allows for robust and rapid development, where all of the finer details can be added later.
My button behavior also needs to know when the fade behavior is done, so it defines the method: onFadeFinish in the owner of the object, and sets Callback true in the fade behavior.
My current solution is to eval a function-definition, just calling the fade_startFade():
1) is there any way to dynamically define a method on an anonymous object ?
2) it is more robust if the method-definition is resolved at compile time, is there any way of doing something like %object.addMethod(xxx,context); or %obj.method = addMethod(xxx,context) ?
I think that behaviors are a really good tools. but they need to be able to interact more in order for us to be able to build really complex behaviors, and off cause hide all of the implementation-details inside the behavior itself. not requiring some specific method X to be defined on an object but rather defining it itself if nonexistant.
Hope to hear some thoughts !
Regards,
/Thomas
btw. is there any plans that behavior data will be stored in a better format than the current string-in-the-level file ? - This is way to primitive and give all sorts of problems when storing strings &c. - or does anybody have a good workaround for this ?
For instance, the fade-behavior defines the function:
function t2dSceneObject::startFade(%this) {...}which is quite easy to do, but the side-effect is that all other t2dSceneObjects also carry this function around.I am examining how behaviors can use other behaviors attached to a given object, for instance my button-behavior wants to change visibility to 0 for an object once the button is pressed. However if the object is equipped with a fade-behavior then this fade-behavior should be used instead. This allows for robust and rapid development, where all of the finer details can be added later.
My button behavior also needs to know when the fade behavior is done, so it defines the method: onFadeFinish in the owner of the object, and sets Callback true in the fade behavior.
My current solution is to eval a function-definition, just calling the fade_startFade():
// add fade methods to object
%object = %this.owner;
if(%this.owner.getName() $= "") {
abort("Fade objects need to be named (setting member functions)");
}
%cmd = "function "@ %object @"::startFade(%this) { "@" return fade_startFade(%this);}";
echo( %cmd );
eval( %cmd );As the code indicates, there is a problem if the object is not named (things like "function 1761::startFade()" gives a parse error when running), this means that the object needs to have a script-name. I would prefer that the behavior could work just as well on anonymous objects, so my question(s) are:1) is there any way to dynamically define a method on an anonymous object ?
2) it is more robust if the method-definition is resolved at compile time, is there any way of doing something like %object.addMethod(xxx,context); or %obj.method = addMethod(xxx,context) ?
I think that behaviors are a really good tools. but they need to be able to interact more in order for us to be able to build really complex behaviors, and off cause hide all of the implementation-details inside the behavior itself. not requiring some specific method X to be defined on an object but rather defining it itself if nonexistant.
Hope to hear some thoughts !
Regards,
/Thomas
btw. is there any plans that behavior data will be stored in a better format than the current string-in-the-level file ? - This is way to primitive and give all sorts of problems when storing strings &c. - or does anybody have a good workaround for this ?
#2
I *am* using currently using getBehavior() (like the original fade does).
It is just an example, but the reason for not just calling startFade() is that my button behavior has to call setVisible(0) if the fade is not a behavior in the object.
If the console-method %object.dump() should have any meaning at all, then it should only list the methods that is actually added to %object and not x 100 other methods polluted into the namespace. It is hard enough to get around in Torque with the documentation scattered around like it is ;-)
From a design perspective, I think that dynamic function overloading is preferred, but would like to know if there is any other way (safer / at compile time) of defining the methods dynamically.
05/05/2008 (8:01 am)
Thanks for the comments ! It is not as much a parent/child architecture but more like an object oriented architecture I am thinking of. I *am* using currently using getBehavior() (like the original fade does).
It is just an example, but the reason for not just calling startFade() is that my button behavior has to call setVisible(0) if the fade is not a behavior in the object.
If the console-method %object.dump() should have any meaning at all, then it should only list the methods that is actually added to %object and not x 100 other methods polluted into the namespace. It is hard enough to get around in Torque with the documentation scattered around like it is ;-)
From a design perspective, I think that dynamic function overloading is preferred, but would like to know if there is any other way (safer / at compile time) of defining the methods dynamically.
#3
05/05/2008 (2:27 pm)
If you have any other questions, feel free to rephrase/post them!
Associate James Ford
Sickhead Games
Why are you doing an eval at all? Why not just:
Defining and evaulating a function like that ( if done frequently ) is going to be horrible for performance. It seems like adding a method to a namespace dynamically could allow you to do some tricks - but I guess I don't really see why it would ever be "necessary". You could put that method in t2dSceneObject ( as you said ), or put it inside one of the behaviors, or even make it a global ( no namespace ) and just take the object to manipulate as a parameter.
But, ( if you thought otherwise ) this does not equate to any performance problem. Your sceneObjects are not in any way actually "carrying" this method around like baggage -- there is no performance hit to defining 200 methods in the t2dSceneObject namespace.
It sounds a bit like you want a parent/child architecture that allows behaviors on an object to override one another's methods? But then what order would they be overridden in? I guess you would have to pay special attention to the order you add behaviors in - or the ability to define your behaviors in a heirarchy so the way they override one another is clearly defined.
Actually, if you call a method on an object, and that method is actually defined inside a behavior attached to that object -- and there is more than one behavior WITH that method -- overriding may already occur. I'm curious what happens in this case.