https://github.com/excessive/pecs
Practical Entity Component System
https://github.com/excessive/pecs
Last synced: 3 months ago
JSON representation
Practical Entity Component System
- Host: GitHub
- URL: https://github.com/excessive/pecs
- Owner: excessive
- License: other
- Created: 2016-09-13T20:12:24.000Z (almost 10 years ago)
- Default Branch: master
- Last Pushed: 2019-01-12T05:02:12.000Z (over 7 years ago)
- Last Synced: 2025-07-06T15:07:21.142Z (12 months ago)
- Language: C++
- Homepage:
- Size: 12.7 KB
- Stars: 18
- Watchers: 3
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# 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 `.
To compile the example, make sure [GENie](https://github.com/bkaradzic/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
```cpp
#include "pecs.hpp"
using namespace pecs;
// Define a bunch of component groups
enum {
COMPONENT_ANY = 0,
COMPONENT_INFO = 1 << 0,
COMPONENT_TRANSFORM = 1 << 1
};
struct component_info_t {
std::string name;
};
struct component_transform_t {
float position[3];
float scale[3];
float orientation[4];
float direction[3];
};
// Resize components as more entities flood in
template
void resize(std::vector &components, uint32_t id) {
size_t c = components.capacity();
while (c <= id) {
c = std::max(c, 1);
c = c << 1;
}
if (components.size() <= id) {
components.reserve(c);
components.resize(id+1);
}
}
struct test_world_t : world_t {
std::vector infos;
std::vector transforms;
void set_component(entity_t *entity, component_info_t component) {
entity->mask |= COMPONENT_INFO;
resize(this->infos, entity->id);
this->infos[entity->id] = component;
}
void set_component(entity_t *entity, component_transform_t component) {
entity->mask |= COMPONENT_TRANSFORM;
resize(this->transforms, entity->id);
this->transforms[entity->id] = component;
}
};
struct test_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;
}
void on_add(world_t *world) {
printf("Added system to world!\n");
}
void on_remove(world_t *world) {
printf("Removed system from world!\n");
}
void on_add(entity_t *entity) {
printf("Added entity to system!\n");
}
void on_remove(entity_t *entity) {
printf("Removed entity form system!\n");
}
void update(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;
}
}
};
int main(int argc, char* argv[]) {
// Create new world
test_world_t world;
// Create new system
test_system_t a = test_system_t("Test System");
world.add(&a);
// Create new entities
const size_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 cycles
for (int i = 0; i < 10; i++) {
world.update(1.0);
}
return 0;
}
```