Remove ecs

master
Louis Pearson 2022-01-22 13:06:34 -07:00
parent c87da2a4ae
commit 555c200033
2 changed files with 66 additions and 266 deletions

View File

@ -1,191 +0,0 @@
const std = @import("std");
const ArgsTuple = std.meta.Tuple;
const Tuple = std.meta.Tuple;
pub fn World(comptime ComponentBase: type) type {
// Build a component type at comptime based off of ComponentBase. It makes all the fields
// nullable so they are easy to pull out of the store.
const ComponentCon = componentConstructor: {
var fields = std.meta.fields(ComponentBase);
var newFields: [fields.len]std.builtin.TypeInfo.StructField = undefined;
inline for (fields) |field, i| {
const T = field.field_type;
const default: ?T = null;
newFields[i] = std.builtin.TypeInfo.StructField{
.name = field.name,
.field_type = ?T,
.default_value = default,
.is_comptime = false,
.alignment = if (@sizeOf(T) > 0) @alignOf(T) else 0,
};
}
break :componentConstructor @Type(.{ .Struct = .{
.layout = .Auto,
.fields = &newFields,
.decls = &[_]std.builtin.TypeInfo.Declaration{},
.is_tuple = false,
} });
};
return struct {
components: ComponentPool,
alloc: std.mem.Allocator,
pub const Query = ComponentQuery;
pub const Component = ComponentCon;
const ComponentPool = std.MultiArrayList(Component);
const ComponentEnum = std.meta.FieldEnum(Component);
const ComponentSet = std.EnumSet(ComponentEnum);
const ComponentQuery = struct {
required: ComponentSet = ComponentSet.init(.{}),
excluded: ComponentSet = ComponentSet.init(.{}),
pub fn init() @This() {
return @This(){};
}
pub fn query(require_set: []const ComponentEnum, exclude_set: []const ComponentEnum) @This() {
var this = @This(){};
for (require_set) |f| {
this.required.insert(f);
}
for (exclude_set) |f| {
this.excluded.insert(f);
}
return this;
}
pub fn require(require_set: []const ComponentEnum) @This() {
var this = @This(){};
for (require_set) |f| {
this.required.insert(f);
}
return this;
}
pub fn exclude(exclude_set: []const ComponentEnum) @This() {
var this = @This(){};
for (exclude_set) |f| {
this.excluded.insert(f);
}
return this;
}
};
const fields = std.meta.fields(Component);
pub fn init(alloc: std.mem.Allocator) @This() {
return @This(){
.components = ComponentPool{},
.alloc = alloc,
};
}
pub fn create(this: *@This(), component: Component) !usize {
const len = this.components.len;
try this.components.append(this.alloc, component);
return len;
}
pub fn destroy(this: *@This(), entity: usize) void {
// TODO
_ = this;
_ = entity;
@compileError("unimplemented");
}
/// Returns a copy of the components on an entity
pub fn get(this: *@This(), entity: usize) Component {
return this.components.get(entity);
}
pub fn set(this: *@This(), entity: usize, component: Component) void {
this.components.set(entity, component);
}
fn enum2type(comptime enumList: []const ComponentEnum) []type {
var t: [enumList.len]type = undefined;
inline for (enumList) |e, i| {
const field_type = @typeInfo(fields[@enumToInt(e)].field_type);
t[i] = *field_type.Optional.child;
}
return &t;
}
pub fn process(this: *@This(), dt: f32, comptime comp: []const ComponentEnum, func: anytype) void {
const Args = Tuple([_]type{f32} ++ enum2type(comp));
var i = this.iter(Query.require(comp));
while (i.next()) |eID| {
var e = this.get(eID);
var args: Args = undefined;
args[0] = dt;
inline for (comp) |f, j| {
args[j + 1] = &(@field(e, @tagName(f)).?);
}
@call(.{}, func, args);
this.set(eID, e);
}
}
pub fn processWithID(this: *@This(), dt: f32, comptime comp: []const ComponentEnum, func: anytype) void {
const Args = Tuple([_]type{ f32, usize } ++ enum2type(comp));
var i = this.iter(Query.require(comp));
while (i.next()) |eID| {
var e = this.get(eID);
var args: Args = undefined;
args[0] = dt;
args[1] = eID;
inline for (comp) |f, j| {
args[j + 2] = &(@field(e, @tagName(f)).?);
}
@call(.{}, func, args);
this.set(eID, e);
}
}
pub fn iterAll(this: *@This()) Iterator {
return Iterator.init(this, ComponentQuery{});
}
pub fn iter(this: *@This(), query: ComponentQuery) Iterator {
return Iterator.init(this, query);
}
const Self = @This();
const Iterator = struct {
world: *Self,
index: usize,
query: ComponentQuery,
pub fn init(w: *Self, q: ComponentQuery) @This() {
return @This(){
.world = w,
.index = 0,
.query = q,
};
}
pub fn next(this: *@This()) ?usize {
if (this.index == this.world.components.len) return null;
var match = false;
while (!match) {
if (this.index == this.world.components.len) return null;
const e = this.world.components.get(this.index);
match = true;
inline for (fields) |f| {
const fenum = std.meta.stringToEnum(ComponentEnum, f.name) orelse unreachable;
const required = this.query.required.contains(fenum);
const excluded = this.query.excluded.contains(fenum);
const has = @field(e, f.name) != null;
if ((required and !has) or (excluded and has)) {
match = false;
break;
}
}
this.index += 1;
if (match) return this.index - 1;
}
return null;
}
};
};
}

