parent
0c6477c852
commit
41d5155d4d
11 changed files with 230 additions and 125 deletions
@ -1,3 +1,8 @@ |
|||||||
pub usingnamespace @cImport({ |
pub usingnamespace @cImport({ |
||||||
|
@cDefine("FLECS_NO_CPP", {}); |
||||||
|
@cDefine("FLECS_USE_OS_ALLOC", {}); |
||||||
|
if (@import("builtin").mode == .Debug) |
||||||
|
@cDefine("FLECS_SANITIZE", {}); |
||||||
|
|
||||||
@cInclude("flecs.h"); |
@cInclude("flecs.h"); |
||||||
}); |
}); |
||||||
|
@ -1,10 +1,58 @@ |
|||||||
const c = @import("./c.zig"); |
const c = @import("./c.zig"); |
||||||
|
|
||||||
|
const Entity = @import("./entity.zig").Entity; |
||||||
|
const Id = @import("./id.zig").Id; |
||||||
const World = @import("./world.zig").World; |
const World = @import("./world.zig").World; |
||||||
|
|
||||||
pub fn Iter(comptime ctx: anytype) type { |
pub fn Iter(comptime ctx: anytype) type { |
||||||
return struct { |
return struct { |
||||||
world: *World(ctx), |
world: *World(ctx), |
||||||
raw: c.ecs_iter_t, |
raw: *c.ecs_iter_t, |
||||||
|
owned: bool, |
||||||
|
|
||||||
|
const Self = @This(); |
||||||
|
|
||||||
|
pub fn fromRawPtr(world: *World(ctx), ptr: *c.ecs_iter_t) Self { |
||||||
|
return .{ .world = world, .raw = ptr, .owned = false }; |
||||||
|
} |
||||||
|
|
||||||
|
pub fn fromRawValue(world: *World(ctx), value: c.ecs_iter_t) !Self { |
||||||
|
var raw = try world.allocator.create(c.ecs_iter_t); |
||||||
|
raw.* = value; |
||||||
|
return .{ .world = world, .raw = raw, .owned = true }; |
||||||
|
} |
||||||
|
|
||||||
|
pub fn deinit(self: Self) void { |
||||||
|
if (self.isValid()) c.ecs_iter_fini(self.raw); |
||||||
|
if (self.owned) self.world.allocator.destroy(self.raw); |
||||||
|
} |
||||||
|
|
||||||
|
pub fn isValid(self: Self) bool { |
||||||
|
return (self.raw.flags & c.EcsIterIsValid) != 0; |
||||||
|
} |
||||||
|
|
||||||
|
pub fn getCount(self: Self) usize { |
||||||
|
return @intCast(self.raw.count); |
||||||
|
} |
||||||
|
|
||||||
|
pub fn getDeltaTime(self: Self) f32 { |
||||||
|
return self.raw.delta_time; |
||||||
|
} |
||||||
|
|
||||||
|
pub fn field(self: Self, comptime T: type, index: usize) []T { |
||||||
|
var raw_ptr = c.ecs_field_w_size(self.raw, @sizeOf(T), @intCast(index)); |
||||||
|
var typed_ptr: [*]T = @alignCast(@ptrCast(raw_ptr)); |
||||||
|
return typed_ptr[0..self.getCount()]; |
||||||
|
} |
||||||
|
|
||||||
|
pub fn fieldId(self: Self, index: usize) Id(ctx) { |
||||||
|
const raw = c.ecs_field_id(self.raw, @intCast(index)); |
||||||
|
return Id(ctx).fromRaw(self.world, raw); |
||||||
|
} |
||||||
|
|
||||||
|
pub fn fieldSource(self: Self, index: usize) Entity(ctx) { |
||||||
|
const raw = c.ecs_field_src(self.raw, @intCast(index)); |
||||||
|
return Entity(ctx).fromRaw(self.world, raw); |
||||||
|
} |
||||||
}; |
}; |
||||||
} |
} |
||||||
|
@ -0,0 +1,68 @@ |
|||||||
|
// Reimplementations of the following tests from Flecs: |
||||||
|
// https://github.com/SanderMertens/flecs/blob/master/test/api/src/World.c |
||||||
|
|
||||||
|
const std = @import("std"); |
||||||
|
const expect = std.testing.expect; |
||||||
|
const expectEql = std.testing.expectEqual; |
||||||
|
const expectStrEql = std.testing.expectEqualStrings; |
||||||
|
|
||||||
|
const util = @import("./util.zig"); |
||||||
|
|
||||||
|
const flecs = @import("../src/main.zig"); |
||||||
|
const c = flecs.c; |
||||||
|
|
||||||
|
const context = flecs.Context(void); |
||||||
|
const World = context.World; |
||||||
|
const Iter = context.Iter; |
||||||
|
const Entity = context.Entity; |
||||||
|
|
||||||
|
const Position = struct { x: f32, y: f32 }; |
||||||
|
const Velocity = struct { x: f32, y: f32 }; |
||||||
|
|
||||||
|
fn move(it: Iter) void { |
||||||
|
var pos = it.field(Position, 1); |
||||||
|
var vel = it.field(Velocity, 2); |
||||||
|
util.Probe.probeIter(it) catch unreachable; |
||||||
|
|
||||||
|
for (pos, vel) |*p, *v| { |
||||||
|
p.x += v.x * it.getDeltaTime(); |
||||||
|
p.y += v.y * it.getDeltaTime(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
test "World_progress_w_0" { |
||||||
|
var world = try World.init(std.testing.allocator); |
||||||
|
defer world.deinit(); |
||||||
|
|
||||||
|
_ = world.component(Position); |
||||||
|
_ = world.component(Velocity); |
||||||
|
|
||||||
|
const e1 = world.entity(&.{ Position, Velocity }); |
||||||
|
|
||||||
|
const phase = Entity.fromRaw(world, c.EcsOnUpdate); |
||||||
|
const move_system = world.system("move", move, phase, "Position, Velocity"); |
||||||
|
|
||||||
|
var ctx = util.Probe.init(); |
||||||
|
c.ecs_set_context(world.raw, &ctx); |
||||||
|
|
||||||
|
e1.set(Position, .{ .x = 0, .y = 0 }); |
||||||
|
e1.set(Velocity, .{ .x = 1, .y = 2 }); |
||||||
|
|
||||||
|
_ = world.progress(0); |
||||||
|
|
||||||
|
try expectEql(ctx.count, 1); |
||||||
|
try expectEql(ctx.invoked, 1); |
||||||
|
try expectEql(ctx.system, move_system.raw); |
||||||
|
try expectEql(ctx.termCount, 2); |
||||||
|
try expectEql(ctx.param, null); |
||||||
|
|
||||||
|
try expectEql(ctx.e[0], e1.raw); |
||||||
|
try expectEql(ctx.c[0][0], world.lookup(Position).?.raw); |
||||||
|
try expectEql(ctx.c[0][1], world.lookup(Velocity).?.raw); |
||||||
|
try expectEql(ctx.s[0][0], 0); |
||||||
|
try expectEql(ctx.s[0][1], 0); |
||||||
|
|
||||||
|
const p = e1.get(Position).?; |
||||||
|
try expect(p.x != 0); |
||||||
|
try expect(p.y != 0); |
||||||
|
} |
@ -1,71 +0,0 @@ |
|||||||
// Reimplementations of the following tests from Flecs: |
|
||||||
// https://github.com/SanderMertens/flecs/blob/master/test/api/src/World.c |
|
||||||
|
|
||||||
const std = @import("std"); |
|
||||||
const expect = std.testing.expect; |
|
||||||
const expectEql = std.testing.expectEqual; |
|
||||||
const expectStrEql = std.testing.expectEqualStrings; |
|
||||||
|
|
||||||
const util = @import("./util.zig"); |
|
||||||
|
|
||||||
const flecs = @import("../src/main.zig"); |
|
||||||
const c = flecs.c; |
|
||||||
|
|
||||||
const context = flecs.Context(void); |
|
||||||
const Lookup = context.Lookup; |
|
||||||
const World = context.World; |
|
||||||
const Iter = context.Iter; |
|
||||||
const Entity = context.Entity; |
|
||||||
|
|
||||||
const Position = struct { x: f32, y: f32 }; |
|
||||||
const Velocity = struct { x: f32, y: f32 }; |
|
||||||
|
|
||||||
fn move(it: *Iter) void { |
|
||||||
var pos = it.field(Position, 1); |
|
||||||
var vel = it.field(Velocity, 2); |
|
||||||
util.Probe.probeIter(it); |
|
||||||
|
|
||||||
for (0..it.count) |row| { |
|
||||||
var p = &pos[row]; |
|
||||||
var v = &vel[row]; |
|
||||||
p.*.x += v.*.x * it.delta_time; |
|
||||||
p.*.y += v.*.y * it.delta_time; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
test "World_progress_w_0" { |
|
||||||
var world = try World.init(std.testing.allocator); |
|
||||||
defer world.deinit(); |
|
||||||
|
|
||||||
_ = world.component(Position); |
|
||||||
_ = world.component(Velocity); |
|
||||||
|
|
||||||
// const e1 = world.entity(&.{ Position, Velocity }); |
|
||||||
|
|
||||||
// // const phase = Entity.fromRaw(world, c.EcsOnUpdate); |
|
||||||
// // const move_system = world.system("move", move, phase, "Position, Velocity"); |
|
||||||
|
|
||||||
// var ctx = util.Probe.init(); |
|
||||||
// c.ecs_set_context(world.raw, &ctx); |
|
||||||
|
|
||||||
// // e1.set(Position, .{ 0, 0 }); |
|
||||||
// // e1.set(Velocity, .{ 1, 2 }); |
|
||||||
|
|
||||||
// _ = world.progress(0); |
|
||||||
|
|
||||||
// try expectEql(ctx.count, 1); |
|
||||||
// try expectEql(ctx.invoked, 1); |
|
||||||
// // try expectEql(ctx.system, move_system); |
|
||||||
// try expectEql(ctx.termCount, 2); |
|
||||||
// try expectEql(ctx.param, null); |
|
||||||
|
|
||||||
// try expectEql(ctx.e[0], e1.raw); |
|
||||||
// try expectEql(ctx.c[0][0], Lookup(Position).id); |
|
||||||
// try expectEql(ctx.c[0][1], Lookup(Velocity).id); |
|
||||||
// try expectEql(ctx.s[0][0], 0); |
|
||||||
// try expectEql(ctx.s[0][1], 0); |
|
||||||
|
|
||||||
// // const p = try e1.get(Position); |
|
||||||
// // try expect(p.x != 0); |
|
||||||
// // try expect(p.y != 0); |
|
||||||
} |
|
Loading…
Reference in new issue