Backlog/lib/p2/src/p2.zig

340 lines
12 KiB
Zig

// ---- ----
const std = @import("std");
const utils = @import("structures/utils.zig");
pub const getFileExtension = utils.getFileExtension;
pub const getBasePath = utils.getBasePath;
pub const getFolder = utils.getFolder;
pub const getDir = utils.getFolder;
pub const BumpArena = @import("structures/bump-arena.zig").BumpArena;
pub const dupeString = utils.dupeString;
pub const xxd = @import("utils/xxd.zig");
pub const stringStrip = utils.stringStrip;
pub const xxdWrite = xxd.xxdWrite;
pub const loadFileAlloc = utils.loadFileAlloc;
const ArrayList = std.ArrayList;
const ArrayListUnmanaged = std.ArrayListUnmanaged;
pub usingnamespace @import("structures/interface.zig");
pub const assertf = utils.assertf;
pub const asserts = utils.asserts;
pub const assert = utils.assert;
pub const createFileWithPath = utils.createFileWithPath;
pub const static_structures = @import("structures/static-structures.zig");
pub const StaticVector = static_structures.StaticVector;
pub const ring_queue = @import("structures/ring-queue.zig");
pub const RingQueueU = ring_queue.RingQueueU;
pub const RingQueue = ring_queue.RingQueue;
pub const sparse_set = @import("structures/sparse-set.zig");
pub const SparseSet = sparse_set.SparseSet;
pub const SparseMap = sparse_set.SparseMap;
pub const SparseMultiSet = sparse_set.SparseMultiSet;
pub const SparseSetAdvanced = sparse_set.SparseSetAdvanced;
pub const SparseMultiSetAdvanced = sparse_set.SparseMultiSetAdvanced;
pub const SetHandle = sparse_set.SetHandle;
pub const EcsContainerInterface = sparse_set.EcsContainerInterface;
pub const stack_structures = @import("structures/stack-structures.zig");
pub const index_pool = @import("structures/index-pool.zig");
pub const IndexPoolHandle = index_pool.Handle;
pub const IndexPool = index_pool.IndexPool;
pub const concurrent_queue = @import("structures/concurrent-queue.zig");
pub const ConcurrentQueueU = concurrent_queue.ConcurrentQueueU;
pub const ConcurrentQueueUnmanagedAdvanced = concurrent_queue.ConcurrentQueueUnmanagedAdvanced;
pub const string_pool = @import("structures/string-pool.zig");
pub const paged_vector = @import("structures/paged-vector.zig");
pub const PagedVector = paged_vector.PagedVector;
pub const names = @import("structures/names.zig");
pub const NameInvalid = names.NameInvalid;
pub const Name = names.Name;
pub const StaticName = names.StaticName;
pub const MakeName = names.MakeName;
pub const DefineName = names.DefineName;
pub const createNameRegistry = names.createNameRegistry;
pub const destroyNameRegistry = names.destroyNameRegistry;
pub const setNameRegistry = names.setNameRegistry;
pub const NameRegistry = names.NameRegistry;
pub const spans = @import("structures/spans.zig");
pub const MergedSpans = spans.MergedSpans;
pub const Span = spans.Span;
pub const shell = @import("utils/shell.zig");
pub fn sharedLibNameAlloc(allocator: std.mem.Allocator, s: []const u8) ![]u8 {
const os_tag = @import("builtin").os.tag;
var suffix: []const u8 = "dll";
var prefix: []const u8 = "";
if (os_tag == .linux) {
prefix = "lib";
suffix = "so";
} else if (os_tag == .macos) {
suffix = "dylib";
prefix = "lib";
}
const path = try std.fmt.allocPrint(allocator, "{s}{s}.{s}", .{ prefix, s, suffix });
return path;
}
comptime {
std.testing.refAllDecls(utils);
std.testing.refAllDecls(static_structures);
std.testing.refAllDecls(ring_queue);
std.testing.refAllDecls(sparse_set);
std.testing.refAllDecls(stack_structures);
std.testing.refAllDecls(index_pool);
std.testing.refAllDecls(concurrent_queue);
std.testing.refAllDecls(string_pool);
std.testing.refAllDecls(spans);
}
// ---- aliases ----
pub const ObjectHandle = SetHandle;
pub inline fn u32_to_slice(array: *u32) []u8 {
var slice: []u8 = undefined;
slice.ptr = @ptrCast(array);
slice.len = 4;
return slice;
}
pub inline fn u64_to_slice(array: *u64) []u8 {
var slice: []u8 = undefined;
slice.ptr = @ptrCast(array);
slice.len = 8;
return slice;
}
pub inline fn arrayTo_u32(array: anytype) u32 {
return @as(*const u32, @ptrCast(@alignCast(&array))).*;
}
pub inline fn arrayTo_u64(array: anytype) u64 {
return @as(*const u64, @ptrCast(@alignCast(&array))).*;
}
// ---- tests ----
test "multi-sparse-basic" {
const allocator = std.testing.allocator;
const TestStructField = struct {
x: u32,
};
const TestStruct = struct {
field1: usize,
structField: TestStructField,
};
var testSet = SparseMultiSet(TestStruct).init(allocator);
defer testSet.deinit();
const sparseHandle = try testSet.createObject(.{ .field1 = 1, .structField = .{ .x = 12 } });
const sparseHandle1 = try testSet.createObject(.{ .field1 = 2, .structField = .{ .x = 34 } });
const sparseHandle2 = try testSet.createObject(.{ .field1 = 3, .structField = .{ .x = 56 } });
std.debug.print("handle: {any}\n", .{testSet.get(sparseHandle, .field1).?.*});
std.debug.print("handle1: {any}\n", .{testSet.get(sparseHandle1, .field1).?.*});
std.debug.print("handle2: {any}\n", .{testSet.get(sparseHandle2, .field1).?.*});
_ = testSet.destroyObject(sparseHandle);
std.debug.print("handle1: {any}\n", .{testSet.get(sparseHandle1, .field1).?.*});
std.debug.print("handle2: {any}\n", .{testSet.get(sparseHandle2, .field1).?.*});
}
// As backlog is primarily a playground for me to learn and practice programming,
// There will be some implementations of basic data structures. For fun ofc
pub fn AppendToArrayListUnique(list: anytype, value: anytype) !void {
for (list.items) |v| {
if (v == value)
return;
}
try list.append(value);
}
fn printSetHandle(s: SetHandle) void {
std.debug.print("{any}\n", .{s});
}
test "sparse-set" {
std.debug.print("\n", .{});
const Payload = struct {
name: []const u8,
v: u32,
};
const PayloadSet = SparseSet(Payload);
const expect = std.testing.expect;
var set = PayloadSet.init(std.testing.allocator);
defer set.deinit();
var set2 = PayloadSet.init(std.testing.allocator);
defer set2.deinit();
const setHandle = (try set.createAndGet(.{ .name = "object1", .v = 0 })).handle;
printSetHandle(setHandle);
const setHandle1 = (try set.createObject(.{ .name = "object2", .v = 1 }));
printSetHandle(setHandle1);
const setHandle2 = (try set.createObject(.{ .name = "object3", .v = 2 }));
printSetHandle(setHandle2);
const setHandle3 = (try set.createObject(.{ .name = "object4", .v = 3 }));
printSetHandle(setHandle3);
const set2Handle1 = (try set2.createWithHandle(setHandle3, set.get(setHandle2).?.*)).handle;
std.debug.print("set2 handle: \n", .{});
printSetHandle(set2Handle1);
for (set.dense.items) |entry| {
std.debug.print("{any}: {s}\n", .{ entry.value, entry.value.name });
}
std.debug.print("\ndestroying handle\n", .{});
set.destroyObject(setHandle);
for (set.dense.items) |entry| {
std.debug.print("{any}: {s}\n", .{ entry.value, entry.value.name });
}
try expect(set.get(setHandle) == null);
try expect(set.get(setHandle1).?.v == 1);
try expect(set.get(setHandle2).?.v == 2);
try expect(set.get(setHandle3).?.v == 3);
std.debug.print("\ndestroying handle\n", .{});
set.destroyObject(setHandle1);
for (set.dense.items) |entry| {
std.debug.print("{any}: {s}\n", .{ entry.value, entry.value.name });
}
try expect(set.get(setHandle) == null);
try expect(set.get(setHandle1) == null);
try expect(set.get(setHandle2).?.v == 2);
try expect(set.get(setHandle3).?.v == 3);
std.debug.print("\ndestroying handle\n", .{});
set.destroyObject(setHandle2);
for (set.dense.items) |entry| {
std.debug.print("{any}: {s}\n", .{ entry.value, entry.value.name });
}
try expect(set.get(setHandle) == null);
try expect(set.get(setHandle1) == null);
try expect(set.get(setHandle3).?.v == 3);
try expect(set.get(setHandle2) == null);
std.debug.print("\ndestroying handle\n", .{});
set.destroyObject(setHandle3);
for (set.dense.items) |entry| {
std.debug.print("{any}: {s}\n", .{ entry.value, entry.value.name });
}
try expect(set.get(setHandle) == null);
try expect(set.get(setHandle1) == null);
try expect(set.get(setHandle2) == null);
try expect(set.get(setHandle3) == null);
try expect(set.dense.items.len == 0);
}
test "ringBuffer" {
std.debug.print("\nbuffer test: filling a ring buffer\n", .{});
const allocator = std.testing.allocator;
var b = try RingQueueU(u32).init(allocator, 4);
defer b.deinit(allocator);
const expect = std.testing.expect;
try b.push(1);
std.debug.print("head={d} tail={d}\n", .{ b.head, b.tail });
try b.push(2);
std.debug.print("head={d} tail={d}\n", .{ b.head, b.tail });
try b.push(3);
std.debug.print("head={d} tail={d}\n", .{ b.head, b.tail });
try expect(b.count() == 3);
std.debug.print("popping: {d}\n", .{b.pop().?});
std.debug.print("head={d} tail={d}\n", .{ b.head, b.tail });
try expect(b.count() == 2);
std.debug.print("popping: {d}\n", .{b.pop().?});
try expect(b.count() == 1);
std.debug.print("head={d} tail={d}\n", .{ b.head, b.tail });
std.debug.print("popping: {d}\n", .{b.pop().?});
try expect(b.count() == 0);
try expect(b.pop() == null);
std.debug.print("head={d} tail={d}\n", .{ b.head, b.tail });
try std.testing.expect(b.head == b.tail);
try std.testing.expect(b.isEmpty());
try b.push(11);
std.debug.print("head={d} tail={d} count={d} len={d}\n", .{ b.head, b.tail, b.count(), b.buffer.len });
try expect(b.count() == 1);
try b.push(12);
std.debug.print("head={d} tail={d} count={d} len={d}\n", .{ b.head, b.tail, b.count(), b.buffer.len });
try expect(b.count() == 2);
try b.push(13);
std.debug.print("head={d} tail={d} count={d} len={d}\n", .{ b.head, b.tail, b.count(), b.buffer.len });
try expect(b.count() == 3);
try b.push(14);
std.debug.print("head={d} tail={d} count={d} len={d}\n", .{ b.head, b.tail, b.count(), b.buffer.len });
try expect(b.head == 3);
try expect(b.count() == 4);
try expect(b.tail == ((b.head + 4) % b.buffer.len));
try expect(b.at(0).? == b.peek().?);
const newSize = b.buffer.len * 4;
try b.resize(allocator, newSize); // grow that shit, expect the new size to be size + 1
try expect(b.capacity() == newSize);
try expect(b.buffer.len == newSize + 1);
var errorHit: bool = false;
b.resize(allocator, 2) catch |e| {
errorHit = true;
try expect(e == error.AllocSizeTooSmall);
std.debug.print("{any}\n", .{e});
};
try expect(errorHit);
try expect(b.peekBack().?.* == 14);
try expect(b.atBack(1).?.* == 14);
try expect(b.atBack(2).?.* == 13);
try expect(b.atBack(3).?.* == 12);
try expect(b.atBack(4).?.* == 11);
try b.pushFront(44);
try expect(b.count() == 5);
try expect(b.peek().?.* == 44);
}
test "spin child process echo" {
{
std.debug.print("spin child process\n", .{});
const process = try shell.ShellProcess.init(std.testing.allocator, &.{ "echo", "lmao 2 nova" });
defer process.deinit();
std.debug.print("child process created: {s}\n", .{process.argv});
}
{
std.debug.print("spin child process 2\n", .{});
const process = try shell.ShellProcess.initCmd(std.testing.allocator, "echo lmao2nova -target='lmao 3 nova'");
defer process.deinit();
std.debug.print("{s}\n", .{process.argv});
}
}