https://github.com/superpuero/kawa_ecs
Lightweight, fast, single-heaeder ecs library written in c++
https://github.com/superpuero/kawa_ecs
blazingly-fast cpp cpp17 cpp20 ecs entity-component-system game game-development game-engine header-only
Last synced: 9 months ago
JSON representation
Lightweight, fast, single-heaeder ecs library written in c++
- Host: GitHub
- URL: https://github.com/superpuero/kawa_ecs
- Owner: superPuero
- Created: 2025-06-21T21:19:59.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2025-06-21T21:55:47.000Z (about 1 year ago)
- Last Synced: 2025-06-21T22:26:51.682Z (about 1 year ago)
- Topics: blazingly-fast, cpp, cpp17, cpp20, ecs, entity-component-system, game, game-development, game-engine, header-only
- Language: C++
- Homepage:
- Size: 21.5 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# kawa::ecs

**kawa::ecs** is a *lightweight, modern and parallel ready* Entity-Component System for modern C++.
It offers a minimal yet powerful API for building games, simulations, and real-time applications with both single-threaded and multi-threaded execution.
---
## Why kawa::ecs?
- **Fast** — cache-friendly storage and minimal indirection
- **Expressive** — functional, intuitive query interface
- **Parallel** — simple thread-pool integration for parallel processing
- **No dependencies** — zero third-party requirements
- **Debug-friendly** — rich runtime assertions
---
## Integration
```bash
cp -r kawa/ ./include/
```
```cpp
#include "kawa/ecs/kwecs.h"
```
- Compile with **C++20**
- Profit!
---
## Quick Start
```cpp
#include "kwecs.h"
#include
#include
struct Position { float x, y; };
struct Velocity { float x, y; };
struct Label { std::string name; };
void update_position(float dt, Position& pos, const Velocity& vel) {
pos.x += vel.x * dt;
pos.y += vel.y * dt;
}
int main() {
using namespace kawa::ecs;
// Create registry
registry reg({
.name = "demo",
.max_entity_count = 255,
});
// Create entities
entity_id e1 = reg.entity(Position{12.4f, 34.6f}, Velocity{2.0f, 3.0f});
entity_id e2 = reg.entity(Position{10, 20}, Velocity{1, 1}, Label{"Ichigo"});
// Query with optional component
reg.query([](Position& pos, Label* label) {
std::cout << (label ? label->name : "unnamed")
<< " is at (" << pos.x << ", " << pos.y << ")\n";
});
// Fall-through parameter
float dt = 0.16f;
reg.query(update_position, dt);
// Parallel query
kawa::thread_pool tp(8);
reg.query_par(tp, [](Position& pos, const Velocity& vel) {
pos.x += vel.x;
pos.y += vel.y;
});
}
```
---
## API Overview
### Entity Management
| Call | Purpose |
|----------------------------------------|-------------------------------------------------------|
| `entity()` | Create a new empty entity |
| `entity(Ts... components)` | Create entity with given components |
| `destroy(id)` | Destroy entity and remove all components |
| `clone(from)` | Clone entity into a new one |
| `clone(from, to)` | Overwrite `to` with `from`’s components |
### Component Management
| Call | Purpose |
|----------------------------------------|-------------------------------------------------------|
| `emplace(id, args…)` | Add component `T` to entity |
| `erase(id)` | Remove one or more components |
| `has(id)` | Check if entity has all listed components |
| `get(id)` / `get_if_has(id)` | Access component (ref / ptr) |
| `copy(from, to)` | Copy specific components |
| `move(from, to)` | Move specific components |
### Querying
| Call | Purpose |
|----------------------------------------|-------------------------------------------------------|
| `query(fn, args…)` | Iterate over matching entities |
| `query_par(tp, fn, args…)` | Same as `query` but parallelized with thread pool |
| `query_with(id, fn, args…)` | Run query on a single entity |
| `query_info(fn)` | Iterate components with metadata for all entities |
| `query_info_with(id, fn)` | Iterate components with metadata for one entity |
### Hooks
| Call | Purpose |
|----------------------------------------|-------------------------------------------------------|
| `on_construct(fn)` | Called when component is added to an entity |
| `on_destroy(fn)` | Called when component is removed from an entity |
---
## Query Semantics
`registry::query` inspects your function parameters and matches entities accordingly.
### Parameter Groups
| Group | Example | Meaning |
|---------------|-------------------------|------------------------------------------------------|
| **Fall-through** | `T`, `T&`, `T*` | Passed in from outside (not from components) |
| **Required** | `Component&` or `const Component&` | Entity must have this to match |
| **Optional** | `Component*` | `nullptr` if the entity lacks this component |
**Order matters:** Fall-through → Components.
Example:
```cpp
reg.query([](float dt, Position& pos, Label* name), 0.16f);
```
---
## Parallel Queries
`query_par` runs queries in parallel using a kawa::thread_pool.
---
> Made with care ❤️ — If you build something cool with **kawa::ecs**, share it!