86 lines
3.0 KiB
Zig
86 lines
3.0 KiB
Zig
const std = @import("std");
|
|
const rl = @import("raylib");
|
|
|
|
const c = @import("../common/constants.zig");
|
|
const e = @import("../errors.zig");
|
|
const st = @import("../common/structures.zig");
|
|
const Road = @import("road.zig").Road;
|
|
|
|
pub const Node = struct {
|
|
/// Possibly unnecessary, but for now it's good as a secondary mean of identification
|
|
id: usize,
|
|
/// Node's position on the simulation 'field'
|
|
pos: rl.Vector2,
|
|
/// Contains references of all the roads this node is connected to
|
|
roads: std.ArrayList(*Road),
|
|
|
|
/// Simple constructor
|
|
pub fn init(new_id: usize, new_pos: rl.Vector2) Node {
|
|
return .{
|
|
.id = new_id,
|
|
.pos = new_pos,
|
|
.roads = .empty,
|
|
};
|
|
}
|
|
|
|
/// This function frees the list that holds road references that are connected to this node
|
|
///
|
|
/// Next it invalidates itself (the pointer), making it invalid
|
|
pub fn deinit(self: *Node, allocator: std.mem.Allocator) !void {
|
|
if (self.roads.items.len != 0) return e.Entity.AlreadyReferenced;
|
|
|
|
self.roads.deinit(allocator);
|
|
allocator.destroy(self);
|
|
}
|
|
|
|
/// Simple function which draws the node
|
|
pub fn draw(self: *const Node, direct_colour: ?rl.Color) void {
|
|
const colour = if (direct_colour) |clr| clr else c.NODE_COLOUR;
|
|
|
|
rl.drawCircleV(self.pos, c.NODE_RADIUS, colour);
|
|
}
|
|
|
|
/// Determines whether the pos (location) is within the snapping radius of the node
|
|
pub fn withinSnapRadius(self: *const Node, pos: rl.Vector2) bool {
|
|
return rl.checkCollisionPointCircle(pos, self.pos, c.NODE_SNAP_RADIUS);
|
|
}
|
|
|
|
/// Determines whether the pos (location) is within the strict (visual representation) radius of the node
|
|
pub fn withinRadius(self: *const Node, pos: rl.Vector2) bool {
|
|
return rl.checkCollisionPointCircle(pos, self.pos, c.NODE_RADIUS);
|
|
}
|
|
|
|
/// Tries to reference the passed road to self
|
|
///
|
|
/// Returns an error if the passed road cannot be appended to the list or if said road is already in the list
|
|
pub fn referenceRoad(self: *Node, allocator: std.mem.Allocator, road_to_add: *Road) !void {
|
|
// Note the road_to_add pointer must be one from the roads list as otherwise the pointer is dangling one
|
|
for (self.roads.items) |road| {
|
|
if (road == road_to_add) return e.Entity.AlreadyReferenced;
|
|
}
|
|
|
|
try self.roads.append(allocator, road_to_add);
|
|
}
|
|
|
|
/// Attempts to unreference the passed road from self (node)
|
|
///
|
|
/// Returns whether the node still has node references (true) or not (false)
|
|
///
|
|
/// Returns an error if the road is not referenced to self in the first place
|
|
pub fn unreferenceRoad(self: *Node, road_to_remove: *const Road) !void {
|
|
for (0..self.roads.items.len) |i| {
|
|
if (self.roads.items[i] != road_to_remove) continue;
|
|
|
|
_ = self.roads.swapRemove(i);
|
|
return;
|
|
}
|
|
|
|
return e.Entity.NotFound;
|
|
}
|
|
};
|
|
|
|
// TODO tests
|
|
// road reference test
|
|
// pos within node test
|
|
// deinit test
|
|
// roads ptr list test |