The root dir of our repository has grown quite a lot the past few months.
I'd like to make it more clear where the bulk of the engine lives (`src/`) and
also make it more clear which Mach libraries are consumable as standalone projects.
As for the name of this directory, `libs` was my first choice but there's a bit of
a convention of that being external libraries in Zig projects _today_, while these
are libraries maintained as part of Mach in this repository - not external ones.
We will name this directory `libs`, and if we have a need for external libraries
we will use `external` or `deps` for that directory name. I considered other names
such as `components`, `systems`, `modules` (which are bad as they overlap with
major ECS / engine concepts), and it seems likely the official Zig package manager
will break the convention of using a `libs` dir anyway.
Performed via:
```sh
mkdir libs/
git mv freetype libs/
git mv basisu libs/
git mv gamemode libs/
git mv glfw libs/
git mv gpu libs/
git mv gpu-dawn libs/
git mv sysaudio libs/
git mv sysjs libs/
git mv ecs libs/
```
git-subtree-dir: glfw
git-subtree-mainline: 0d5b853443
git-subtree-split: 572d1144f11b353abdb64fff828b25a4f0fbb7ca
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
git mv ecs libs/
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
99 lines
3.4 KiB
Zig
99 lines
3.4 KiB
Zig
//! mach/ecs is an Entity component system implementation.
|
|
//!
|
|
//! ## Design principles:
|
|
//!
|
|
//! * Clean-room implementation (author has not read any other ECS implementation code.)
|
|
//! * Solve the problems ECS solves, in a way that is natural to Zig and leverages Zig comptime.
|
|
//! * Avoid patent infringement upon Unity ECS patent claims.
|
|
//! * Fast. Optimal for CPU caches, multi-threaded, leverage comptime as much as is reasonable.
|
|
//! * Simple. Small API footprint, should be natural and fun - not like you're writing boilerplate.
|
|
//! * Enable other libraries to provide tracing, editors, visualizers, profilers, etc.
|
|
//!
|
|
//! ## Copyright & patent mitigation
|
|
//!
|
|
//! The initial implementation was a clean-room implementation by Stephen Gutekanst without having
|
|
//! read other ECS implementations' code, but with speaking to people familiar with other ECS
|
|
//! implementations. Contributions past the initial implementation may be made by individuals in
|
|
//! non-clean-room settings.
|
|
//!
|
|
//! Critically, this entity component system stores components for a classified archetype using
|
|
//! independent arrays allocated per component as well as hashmaps for sparse component data as an
|
|
//! optimization. This is a novel and fundamentally different process than what is described in
|
|
//! Unity Software Inc's patent US 10,599,560. This is not legal advice.
|
|
//!
|
|
|
|
const std = @import("std");
|
|
const testing = std.testing;
|
|
|
|
pub const EntityID = @import("entities.zig").EntityID;
|
|
pub const Entities = @import("entities.zig").Entities;
|
|
|
|
pub const Module = @import("systems.zig").Module;
|
|
pub const Modules = @import("systems.zig").Modules;
|
|
pub const Messages = @import("systems.zig").Messages;
|
|
pub const MessagesTag = @import("systems.zig").MessagesTag;
|
|
pub const World = @import("systems.zig").World;
|
|
|
|
// TODO:
|
|
// * Iteration
|
|
// * Querying
|
|
// * Multi threading
|
|
// * Multiple entities having one value
|
|
// * Sparse storage?
|
|
|
|
test "inclusion" {
|
|
std.testing.refAllDeclsRecursive(@This());
|
|
}
|
|
|
|
test "example" {
|
|
const allocator = testing.allocator;
|
|
|
|
const PhysicsMsg = Messages(.{
|
|
.tick = void,
|
|
});
|
|
const physicsUpdate = (struct {
|
|
pub fn physicsUpdate(msg: PhysicsMsg) void {
|
|
switch (msg) {
|
|
.tick => std.debug.print("\nphysics tick!\n", .{}),
|
|
}
|
|
}
|
|
}).physicsUpdate;
|
|
|
|
const modules = Modules(.{
|
|
.physics = Module(.{
|
|
.components = .{
|
|
.id = u32,
|
|
},
|
|
.globals = struct {
|
|
pointer: u8,
|
|
},
|
|
.messages = PhysicsMsg,
|
|
.update = physicsUpdate,
|
|
}),
|
|
.renderer = Module(.{
|
|
.components = .{
|
|
.id = u16,
|
|
},
|
|
}),
|
|
});
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Create a world.
|
|
var world = try World(modules).init(allocator);
|
|
defer world.deinit();
|
|
|
|
// Initialize globals.
|
|
world.set(.physics, .pointer, 123);
|
|
_ = world.get(.physics, .pointer); // == 123
|
|
|
|
const player1 = try world.entities.new();
|
|
const player2 = try world.entities.new();
|
|
const player3 = try world.entities.new();
|
|
try world.entities.setComponent(player1, .physics, .id, 1234);
|
|
try world.entities.setComponent(player1, .renderer, .id, 1234);
|
|
|
|
try world.entities.setComponent(player2, .physics, .id, 1234);
|
|
try world.entities.setComponent(player3, .physics, .id, 1234);
|
|
|
|
world.tick();
|
|
}
|