View File

@ -1,6 +1,5 @@
const std = @import("std"); const std = @import("std");
const w4 = @import("wasm4.zig"); const w4 = @import("wasm4.zig");
const ecs = @import("ecs.zig");
const assets = @import("assets"); const assets = @import("assets");
const input = @import("input.zig"); const input = @import("input.zig");
const util = @import("util.zig"); const util = @import("util.zig");
@ -271,6 +270,7 @@ export fn update() void {
velocityProcess(1, &player.pos); velocityProcess(1, &player.pos);
physicsProcess(1, &player.pos, &player.physics); physicsProcess(1, &player.pos, &player.physics);
circuitManipulationProcess(1, &player.pos, &player.control); circuitManipulationProcess(1, &player.pos, &player.control);
wireManipulationProcess(1, &player.pos, &player.control);
controlProcess(1, &player.pos, &player.control, &player.physics, &player.kinematic); controlProcess(1, &player.pos, &player.control, &player.physics, &player.kinematic);
kinematicProcess(1, &player.pos, &player.kinematic); kinematicProcess(1, &player.pos, &player.kinematic);
controlAnimProcess(1, &player.sprite, &player.controlAnim, &player.control); controlAnimProcess(1, &player.sprite, &player.controlAnim, &player.control);
@ -369,84 +369,75 @@ fn circuitManipulationProcess(_: f32, pos: *Pos, control: *Control) void {
} }
} }
// fn wireManipulationProcess(_: f32, pos: *Pos, control: *Control) void { fn wireManipulationProcess(_: f32, pos: *Pos, control: *Control) void {
// var offset = switch (control.facing) { var offset = switch (control.facing) {
// .left => Vec2f{ -6, -4 }, .left => Vec2f{ -6, -4 },
// .right => Vec2f{ 6, -4 }, .right => Vec2f{ 6, -4 },
// .up => Vec2f{ 0, -12 }, .up => Vec2f{ 0, -12 },
// .down => Vec2f{ 0, 4 }, .down => Vec2f{ 0, 4 },
// }; };
// var offsetPos = pos.pos + offset; var offsetPos = pos.pos + offset;
// var entity: World.Component = undefined; var mapPos = util.world2cell(offsetPos);
// var mapPos = util.world2cell(offsetPos);
// if (control.grabbing) |details| { if (control.grabbing) |details| {
// entity = world.get(details.id); var wire = &wires.slice()[details.id];
// var wire = &entity.wire.?; var nodes = wire.nodes.slice();
// var nodes = wire.nodes.slice();
// var maxLength = wireMaxLength(wire); var maxLength = wireMaxLength(wire);
// var length = wireLength(wire); var length = wireLength(wire);
// if (length > maxLength * 1.5) { if (length > maxLength * 1.5) {
// nodes[details.which].pinned = false; nodes[details.which].pinned = false;
// control.grabbing = null; control.grabbing = null;
// world.set(details.id, entity); return;
// return; } else {
// } else { nodes[details.which].pos = pos.pos + Vec2f{ 0, -4 };
// nodes[details.which].pos = pos.pos + Vec2f{ 0, -4 }; }
// }
// if (Circuit.is_plug(circuit.get_cell(mapPos) orelse 0)) { if (Circuit.is_plug(circuit.get_cell(mapPos) orelse 0)) {
// const active = circuit.isEnabled(mapPos); const active = circuit.isEnabled(mapPos);
// indicator = .{ .t = .plug, .pos = mapPos * @splat(2, @as(i32, 8)) + Vec2{ 4, 4 }, .active = active }; indicator = .{ .t = .plug, .pos = mapPos * @splat(2, @as(i32, 8)) + Vec2{ 4, 4 }, .active = active };
// if (input.btnp(.one, .two)) { if (input.btnp(.one, .two)) {
// nodes[details.which].pinned = true; nodes[details.which].pinned = true;
// nodes[details.which].pos = vec2tovec2f(indicator.?.pos); nodes[details.which].pos = vec2tovec2f(indicator.?.pos);
// nodes[details.which].last = vec2tovec2f(indicator.?.pos); nodes[details.which].last = vec2tovec2f(indicator.?.pos);
// control.grabbing = null; control.grabbing = null;
// } }
// } else if (input.btnp(.one, .two)) { } else if (input.btnp(.one, .two)) {
// nodes[details.which].pinned = false; nodes[details.which].pinned = false;
// control.grabbing = null; control.grabbing = null;
// } }
// world.set(details.id, entity); } else {
// } else { const interactDistance = 4;
// const interactDistance = 4; var minDistance: f32 = interactDistance;
// var minDistance: f32 = interactDistance; var interactWireID: ?usize = null;
// var wireIter = world.iter(WireQuery); var which: usize = 0;
// var interactWireID: ?usize = null; for (wires.slice()) |*wire, wireID| {
// var which: usize = 0; const nodes = wire.nodes.constSlice();
// while (wireIter.next()) |entityID| { const begin = nodes[0].pos;
// entity = world.get(entityID); const end = nodes[wire.nodes.len - 1].pos;
// const wire = entity.wire.?; var dist = util.distancef(begin, offsetPos);
// const nodes = wire.nodes.constSlice(); if (dist < minDistance) {
// const begin = nodes[0].pos; minDistance = dist;
// const end = nodes[wire.nodes.len - 1].pos; indicator = .{ .t = .wire, .pos = vec2ftovec2(begin), .active = wire.enabled };
// var dist = util.distancef(begin, offsetPos); interactWireID = wireID;
// if (dist < minDistance) { which = 0;
// minDistance = dist; }
// indicator = .{ .t = .wire, .pos = vec2ftovec2(begin), .active = wire.enabled }; dist = util.distancef(end, offsetPos);
// interactWireID = entityID; if (dist < minDistance) {
// which = 0; minDistance = dist;
// } indicator = .{ .t = .wire, .pos = vec2ftovec2(end), .active = wire.enabled };
// dist = util.distancef(end, offsetPos); interactWireID = wireID;
// if (dist < minDistance) { which = wire.nodes.len - 1;
// minDistance = dist; }
// indicator = .{ .t = .wire, .pos = vec2ftovec2(end), .active = wire.enabled }; }
// interactWireID = entityID; if (interactWireID) |wireID| {
// which = wire.nodes.len - 1; if (input.btnp(.one, .two)) {
// } control.grabbing = .{ .id = wireID, .which = which };
// } }
// if (interactWireID) |wireID| { }
// entity = world.get(wireID); }
// if (input.btnp(.one, .two)) { }
// control.grabbing = .{ .id = wireID, .which = which };
// }
// world.set(wireID, entity);
// }
// }
// }
fn wirePhysicsProcess(dt: f32, wire: *Wire) void { fn wirePhysicsProcess(dt: f32, wire: *Wire) void {
var nodes = wire.nodes.slice(); var nodes = wire.nodes.slice();