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!
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.
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)
#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;
}