From eca857cda1a0fe31b43a593cae3e1120a4027c79 Mon Sep 17 00:00:00 2001 From: Marto Date: Sat, 2 May 2026 20:47:51 +0200 Subject: [PATCH] Implementation of car removal when infrastructure where car is located gets removed itself --- src/common/structures.zig | 4 +-- src/infrastructure/node_manager.zig | 4 +-- src/simulator.zig | 24 ++++++++++----- src/vehicles/car.zig | 26 +++++++++++++--- src/vehicles/car_manager.zig | 47 +++++++++++++++++++++++++++-- 5 files changed, 88 insertions(+), 17 deletions(-) diff --git a/src/common/structures.zig b/src/common/structures.zig index 1e5ac80..5f80472 100644 --- a/src/common/structures.zig +++ b/src/common/structures.zig @@ -18,8 +18,8 @@ pub const Entity = union(enum) { /// Similar to `Entity` but only for infrastructure entities, so road and node only (for now) pub const Infrastructure = union(enum) { - node: *Node, - road: *Road, + node: *const Node, + road: *const Road, }; /// Represents intersection data, mainly used in cases where we draw over existing roads diff --git a/src/infrastructure/node_manager.zig b/src/infrastructure/node_manager.zig index 8369c97..c86219a 100644 --- a/src/infrastructure/node_manager.zig +++ b/src/infrastructure/node_manager.zig @@ -95,7 +95,7 @@ pub const NodeManager = struct { } /// Deletes node, returns error if node still has road references - pub fn deleteNode(self: *NodeManager, allocator: std.mem.Allocator, node_to_delete: *Node) !void { + pub fn removeNode(self: *NodeManager, allocator: std.mem.Allocator, node_to_delete: *Node) !void { for (0..self.nodes.items.len) |i| { if (self.nodes.items[i] != node_to_delete) continue; @@ -126,7 +126,7 @@ pub const NodeManager = struct { self.temp_node = null; if (node.roads.items.len != 0) return; - self.deleteNode(allocator, node) catch |err| { + self.removeNode(allocator, node) catch |err| { std.debug.panic("Failed to delete the temporary node: {}\n", .{err}); }; diff --git a/src/simulator.zig b/src/simulator.zig index a88bf0a..bd81417 100644 --- a/src/simulator.zig +++ b/src/simulator.zig @@ -189,15 +189,25 @@ pub const Simulator = struct { const start_node = h_road.nodes[0]; const end_node = h_road.nodes[1]; - self.road_man.deleteRoad(self.allocator, h_road) catch |err| { - std.debug.panic("Road deletion failed: {}\n", .{err}); - }; + try self.road_man.deleteRoad(self.allocator, h_road); - if (start_node.roads.items.len == 0) - try self.node_man.deleteNode(self.allocator, start_node); + if (start_node.roads.items.len == 0) { + const cars = try self.car_man.getCarsOnInf(self.allocator, .{ .node = start_node }); + defer self.allocator.free(cars); - if (end_node.roads.items.len == 0) - try self.node_man.deleteNode(self.allocator, end_node); + // TODO replace with removeMultipleCars + for (self.car_man.cars.items) |car| { + try self.car_man.removeCar(self.allocator, car); + } + + try self.node_man.removeNode(self.allocator, start_node); + } + + if (end_node.roads.items.len == 0) { + // TODO same as above + try self.node_man.removeNode(self.allocator, end_node); + // TODO after this is done, do the same with the function that removes roads + } } /// Clearing node and road lists without deinitialising them (only the children) diff --git a/src/vehicles/car.zig b/src/vehicles/car.zig index fad13fb..0c2c340 100644 --- a/src/vehicles/car.zig +++ b/src/vehicles/car.zig @@ -3,17 +3,21 @@ const rl = @import("raylib"); const c = @import("../common/constants.zig"); const st = @import("../common/structures.zig"); +const ut = @import("../common/utils.zig"); const Node = @import("../infrastructure/node.zig").Node; pub const Car = struct { + /// Car ID, for easier debugging and identification id: usize, - pos: rl.Vector2, + /// When car progresses along the road its location is determined via entity id and progress + progress: f32, + /// Tracks which infrastructure (pointer) the car is currently located at inf: st.Infrastructure, pub fn init(new_id: usize, spawn_node: *Node) Car { return .{ .id = new_id, - .pos = spawn_node.pos, + .progress = 0, .inf = .{ .node = spawn_node }, }; } @@ -23,7 +27,20 @@ pub const Car = struct { } pub fn draw(self: *const Car, display_info: bool) void { - rl.drawEllipseV(self.pos, 20, 15, .red); + var pos: rl.Vector2 = undefined; + + switch (self.inf) { + .node => |node| pos = node.pos, + .road => |road| { + const road_vector = ut.getVectorP1P2(road.nodes[0].pos, road.nodes[1].pos); + pos = .{ + .x = road_vector.x / 2, + .y = road_vector.y / 2, + }; + } + } + + rl.drawEllipseV(pos, 20, 15, .red); if (!display_info) return; @@ -32,6 +49,7 @@ pub const Car = struct { std.debug.panic("Failed to allocate space for ID???: {}\n", .{ err }); }; - rl.drawText(entity_info, @trunc(self.pos.x), @trunc(self.pos.y), c.ENTITY_DATA_TEXT_SIZE, c.ENTITY_DATA_TEXT_COLOUR); + + rl.drawText(entity_info, @trunc(pos.x), @trunc(pos.y), c.ENTITY_DATA_TEXT_SIZE, c.ENTITY_DATA_TEXT_COLOUR); } }; \ No newline at end of file diff --git a/src/vehicles/car_manager.zig b/src/vehicles/car_manager.zig index 712c36e..e8833e1 100644 --- a/src/vehicles/car_manager.zig +++ b/src/vehicles/car_manager.zig @@ -1,6 +1,8 @@ const std = @import("std"); const Vector2 = @import("raylib").Vector2; +const e = @import("../common/errors.zig"); +const ut = @import("../common/structures.zig"); const Node = @import("../infrastructure/node.zig").Node; const Car = @import("car.zig").Car; @@ -42,11 +44,52 @@ pub const CarManager = struct { } pub fn clear(self: *CarManager, allocator: std.mem.Allocator) void { - // todo full impl for (self.cars.items) |car| { car.deinit(allocator); } self.cars.clearRetainingCapacity(); - self.next_id = 0; // reset + self.next_id = 0; + } + + /// This function returns array of cars which are located on the node/road specified in the `inf` parameter + pub fn getCarsOnInf(self: *const CarManager, allocator: std.mem.Allocator, inf: ut.Infrastructure) ![]*Car { + var cars: std.ArrayList(*Car) = .empty; + + const active_inf = std.meta.activeTag(inf); + + for (self.cars.items) |car| { + if (std.meta.activeTag(car.inf) != active_inf) continue; + + switch (car.inf) { + inline else => |a, tag| { + const b = @field(inf, @tagName(tag)); + if (a == b) try cars.append(allocator, car); + } + } + } + + return cars.toOwnedSlice(allocator); + } + + /// Attempts to deinit and remove the (passed) car; + /// returns an error if car doesn't exist in the list + pub fn removeCar(self: *CarManager, allocator: std.mem.Allocator, car_to_delete: *Car) !void { + for (self.cars.items, 0..) |car, index| { + if (car != car_to_delete) continue; + + car.deinit(allocator); + _ = self.cars.swapRemove(index); + return; + } + + return e.Entity.NotFound; + } + + /// TODO + pub fn removeMultipleCars(self: *CarManager, allocator: std.mem.Allocator, cars_to_delete: []*Car) !void { + _ = cars_to_delete; // autofix + _ = allocator; // autofix + _ = self; // autofix + } }; \ No newline at end of file