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**
|
||||
- ANSI
|
||||
- SlotMap | KeyedSlotMap
|
||||
- Custom Log
|
||||
# Includes
|
||||
|
||||
## Arrays
|
||||
- SlotMap
|
||||
- KeyedSlotMap
|
||||
|
||||
- FixedSlotMap
|
||||
- FixedArrayList
|
||||
- RingBuffer
|
||||
- Handle(T) **Generational**
|
||||
|
||||
## Misc
|
||||
- log
|
||||
- ansi (colors etc)
|
||||
- TypeID
|
||||
|
||||
**Logs**
|
||||
```zig
|
||||
log.warn("...", .{});
|
||||
log.err("...", .{});
|
||||
log.info("...", .{});
|
||||
log.debug("...", .{});
|
||||
log.trace("...", .{});
|
||||
log.fatal("...", .{});
|
||||
```
|
||||
# Examples
|
||||
|
||||
## KeyedSlotMap
|
||||
|
||||
**KeyedSlotMap**
|
||||
```zig
|
||||
// --- SHADER MAP ---
|
||||
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);
|
||||
```
|
||||
|
||||
**TypeID**
|
||||
## TypeID
|
||||
|
||||
```zig
|
||||
const Player = struct {};
|
||||
std.debug.print("TypeID(Player): {}\n", .{TypeID(Player)});
|
||||
|
|
@ -34,15 +38,26 @@ std.debug.print("TypeID(Player): {}\n", .{TypeID(Player)});
|
|||
Output: TypeID(Player): 2462284566368800629
|
||||
```
|
||||
|
||||
# NicePrint
|
||||
## Logs
|
||||
|
||||
## Styles
|
||||
```zig
|
||||
log.warn("...", .{});
|
||||
log.err("...", .{});
|
||||
log.info("...", .{});
|
||||
log.debug("...", .{});
|
||||
log.trace("...", .{});
|
||||
log.fatal("...", .{});
|
||||
```
|
||||
|
||||
## NicePrint
|
||||
|
||||
### Styles
|
||||
- default
|
||||
- rounded
|
||||
- pipe
|
||||
- custom
|
||||
|
||||
## Example
|
||||
### Example
|
||||
```zig
|
||||
// --- PRINT ---
|
||||
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
|
||||
┏━ DEVICE INFO
|
||||
┃ 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 ansi = @import("ansi.zig");
|
||||
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 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 TypeID = @import("type_id.zig").of;
|
||||
|
||||
//
|
||||
// STRUCTS
|
||||
|
|
@ -28,12 +32,6 @@ const GPUShader = struct { raw: *anyopaque };
|
|||
const PipelineKey = struct { shader: ShaderID };
|
||||
const GPUPipeline = struct { raw: *anyopaque };
|
||||
|
||||
// --- MATERIAL ---
|
||||
const MaterialDep = struct {
|
||||
shader: ShaderID = .pbr,
|
||||
albedo: @Vector(4, f32) = .{ 0, 0, 0, 1 },
|
||||
};
|
||||
|
||||
/// ----------------------------------------------------
|
||||
/// ----------------------------------------------------
|
||||
const Material = struct {
|
||||
|
|
@ -170,10 +168,10 @@ test "SlotMap-DEP" {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// RING BUFFER EXAMPLE
|
||||
//
|
||||
test "RingBuffer" {
|
||||
std.debug.print("{s}━━━ RING BUFFER ━━━{s}\n", .{ ansi.blue, ansi.reset });
|
||||
|
||||
var prev_inputs: RingBuffer([]const u8, 256) = .{};
|
||||
|
||||
|
|
@ -185,6 +183,36 @@ test "SlotMap-DEP" {
|
|||
var i: usize = 0;
|
||||
while (prev_inputs.pop()) |data| {
|
||||
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