Would an UserObject in ISceneNode be a good thing?

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Post Reply

Would it be nice to have a UserObject in ISceneNode?

Yes, great Idea!
5
50%
Don't know what ya talking about!
3
30%
Hell, no! You can do it a better way!
2
20%
 
Total votes: 10

juangamnik
Posts: 8
Joined: Thu Oct 27, 2005 11:28 pm

Would an UserObject in ISceneNode be a good thing?

Post by juangamnik »

Hi there,

I'm used to Java and make my first steps with C++, because I'd like to use this engine. I made a small change to the engine, which might be usefull for everyone. If you think this is a bad idea, please tell me how YOU solve the problem.

In order to have my own code for ISceneNodes and all of its subclasses (e.g. for loading it from XML or for showing an inspector for a editor), without reemplementing ISceneNode and its subclasses, because I don't like to patch the engine every time there's a new version ;), I inserted a pointer to a UserObject in the ISceneNode, which can provide the code.

I am not very familiar with the 'C++ library programming paradigm', so providing methods that create objects like ILightSceneNodes is new and unlikely for me, but I have the problem that this methods keep me from merging ISceneNode with a class of mine (providing my code), because I would either have to write wrappers for the creation methods, in which the two interfaces would be merged, or reemplement all subclasses of ISceneNode. Perhaps I got it wrong all along?!? I think, if I don't want to change the engine I have to do this (wrappers). Now my tradeoff is changing the engine only in a very tiny part (adding the pointer and getter and setter method), so that I easily can update to a new version.

If I'm right this might be a common problem, so Nicolaus Gebhard might add a UserObject to the ISceneNode "interface" in the next release?!?

It would be very nice, if someone will discuss this issue with me ;)!

wfg,
Jonny.
You can divide men into 10 different groups. Peoble either think binary or not. ;)
Pardon my English. Corrections are welcome.
Alberto Rubinato
Posts: 7
Joined: Fri Dec 09, 2005 9:41 pm
Location: Italy

Post by Alberto Rubinato »

Hi,
I don't know Java, but I think that Java OOP ( object oriented programming ) is equal to C++ capabilities.

I think you should simply cretate a new ISceneNodeSomeWhat class deriving it from ISceneNode in this way:

#include "ISceneNode"

class ISceneNodeSomeWhat : ISceneNode
{
......
}

In this way you can overrides member functions of base ISceneNode class with your own or inherites that functions and add other stuff. You can also add your UserObject and other member functions or variables to this new class. You can use it with other standard ISceneNode or ISceneNode derivated classes.

Try to watch for example IBillboardSceneNode class in Irrlicht doc or source code. It derives from standard base ISceneNode class, but it is different in some things.

But if you want to add your base stuff also to all standard derived ISceneNode classes ( such as IBillboardSceneNode, and so on ) I think this is not the way to go. If you don't want to apply a patch any time Irrlicht will released, you could make in this way:

- Create your own class ( UserObject ) with the functions, variables and other things that you would to add to base standard ISceneNode class.
- Create a set of classes that derives from the standard classes and at the same time from your UserObject class. For example:

class IMyBillboardSceneNode : public IBillboardSceneNode, UserObject
{
.........
}

In theese classes specify only constructor or what you want to overrides from standard class.

In this way you must write a new class for each standard you want to modify.

It is not speedy to obtain this ( compared with your solution ), but when you have done you are okay for the future. If Niko will add new ISceneNode specific class you will simply implement it with your own.

I hope this useful to you

Alberto
etcaptor
Posts: 871
Joined: Fri Apr 09, 2004 10:32 pm
Location: Valhalla
Contact:

Post by etcaptor »

ISceneNode is not the best root class which can provide user object with properties. You will not able to get properties for many instances like meshes, animators, gui and others. By me if this goal is important the more advanced method is using of irr::IUnknown.
ImageImage
Site development -Rock and metal online
--- etcaptor.com ------freenetlife.com
juangamnik
Posts: 8
Joined: Thu Oct 27, 2005 11:28 pm

Post by juangamnik »

@etcaptor: You might be right, IUnknown seems to be a better place for a UserObject. But if you use the UserObject for different cases (like ISceneNode gui, and so on) the userobject has to implement different interfaces and that leads us to using either a template type for the UserObject or making the class UserObject a very abstract class itself so that every type can have its own user object. The latter solution has the fallback, we need to cast to our object which might be error prone. The first solution has a problem, too. Using a template type seems to be a more deep intervention in the engine, so it should be in the engine by default not inserted by me every time.

@Alberto Rubinato: Perhaps you misunderstood me a little bit ;). My english is not as good as it should be... I know that C++ has more or less the same oop capabilities like java and with multiple inheritance even more, but dynamic librarys are function libraries in first case, so they are written differently than Java librarys, which are pure object libraries. I think the create...() methods are used in order to be compatible to non oo languages, which might be binded to Irrlicht, but this is only a guess ;). So deriving all types wouldn't help, because I would still get the ISceneNode object from any method in the engine, so methods I have added won't be visible for me. Sure I might change the existing methods (override them), but that wouldn't enhance the interface. I would like to add methods like: getPropertyEditor() or so for my Editor. Using your solution I would have to make an Interface like IEditor and cast my ISceneNode Object to this object every time. That is not so good programming style, isn't it? Perhaps some programming patterns are different for C++, so if I'm wrong please tell me ;).

