Sign in to follow this  
AsOne

What design pattern am I looking for?

Recommended Posts

Hey everyone, I'm in the beginnings of writing a game engine, and have come across (yet another) design problem. I'm just not sure what I should be doing. I'll try to explain as best as possible. OK my main goal is to have the engine very extensible, almost every class should be able to be used as a base class, therefore it should be easy for others to write their own scene manager classes, physics manager class, resource manager class, etc., with as little code as possible. So my problem revolves around writing extensible code for manager classes and node classes (objects which managers will 'hold'), but also writing maintainable code. I'll give an example, otherwise it will be difficult to explain. In this example I have a scene manager + interface, and a physics manager + interface, both interface objects need to be able to 'release' themselves from their managers, however when the object is released it is not deleted, because objects are reference counted. Here is some sample code:
class ISceneManager;

class ISceneObject : public IMMObject // memory managed object
{
  ISceneManager *const mManager;
  // ...
public:
  ISceneObject(ISceneManager *const manager, // other param's)
  virtual void releaseSceneManager(); // call mManager->removeSceneObject(this);
  // ...
};

class ISceneManager
{
  std::list<ISceneObject*> mObjects;
  // ...
public:
  virtual ~ISceneManager(); // this will remove all objects but not delete them
  virtual void addSceneObject(ISceneObject *const object);
  virtual void removeSceneObject(ISceneObject *const object);
  virtual ISceneObject *createObject(// will create object and pass 'this')
  // ...
};

// the phsyics object and manager i will assume to be the same as the scene
// for the sake of this example.

// now say i have this class
class IGameObject : public ISceneObject, public IPhysicsObject
{
  public:
  virtual void releaseSceneObject();
  virtual void releasePhsyicsObject();
  // ...
};



As I have found out, it gets very annoying to have all these 'releaseXXXObject', especially when a class uses five different interfaces. Also it is annoying to write manager classes over and over again because they all contain certain components that are common to all of them. I have though about doing this ...
template <typename T> class TManager
{
  std::list<T> mObjects;
public:
  virtual ~TManager();
  virtual void add(T const object);
  virtual void remove T const object);
};

class SceneManager : public TManager<ISceneObject>
{
// ...
};



However I am still stuck with terrible release function calls. Should I be using function pointers somehow here? I know there has got to be a way to accomplish what I want in a more elegant way then I have found to this point (am I trying to hard? Overlooking something obvious?). If there is a design pattern I should be looking into, or you have some suggestions, ideas, it would be greatly appreciated! Thanks. [Edited by - AsOne on July 9, 2005 3:38:18 PM]

Share this post


Link to post
Share on other sites
You are really trying hard to make everything extensible, not an easy problem to tackle.

One idea I got with the manager problem was that you could try doing some smart pointer sollution. That is not use a "raw" object pointer but rather a small object that handles the release when it's destructor is invoked.

Smart pointers are generally a good idea :)

Regards and good luck,
hObbE

Share this post


Link to post
Share on other sites
Why do you need a release method of each base interface?

Why would you ever have an IGameObject, and delete the scene data but retain the physics data? In that case, why not just make a physics object in the first place?

But, if you really want to be able to do that, place the releaseSceneObject method in ISceneObject, and releasePhysicsObject in IPhysicsObject, so that those methods don't have to be redefined over and over (as I don't think they'll be changing).

OR, an even more automated method would be smart pointers. I personally use boost::<ptr type>_ptr classes in my projects. Look at boost.org to find the files to download.

BTW, be careful throwing around the 'I' prefix. Only use in on classes which are true pure interfaces (i.e., implement no functionality or data encapsulation themselves whatsoever). The 'I' prefix is used to signify that the class cannot be instanciated and must be derived from. If it's possible to instantiate an I<insert class name> on the stack, then lose the 'I' prefix.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this