[Resolved] Sifting through engine code

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Shizuka-Konmei
Posts: 11
Joined: Tue Feb 02, 2010 1:03 am

[Resolved] Sifting through engine code

Post by Shizuka-Konmei »

Ok, so I've been sifting through engine code in an attempt to learn something for a project I'm starting. The curiosity I have starts with being unable to create an instance of ITexture. I know why, of course, so I tried to dig to find a subclass that can be instantiated and potentially used, should I want to go through that trouble (which, really, I don't).

In sifting through Irrlicht's code, I found COpenGLTexture.h. I figured I should be able to create an instance of it, but I can't. I'm sure the answer is simple enough, but why not? How is the engine setup so that this class is hidden from the programmer? I can't even find other files that include the header other than COpenGLDriver.h, which pretty much deadends, as well.

Simple example:

Code: Select all

#include <irrlicht.h>

int main()
{
   COpenGLTexture texture( proper params );

   return 0;
}
Last edited by Shizuka-Konmei on Sun Feb 07, 2010 7:51 pm, edited 1 time in total.
DavidJE13
Posts: 165
Joined: Tue Jan 09, 2007 7:17 pm

Post by DavidJE13 »

it's set up this way intentionally. Any class which begins I is virtual and cannot be created. Sometimes the sub-classes are available, such as with scene nodes, but often they are hidden in the engine, such as ITimer, ITexture, etc. This is to prevent you creating a texture object (or whatever else) by any means other than through IVideoDriver's functions, because a texture created any other way would not work.
randomMesh has pointed you to the correct functions. I'll also point out this one;
http://irrlicht.sourceforge.net/docu/cl ... 054b0b8797
which is also quite a useful way to get a texture, though for more advanced uses.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Re: Sifting through engine code

Post by Acki »

Shizuka-Konmei wrote:How is the engine setup so that this class is hidden from the programmer?
Irrlicht classes are build with an interface structure...
that means a class is build out of 3 files...

example:
ITexture.h the interface (the user will see)
it declares an abstract class with only public members...

CTexture.h and CTexture.cpp the code (hidden from user)
it inherits from ITexture and declares and defines the class and it's code...

if you want to create an instance of the class you'll need to have access to the code files (CTexture.h) and all source files that are needed by this class..
then you create it like this:

Code: Select all

ITexture* txt = new CTexture(proper params);
txt->drop();
if you don't have access to the source files you'll need to get access to them somehow... ;)
Shizuka-Konmei wrote:I can't even find other files that include the header other than COpenGLDriver.h
but all files that are including COpenGLDriver.h are also including the files that COpenGLDriver.h includes... :lol:
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Shizuka-Konmei
Posts: 11
Joined: Tue Feb 02, 2010 1:03 am

Post by Shizuka-Konmei »

I think my question was misunderstood, except possibly by Acki.

I know why it is setup this way. I also know why instances of ITexture can not be made. I'm not trying to get a texture or add a new one, as I already know how. I'm more interested in how it was designed this way...what exactly the hierarchy is. How are the actual subclasses hidden from the user, but not from the engine itself? It's not in the documentation. In fact, the documentation only documents the various interfaces and not the underlying structure.

Basically, I can't trace a route from the abstracted interface down to the implemented subclass used when running the engine. (i.e. What route is taken to create a COpenGLTexture so that it can be stored in an ITexture pointer and so that its functions can be called?)

It's alright if I can't figure it out for now. It turns out that I don't need to know for what I'm doing. I'm simply curious at this point.
DavidJE13
Posts: 165
Joined: Tue Jan 09, 2007 7:17 pm

Post by DavidJE13 »

ok, well it's not too difficult to do. I'm not sure if this is how irrlicht does it but I think it is.
edit: I may have misunderstood you again. Are you asking how to do this yourself or what the specifics of the inheritance in Irrlicht is? If the latter I can't help with that.

Setup (you already know this bit I guess);
Create IWhatever.h. Prototype all the methods of Whatever that you want to be accessible to the programmer there.
Create CWhatever.h. Tell it to include IWhatever.h and sub-class IWhatever. Prototype all the methods of Whatever that you want *your* code to have access to, and all the internal variables, etc.
Create CWhatever.cpp. Add all the code to do both the public and private stuff, include CWhatever.h.

now the bit you want to know;

In your code's cpp files (all of them which use CWhatever's internal functions or create it), include "CWhatever.h"
In the project, set IWhatever.h to be included as a header file in the built library, but not CWhatever.h. In other words, don't give the user CWhatever.h to include. All the internal functions will still have compiled with it but the programmer cannot add it themself. Just be sure that no function ever tries to return a CWhatever; always an IWhatever
If the programmer does add CWhatever.h, they'll get a bunch of compile errors.

In some cases you could do without CWhatever.h and CWhatever.cpp and just put all the code for CWhatever in the cpp of another object. Then only that object will be able to use it, and you don't even need to think about preventing the user adding the header file, because it doesn't exist. This isn't ideal for most uses because you usually want to be able to use the internal class in many objects.
Shizuka-Konmei
Posts: 11
Joined: Tue Feb 02, 2010 1:03 am

Post by Shizuka-Konmei »

That is precisely the information I was looking for! I didn't really need to know the specifics of irrlicht. I just wanted to understand how it's done, in general.

The singleton concept and the bit you mentioned in your final paragraph are the methods of preventing instantiations of a class that I already knew.

I didn't know you could exclude a header file when building a library project. Wouldn't that give some compile errors? I'd like to play around with it and see if I can get it to work. I'm guessing it's more complicated than it sounds, but I'm sure I'd be able to find a use for it in the future.

Thank you very much. Now I just need to research a bit more. :)
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

No headers are excluded from the engine code, because inheritance needs full class definitions. But the other way round is possible. The implementations are hidden inside the engine, and the linker even forbids access to the internal data on many platforms. That way, you can only access those parts which are available through the interfaces. You cannot extend the engine by inheritance, though, as you only have access to the interfaces. This is not special to Irrlicht, though, it's just plain OO technique and ver much abstraction/data hiding.
Shizuka-Konmei
Posts: 11
Joined: Tue Feb 02, 2010 1:03 am

Post by Shizuka-Konmei »

That maybe so, but using the linker to prevent access to details to the point where I can't even see subclasses is completely new to me.

Edit: Nevermind. I finally managed to connect everything (well, not completely, but well enough) within the irrlicht source code and it turns out it's something quite simple. This just happens to be my first time looking at so much source code at once that I was over-thinking it.

Everything takes place internally -- inheritance, implementation, etc -- but when compiling the library, the header file that's produced (irrlicht.h) only links to the interfaces, helper/container classes, and the absolute minimum to use the implemented subclasses (which, I think, is simply irrlicht.h itself. I believe it all starts with the createDevice[Ex]() function and the rest is magic).

Something so simple and I missed it completely. *sigh*

Thanks for the help, everyone. In the end, I learned something I already knew, but I most definitely learned other things, too.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yep, that's exactly how it works. There are a few structures in the include directory, which are also accessible without going through the engine. These simply ease the development of custom scene nodes, loaders, or animators, without having too much overhead from the engine. But the main goal for Irrlicht is to provide only a very few ways into the library, and all the rest is available from those entry points.
Shizuka-Konmei
Posts: 11
Joined: Tue Feb 02, 2010 1:03 am

Post by Shizuka-Konmei »

Yeah, I don't know why I got so confused by it. :oops:

At least I got my answer and intend to apply the concept to my own project.
Post Reply