I'm a gameplay programmer
focused on developing
engaging and unique experiences!

My Resume Learn more

Entity-Component-System (ECS) : A Data-Oriented Gameplay Framework in C++ - Part 2

To get this gameplay framework going, I decided to layout all the interfaces for the entities, components, and systems to get a better understanding of the ECS architecture. These user facing interfaces are based on looking at other ECS implementations and from my experience with Unity and Unreal.

Entity Interface

The Entity Interface looks and acts similar to Unity and Unreal, which is following the component pattern of being able to dynamically add and remove components. They can also be disabled and enabled.

class IEntity 
		{
		public:
			template<class T>
			T* GetComponent() const {}

			template<class T, class ...ARGS>
			T* AddComponent(ARGS&&... args) const {}

			template<class T>
			void RemoveComponent() {}

			inline void SetActive(bool isActive) {}
			inline bool IsActive() const {}

			virtual void OnEnable() {}
			virtual void OnDisable() {}
		};

Component Interface

Components have a much simpler interface as ideally they are just containers of data. They have their own ID and a reference to their owner. Like entities, they can also be disabled and enabled.

class IComponent
		{
		public:
			inline const size_t GetId() const {}
			inline const size_t GetOwner() const {}

			inline void SetActive(bool isActive) {}
			inline bool IsActive() const {}
		}

System Interface

The system is where the core logic on the components is run. So they are where the update loops are defined.

class ISystem
		{
		public:
			virtual void PreUpdate(float deltaTime) = 0;
			virtual void Update(float deltaTime) = 0;
			virtual void PostUpdate(float deltaTime) = 0;
		};

System Dependencies

Something to note about systems is that they are also where dependencies are managed. This is the interface of the system manager where there are update loops, but also functions to add system dependencies such as a collision system depending on a physics system.

class SystemManager
		{
		public:
			template<class T, class... ARGS>
			T* AddSystem(ARGS&&... args) {}

			template<class System_, class Dependency_>
			T* AddSystemDependency(System_ target, Dependency_ dependency){}

			virtual void PreUpdate(float deltaTime) override;
			virtual void Update(float deltaTime) override;
			virtual void PostUpdate(float deltaTime) override;
		};

Event Dispatcher

An unexpected part of my ECS implementation was the necessity for an event dispatcher. While having completely decoupled entities, components, and systems would be ideal, game systems eventually need to be able to communicate with each other. In most of the ECS implementations I've looked through, this was done using an event dispatcher.

class IEventDispatcher
		{
		public:
			virtual void Dispatch(IEvent* event) = 0;
			virtual void AddCallback(IEventDelegate* const eventDelegate) = 0;
			virtual void RemoveCallback(IEventDelegate* eventDelegate) = 0;
		};

No Comments Yet.

Leave a comment