Skip to content

Instantly share code, notes, and snippets.

@gruebite
Last active October 25, 2020 23:46
Show Gist options
  • Save gruebite/58e2f683d7028adc32b987d43f429f47 to your computer and use it in GitHub Desktop.
Save gruebite/58e2f683d7028adc32b987d43f429f47 to your computer and use it in GitHub Desktop.
fn noopEvent(context: *c_void, parts: *Particles) anyerror!void { }
fn noopDestroyContext(context: *c_void, parts: *Particles) void { }
// Necessary for something to return an non-undefined pointer.
// TODO: Investigate.
var _static: i32 = 0;
fn noopCreateContext(allocator: *std.mem.Allocator, params: ?*const zzz.ZNode) anyerror!*c_void { return &_static; }
// TODO: Reset functionality so systems aren't allocating contexts everytime a system is created.
pub const System = struct {
startEvent: fn(*c_void, *Particles) anyerror!void = noopEvent,
updateEvent: fn(*c_void, *Particles) anyerror!void = noopEvent,
drawEvent: fn(*c_void, *Particles) anyerror!void = noopEvent,
spawnedEvent: fn(*c_void, *Particles) anyerror!void = noopEvent,
killedEvent: fn(*c_void, *Particles) anyerror!void = noopEvent,
deinitializeContext: fn(*c_void, *Particles) void = noopDestroyContext,
initializeContext: fn(allocator: *std.mem.Allocator, params: ?*const zzz.ZNode) anyerror!*c_void = noopCreateContext,
};
pub fn registerSystem(comptime SYST: anytype) !void {
const TI = @typeInfo(SYST);
if (TI != .Struct) {
@compileError("Expected struct got: " ++ @typeName(T));
}
var system = System{};
const Context = @field(SYST, SYST.NAME ++ "Context");
if (@hasDecl(SYST, "start")) {
system.startEvent = wrapEvent(Context, @field(SYST, "start"));
}
if (@hasDecl(SYST, "update")) {
system.updateEvent = wrapEvent(Context, @field(SYST, "update"));
}
if (@hasDecl(SYST, "draw")) {
system.drawEvent = wrapEvent(Context, @field(SYST, "draw"));
}
if (@hasDecl(SYST, "spawned")) {
system.spawnedEvent = wrapEvent(Context, @field(SYST, "spawned"));
}
if (@hasDecl(SYST, "killed")) {
system.killedEvent = wrapEvent(Context, @field(SYST, "killed"));
}
if (@hasDecl(SYST, "deinitialize")) {
system.deinitializeContext = wrapDeinitialize(Context, @field(SYST, "deinitialize"));
}
if (@hasDecl(SYST, "initialize")) {
system.initializeContext = wrapInitialize(Context, @field(SYST, "initialize"));
}
const entry_bytes = std.mem.sliceAsBytes(&[_]System{system});
try global.registered_systems.set(SYST.NAME, entry_bytes);
}
pub const InitialScaleRandomSystem = struct {
pub const NAME = "InitialScaleRandom";
pub const InitialScaleRandomContext = struct {
sx: f32 = 1,
sy: f32 = 1,
sx_max: ?f32 = null,
sy_max: ?f32 = null,
};
pub fn initialize(context: *InitialScaleRandomContext, allocator: *std.mem.Allocator) anyerror!void { }
pub fn deinitialize(context: *InitialScaleRandomContext, particles: *Particles) void { }
pub fn spawned(context: *InitialScaleRandomContext, particles: *Particles) anyerror!void {
const attr = particles.attribute;
const idx = particles.last_spawned_idx;
if (context.sx_max) |sxm| {
attr[idx].scale.arr[0] = particles.random.float(f32) * (sxm - context.sx) + context.sx;
} else {
attr[idx].scale.arr[0] = context.sx;
}
if (context.sy_max) |sym| {
attr[idx].scale.arr[1] = particles.random.float(f32) * (sym - context.sy) + context.sy;
} else {
attr[idx].scale.arr[1] = context.sy;
}
}
};
pub fn wrapDeinitialize(comptime T: type, comptime deinitialize: fn(context: *T, parts: *Particles) void) fn(*c_void, *Particles) void {
return struct {
pub fn f(context: *c_void, parts: *Particles) void {
var ptr = if (@alignOf(T) == 0) @ptrCast(*T, @alignCast(@alignOf(i32), context)) else @ptrCast(*T, @alignCast(@alignOf(T), context));
deinitialize(ptr, parts);
parts.allocator.destroy(ptr);
}
}.f;
}
pub fn wrapInitialize(comptime T: type, comptime initialize: fn(context: *T, allocator: *std.mem.Allocator) anyerror!void) fn(allocator: *std.mem.Allocator, node: ?*const zzz.ZNode) anyerror!*c_void {
return struct {
pub fn f(allocator: *std.mem.Allocator, node: ?*const zzz.ZNode) anyerror!*c_void {
var context = try allocator.create(T);
context.* = T{};
errdefer allocator.destroy(context);
if (node) |n| {
try zzz.imprint(n, zzz.ImprintChecks{}, context);
}
try initialize(context, allocator);
return context;
}
}.f;
}
pub fn wrapEvent(comptime T: type, comptime event: fn(context: *T, particles: *Particles) anyerror!void) fn(*c_void, *Particles) anyerror!void {
return struct {
pub inline fn f(context: *c_void, particles: *Particles) anyerror!void {
var ptr = if (@alignOf(T) == 0) @ptrCast(*T, @alignCast(@alignOf(i32), context)) else @ptrCast(*T, @alignCast(@alignOf(T), context));
try event(ptr, particles);
}
}.f;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment