cleaned .bak
This commit is contained in:
244
src/main.zig.bak
244
src/main.zig.bak
@@ -1,244 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
|
|
||||||
const glfw = @import("zglfw");
|
|
||||||
const zgl = @import("zgl");
|
|
||||||
|
|
||||||
const zm = @import("zmath");
|
|
||||||
const Mat = zm.Mat;
|
|
||||||
|
|
||||||
const zmesh = @import("zmesh");
|
|
||||||
const Shape = zmesh.Shape;
|
|
||||||
|
|
||||||
const glfw_helper = @import("glfw_helper/root.zig");
|
|
||||||
const GlfwContect = glfw_helper.GlfwContext;
|
|
||||||
const AppState = glfw_helper.AppState;
|
|
||||||
|
|
||||||
const gl_helper = @import("gl_helper/root.zig");
|
|
||||||
const Shader = gl_helper.Shader;
|
|
||||||
const Texture = gl_helper.Texture;
|
|
||||||
const Mesh = gl_helper.Mesh;
|
|
||||||
const ByteColor = gl_helper.Color.Byte;
|
|
||||||
const FloatColor = gl_helper.Color.Float;
|
|
||||||
|
|
||||||
pub const texture =
|
|
||||||
ByteColor.red ++ ByteColor.gold ++
|
|
||||||
ByteColor.gold ++ ByteColor.red;
|
|
||||||
|
|
||||||
pub const pyramid_texture =
|
|
||||||
ByteColor.violet ++ ByteColor.violet ++ ByteColor.violet ++ ByteColor.violet ++
|
|
||||||
ByteColor.blue ++ ByteColor.blue ++ ByteColor.blue ++ ByteColor.blue ++
|
|
||||||
ByteColor.green ++ ByteColor.green ++ ByteColor.green ++ ByteColor.green ++
|
|
||||||
ByteColor.red ++ ByteColor.red ++ ByteColor.red ++ ByteColor.red;
|
|
||||||
|
|
||||||
var app_state = AppState.init(
|
|
||||||
600,
|
|
||||||
600,
|
|
||||||
.diffuse,
|
|
||||||
zm.f32x4(0, 2, 3, 1),
|
|
||||||
3,
|
|
||||||
);
|
|
||||||
|
|
||||||
pub fn main() !void {
|
|
||||||
var debug_allocator = std.heap.DebugAllocator(.{}).init;
|
|
||||||
defer _ = debug_allocator.deinit();
|
|
||||||
const allocator = debug_allocator.allocator();
|
|
||||||
|
|
||||||
const context = try GlfwContect.init(&app_state, "ZGL Test");
|
|
||||||
|
|
||||||
zmesh.init(allocator);
|
|
||||||
defer zmesh.deinit();
|
|
||||||
|
|
||||||
// shaders
|
|
||||||
var model_shader = try Shader.initFile("shaders/default.vert", "shaders/default.frag");
|
|
||||||
defer model_shader.delete();
|
|
||||||
|
|
||||||
var instanced_shader = try Shader.initFile("shaders/instanced.vert", "shaders/default.frag");
|
|
||||||
defer instanced_shader.delete();
|
|
||||||
|
|
||||||
var diffuse_shader = try Shader.initFile("shaders/default.vert", "shaders/diffuse.frag");
|
|
||||||
defer diffuse_shader.delete();
|
|
||||||
|
|
||||||
var specular_shader = try Shader.initFile("shaders/default.vert", "shaders/specular.frag");
|
|
||||||
defer specular_shader.delete();
|
|
||||||
|
|
||||||
var light_shader = try Shader.initFile("shaders/light.vert", "shaders/light.frag");
|
|
||||||
defer light_shader.delete();
|
|
||||||
|
|
||||||
// textures
|
|
||||||
const textures: []const Texture = &.{Texture.init(0, .@"2d")};
|
|
||||||
textures[0].load(&texture, 2, 2, .rgba8, .rgba, .unsigned_byte);
|
|
||||||
|
|
||||||
const p_textures: []const Texture = &.{Texture.init(0, .@"2d")};
|
|
||||||
p_textures[0].load(&pyramid_texture, 4, 4, .rgba8, .rgba, .unsigned_byte);
|
|
||||||
|
|
||||||
// meshes
|
|
||||||
var floor_shape = Shape.initPlane(1, 1);
|
|
||||||
defer floor_shape.deinit();
|
|
||||||
floor_shape.translate(-0.5, -0.5, 0);
|
|
||||||
floor_shape.rotate(std.math.degreesToRadians(-90), 1, 0, 0);
|
|
||||||
floor_shape.scale(6, 1, 6);
|
|
||||||
if (floor_shape.texcoords) |texcoords| {
|
|
||||||
for (texcoords) |*coord| {
|
|
||||||
coord[0] *= 6;
|
|
||||||
coord[1] *= 6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const floor = Mesh.initShape(floor_shape, textures, .triangles);
|
|
||||||
defer floor.delete();
|
|
||||||
|
|
||||||
var pyramid_shape = Shape.initCone(4, 1);
|
|
||||||
defer pyramid_shape.deinit();
|
|
||||||
pyramid_shape.rotate(std.math.degreesToRadians(-90), 1, 0, 0);
|
|
||||||
pyramid_shape.scale(1, 1.5, 1);
|
|
||||||
for (pyramid_shape.texcoords.?) |*texcoord| {
|
|
||||||
texcoord[0] *= 3;
|
|
||||||
}
|
|
||||||
const pyramid = Mesh.initShape(pyramid_shape, p_textures, .triangles);
|
|
||||||
defer pyramid.delete();
|
|
||||||
|
|
||||||
var cube_shape = Shape.initCube();
|
|
||||||
defer cube_shape.deinit();
|
|
||||||
cube_shape.computeNormals();
|
|
||||||
cube_shape.translate(-3, 0, -3);
|
|
||||||
const cube = Mesh.initShape(cube_shape, textures, .triangles);
|
|
||||||
defer cube.delete();
|
|
||||||
|
|
||||||
// instancing uniforms
|
|
||||||
var cube_transformations: [27]Mat = undefined;
|
|
||||||
var cube_normals: [27]Mat = undefined;
|
|
||||||
for (0..3) |i| {
|
|
||||||
for (0..3) |j| {
|
|
||||||
for (0..3) |k| {
|
|
||||||
cube_transformations[i + 3 * (j + k * 3)] = zm.translation(
|
|
||||||
@as(f32, @floatFromInt(i)) * 2.5,
|
|
||||||
@as(f32, @floatFromInt(j)) * 2.5,
|
|
||||||
@as(f32, @floatFromInt(k)) * 2.5,
|
|
||||||
);
|
|
||||||
cube_normals[i + 3 * (j + k * 3)] = zm.transpose(zm.inverse(cube_transformations[i + 3 * (j + k * 3)]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// uniform data
|
|
||||||
const light_color = zm.f32x4s(1);
|
|
||||||
var pyramid_rotation = zm.quatFromRollPitchYaw(0, std.math.degreesToRadians(45), 0);
|
|
||||||
var light_pos = zm.f32x4(0, 2, 0, 1);
|
|
||||||
|
|
||||||
// uniform buffer objects
|
|
||||||
const matrix_ubo = gl_helper.initUbo(zm.Mat, &.{
|
|
||||||
model_shader,
|
|
||||||
instanced_shader,
|
|
||||||
diffuse_shader,
|
|
||||||
specular_shader,
|
|
||||||
light_shader,
|
|
||||||
}, "SharedMatrices", 0, 1);
|
|
||||||
defer matrix_ubo.delete();
|
|
||||||
|
|
||||||
const light_ubo = gl_helper.initUbo(f32, &.{
|
|
||||||
model_shader,
|
|
||||||
instanced_shader,
|
|
||||||
diffuse_shader,
|
|
||||||
specular_shader,
|
|
||||||
}, "Light", 1, 12);
|
|
||||||
defer light_ubo.delete();
|
|
||||||
light_ubo.subData(0, zm.Vec, &.{light_color});
|
|
||||||
|
|
||||||
// const uniforms
|
|
||||||
diffuse_shader.updateUniformMatrix("u_model_matrix", &.{zm.identity()});
|
|
||||||
diffuse_shader.updateUniformMatrix("u_normal_matrix", &.{zm.identity()});
|
|
||||||
specular_shader.updateUniformMatrix("u_model_matrix", &.{zm.identity()});
|
|
||||||
specular_shader.updateUniformMatrix("u_normal_matrix", &.{zm.identity()});
|
|
||||||
instanced_shader.updateUniformMatrix("u_model_matrix[0]", &cube_transformations);
|
|
||||||
instanced_shader.updateUniformMatrix("u_normal_matrix[0]", &cube_normals);
|
|
||||||
light_shader.updateUniformVec4("light_color", &.{light_color});
|
|
||||||
|
|
||||||
// time handling
|
|
||||||
var previous_time = glfw_helper.getTime();
|
|
||||||
var current_time: f64 = 0;
|
|
||||||
var delta_time: f64 = undefined;
|
|
||||||
|
|
||||||
// OpenGL setup
|
|
||||||
const clear_color = FloatColor.sky_blue;
|
|
||||||
zgl.clearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
|
|
||||||
zgl.enable(.program_point_size);
|
|
||||||
zgl.enable(.depth_test);
|
|
||||||
zgl.enable(.cull_face);
|
|
||||||
|
|
||||||
while (!context.window.shouldClose()) : (context.postRender()) {
|
|
||||||
// input
|
|
||||||
app_state.camera.move(@floatCast(delta_time));
|
|
||||||
moveLight(&light_pos, @floatCast(delta_time));
|
|
||||||
|
|
||||||
// ubo updates
|
|
||||||
app_state.camera.updateMatrix(60, 0.1, 200);
|
|
||||||
matrix_ubo.subData(0, Mat, &.{app_state.camera.matrix});
|
|
||||||
|
|
||||||
light_ubo.subData(@sizeOf(f32) * 4, zm.Vec, &.{light_pos});
|
|
||||||
light_ubo.subData(@sizeOf(f32) * 4 * 2, zm.Vec, &.{app_state.camera.position});
|
|
||||||
|
|
||||||
// render
|
|
||||||
zgl.clear(.{ .color = true, .depth = true });
|
|
||||||
|
|
||||||
switch (app_state.scene) {
|
|
||||||
.pyramid => {
|
|
||||||
model_shader.updateUniformMatrix("u_model_matrix", &.{zm.identity()});
|
|
||||||
model_shader.updateUniformMatrix("u_normal_matrix", &.{zm.identity()});
|
|
||||||
floor.draw(model_shader);
|
|
||||||
|
|
||||||
pyramid_rotation = zm.qmul(pyramid_rotation, zm.quatFromRollPitchYaw(0, @floatCast(-1 * delta_time), 0));
|
|
||||||
const pyramid_matrix = zm.quatToMat(pyramid_rotation);
|
|
||||||
model_shader.updateUniformMatrix("u_model_matrix", &.{pyramid_matrix});
|
|
||||||
model_shader.updateUniformMatrix("u_normal_matrix", &.{zm.transpose(zm.inverse(pyramid_matrix))});
|
|
||||||
pyramid.draw(model_shader);
|
|
||||||
},
|
|
||||||
.cubes => {
|
|
||||||
model_shader.updateUniformMatrix("u_model_matrix", &.{zm.identity()});
|
|
||||||
model_shader.updateUniformMatrix("u_normal_matrix", &.{zm.identity()});
|
|
||||||
floor.draw(model_shader);
|
|
||||||
|
|
||||||
cube.drawInstanced(instanced_shader, 27);
|
|
||||||
},
|
|
||||||
.diffuse => {
|
|
||||||
floor.draw(diffuse_shader);
|
|
||||||
},
|
|
||||||
.specular => {
|
|
||||||
floor.draw(specular_shader);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
light_shader.use();
|
|
||||||
light_shader.updateUniformVec4("u_position", &.{light_pos});
|
|
||||||
light_shader.updateUniformVec3("camera_pos", &.{zm.vecToArr3(app_state.camera.position)});
|
|
||||||
zgl.drawArrays(.points, 0, 1);
|
|
||||||
|
|
||||||
// time
|
|
||||||
current_time = glfw_helper.getTime();
|
|
||||||
delta_time = current_time - previous_time;
|
|
||||||
previous_time = current_time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn moveLight(light_pos: *zm.Vec, delta_time: f32) void {
|
|
||||||
if (app_state.light_controls.forward) {
|
|
||||||
light_pos[2] -= 3 * delta_time;
|
|
||||||
}
|
|
||||||
if (app_state.light_controls.left) {
|
|
||||||
light_pos[0] -= 3 * delta_time;
|
|
||||||
}
|
|
||||||
if (app_state.light_controls.backward) {
|
|
||||||
light_pos[2] += 3 * delta_time;
|
|
||||||
}
|
|
||||||
if (app_state.light_controls.right) {
|
|
||||||
light_pos[0] += 3 * delta_time;
|
|
||||||
}
|
|
||||||
if (app_state.light_controls.up) {
|
|
||||||
light_pos[1] += 3 * delta_time;
|
|
||||||
}
|
|
||||||
if (app_state.light_controls.down) {
|
|
||||||
light_pos[1] -= 3 * delta_time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
comptime {
|
|
||||||
std.testing.refAllDeclsRecursive(@This());
|
|
||||||
}
|
|
||||||
319
src/tree.zig.bak
319
src/tree.zig.bak
@@ -1,319 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const Allocator = std.mem.Allocator;
|
|
||||||
const testing = std.testing;
|
|
||||||
const assert = std.debug.assert;
|
|
||||||
const FixedBufferAllocator = std.heap.FixedBufferAllocator;
|
|
||||||
|
|
||||||
/// Generic k-ary tree represented as a "left-child right-sibling" binary tree.
|
|
||||||
pub fn Tree(comptime T: type) type {
|
|
||||||
return struct {
|
|
||||||
const Self = @This();
|
|
||||||
root: Node,
|
|
||||||
|
|
||||||
/// Node inside the tree.
|
|
||||||
pub const Node = struct {
|
|
||||||
value: T,
|
|
||||||
parent: ?*Node,
|
|
||||||
leftmost_child: ?*Node,
|
|
||||||
right_sibling: ?*Node,
|
|
||||||
|
|
||||||
fn init(value: T) Node {
|
|
||||||
return Node{
|
|
||||||
.value = value,
|
|
||||||
.parent = null,
|
|
||||||
.leftmost_child = null,
|
|
||||||
.right_sibling = null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Initialize a tree.
|
|
||||||
///
|
|
||||||
/// Arguments:
|
|
||||||
/// value: Value (aka weight, key, etc.) of the root node.
|
|
||||||
///
|
|
||||||
/// Returns:
|
|
||||||
/// A tree containing one node with specified value.
|
|
||||||
pub fn init(value: T) Self {
|
|
||||||
return Self{
|
|
||||||
.root = Node.init(value),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Allocate a new node. Caller owns returned Node and must free with `destroyNode`.
|
|
||||||
///
|
|
||||||
/// Arguments:
|
|
||||||
/// allocator: Dynamic memory allocator.
|
|
||||||
///
|
|
||||||
/// Returns:
|
|
||||||
/// A pointer to the new node.
|
|
||||||
///
|
|
||||||
/// Errors:
|
|
||||||
/// If a new node cannot be allocated.
|
|
||||||
pub fn allocateNode(tree: *Self, allocator: *Allocator) !*Node {
|
|
||||||
_ = tree; // autofix
|
|
||||||
return allocator.create(Node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Deallocate a node. Node must have been allocated with `allocator`.
|
|
||||||
///
|
|
||||||
/// Arguments:
|
|
||||||
/// node: Pointer to the node to deallocate.
|
|
||||||
/// allocator: Dynamic memory allocator.
|
|
||||||
pub fn destroyNode(tree: *Self, node: *Node, allocator: *Allocator) void {
|
|
||||||
assert(tree.containsNode(node));
|
|
||||||
allocator.destroy(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Allocate and initialize a node and its value.
|
|
||||||
///
|
|
||||||
/// Arguments:
|
|
||||||
/// value: Value (aka weight, key, etc.) of newly created node.
|
|
||||||
/// allocator: Dynamic memory allocator.
|
|
||||||
///
|
|
||||||
/// Returns:
|
|
||||||
/// A pointer to the new node.
|
|
||||||
///
|
|
||||||
/// Errors:
|
|
||||||
/// If a new node cannot be allocated.
|
|
||||||
pub fn createNode(tree: *Self, value: T, allocator: *Allocator) !*Node {
|
|
||||||
const node = try tree.allocateNode(allocator);
|
|
||||||
node.* = Node.init(value);
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Insert a node at the specified position inside the tree.
|
|
||||||
///
|
|
||||||
/// Arguments:
|
|
||||||
/// node: Pointer to the node to insert.
|
|
||||||
/// parent: Pointer to node which the newly created node will be a child of.
|
|
||||||
///
|
|
||||||
/// Returns:
|
|
||||||
/// A pointer to the new node.
|
|
||||||
pub fn insert(tree: *Self, node: *Node, parent: *Node) void {
|
|
||||||
_ = tree; // autofix
|
|
||||||
node.parent = parent;
|
|
||||||
node.right_sibling = parent.leftmost_child;
|
|
||||||
parent.leftmost_child = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add another tree at the specified position inside this tree.
|
|
||||||
///
|
|
||||||
/// Arguments:
|
|
||||||
/// other: Pointer to the tree to insert.
|
|
||||||
/// parent: Pointer to node which the newly created node will be a parent of.
|
|
||||||
pub fn graft(tree: *Self, other: *Self, parent: *Node) void {
|
|
||||||
_ = tree; // autofix
|
|
||||||
_ = other; // autofix
|
|
||||||
_ = parent; // autofix
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove (detach) a "branch" from the tree (remove node and all its descendants).
|
|
||||||
/// Does nothing when applied to root node.
|
|
||||||
///
|
|
||||||
/// Arguments:
|
|
||||||
/// node: Pointer to node to be removed.
|
|
||||||
pub fn prune(tree: *Self, node: *Node) void {
|
|
||||||
assert(tree.containsNode(node));
|
|
||||||
if (node.parent) |parent| {
|
|
||||||
var ptr = &parent.leftmost_child;
|
|
||||||
while (ptr.*) |sibling| : (ptr = &sibling.right_sibling) {
|
|
||||||
if (sibling == node) {
|
|
||||||
ptr.* = node.right_sibling;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
node.right_sibling = null;
|
|
||||||
node.parent = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove a node preserving all its children, which take its place inside the tree.
|
|
||||||
/// Does nothing when applied to root node.
|
|
||||||
///
|
|
||||||
/// Arguments:
|
|
||||||
/// node: Pointer to node to be removed.
|
|
||||||
pub fn remove(tree: *Self, node: *Node) void {
|
|
||||||
assert(tree.containsNode(node));
|
|
||||||
if (node.parent) |parent| {
|
|
||||||
var ptr = &parent.leftmost_child;
|
|
||||||
while (ptr.*) |sibling| : (ptr = &sibling.right_sibling) {
|
|
||||||
if (sibling == node) break;
|
|
||||||
}
|
|
||||||
ptr.* = node.leftmost_child;
|
|
||||||
while (ptr.*) |old_child| : (ptr = &old_child.right_sibling) {
|
|
||||||
old_child.parent = parent;
|
|
||||||
}
|
|
||||||
ptr.* = node.right_sibling;
|
|
||||||
node.parent = null;
|
|
||||||
node.leftmost_child = null;
|
|
||||||
node.right_sibling = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Iterator that performs a depth-first post-order traversal of the tree.
|
|
||||||
/// It is non-recursive and uses constant memory (no allocator needed).
|
|
||||||
pub const DepthFirstIterator = struct {
|
|
||||||
const State = enum {
|
|
||||||
GoDeeper,
|
|
||||||
GoBroader,
|
|
||||||
};
|
|
||||||
tree: *Self,
|
|
||||||
current: ?*Node,
|
|
||||||
state: State,
|
|
||||||
|
|
||||||
// NB:
|
|
||||||
// If not children_done:
|
|
||||||
// Go as deep as possible
|
|
||||||
// Yield node
|
|
||||||
// If can move right:
|
|
||||||
// children_done = false;
|
|
||||||
// Move right
|
|
||||||
// Else:
|
|
||||||
// children_done = true;
|
|
||||||
// Move up
|
|
||||||
|
|
||||||
pub fn init(tree: *Self) DepthFirstIterator {
|
|
||||||
return DepthFirstIterator{
|
|
||||||
.tree = tree,
|
|
||||||
.current = &tree.root,
|
|
||||||
.state = State.GoDeeper,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next(it: *DepthFirstIterator) ?*Node {
|
|
||||||
// State machine
|
|
||||||
while (it.current) |current| {
|
|
||||||
switch (it.state) {
|
|
||||||
State.GoDeeper => {
|
|
||||||
// Follow child node until deepest possible level
|
|
||||||
if (current.leftmost_child) |child| {
|
|
||||||
it.current = child;
|
|
||||||
} else {
|
|
||||||
it.state = State.GoBroader;
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State.GoBroader => {
|
|
||||||
if (current.right_sibling) |sibling| {
|
|
||||||
it.current = sibling;
|
|
||||||
it.state = State.GoDeeper;
|
|
||||||
} else {
|
|
||||||
it.current = current.parent;
|
|
||||||
return current.parent;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset(it: *DepthFirstIterator) void {
|
|
||||||
it.current = it.tree.root;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Get a depth-first iterator over the nodes of this tree.
|
|
||||||
///
|
|
||||||
/// Returns:
|
|
||||||
/// An iterator struct (one containing `next` and `reset` member functions).
|
|
||||||
pub fn depthFirstIterator(tree: *Self) DepthFirstIterator {
|
|
||||||
return DepthFirstIterator.init(tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if a node is contained in this tree.
|
|
||||||
///
|
|
||||||
/// Arguments:
|
|
||||||
/// target: Pointer to node to be searched for.
|
|
||||||
///
|
|
||||||
/// Returns:
|
|
||||||
/// A bool telling whether it has been found.
|
|
||||||
pub fn containsNode(tree: *Self, target: *Node) bool {
|
|
||||||
var iter = tree.depthFirstIterator();
|
|
||||||
while (iter.next()) |node| {
|
|
||||||
if (node == target) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
test "tree node insertion" {
|
|
||||||
var tree = Tree(u32).init(1);
|
|
||||||
|
|
||||||
const allocator = std.debug.global_allocator;
|
|
||||||
//var buffer: [5000]u8 = undefined;
|
|
||||||
// const allocator = &FixedBufferAllocator.init(buffer[0..]).allocator;
|
|
||||||
|
|
||||||
const two = try tree.createNode(2, allocator);
|
|
||||||
const three = try tree.createNode(3, allocator);
|
|
||||||
const four = try tree.createNode(4, allocator);
|
|
||||||
const five = try tree.createNode(5, allocator);
|
|
||||||
const six = try tree.createNode(6, allocator);
|
|
||||||
const fortytwo = try tree.createNode(42, allocator);
|
|
||||||
defer {
|
|
||||||
tree.destroyNode(two, allocator);
|
|
||||||
tree.destroyNode(three, allocator);
|
|
||||||
tree.destroyNode(four, allocator);
|
|
||||||
tree.destroyNode(five, allocator);
|
|
||||||
tree.destroyNode(six, allocator);
|
|
||||||
allocator.destroy(fortytwo);
|
|
||||||
}
|
|
||||||
|
|
||||||
tree.insert(two, &tree.root);
|
|
||||||
tree.insert(three, &tree.root);
|
|
||||||
tree.insert(four, &tree.root);
|
|
||||||
tree.insert(five, two);
|
|
||||||
tree.insert(six, two);
|
|
||||||
|
|
||||||
testing.expect(tree.root.value == 1);
|
|
||||||
testing.expect(two.parent == &tree.root);
|
|
||||||
testing.expect(three.parent == &tree.root);
|
|
||||||
testing.expect(tree.containsNode(four));
|
|
||||||
testing.expect(five.parent == two);
|
|
||||||
testing.expect(!tree.containsNode(fortytwo));
|
|
||||||
|
|
||||||
var iter = tree.depthFirstIterator();
|
|
||||||
while (iter.next()) |node| {
|
|
||||||
std.debug.warn("{} ", node.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test "tree node removal" {
|
|
||||||
var tree = Tree(u32).init(1);
|
|
||||||
|
|
||||||
const allocator = std.debug.global_allocator;
|
|
||||||
|
|
||||||
const two = try tree.createNode(2, allocator);
|
|
||||||
const three = try tree.createNode(3, allocator);
|
|
||||||
const four = try tree.createNode(4, allocator);
|
|
||||||
const five = try tree.createNode(5, allocator);
|
|
||||||
const six = try tree.createNode(6, allocator);
|
|
||||||
defer {
|
|
||||||
tree.destroyNode(three, allocator);
|
|
||||||
tree.destroyNode(four, allocator);
|
|
||||||
allocator.destroy(two);
|
|
||||||
allocator.destroy(five);
|
|
||||||
allocator.destroy(six);
|
|
||||||
}
|
|
||||||
|
|
||||||
tree.insert(two, &tree.root);
|
|
||||||
tree.insert(three, &tree.root);
|
|
||||||
tree.insert(four, &tree.root);
|
|
||||||
tree.insert(five, two);
|
|
||||||
tree.insert(six, two);
|
|
||||||
|
|
||||||
tree.prune(two);
|
|
||||||
|
|
||||||
testing.expect(tree.containsNode(three));
|
|
||||||
testing.expect(tree.containsNode(four));
|
|
||||||
testing.expect(!tree.containsNode(two));
|
|
||||||
testing.expect(!tree.containsNode(five));
|
|
||||||
testing.expect(!tree.containsNode(six));
|
|
||||||
var iter = tree.depthFirstIterator();
|
|
||||||
while (iter.next()) |node| {
|
|
||||||
std.debug.warn("{} ", node.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user