@all: It would be great to have more discussion, especially other workarounds you have made would be interresting!!!

Thank you very much,
greets,
Jonny.
You can divide men into 10 different groups. Peoble either think binary or not. ;)
Pardon my English. Corrections are welcome.
juangamnik
Posts: 8
Joined: Thu Oct 27, 2005 11:28 pm

Post by juangamnik »

Hey etcaptor I followed the link in your signature. I'll try out your editor. How did you manage my problem? Is your project open source? What's the licence for using it? I'm writing an editor, too. It's the warming up project for my game ;), in order to learn C++.

mfg,
Jonny
You can divide men into 10 different groups. Peoble either think binary or not. ;)
Pardon my English. Corrections are welcome.
etcaptor
Posts: 871
Joined: Fri Apr 09, 2004 10:32 pm
Location: Valhalla
Contact:

Post by etcaptor »

It's freeware, but closed source. I use Borland C++Builder and there are some specifically types and methods. By me my property system is not universal. It's not possible to use it outside from this application. I just started to write any improvements.
By me in C++ you can't avoid casting of types, when you create any property list. It's impossible. OK, let's see some variants of this task. For example if you use C++Builder you can use their property system like:
example

Code: Select all


class PropertyExample : public TObject{

private:
		int Fx,Fy;
		float Fcells[100][100];
	protected:
		__fastcall int  readX()          { return(Fx); }
		__fastcall void writeX(int newFx) { Fx = newFx;  }
		__fastcall double computeZ() {
				// Do some computation and return a floating point value...
				return(0.0);
		}


		__fastcall float cellValue(int row, int col) { return(Fcells[row][col]); }
	public:
    PropertyExample()
    {
     Fx = 666;
    }

    __published:

        __property int    prX = { read=readX, write=writeX };
		__property int    Y = { read=Fy };
		__property double Z = { read=computeZ };
		__property float Cells[int row][int col] = { read=cellValue };


};

Code: Select all

void TestFunction()
{
  PropertyExample * myPropertyExample = new PropertyExample();
  derivedPropertyExample * myderivedPropertyExample = new derivedPropertyExample();

TTypeKinds TypeKinds; 


   TTypeInfo *ptypeinfo=(TTypeInfo *)myderivedPropertyExample->ClassInfo();

   int Count=(GetTypeData(ptypeinfo))->PropCount;


   PPropList PropList=(PPropList)new Pointer[Count];


   TypeKinds<<tkInteger<<tkString<<tkLString<<tkEnumeration<<tkClass;//...

   int Count2=GetPropList(ptypeinfo,TypeKinds, PropList);


   ListBox1->Clear();
   for(int i=0; i < Count2; i++)
   {

     ListBox1->Items->Add(PropList[i]->Name);
     ShowMessage((*(PropList[i]->PropType))->Kind);
     ShowMessage((*(PropList[i]->PropType))->Name);
      if((*(PropList[i]->PropType))->Kind ==7)//class
        PropList[i]->GetProc;

     if((*(PropList[i]->PropType))->Kind ==1)//int
     {
        int a = (int)PropList[i]->GetProc;
        ShowMessage(a);
     }

     ShowMessage(GetOrdProp(myderivedPropertyExample, "prM"));
     PropertyExample* prObj = (PropertyExample*)GetObjectPropClass(myderivedPropertyExample,"prObj");
     prObj->prX = 69;
     ShowMessage(prObj->prX);

   }

}

You can see that here also any cast is needed. Also if you use their property system you must to derive all your classes from TObject - base class.
Similar are things with MS property system but I'm not familiar with it. In both casses /Borland or Microsoft/ you are forced to use or TObject or MS Common Object Model /COM/

Another variant is writing of compiler and IDE independent property template class like:

template<class Container, class ValueType, int nPropType>

class PropTest;
Property<PropTest,std::tring,READ_WRITE> MyProperty1;
Property<PropTest,int,READ_WRITE> MyProperty2;

With this method you will be able to add properties even outside of any class. Seems easy, flexible,...but... We want any property list for each instance of any class. But in this case each property is from different type. Try typeid for testing. So, for collecting of propertyes we can use or any heterogeneous container /not implemented in C++/ or any list with void objects. In both cases any typecast is needed when properties are extracted from container.

My opinion is that property class must be independent from compiler and IDE, therefore will choice second /template/ method with container /list/ to void values. Yes, any enumeration for property types is compulsory.

I don't know many about Niko's plans, but he was planned Scene serialization for Irrlicht and I suppose that he will implement any property system for Irrlicht, but I can mistake. I know that if you have property system you can very easy to save each instance of any class. So, if Niko is planned this our efforts can be for nothing, because he is master in C++ and will able to implement this with better issue.
ImageImage
Site development -Rock and metal online
--- etcaptor.com ------freenetlife.com
Guest

Post by Guest »

Code: Select all

class GameObject
{
   private:
      ISceneNode* node;
};
juangamnik
Posts: 8
Joined: Thu Oct 27, 2005 11:28 pm

Post by juangamnik »

@Guest: If you call the method getSceneNodeFromCameraBB ( ... ), you'll get a Pointer to ISceneNode. Where do you get the corresponding GameObject???

fg,
Jonny.
You can divide men into 10 different groups. Peoble either think binary or not. ;)
Pardon my English. Corrections are welcome.
Post Reply