feat(core): appstate
This commit is contained in:
@@ -1,19 +1,12 @@
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const Mutex = std.Thread.Mutex;
|
||||
|
||||
const models = @import("../models.zig");
|
||||
const Container = models.Container;
|
||||
const Item = models.Item;
|
||||
|
||||
const locked = @import("../sync.zig").locked;
|
||||
|
||||
pub const Tab = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
currentLocation: ?*Container,
|
||||
currentItems: locked(?std.ArrayList(*Item)),
|
||||
currentLocationChanged: Observable(?*Container),
|
||||
currentItemsChanged: bool = false,
|
||||
preCurrentItemsUnload: Observable(*Tab),
|
||||
threadPool: *std.Thread.Pool,
|
||||
rootProvider: *RootProvider,
|
||||
_private: Private,
|
||||
|
||||
const Private = struct {
|
||||
@@ -23,44 +16,67 @@ pub const Tab = struct {
|
||||
pub fn init(
|
||||
self: *Tab,
|
||||
threadPool: *std.Thread.Pool,
|
||||
rootProvider: *RootProvider,
|
||||
allocator: std.mem.Allocator,
|
||||
) void {
|
||||
self.* = Tab{
|
||||
.allocator = allocator,
|
||||
.currentItems = .{ .data = null },
|
||||
.currentLocationChanged = Observable(?*Container).init(allocator),
|
||||
.currentLocation = null,
|
||||
.threadPool = threadPool,
|
||||
.rootProvider = rootProvider,
|
||||
.preCurrentItemsUnload = Observable(*Tab).init(allocator),
|
||||
._private = .{
|
||||
.currentItemsAllocator = std.heap.ArenaAllocator.init(allocator),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn setCurrentLocation(self: *Tab, newLocation: *Container) void {
|
||||
pub fn setCurrentLocation(self: *Tab, newLocationFullName: models.FullName) !void {
|
||||
if (self.currentLocation) |c| {
|
||||
c.item.deinit();
|
||||
self.allocator.destroy(c);
|
||||
}
|
||||
|
||||
self.currentLocation = newLocation;
|
||||
errdefer {
|
||||
self.currentLocation = null;
|
||||
self.currentLocationChanged.notify(null);
|
||||
}
|
||||
|
||||
const newLocation = try self.rootProvider.getItemByFullName(newLocationFullName, &.{}, self.allocator);
|
||||
|
||||
const newLocationContainer = switch (newLocation.item) {
|
||||
.container => |c| c,
|
||||
.element => return error.NotContainer,
|
||||
};
|
||||
|
||||
self.currentLocation = newLocationContainer;
|
||||
self.currentLocationChanged.notify(newLocationContainer);
|
||||
|
||||
//TODO: Proper error handling
|
||||
std.Thread.Pool.spawn(self.threadPool, loadItemsWrapper, .{ self, newLocation }) catch unreachable;
|
||||
std.Thread.Pool.spawn(self.threadPool, loadItemsWrapper, .{ self, newLocationContainer }) catch unreachable;
|
||||
}
|
||||
|
||||
fn loadItemsWrapper(self: *Tab, location: *Container) void {
|
||||
loadItems(self, location) catch return;
|
||||
}
|
||||
fn loadItems(self: *Tab, location: *Container) !void {
|
||||
_ = self._private.currentItemsAllocator.reset(.retain_capacity);
|
||||
|
||||
{
|
||||
self.currentItems.mutex.lock();
|
||||
defer self.currentItems.mutex.unlock();
|
||||
|
||||
self.preCurrentItemsUnload.notify(self);
|
||||
|
||||
if (self.currentItems.data) |items| {
|
||||
items.deinit();
|
||||
}
|
||||
|
||||
self.currentItems.data = null;
|
||||
}
|
||||
|
||||
_ = self._private.currentItemsAllocator.reset(.retain_capacity);
|
||||
|
||||
const arenaAllocator = &self._private.currentItemsAllocator;
|
||||
const arena = arenaAllocator.allocator();
|
||||
|
||||
@@ -90,7 +106,7 @@ pub const Tab = struct {
|
||||
for (location.children.items) |item| {
|
||||
const resolvedItem = location.item.provider.getItemByFullName(item, &.{ .skipChildInit = true }, allocator) catch |e| {
|
||||
//TODO: save error to container errors
|
||||
std.debug.print("error {} {s}\r\n", .{e, item.path});
|
||||
std.debug.print("error {} {s}\r\n", .{ e, item.path });
|
||||
continue;
|
||||
};
|
||||
|
||||
@@ -98,6 +114,11 @@ pub const Tab = struct {
|
||||
defer self.currentItems.mutex.unlock();
|
||||
|
||||
try self.currentItems.data.?.append(resolvedItem);
|
||||
}
|
||||
|
||||
{
|
||||
self.currentItems.mutex.lock();
|
||||
defer self.currentItems.mutex.unlock();
|
||||
self.currentItemsChanged = true;
|
||||
}
|
||||
}
|
||||
@@ -109,3 +130,15 @@ pub const Tab = struct {
|
||||
self._private.currentItemsAllocator.deinit();
|
||||
}
|
||||
};
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const Mutex = std.Thread.Mutex;
|
||||
|
||||
const models = @import("../models.zig");
|
||||
const Container = models.Container;
|
||||
const Item = models.Item;
|
||||
|
||||
const locked = @import("../sync.zig").locked;
|
||||
const Observable = @import("../observable.zig").Observable;
|
||||
const RootProvider = @import("../provider/root.zig").RootProvider;
|
||||
|
||||
Reference in New Issue
Block a user