Added [FixedArrayList, FixedSlotMap] | Updated [gtl.zig, README.md]
This commit is contained in:
parent
054ca5ea21
commit
e20ce39550
4 changed files with 315 additions and 30 deletions
56
README.md
56
README.md
|
|
@ -1,20 +1,23 @@
|
||||||
**Includes**
|
# Includes
|
||||||
- ANSI
|
|
||||||
- SlotMap | KeyedSlotMap
|
## Arrays
|
||||||
- Custom Log
|
- SlotMap
|
||||||
|
- KeyedSlotMap
|
||||||
|
|
||||||
|
- FixedSlotMap
|
||||||
|
- FixedArrayList
|
||||||
|
- RingBuffer
|
||||||
|
- Handle(T) **Generational**
|
||||||
|
|
||||||
|
## Misc
|
||||||
|
- log
|
||||||
|
- ansi (colors etc)
|
||||||
- TypeID
|
- TypeID
|
||||||
|
|
||||||
**Logs**
|
# Examples
|
||||||
```zig
|
|
||||||
log.warn("...", .{});
|
## KeyedSlotMap
|
||||||
log.err("...", .{});
|
|
||||||
log.info("...", .{});
|
|
||||||
log.debug("...", .{});
|
|
||||||
log.trace("...", .{});
|
|
||||||
log.fatal("...", .{});
|
|
||||||
```
|
|
||||||
|
|
||||||
**KeyedSlotMap**
|
|
||||||
```zig
|
```zig
|
||||||
// --- SHADER MAP ---
|
// --- SHADER MAP ---
|
||||||
var shaders: KeyedSlotMap(ShaderID, GPUShader) = .init(alloc);
|
var shaders: KeyedSlotMap(ShaderID, GPUShader) = .init(alloc);
|
||||||
|
|
@ -25,7 +28,8 @@ const shader_handle = try shaders.put(.pbr, .{ .raw = undefined });
|
||||||
defer shaders.remove(shader_handle);
|
defer shaders.remove(shader_handle);
|
||||||
```
|
```
|
||||||
|
|
||||||
**TypeID**
|
## TypeID
|
||||||
|
|
||||||
```zig
|
```zig
|
||||||
const Player = struct {};
|
const Player = struct {};
|
||||||
std.debug.print("TypeID(Player): {}\n", .{TypeID(Player)});
|
std.debug.print("TypeID(Player): {}\n", .{TypeID(Player)});
|
||||||
|
|
@ -34,15 +38,26 @@ std.debug.print("TypeID(Player): {}\n", .{TypeID(Player)});
|
||||||
Output: TypeID(Player): 2462284566368800629
|
Output: TypeID(Player): 2462284566368800629
|
||||||
```
|
```
|
||||||
|
|
||||||
# NicePrint
|
## Logs
|
||||||
|
|
||||||
## Styles
|
```zig
|
||||||
|
log.warn("...", .{});
|
||||||
|
log.err("...", .{});
|
||||||
|
log.info("...", .{});
|
||||||
|
log.debug("...", .{});
|
||||||
|
log.trace("...", .{});
|
||||||
|
log.fatal("...", .{});
|
||||||
|
```
|
||||||
|
|
||||||
|
## NicePrint
|
||||||
|
|
||||||
|
### Styles
|
||||||
- default
|
- default
|
||||||
- rounded
|
- rounded
|
||||||
- pipe
|
- pipe
|
||||||
- custom
|
- custom
|
||||||
|
|
||||||
## Example
|
### Example
|
||||||
```zig
|
```zig
|
||||||
// --- PRINT ---
|
// --- PRINT ---
|
||||||
if (log.print(.debug, "DEVICE INFO", ansi.bold ++ ansi.red)) |a| {
|
if (log.print(.debug, "DEVICE INFO", ansi.bold ++ ansi.red)) |a| {
|
||||||
|
|
@ -61,7 +76,7 @@ if (log.print(.debug, "DEVICE INFO", ansi.bold ++ ansi.red)) |a| {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Output
|
### Output
|
||||||
```text
|
```text
|
||||||
┏━ DEVICE INFO
|
┏━ DEVICE INFO
|
||||||
┃ device -> GTX
|
┃ device -> GTX
|
||||||
|
|
@ -71,3 +86,6 @@ if (log.print(.debug, "DEVICE INFO", ansi.bold ++ ansi.red)) |a| {
|
||||||
┃ ┗━
|
┃ ┗━
|
||||||
┗━
|
┗━
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
[ ] Lear how to properly structure markdown 🥀️
|
||||||
|
|
|
||||||
134
src/fixed_array_list.zig
Normal file
134
src/fixed_array_list.zig
Normal file
|
|
@ -0,0 +1,134 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn FixedArrayList(
|
||||||
|
comptime T: type,
|
||||||
|
comptime Capacity: usize,
|
||||||
|
) type {
|
||||||
|
return struct {
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIELDS
|
||||||
|
//
|
||||||
|
|
||||||
|
data: [Capacity]T,
|
||||||
|
cursor: usize = 0,
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub const empty = Self{
|
||||||
|
.data = undefined,
|
||||||
|
.cursor = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn append(self: *Self, item: T) error{Full}!void {
|
||||||
|
if (self.isFull()) return error.Full;
|
||||||
|
self.data[self.cursor] = item;
|
||||||
|
self.cursor += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn appendMany(self: *Self, values: []const T) error{Full}!void {
|
||||||
|
if (self.cursor + values.len > Capacity) return error.Full;
|
||||||
|
|
||||||
|
@memcpy(
|
||||||
|
self.data[self.cursor .. self.cursor + values.len],
|
||||||
|
values,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.cursor += values.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn pop(self: *Self) ?T {
|
||||||
|
if (self.cursor == 0) return null;
|
||||||
|
self.cursor -= 1;
|
||||||
|
return self.data[self.cursor];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn swapRemove(self: *Self, i: usize) ?T {
|
||||||
|
if (i >= self.cursor) return null;
|
||||||
|
|
||||||
|
const removed: T = self.data[i];
|
||||||
|
|
||||||
|
self.cursor -= 1;
|
||||||
|
|
||||||
|
if (i != self.cursor) {
|
||||||
|
self.data[i] = self.data[self.cursor];
|
||||||
|
}
|
||||||
|
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn get(self: *Self, i: usize) ?T {
|
||||||
|
if (i >= self.cursor) return null;
|
||||||
|
return self.data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn getPtr(self: *Self, i: usize) ?*T {
|
||||||
|
if (i >= self.cursor) return null;
|
||||||
|
return &self.data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn getConstPtr(self: *const Self, i: usize) ?*const T {
|
||||||
|
if (i >= self.cursor) return null;
|
||||||
|
return &self.data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn items(self: *Self) []T {
|
||||||
|
return self.data[0..self.cursor];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn len(self: *const Self) usize {
|
||||||
|
return self.cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn capacity(_: *const Self) usize {
|
||||||
|
return Capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn available(self: *const Self) usize {
|
||||||
|
return Capacity - self.cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn clear(self: *Self) void {
|
||||||
|
self.cursor = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn isEmpty(self: *const Self) bool {
|
||||||
|
return self.cursor == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn isFull(self: *const Self) bool {
|
||||||
|
return self.cursor == Capacity;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
105
src/fixed_slot_map.zig
Normal file
105
src/fixed_slot_map.zig
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const FixedArrayList = @import("fixed_array_list.zig").FixedArrayList;
|
||||||
|
const Handle = @import("handle.zig").Handle;
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```zig
|
||||||
|
/// ```
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn FixedSlotMap(
|
||||||
|
comptime T: type,
|
||||||
|
comptime Capacity: usize,
|
||||||
|
) type {
|
||||||
|
return struct {
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIELDS
|
||||||
|
//
|
||||||
|
|
||||||
|
// --- VALUES ---
|
||||||
|
values: FixedArrayList(T, Capacity),
|
||||||
|
|
||||||
|
// --- LIFE TIMES ---
|
||||||
|
generations: FixedArrayList(u32, Capacity),
|
||||||
|
free_list: FixedArrayList(u32, Capacity),
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub const empty = Self{
|
||||||
|
.values = .empty,
|
||||||
|
.generations = .empty,
|
||||||
|
.free_list = .empty,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn put(
|
||||||
|
self: *Self,
|
||||||
|
value: T,
|
||||||
|
) error{Full}!Handle(T) {
|
||||||
|
// --- NEW GENERATION ---
|
||||||
|
if (self.free_list.pop()) |idx| {
|
||||||
|
self.values.data[@intCast(idx)] = value;
|
||||||
|
self.generations.data[@intCast(idx)] += 1;
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.idx = idx,
|
||||||
|
.gen = self.generations.data[idx],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- METADATA ---
|
||||||
|
const idx = self.values.len();
|
||||||
|
const handle: Handle(T) = .{
|
||||||
|
.idx = @intCast(idx),
|
||||||
|
.gen = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- NEW VALUE ---
|
||||||
|
try self.values.append(value);
|
||||||
|
errdefer _ = self.values.swapRemove(idx);
|
||||||
|
|
||||||
|
// --- NEW GENERATION ---
|
||||||
|
try self.generations.append(1);
|
||||||
|
|
||||||
|
// --- RESULT ---
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn remove(
|
||||||
|
self: *Self,
|
||||||
|
handle: Handle(T),
|
||||||
|
) void {
|
||||||
|
const idx: u32 = handle.idx;
|
||||||
|
|
||||||
|
// --- CHECK IF STALE ---
|
||||||
|
if (idx >= self.generations.len()) return;
|
||||||
|
if (self.generations.data[idx] != handle.gen) return;
|
||||||
|
|
||||||
|
// --- GENERATION ---
|
||||||
|
self.generations.data[idx] +|= 1;
|
||||||
|
self.free_list.append(idx) catch |err| {
|
||||||
|
std.debug.print("[SLOTMAP_ERROR] {s}\n", .{@errorName(err)});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn get(self: *Self, handle: Handle(T)) ?*T {
|
||||||
|
if (handle.idx >= self.values.len()) return null;
|
||||||
|
if (self.generations.data[handle.idx] != handle.gen) return null;
|
||||||
|
return &self.values.data[handle.idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
/// ----------------------------------------------------
|
||||||
|
pub fn items(self: *Self) []T {
|
||||||
|
return self.values.items();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
50
src/gtl.zig
50
src/gtl.zig
|
|
@ -11,10 +11,14 @@ const std = @import("std");
|
||||||
pub const log = @import("log.zig");
|
pub const log = @import("log.zig");
|
||||||
pub const ansi = @import("ansi.zig");
|
pub const ansi = @import("ansi.zig");
|
||||||
pub const Handle = @import("handle.zig").Handle;
|
pub const Handle = @import("handle.zig").Handle;
|
||||||
|
pub const TypeID = @import("type_id.zig").of;
|
||||||
|
|
||||||
|
// --- ARRAYS ---
|
||||||
pub const SlotMap = @import("slot_map.zig").SlotMap;
|
pub const SlotMap = @import("slot_map.zig").SlotMap;
|
||||||
pub const KeyedSlotMap = @import("keyed_slot_map.zig").KeyedSlotMap;
|
pub const KeyedSlotMap = @import("keyed_slot_map.zig").KeyedSlotMap;
|
||||||
|
pub const FixedArrayList = @import("fixed_array_list.zig").FixedArrayList;
|
||||||
|
pub const FixedSlotMap = @import("fixed_slot_map.zig").FixedSlotMap;
|
||||||
pub const RingBuffer = @import("ring_buffer.zig").RingBuffer;
|
pub const RingBuffer = @import("ring_buffer.zig").RingBuffer;
|
||||||
pub const TypeID = @import("type_id.zig").of;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// STRUCTS
|
// STRUCTS
|
||||||
|
|
@ -28,12 +32,6 @@ const GPUShader = struct { raw: *anyopaque };
|
||||||
const PipelineKey = struct { shader: ShaderID };
|
const PipelineKey = struct { shader: ShaderID };
|
||||||
const GPUPipeline = struct { raw: *anyopaque };
|
const GPUPipeline = struct { raw: *anyopaque };
|
||||||
|
|
||||||
// --- MATERIAL ---
|
|
||||||
const MaterialDep = struct {
|
|
||||||
shader: ShaderID = .pbr,
|
|
||||||
albedo: @Vector(4, f32) = .{ 0, 0, 0, 1 },
|
|
||||||
};
|
|
||||||
|
|
||||||
/// ----------------------------------------------------
|
/// ----------------------------------------------------
|
||||||
/// ----------------------------------------------------
|
/// ----------------------------------------------------
|
||||||
const Material = struct {
|
const Material = struct {
|
||||||
|
|
@ -170,10 +168,10 @@ test "SlotMap-DEP" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
test "RingBuffer" {
|
||||||
// RING BUFFER EXAMPLE
|
std.debug.print("{s}━━━ RING BUFFER ━━━{s}\n", .{ ansi.blue, ansi.reset });
|
||||||
//
|
|
||||||
|
|
||||||
var prev_inputs: RingBuffer([]const u8, 256) = .{};
|
var prev_inputs: RingBuffer([]const u8, 256) = .{};
|
||||||
|
|
||||||
|
|
@ -185,6 +183,36 @@ test "SlotMap-DEP" {
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (prev_inputs.pop()) |data| {
|
while (prev_inputs.pop()) |data| {
|
||||||
defer i += 1;
|
defer i += 1;
|
||||||
log.debug("[{}][PreviousInputs] -> \"{s}\"", .{ i, data }, null);
|
std.debug.print("[{}][PreviousInputs] -> \"{s}\"\n", .{ i, data });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "FixedArrayList" {
|
||||||
|
std.debug.print("{s}━━━ FIXED ARRAY LIST ━━━{s}\n", .{ ansi.blue, ansi.reset });
|
||||||
|
|
||||||
|
var entities: FixedArrayList(u32, 4) = .empty;
|
||||||
|
|
||||||
|
try entities.append(1);
|
||||||
|
try entities.append(2);
|
||||||
|
try entities.append(3);
|
||||||
|
|
||||||
|
if (entities.getPtr(0)) |v| v.* = 69;
|
||||||
|
|
||||||
|
for (entities.items()) |item| {
|
||||||
|
std.debug.print("Entity: {}\n", .{item});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "FixedSlotMap" {
|
||||||
|
std.debug.print("{s}━━━ FIXED SLOT MAP ━━━{s}\n", .{ ansi.blue, ansi.reset });
|
||||||
|
|
||||||
|
var materials: FixedSlotMap(Material, 3) = .empty;
|
||||||
|
|
||||||
|
_ = try materials.put(.{});
|
||||||
|
_ = try materials.put(.{});
|
||||||
|
const handle = try materials.put(.{ .unique = .{ .topology = .line_list } });
|
||||||
|
|
||||||
|
if (materials.get(handle)) |v| {
|
||||||
|
std.debug.print("Material: {}\n", .{v.unique.topology});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue