445,804 Members | 1,634 Online
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,804 IT Pros & Developers. It's quick & easy.

# Beginning design patterns

 P: n/a whew. This must be my tenth post or so just this week - thank you to everyone who took the time to answer my questions! Now, I'm helping a friend with an OpenGL application and we need some help in figuring out a design pattern. Here's the deal: Each frame we draw lots of "3DObjects" and if they implement "Actor" they should also think (ie call Think(), or whatever). So, we tought of using RTTI to check wheter it's an object that is also an Actor - but thats complicated and a bit too slow. There is probably a very simple solution to this, but I'm all out of ideas (or *cough* knowledge...) -- Pelle Jul 23 '05 #1
6 Replies

 P: n/a Pelle Beckman wrote: Each frame we draw lots of "3DObjects" and if they implement "Actor" they should also think (ie call Think(), or whatever). So, we tought of using RTTI to check wheter it's an object that is also an Actor - but thats complicated and a bit too slow. Give everything a Brain *, and set them all to NULL. Point some Actors' Brain pointers to a real Brain object. At draw time, test the Brain * and if it's not NULL call its Think(). (If I only had a ...) -- Phlip http://industrialxp.org/community/bi...UserInterfaces Jul 23 '05 #2

 P: n/a "Pelle Beckman" wrote in message news:ANR6e.807\$184.543@amstwist00... | whew. This must be my tenth post or so just this | week - thank you to everyone who took the time | to answer my questions! | | Now, I'm helping a friend with an OpenGL application | and we need some help in figuring out a design pattern. | Here's the deal: | | Each frame we draw lots of "3DObjects" and | if they implement "Actor" they should also | think (ie call Think(), or whatever). | So, we tought of using RTTI to check | wheter it's an object that is also an Actor - | but thats complicated and a bit too slow. | | There is probably a very simple solution to | this, but I'm all out of ideas (or *cough* knowledge...) | | -- Pelle Isn't this typically work for inherritance and polymorphism? class Player { public: virtual void do_it() = 0; }; class HumanPlayer : public Player { public: virtual void do_it() { //Process result. } }; class NPC : public Player { public: virtual void do_it() { think_first(); //Process result. } private: void think_first() { //Use smart engine. } }; Jul 23 '05 #3

 P: n/a Pelle Beckman wrote: whew. This must be my tenth post or so just this week - thank you to everyone who took the time to answer my questions! Now, I'm helping a friend with an OpenGL application and we need some help in figuring out a design pattern. Here's the deal: Each frame we draw lots of "3DObjects" and if they implement "Actor" they should also think (ie call Think(), or whatever). So, we tought of using RTTI to check wheter it's an object that is also an Actor - but thats complicated and a bit too slow. There is probably a very simple solution to this, but I'm all out of ideas (or *cough* knowledge...) One obvious way: struct Actor { virtual void Think() = 0; virtual ~Actor() {} }; struct real_Actor : public Actor { virtual void Think() { // do thinking. } }; struct stupid_Actor : public Actor { virtual void Think() { return; } }; Then create the real actors as (of course) real_actors, and the ones you now have as non-actors as stupid_actors. All of them can respond to being told to think, but if it's a stupid_actor, its attempt at thinking does nothing. If you want to fix the terminology, you might want to change the name to something saying it's supposed to try to think. I should caution against trying to draw too close of a real-world analogy to what's done in programs. Based on the movies I've seen recently, it would appear that real-world actors bear a much closer resemblance to stupid_actor than to real_actor! :-) -- Later, Jerry. The universe is a figment of its own imagination. Jul 23 '05 #4

 P: n/a Pelle Beckman wrote: whew. This must be my tenth post or so just this week - thank you to everyone who took the time to answer my questions! Now, I'm helping a friend with an OpenGL application and we need some help in figuring out a design pattern. Here's the deal: Each frame we draw lots of "3DObjects" and if they implement "Actor" they should also think (ie call Think(), or whatever). So, we tought of using RTTI to check wheter it's an object that is also an Actor - but thats complicated and a bit too slow. There is probably a very simple solution to this, but I'm all out of ideas (or *cough* knowledge...) -- Pelle Yes, there is an elegant solution to this described in "Game Programming Gems pt. 2". It sort of works like Microsoft's COM and is realized using type trait interfaces. You let each of your classes which you want to perform some action on (like your 3DObject) inherit from an ABC Object, which provides a method to query which operations it supports: class Object { public: enum InterfaceType { RENDERABLE, PLAYABLE, WHATEVER-ABLE }; virtual bool QueryInterface(InterfaceType, void**) = 0; }; Now all child classes have to implement this function, like this: class 3DObject: public Object, public Renderable { public: void render(); // ... }; bool 3DObject::QueryInterface( InterfaceType type, void ** pObject ) { bool bSucceeded = false; if( type == RENDERABLE ) { *pObject = dynamic_cast(this); assert( *pObject != 0 ); bSucceeded = true; } return bSucceeded; } In your code, you can now use these objects like this: // be objects a list of all kinds of ObjectS, and you now want to call a // render() method on all those objects in the list, which implement the // Renderable() interface: // (loop through list, be obj the current object) //... Renderable *pRenderable = 0; if( obj->QueryInterface( Object::RENDERABLE, &pRenderable ) ) pRenderable->render(); // ... In this loop all renderable objects will call render(), cool eh? Hope that helps. -- Matthias Kaeppler Jul 23 '05 #5

 P: n/a "Pelle Beckman" wrote in message news:ANR6e.807\$184.543@amstwist00... whew. This must be my tenth post or so just this week - thank you to everyone who took the time to answer my questions! Now, I'm helping a friend with an OpenGL application and we need some help in figuring out a design pattern. Here's the deal: Each frame we draw lots of "3DObjects" and if they implement "Actor" they should also think (ie call Think(), or whatever). So, we tought of using RTTI to check wheter it's an object that is also an Actor - but thats complicated and a bit too slow. There is probably a very simple solution to this, but I'm all out of ideas (or *cough* knowledge...) -- Pelle If you look at the composite pattern: class Composite; class Component { public: virtual Composite* GetComposite() {return 0; }; }; class Composite : public Component { public: virtual Composite* GetComposite() {return this; }; }; it has as GetComposite() function... You can use this same technique for multiple functions.. If you make an interface class with all the "objects" you can query... Let them own or aquire their pointers.. Jesper Madsen, SAXOTECH Jul 23 '05 #6

 P: n/a Matthias Kaeppler skrev: Pelle Beckman wrote: whew. This must be my tenth post or so just this week - thank you to everyone who took the time to answer my questions! Now, I'm helping a friend with an OpenGL application and we need some help in figuring out a design pattern. Here's the deal: Each frame we draw lots of "3DObjects" and if they implement "Actor" they should also think (ie call Think(), or whatever). So, we tought of using RTTI to check wheter it's an object that is also an Actor - but thats complicated and a bit too slow. There is probably a very simple solution to this, but I'm all out of ideas (or *cough* knowledge...) -- Pelle Yes, there is an elegant solution to this described in "Game Programming Gems pt. 2". It sort of works like Microsoft's COM and is realized using type trait interfaces. You let each of your classes which you want to perform some action on (like your 3DObject) inherit from an ABC Object, which provides a method to query which operations it supports: class Object { public: enum InterfaceType { RENDERABLE, PLAYABLE, WHATEVER-ABLE }; virtual bool QueryInterface(InterfaceType, void**) = 0; }; Now all child classes have to implement this function, like this: class 3DObject: public Object, public Renderable { public: void render(); // ... }; bool 3DObject::QueryInterface( InterfaceType type, void ** pObject ) { bool bSucceeded = false; if( type == RENDERABLE ) { *pObject = dynamic_cast(this); assert( *pObject != 0 ); bSucceeded = true; } return bSucceeded; } In your code, you can now use these objects like this: // be objects a list of all kinds of ObjectS, and you now want to call a // render() method on all those objects in the list, which implement the // Renderable() interface: // (loop through list, be obj the current object) //... Renderable *pRenderable = 0; if( obj->QueryInterface( Object::RENDERABLE, &pRenderable ) ) pRenderable->render(); // ... In this loop all renderable objects will call render(), cool eh? Hope that helps. Sounds very good to me Matthias, but how would you say the class "Renderable" would look like? -- Pelle Jul 23 '05 #7

### This discussion thread is closed

Replies have been disabled for this discussion.