Sign in to follow this  
DrZoidberg

What is this? Can I make it better? (design patterns)

Recommended Posts

hello, finally i have got everything working in a game engine i'm working on (well not everything, it just works adequately), but i always feel the need to better the code, and make it more flexible. i started off on the idea that i would have multiple systems and objects could inherit from interfaces and then be added to those systems and they would be taken care of automatically. firstly the problem: the code is somewhat high maintenance for any new features, and there is little code reuse. I'm looking for a design pattern for what I'm doing, but most that i know of seem overly complicated to what I'm doing, or i cant find a site the explains them in a non-complicated manner. Is what I'm doing an actual design pattern but don't know it? OK, I have 5 differnt managers / systems, each with an interface to go with them and for each interface there is an object which derives from them and defines functions for attaching and detaching itself to the respective system. I had some trouble with class dependencies so the whole thing kinda came out funny. here are are the definitions for the three components of the scene system. sceneI.h (interface for scene objects)
struct ISceneObj {
  virtual void draw(BITMAP*, CVec2d) = 0;
};


sceneObj.h (actual object for scene ... objects)
class CSceneObj : public ISceneObj {
  protected:
    CSceneSys *m_pSceneSys;
  public:
    CSceneObj();
    virtual ~CSceneObj();
    virtual void attachSceneSys(CSceneSys*);
    virtual void detachSceneSys();
    virtual void draw(BITMAP*, CVec2d) = 0;	
};


sceneSys.h (system for managing scene objects)
class CSceneSys : public CSystem {
  private:
    vector < list<ISceneObj*> > m_tree;
    BITMAP *m_bmpBuffer;
    CVec2d m_vCam;
    bool m_bAxis;
    bool m_bGrid;
  public:
    CSceneSys(BITMAP*);
    CSceneSys();
    void update();
    void debug(BITMAP*);
    void addObj(ISceneObj*);
    void removeObj(ISceneObj*);
    void pushLayer();
    void popLayer();
    void moveCam(CVec2d);
    void render();	
};


i should note that CSystem (base class of CSceneSys) defines the update and debug methods, which the main part of the whole thing uses. the only reason there is a ISceneObj is becasue i cant have the CSceneObj header file include the SceneSys header file and then the SceneSys header file include the SceneObj header file. so all i do when i want to add a scene obj is go ... car->attachSceneSys(scene); and its done ... when its deleted it removes itself from the scene system and there are no dead objects when rendering and updating. all the other managing classes work the same. the problem is, is that whenever i create a new 'kind' of object, and a new system to manage it, i need to rewrite the same code over and over again, i'm thinking of rewriting must of the code to use a single node class which will provide everything to attach and detach aswell as a systems class which defines methods for adding and removing objects, then using specific interfaces for the differnt parts of the engine like scene management and event scheduling. however this smells of awkward class depencides which nearly foiled my first plan. what should i be doing in this situation? keep going witth he objects attaching and detaching themselves, and either live with what i got, or try and simplify by using more base classes and possibly templates? or should i go in another direction, and a new design pattern? before i go any further with this project i want to ensure i wont be overencumbered with design problems with which i should of fixed earlier, and that is why im here! :) wow sorry for the lengthy post, thanks to anyone who took the time to read and another thanks to those who reply!

Share this post


Link to post
Share on other sites
Surely go with creating base classes encapsulating all the basic node and manager code. It is the main advantage of OO programming. If you have class dependency problems, try to solve them and not avoid them. It will take more work at first (probably) but pay off tenfold.

As a tip: if you have the node class (CNode) requiring the manager class (CManager) and vice verse, try the following:

In Node.h:

#ifndef _CNODE_H_
#define _CNODE_H_

#include "Manager.h"

...

#endif


In Manager.h:

#ifndef _CNODE_H_
#define _CNODE_H_

// Forward class declaration
class CNode;

...

#endif


In Manager.cpp:

#include "Manager.h"
#include "Node.h"

...

Share this post


Link to post
Share on other sites
I try to explain how I'd do tht if I were in your shoes.

file BaseManager.h

class CBaseManagedObject;

class CBaseManager
{
protected:
CBaseManager() {}; // (you need to derive your own manager classes)

List <CBaseManagedObject * > m_List;

public:
~CBaseManager()
{
// TODO: destroy list m_List (for example)
}
void Attach(CBaseManagedObject * pObj) {List.Add(pObj);}
void Detach(CBaseManagedObject * pObj) {List.Remove(pObj);}
};



file BaseManagedObject.h

class CBaseManagedObject
{
public:
CBaseManagedObject() {}
~CBaseManagedObject() {}

// NOTE: can be even empty (without data members or methods)... in this case is a true interface, so you can even change its name in IBaseManagedObject
};



Now you can derive all your manager from CBaseManager and all your managed object from CBaseManagedObject class/interface without duplicating the same code all the time.
If you don't want to/can't use a base class for all your managed objects, you can use template:

template <class T> class CBaseManager
{
the same as above but with List <T *> m_List.
}

Note that CBaseManager doesn't need to know what is CBaseManagedObject (so you don't need to include BaseManagedObject.h in BaseManager.cpp since it is a reference in name only!).

Hope that's of help. :)

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