1

I want to reconstruct my small 3d-engine, it is very small so i place all files in only one project. now, i want to reconstruct it with interfaces, so i can disperse different modules to the different projects and build them as a dll. when i do that, i have met a lot of difficulties in the basic design of framework code. I want to design a 'Object Hierarchy' of my small engine, it is realized in the previous work. for example:

Object
Component
SceneComponent
StaticMeshComponent/SkelMeshComponent
D3DSkelComponent 
...

but they are implement directly. now, i want to use interface(pure virtual class), i have design the basic interfaces(for test ):

#include <cstdio>
#include <iostream>
#include <string>
using namespace std;

class IObject
{
public:
    virtual std::string GetName() = 0;
};

class IMesh : public IObject
{
public:
    virtual void Draw() = 0;
};

class IStaticMesh : public IMesh
{
public:    
    virtual void BuildSomeMesh() = 0;
};

class ISkeletalMesh : public IMesh
{
public:
    virtual void PlayAnim( const std::string& strAnimName ) = 0;
};

class ID3DSkeletalMesh : public ISkeletalMesh
{
public:
    virtual void LoadD3D( const std::string& strD3D ) = 0;
};

it looks like ok, but when i try to implement them, i find that it may be a impossible mission. first, i can write a template class or normal class for IObject, eg:

template < typename TBase >
class TObject : public TBase
{
public:
    virtual std::string GetName()
    {
        return m_strTest;
    }

    std::string m_strTest;
};

based on this TObject, I can implement a CMesh:

class CMesh : public TObject< IMesh >
{
public:
    virtual void Draw()
    {
        cout<<"draw mesh" <<endl;
    }
};
   IMesh* pMesh = new CMesh();  // ok
   IObject* pObj = pMesh;      // ok

so far, it works well. but how to implement the CStaticMesh/CSkeletalMesh/CD3DSkeletalMesh? it maybe like this:

class CStaticMesh : public CMesh, public IStaticMesh
{
public:

};

but i have two IObject base class, so i must change all "public xxx" to "virtual public xxx", it looks bad. another question is CStaticMesh must implement all virtual member function of IStaticMesh, include:

virtual void Draw() = 0;
virtual void BuildSomeMesh() = 0;

even if there is a Draw in CMesh which is a base call of CStaticMesh. ok, maybe i need a TMesh:

template < typename TBase >
class TMesh : public TObject< TBase >
{
public:
    virtual void Draw()
    {
        cout<<"draw mesh" <<endl;
    }
};

and implement CStaticMesh like this:

class CStaticMesh : public TMesh<IStaticMesh>
{
public:
    virtual void BuildSomeMesh()
    {
        cout<<"Build Some Mesh!"<<endl;
    }
};

it looks like ok, but how to implment CD3DSkeletalMesh? make a TSkeletalMesh? ok, it is crazy!!!

i think, this is abime. which is the mistake in this design? how to change the design idea to avoid this dilemma? do you know a idea which can keep the inheritance hierarchy of those interfaces and implement easily? if i use many virtual inheritance, is there any performance isuue?

sampson-chen
  • 45,805
  • 12
  • 84
  • 81
boo
  • 493
  • 6
  • 17

1 Answers1

0

You can solve this, as you mentioned, with virtual inheritance. This will create only one instance of a multiply inherited interface class in the hierarchy.

First the interfaces:

class IObject
{
public:
    virtual std::string GetName() = 0;
};

class IMesh : virtual public IObject
{
public:
    virtual void Draw() = 0;
};

class IStaticMesh : virtual public IMesh
{
public:    
    virtual void BuildSomeMesh() = 0;
};

class ISkeletalMesh : virtual public IMesh
{
public:
    virtual void PlayAnim( const std::string& strAnimName ) = 0;
};

class ID3DSkeletalMesh : virtual public ISkeletalMesh
{
public:
    virtual void LoadD3D( const std::string& strD3D ) = 0;
};

Then the implementations:

class CObject : virtual public IObject
{
public:
    std::string GetName()
    {
        return m_strTest;
    }

    std::string m_strTest;
};

class CMesh : public CObject, virtual public IMesh
{
public:
    void Draw()
    {
        cout<<"draw mesh" <<endl;
    }
};

class CStaticMesh : public CMesh, virtual public IStaticMesh
{
public:
    void BuildSomeMesh()
    {
        cout<<"Build Some Mesh!"<<endl;
    }    
};
...

For the performance implications of this, look at this question.

Community
  • 1
  • 1
Jordão
  • 55,340
  • 13
  • 112
  • 144