diff --git a/src/core/models.zig b/src/core/models.zig index e389c2d..439e48a 100644 --- a/src/core/models.zig +++ b/src/core/models.zig @@ -14,13 +14,8 @@ pub const Item = struct { parent: ?AbsolutePath, item: ItemEnum, errors: std.ArrayList(Error), - deiniting: bool = false, - deinited: bool = false, pub fn deinit(self: *Item) void { - if (self.deinited) return; - self.deiniting = true; - self.allocator.free(self.name); self.allocator.free(self.displayName); self.allocator.free(self.fullName.path); @@ -31,7 +26,6 @@ pub const Item = struct { self.allocator.free(e.content); } self.item.deinit(); - self.deinited = true; } }; diff --git a/src/core/provider/local.zig b/src/core/provider/local.zig index 87fd340..3e4706a 100644 --- a/src/core/provider/local.zig +++ b/src/core/provider/local.zig @@ -35,6 +35,7 @@ fn loadChildren(container: *Container, deinitTracker: *DeinitTracker) void { var it = dir.iterate(); while (it.next() catch return) |entry| { const child = container.item.fullName.getChild(entry.name, container.item.allocator) catch return; + if (deinitTracker.deinited) return; container.children.append(child) catch return; } @@ -64,6 +65,67 @@ pub const LocalContentProvider = struct { globalAllocator: std.mem.Allocator, ) GetItemsError!Item { const stat = std.fs.cwd().statFile(fullName.path) catch return GetItemsError.NotExists; + + return switch (stat.kind) { + .directory => blk: { + const container = try allocator.create(Container); + container.* = Container{ + .children = std.ArrayList(FullName).init(allocator), + .childrenLoading = true, + .item = undefined, + }; + + const val: ItemEnum = .{ + .container = container, + }; + try initItem( + self, + &container.item, + val, + fullName, + allocator, + globalAllocator, + ); + + try self.threadPool.spawn(loadChildren, .{ container, container.item.deinitTracker }); + + break :blk container.item; + }, + .file => blk: { + const element = try allocator.create(Element); + element.* = Element{ + .item = undefined, + }; + + const val: ItemEnum = .{ + .element = element, + }; + + try initItem( + self, + &element.item, + val, + fullName, + allocator, + globalAllocator, + ); + + break :blk element.item; + }, + else => @panic( + "Unsupported file type\n", + ), + }; + } + + fn initItem( + contentProvider: *LocalContentProvider, + item: *Item, + innerItem: ItemEnum, + fullName: FullName, + allocator: std.mem.Allocator, + globalAllocator: std.mem.Allocator, + ) !void { var deinitTracker = try globalAllocator.create(DeinitTracker); deinitTracker.init(globalAllocator); @@ -81,55 +143,18 @@ pub const LocalContentProvider = struct { const nativePath = try allocator.alloc(u8, fullName.path.len); @memcpy(nativePath, fullName.path); - var item = Item{ + item.* = Item{ .allocator = allocator, - .provider = self.provider(), + .provider = contentProvider.provider(), .deinitTracker = deinitTracker, .name = name, .displayName = displayName, .fullName = .{ .path = fullName2 }, .nativePath = models.NativePath{ .path = nativePath }, .parent = null, - .item = undefined, + .item = innerItem, .errors = std.ArrayList(models.Error).init(allocator), }; - - const innerItem: ItemEnum = switch (stat.kind) { - .directory => blk: { - const container = try allocator.create(Container); - container.* = Container{ - .children = std.ArrayList(FullName).init(allocator), - .childrenLoading = true, - .item = item, - }; - - const val: ItemEnum = .{ - .container = container, - }; - - try self.threadPool.spawn(loadChildren, .{ container, deinitTracker }); - - break :blk val; - }, - .file => blk: { - const element = try allocator.create(Element); - element.* = Element{ - .item = item, - }; - - const val: ItemEnum = .{ - .element = element, - }; - break :blk val; - }, - else => @panic( - "Unsupported file type\n", - ), - }; - - item.item = innerItem; - - return item; } pub fn provider(self: *LocalContentProvider) Provider { diff --git a/src/core/tab/tab.zig b/src/core/tab/tab.zig index ef3089d..97d3617 100644 --- a/src/core/tab/tab.zig +++ b/src/core/tab/tab.zig @@ -17,11 +17,12 @@ pub const Tab = struct { currentItemsAllocator: ?std.heap.ArenaAllocator, }; - pub fn create( + pub fn init( + self: *Tab, threadPool: *std.Thread.Pool, allocator: std.mem.Allocator, - ) Tab { - return Tab{ + ) void { + self.* = Tab{ .allocator = allocator, .currentItems = null, .currentLocation = null, @@ -56,10 +57,11 @@ pub const Tab = struct { pub fn deinit(self: *Tab) void { if (self.currentLocation) |c| { - c.deinit(); + c.item.deinit(); } if (self._private.currentItemsAllocator) |arena| { arena.deinit(); } + self.allocator.destroy(self); } };