Cleanup | Removed template | Use GTL instead

This commit is contained in:
abux 2026-07-12 20:04:35 +01:00
parent 93a4606c94
commit 7de0e277de
10 changed files with 566 additions and 21 deletions

View file

@ -108,16 +108,6 @@ test "Main" {
**Default App Stages**
``` zig
pub const stage = struct {
// --- BEGIN FRAME ---
pub const pre_begin_frame = struct {};
pub const begin_frame = struct {};
pub const post_begin_frame = struct {};
// --- END FRAME ---
pub const pre_end_frame = struct {};
pub const end_frame = struct {};
pub const post_end_frame = struct {};
// --- INIT ---
pub const pre_init = struct {};
pub const init = struct {};
@ -128,6 +118,16 @@ pub const stage = struct {
pub const deinit = struct {};
pub const post_deinit = struct {};
// --- BEGIN FRAME ---
pub const pre_begin_frame = struct {};
pub const begin_frame = struct {};
pub const post_begin_frame = struct {};
// --- END FRAME ---
pub const pre_end_frame = struct {};
pub const end_frame = struct {};
pub const post_end_frame = struct {};
// --- INPUTS ---
pub const pre_inputs = struct {};
pub const inputs = struct {};

View file

@ -5,24 +5,14 @@ pub const event = @import("event/root.zig");
pub const plugin = @import("plugin/root.zig");
pub const resource = @import("resource/root.zig");
pub const scheduler = @import("scheduler/root.zig");
pub const template = @import("template/root.zig");
pub const ecs = @import("world/root.zig");
const template = @import("template/root.zig");
const Self = @This();
/// ----------------------------------------------------
/// Default app stages
/// ----------------------------------------------------
pub const stage = struct {
// --- BEGIN FRAME ---
pub const pre_begin_frame = struct {};
pub const begin_frame = struct {};
pub const post_begin_frame = struct {};
// --- END FRAME ---
pub const pre_end_frame = struct {};
pub const end_frame = struct {};
pub const post_end_frame = struct {};
// --- INIT ---
pub const pre_init = struct {};
pub const init = struct {};
@ -33,6 +23,16 @@ pub const stage = struct {
pub const deinit = struct {};
pub const post_deinit = struct {};
// --- BEGIN FRAME ---
pub const pre_begin_frame = struct {};
pub const begin_frame = struct {};
pub const post_begin_frame = struct {};
// --- END FRAME ---
pub const pre_end_frame = struct {};
pub const end_frame = struct {};
pub const post_end_frame = struct {};
// --- INPUTS ---
pub const pre_inputs = struct {};
pub const inputs = struct {};

View file

@ -0,0 +1,24 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
// --- TARGET ---
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// --- MOD ---
const mod = b.addModule("gtl", .{
.root_source_file = b.path("src/gtl.zig"),
.target = target,
.optimize = optimize,
});
const mod_tests = b.addTest(.{
.root_module = mod,
});
const run_mod_tests = b.addRunArtifact(mod_tests);
const test_step = b.step("test", "Run tests");
test_step.dependOn(&run_mod_tests.step);
}

View file

@ -0,0 +1,17 @@
.{
.name = .gtl,
.version = "0.0.0",
.fingerprint = 0xbd8e95362428747b,
.minimum_zig_version = "0.16.0",
.dependencies = .{},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
},
}

View file

@ -0,0 +1,59 @@
// --- RESET ---
pub const reset = "\x1b[0m";
// --- STYLES ---
pub const bold = "\x1b[1m";
pub const dim = "\x1b[2m";
pub const italic = "\x1b[3m";
pub const underline = "\x1b[4m";
pub const slow_blink = "\x1b[5m";
pub const rapid_blink = "\x1b[6m";
pub const invert = "\x1b[7m";
pub const hidden = "\x1b[8m";
pub const strikethrough = "\x1b[9m";
// --- STYLE RESETS ---
pub const bold_off = "\x1b[22m";
pub const dim_off = "\x1b[22m";
pub const italic_off = "\x1b[23m";
pub const underline_off = "\x1b[24m";
pub const blink_off = "\x1b[25m";
pub const invert_off = "\x1b[27m";
pub const hidden_off = "\x1b[28m";
pub const strikethrough_off = "\x1b[29m";
// --- FOREGROUND ---
pub const black = "\x1b[30m";
pub const red = "\x1b[31m";
pub const green = "\x1b[32m";
pub const yellow = "\x1b[33m";
pub const blue = "\x1b[34m";
pub const purple = "\x1b[35m";
pub const cyan = "\x1b[36m";
pub const white = "\x1b[37m";
pub const bright_black = "\x1b[90m";
pub const bright_red = "\x1b[91m";
pub const bright_green = "\x1b[92m";
pub const bright_yellow = "\x1b[93m";
pub const bright_blue = "\x1b[94m";
pub const bright_purple = "\x1b[95m";
pub const bright_cyan = "\x1b[96m";
pub const bright_white = "\x1b[97m";
// --- BACKGROUND ---
pub const bg_black = "\x1b[40m";
pub const bg_red = "\x1b[41m";
pub const bg_green = "\x1b[42m";
pub const bg_yellow = "\x1b[43m";
pub const bg_blue = "\x1b[44m";
pub const bg_purple = "\x1b[45m";
pub const bg_cyan = "\x1b[46m";
pub const bg_white = "\x1b[47m";
pub const bg_bright_black = "\x1b[100m";
pub const bg_bright_red = "\x1b[101m";
pub const bg_bright_green = "\x1b[102m";
pub const bg_bright_yellow = "\x1b[103m";
pub const bg_bright_blue = "\x1b[104m";
pub const bg_bright_purple = "\x1b[105m";
pub const bg_bright_cyan = "\x1b[106m";
pub const bg_bright_white = "\x1b[107m";

View file

@ -0,0 +1,128 @@
//
// PRIVATE
//
const std = @import("std");
//
// PUBLIC
//
pub const log = @import("log.zig");
pub const ansi = @import("ansi.zig");
pub const Handle = @import("handle.zig").Handle;
pub const SlotMap = @import("slot_map.zig").SlotMap;
pub const TypeID = @import("type_id.zig").of;
//
// STRUCTS
//
// --- SHADER ---
const ShaderID = union(enum) { pbr, unlit, custom: Handle([]const u8) };
const GPUShader = struct { raw: *anyopaque };
// --- PIPELINE ---
const PipelineKey = struct { shader: ShaderID };
const GPUPipeline = struct { raw: *anyopaque };
// --- MATERIAL ---
const Material = struct {
shader: ShaderID = .pbr,
albedo: @Vector(4, f32) = .{ 0, 0, 0, 1 },
};
test "SlotMap" {
// --- ALLOCATOR ---
const alloc = std.testing.allocator;
//
// LISTS
//
// --- MATERIALS ---
var materials: std.ArrayList(Material) = .empty;
defer materials.deinit(alloc);
//
// SLOT MAPS
//
// --- SHADER MAP ---
var shaders: SlotMap(ShaderID, GPUShader) = .init(alloc);
defer shaders.deinit();
// --- PIPELINE MAP ---
var pipelines: SlotMap(PipelineKey, GPUPipeline) = .init(alloc);
defer pipelines.deinit();
// --- ADD MATERIALS ---
try materials.append(alloc, .{ .shader = .pbr }); // BLACK
try materials.append(alloc, .{ .shader = .pbr, .albedo = .{ 1, 0, 0, 1 } }); // RED
try materials.append(alloc, .{ .shader = .unlit, .albedo = .{ 0, 1, 0, 1 } }); // GREEN
try materials.append(alloc, .{ .shader = .unlit, .albedo = .{ 0, 0, 1, 1 } }); // GREEN
{
// --- DEBUG ---
std.debug.print("┏━ MATERIALS\n", .{});
defer std.debug.print("┗━\n", .{});
for (materials.items) |material| {
// --- REGISTER SHADER ---
const shader = shaders.getByKey(material.shader) orelse blk: {
const handle = try shaders.put(material.shader, .{ .raw = undefined });
break :blk shaders.get(handle).?;
};
_ = shader;
// --- DEBUG ---
std.debug.print("┃ ┏━\n", .{});
std.debug.print("┃ ┃ Shader: {s}\n", .{@tagName(material.shader)});
std.debug.print("┃ ┃ Albedo: rgba({}, {}, {}, {})\n", .{ material.albedo[0], material.albedo[1], material.albedo[2], material.albedo[3] });
std.debug.print("┃ ┗━\n", .{});
}
}
{
// --- DEBUG ---
std.debug.print("┏━ SHADERS\n", .{});
defer std.debug.print("┗━\n", .{});
for (shaders.values.items) |entry| {
const source = switch (entry.key) {
.pbr => "assets/shaders/pbr.wgsl",
.unlit => "assets/shaders/unlit.wgsl",
.custom => "idk",
};
std.debug.print("┃ ┏━\n", .{});
std.debug.print("┃ ┃ ID: {s}\n", .{@tagName(entry.key)});
std.debug.print("┃ ┃ Source: {s}\n", .{source});
std.debug.print("┃ ┗━\n", .{});
}
}
{
std.debug.print("┏━ ANSI\n", .{});
defer std.debug.print("┗━\n", .{});
std.debug.print(
\\{s}┃ RED
\\{s}┃ GREEN
\\{s}┃ BLUE
\\{s}
, .{
ansi.red,
ansi.green,
ansi.blue,
ansi.reset,
});
}
{
log.warn("...", .{});
log.err("...", .{});
log.info("...", .{});
log.debug("...", .{});
log.trace("...", .{});
}
}

View file

@ -0,0 +1,17 @@
pub fn Handle(comptime T: type) type {
_ = T;
return struct {
const Self = @This();
idx: u32 = 0,
gen: u32 = 0,
pub fn eql(
self: Self,
other: Self,
) bool {
return self.idx == other.idx and
self.gen == other.gen;
}
};
}

View file

@ -0,0 +1,123 @@
const std = @import("std");
const ansi = @import("ansi.zig");
/// ----------------------------------------------------
/// ----------------------------------------------------
pub const Level = enum(u8) {
debug = 0,
trace = 1,
info = 2,
warn = 3,
err = 4,
fatal = 5,
fn label(self: Level) []const u8 {
return switch (self) {
.debug => "DEBUG",
.trace => "TRACE",
.info => "INFO",
.warn => "WARN",
.err => "ERROR",
.fatal => "FATAL",
};
}
fn color(self: Level) []const u8 {
return switch (self) {
.debug => ansi.bright_black,
.trace => ansi.cyan,
.info => ansi.green,
.warn => ansi.yellow,
.err => ansi.red,
.fatal => ansi.bright_red ++ ansi.bold,
};
}
};
/// ----------------------------------------------------
/// ----------------------------------------------------
pub const Config = struct {
level: Level = .debug,
source_loc: bool = true,
};
// --- CONFIG ---
var config: Config = .{};
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn set(c: Config) void {
config = c;
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn debug(comptime fmt: []const u8, args: anytype) void {
log(.debug, @src(), fmt, args);
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn trace(comptime fmt: []const u8, args: anytype) void {
log(.trace, @src(), fmt, args);
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn info(comptime fmt: []const u8, args: anytype) void {
log(.info, @src(), fmt, args);
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn warn(comptime fmt: []const u8, args: anytype) void {
log(.warn, @src(), fmt, args);
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn err(comptime fmt: []const u8, args: anytype) void {
log(.err, @src(), fmt, args);
}
/// ----------------------------------------------------
/// Uses **@breakpoint()**
/// ----------------------------------------------------
pub fn fatal(comptime fmt: []const u8, args: anytype) void {
log(.fatal, @src(), fmt, args);
if (@import("builtin").mode == .Debug) @breakpoint();
}
/// ----------------------------------------------------
/// ----------------------------------------------------
fn log(
level: Level,
src: std.builtin.SourceLocation,
comptime fmt: []const u8,
args: anytype,
) void {
// --- CHECK LOG LVL ---
if (@intFromEnum(level) < @intFromEnum(config.level)) return;
// --- BUFFER ---
var buf: [64]u8 = undefined;
const stderr = std.debug.lockStderr(&buf);
defer std.debug.unlockStderr();
// --- WRITE ---
const w = &stderr.file_writer.interface;
w.writeAll(level.color()) catch return;
w.print("[" ++ ansi.bold ++ "{s}" ++ ansi.reset, .{level.label()}) catch return;
w.writeAll(level.color()) catch return;
w.writeAll("]" ++ ansi.reset ++ " ") catch return;
// --- CHECK LOCATION ---
if (config.source_loc) {
w.writeAll(ansi.bright_black) catch return;
w.print("({s}:{d}) ", .{ std.fs.path.basename(src.file), src.line }) catch return;
w.writeAll(ansi.reset) catch return;
}
// --- OUTPUT ---
w.print(fmt ++ "\n", args) catch return;
}

View file

@ -0,0 +1,169 @@
const std = @import("std");
const Handle = @import("handle.zig").Handle;
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn SlotMap(
comptime K: type,
comptime V: type,
) type {
return struct {
const Self = @This();
/// ----------------------------------------------------
/// ----------------------------------------------------
pub const Entry = struct {
key: K,
value: V,
};
//
// FIELDS
//
// --- VALUES ---
values: std.ArrayList(Entry),
lookup: std.AutoHashMap(K, Handle(V)),
// --- LIFE TIMES ---
generations: std.ArrayList(u32),
free_list: std.ArrayList(u32),
alloc: std.mem.Allocator,
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn init(alloc: std.mem.Allocator) Self {
return .{
.values = .empty,
.lookup = .init(alloc),
.generations = .empty,
.free_list = .empty,
.alloc = alloc,
};
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn deinit(self: *Self) void {
self.values.deinit(self.alloc);
self.lookup.deinit();
self.generations.deinit(self.alloc);
self.free_list.deinit(self.alloc);
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn put(
self: *Self,
key: K,
value: V,
) error{ Duplicate, OutOfMemory }!Handle(V) {
// --- PREVENT DUPS ---
if (self.lookup.contains(key)) return error.Duplicate;
// --- NEW GENERATION ---
if (self.free_list.pop()) |idx| {
self.values.items[@intCast(idx)] = .{
.key = key,
.value = value,
};
self.generations.items[@intCast(idx)] += 1;
return .{
.idx = idx,
.gen = self.generations.items[idx],
};
}
// --- METADATA ---
const idx = self.values.items.len;
const handle: Handle(V) = .{
.idx = @intCast(idx),
.gen = 1,
};
// --- NEW VALUE ---
try self.values.append(self.alloc, .{
.value = value,
.key = key,
});
errdefer _ = self.values.swapRemove(idx);
// --- NEW LOOKUP ---
try self.lookup.put(key, handle);
errdefer _ = self.lookup.remove(key);
// --- NEW GENERATION ---
try self.generations.append(self.alloc, 1);
// --- RESULT ---
return handle;
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn remove(
self: *Self,
handle: Handle(V),
) void {
const idx: u32 = handle.idx;
// --- CHECK IF STALE ---
if (idx >= self.generations.items.len) return;
if (self.generations.items[idx] != handle.gen) return;
// --- REMOVE KEY ---
const key = self.values.items[idx].key;
_ = self.lookup.remove(key);
// --- GENERATION ---
self.generations.items[idx] +|= 1;
self.free_list.append(self.alloc, idx) catch unreachable;
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn removeByKey(self: *Self, key: K) void {
const idx = self.lookup.get(key) orelse return;
_ = self.lookup.remove(key);
self.generations.items[idx] +|= 1;
self.free_list.append(self.alloc, idx) catch unreachable;
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn get(self: *Self, handle: Handle(V)) ?*V {
if (handle.idx >= self.values.items.len) return null;
if (self.generations.items[handle.idx] != handle.gen) return null;
return &self.values.items[handle.idx].value;
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn getByKey(self: *Self, key: K) ?*V {
const handle = self.lookup.get(key) orelse return null;
return self.get(handle);
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn getHandle(self: *Self, key: K) ?Handle(V) {
return self.lookup.get(key);
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn contains(self: *Self, key: K) bool {
return self.lookup.contains(key);
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn count(self: *Self) u32 {
return self.lookup.count();
}
};
}

View file

@ -0,0 +1,8 @@
const std = @import("std");
pub fn of(comptime T: type) u64 {
return std.hash.Wyhash.hash(
694721,
@typeName(T),
);
}