Skip to content

Latest commit

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Practical Entity Component System

PECS is a practical, powerful, and provocative ECS designed to be easy to use, easy to understand, and FAST! Build PECS into your game and let it do all the heavy lifting for you!

Building

To use PECS in your own project, just update your include paths and #include <pecs.hpp>.

To compile the example, make sure GENie is in your path and then simply run make.

Requirements

Any more-or-less C++11-compatible compiler. May support older compilers in the future, but we like Lambdas and range-based for.

Known good:

  • VS 2013
  • GCC 6.1 (older should be fine)
  • Clang 3.8 (older should be fine)

Example

#include"pecs.hpp"usingnamespacepecs;// Define a bunch of component groupsenum {
COMPONENT_ANY = 0,
COMPONENT_INFO = 1 << 0,
COMPONENT_TRANSFORM = 1 << 1
};
structcomponent_info_t {
std::string name;
};
structcomponent_transform_t {
float position[3];
float scale[3];
float orientation[4];
float direction[3];
};
// Resize components as more entities flood intemplate <typename T>
voidresize(std::vector<T> &components, uint32_t id) {
size_t c = components.capacity();
while (c <= id) {
c = std::max<size_t>(c, 1);
c = c << 1;
}
if (components.size() <= id) {
components.reserve(c);
components.resize(id+1);
}
}
structtest_world_t : world_t {
std::vector<component_info_t> infos;
std::vector<component_transform_t> transforms;
voidset_component(entity_t *entity, component_info_t component) {
entity->mask |= COMPONENT_INFO;
resize(this->infos, entity->id);
this->infos[entity->id] = component;
}
voidset_component(entity_t *entity, component_transform_t component) {
entity->mask |= COMPONENT_TRANSFORM;
resize(this->transforms, entity->id);
this->transforms[entity->id] = component;
}
};
structtest_system_t : system_t {
std::string name;
test_system_t(std::string name) {
this->name = name;
this->priority = 0;
this->mask = COMPONENT_INFO | COMPONENT_TRANSFORM;
}
voidon_add(world_t *world) {
printf("Added system to world!\n");
}
voidon_remove(world_t *world) {
printf("Removed system from world!\n");
}
voidon_add(entity_t *entity) {
printf("Added entity to system!\n");
}
voidon_remove(entity_t *entity) {
printf("Removed entity form system!\n");
}
voidupdate(double dt) {
test_world_t *world = (test_world_t*)this->world;
for (auto &entity : world->entities) {
PECS_SKIP_INVALID_ENTITY;
auto &info = world->infos[entity.id];
printf("%s\n", info.name.c_str());
auto &transform = world->transforms[entity.id];
transform.position[0] += transform.position[1];
(void)info;
(void)transform;
}
}
};
intmain(int argc, char* argv[]) {
// Create new worldtest_world_t world;
// Create new systemtest_system_t a = test_system_t("Test System");
world.add(&a);
// Create new entitiesconstsize_t num_entities = 5;
printf("Adding %ld entities...\n", num_entities);
for (size_t i = 0; i < num_entities; i++) {
entity_t entity = world.get_entity();
world.set_component(&entity,
component_info_t { "I am an entity!" }
);
world.set_component(&entity,
component_transform_t {
{ 5.0, 6.0, 7.0 },
{ 1.0, 1.0, 1.0 },
{ 0.0, 0.0, 0.0, 1.0 },
{ 0.0, 0.0, 1.0 }
}
);
world.add(entity);
}
// Run a few update cyclesfor (int i = 0; i < 10; i++) {
world.update(1.0);
}
return0;
}

About

Practical Entity Component System

Resources

Stars

18 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages