Skip to content

A Simple and Fast Implementation Entity Component Systems Pattern leveraging Sparse Sets and Bit Fields for Efficiency and Performance.

License

Notifications You must be signed in to change notification settings

VigneshGunasekaran96/AtlasECS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 

Repository files navigation

AtlasECS

An Implementation of Entity Component Systems Pattern leveraging Sparse Sets and Bit Fields for Efficiency and Performance.

Features

  • A Simple Entity System and API, where Entities are just integers.
  • Smart and Fast Iterations by Storing Matching Entities in a Sparse set.
  • Safety Measures to avoid adding Duplicate Components to Entities, removing non-existent Components from Entities or destroying Dead entities.
  • Automatic de-allocation of Component Resources on Entity Deletion. This means, No need to worry about Components once added.
  • Filtering allows Inclusion and Exclusion of specific Components, on a Per-System Basis.
  • Components are stored in contiguous Memory for Cache Efficiency.

Usage

Include the Single Header AtlasECS.hpp in your Project. Following is an Example of how to use the Library:

//Include this File
#include "include/AtlasECS.hpp"

#include "TestComponents.h"
#include "TestSystem.h"

#include <iostream>


int main()
{
	// Create an ECS World/Context. There can be Multiple Worlds for Physics, 
	// Rendering, Networking and So on.
	// The Parameter takes the Initial Number of Entities to reserve Memory.
	// Choose a Large Number to avoid Memory Moving Around.
	std::shared_ptr<atlas::CWorld> world = std::make_shared<atlas::CWorld>(1000);
	
	// Systems derive from CSystem and can selectively access 
	// for a Combination of Components.
	CTestSystem testSystem(world);	

	// Entities can be Created using the CreateEntity Function
	// Entity IDs can repeat across Worlds, but is unique within a World.
	Entity e1 = world->CreateEntity();

	// Components can be Added to an Entity using the Following Syntax.
	world->AddComponent<FNameComponent>(e2, std::move(FNameComponent("Entity 1")));

	// Multiple Components can be added with the Same AddComponent Call
	world->AddComponent<FPositionComponent, FRotationComponent>(e2, FPositionComponent(0,0,0), FRotationComponent(30,85,90));

	// Or Entities can be Created with Components, as Shown Below
	Entity e2 = world->CreateEntity<FNameComponent, FPositionComponent, FRotationComponent>
		(FNameComponent("Entity 2"),FPositionComponent(1,1,1), FRotationComponent(0,0,0));

	// A Component can be Removed using the `RemoveComponent` Function
	world->RemoveComponent<FPositionComponent>(e2);

	// Destroying an Entity would destroy all the Components associated with it.
	world->DestroyEntity(e2);
	
	// Query whether the Entity is alive.
	world->IsEntityAlive(e2);

	// Get Components of type would return an Array of the Components of the Passed Type
	// and the Number of **Valid** Components in the Array.
	auto[array, count] = world->GetComponentsOfType<FNameComponent>();

	return 0;
}

And, here is how to setup a System:

#include "AtlasECS.hpp"

class CTestSystem : public atlas::CSystem
{
public:
	CTestSystem(std::shared_ptr<atlas::CWorld> world)
		:CSystem(world)
	{
		// Entities are automatically added and removed from this 
		// System's Group, as Components are added/removed
		// and upon entity Destruction.

		// Only consider Elements with the Following Components
		this->MatchEntitiesWith<FPositionComponent, FRotationComponent>();

		// Discard Entities with atleast one of these Components,
		// even if they have matching Components.
		this->ExcludeEntitiesWithAnyOf<FStaticMeshComponent, FTurretComponent>();
		
		// Discard Entities with all of these Components,
		// even if they have matching Components.
		this->ExcludeEntitiesWithAllOf<FHealthComponent, FNavmeshComponent>();
	}

	void OnUpdate(float dt)
	{
		// GetComponentsOfType returns a Tuple of [T*, count] 
		auto[position_array, pcount] = world->GetComponentsOfType<FPositionComponent>();
		auto[rotation_array, rcount] = world->GetComponentsOfType<FRotationComponent>();

		// All the Matching Entities can be Accessed from
		// the m_MatchingEntities Member of the System
		for(auto itr = m_MatchingEntities.begin(); itr != m_MatchingEntities.end(); ++itr)
		{
			Entity e = *itr;
			
			position_array[e] += vec3(1.0,5.0,10.0) * dt;
			rotation_array[e] += vec3(0.5f, 1.0f, 0.6f) * dt;
		}
	}
};

References

About

A Simple and Fast Implementation Entity Component Systems Pattern leveraging Sparse Sets and Bit Fields for Efficiency and Performance.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages