Game Developer working on my own engine framework.

Report RSS JBEngine: Entity Component System and Messaging

Posted by on

So after a long while fighting with templates I have finally got a decent implementation of the ECS. I now have Systems, Components and Component Pools.

There is a Component Pool for each component and that holds every single component of that type.

Each System keeps track of each of the entities that is registered for it and then on update the system loops through all the entities getting the components that it needs for that entity and performing the actions on it.

This new way of doing things, having systems work on their own will give me the opportunity to add thread pools once that is necessary. This will allow me to use worker threads for sections of entities registered for the system.

So that is the general usage of the Systems and Components. The next part I will talk about is messaging, this has been a very tricky part of the Entity System.

I have again used CRTP to accomplish this, and I believe allowing a system to register for messages is easier than ever now.

The Messaging system is technically something completely seperate from the Entity System/Component architecture and because of this it is not just Systems that can listen for messages.

Okay so how does it work?

So the Message class is where the CRTP occurs, each derived message type will supply itself as the template parameter for the base class:

class DerivedMessage : public Message<DerivedMessage>
{
public: 
   DerivedMessage(); 
   virtual ~DerivedMessage(){};
};

This allows for much easier dispatch of the messages now to show how to make a class receive messages:

first of all you have to derive the class that will listen to the messages from the MessageListener class supplying the message you will be using:

template < class MessageType > 
class MessageListener 
{
public:
   virtual void HandleMessage(MessageType* message) = 0;
};

class MovementSystem : public System<MovementSystem>, 
                       public MessageListener<MovementMessage>, 
                       public MessageListener<RotationMessage> 
{
public:
   MovementSystem(MessageManager* msgManager);
   virtual void Update(); 
   virtual ~MovementSystem(void);
   void HandleMessage(MovementMessage*message); 
   void HandleMessage(RotationMessage* message); 
   virtual void RegisterMessages(); 
};

The next step is merely to register to receive the messages of a certain type in the RegisterMessages function. This is called just after creation of any System.

void MovementSystem::RegisterMessages() 
{
   mMessageManager->RegisterListener<MovementMessage>(this);
   mMessageManager->RegisterListener<RotationMessage>(this);
}

and then of course all that is left is to handle the messages with each of the HandleMessage functions.

Finally this is a little demo program that shows the use of the ECS and messaging:

int _tmain(int argc, _TCHAR* argv[]) 
{
   MessageManager messManager; 
   EntityManager manager(&amp;messManager);
   Entity* newEnt = manager.CreateEntity( string( "MyFirstEntity" ) );
   newEnt->AddComponent<PositionComponent>( newEnt ); 
   newEnt->AddComponent<VelocityComponent>( newEnt ); 
   newEnt->AddSystem<MovementSystem>(); 
   messManager.SendMessage<MovementMessage>( 40.0f, 0.2f, 0.0f );
   messManager.SendMessage<RotationdMessage>( 20.0f, 0.0f, 0.0f ); 
   return 0;
}

I have used variadic templates throughout to make creating Messages and Components really simple.

So I believe this is a fairly flexible approach, there are probably a few more things that I could do to make this better but for now I am going to leave it as it is and try and re-implement all the functionality that is in my previous version of the ECS. Once this is all integrated back into my Engine then I will run some tests and see if there is need for any more changes.

All is going well after a lot of frustrating times with templates. There are still some things that need tidying up to ensure the system is a little more robust but I am very happy with the progress.

Thanks

Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: