feat: items with arc instead of arena
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
running: bool = true,
|
running: bool = true,
|
||||||
usage_number: locked(u16) = .{ .data = 0 },
|
usage_number: locked(u16) = .{ .data = 0 },
|
||||||
current_items: locked(?[]*models.Item) = .{ .data = null },
|
current_items: locked(?[]Arc(*models.Item).Weak) = .{ .data = null },
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
appState: AppState,
|
appState: AppState,
|
||||||
_private: Private,
|
_private: Private,
|
||||||
@@ -24,20 +24,36 @@ pub fn init(model: *Self, allocator: std.mem.Allocator, appState: AppState) !voi
|
|||||||
try model.appState.tabPreCurrentItemsUnload.attach(&model._private.preCurrentItemsUnload);
|
try model.appState.tabPreCurrentItemsUnload.attach(&model._private.preCurrentItemsUnload);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn updateCurrentItems(self: *Self, tab_current_items: *std.ArrayList(*models.Item)) !void {
|
pub fn updateCurrentItems(self: *Self, tab_current_items: *std.ArrayList(Arc(*models.Item))) !void {
|
||||||
self.resetCurrentItems();
|
self.resetCurrentItems();
|
||||||
|
|
||||||
const items = try self.allocator.alloc(*models.Item, tab_current_items.items.len);
|
var items = try self.allocator.alloc(Arc(*models.Item).Weak, tab_current_items.items.len);
|
||||||
errdefer {
|
errdefer {
|
||||||
self.allocator.free(items);
|
self.allocator.free(items);
|
||||||
self.current_items.data = null;
|
self.current_items.data = null;
|
||||||
}
|
}
|
||||||
for (tab_current_items.items, 0..) |item, i| {
|
for (tab_current_items.items, 0..) |*item, i| {
|
||||||
items[i] = item;
|
items[i] = item.downgrade();
|
||||||
}
|
}
|
||||||
|
|
||||||
std.mem.sort(*models.Item, items, {}, struct {
|
std.mem.sort(Arc(*models.Item).Weak, items, {}, struct {
|
||||||
fn sort(_: void, lhs: *models.Item, rhs: *models.Item) bool {
|
fn sort(_: void, lhs_weak: Arc(*models.Item).Weak, rhs_weak: Arc(*models.Item).Weak) bool {
|
||||||
|
const lhs_arc = @constCast(&lhs_weak).upgrade();
|
||||||
|
defer if (lhs_arc) |l1| if (l1.releaseUnwrap()) |l2| l2.deinit();
|
||||||
|
|
||||||
|
const rhs_arc = @constCast(&rhs_weak).upgrade();
|
||||||
|
defer if (rhs_arc) |r1| if (r1.releaseUnwrap()) |r2| r2.deinit();
|
||||||
|
|
||||||
|
const lhs = if (lhs_arc) |l|
|
||||||
|
l.value.*
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const rhs = if (rhs_arc) |r|
|
||||||
|
r.value.*
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
if (lhs.item == .container and rhs.item == .element) return true;
|
if (lhs.item == .container and rhs.item == .element) return true;
|
||||||
if (lhs.item == .element and rhs.item == .container) return false;
|
if (lhs.item == .element and rhs.item == .container) return false;
|
||||||
return std.mem.order(u8, lhs.displayName, rhs.displayName) == .lt;
|
return std.mem.order(u8, lhs.displayName, rhs.displayName) == .lt;
|
||||||
@@ -65,6 +81,9 @@ fn resetCurrentItems(self: *@This()) void {
|
|||||||
// self.current_items.data = null;
|
// self.current_items.data = null;
|
||||||
|
|
||||||
if (data) |currentItems| {
|
if (data) |currentItems| {
|
||||||
|
for (currentItems) |item| {
|
||||||
|
item.release();
|
||||||
|
}
|
||||||
self.allocator.free(currentItems);
|
self.allocator.free(currentItems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,4 +101,5 @@ const Tab = @import("../core/tab/tab.zig").Tab;
|
|||||||
const locked = @import("../core/sync.zig").locked;
|
const locked = @import("../core/sync.zig").locked;
|
||||||
const AppState = @import("../core/app_state.zig").AppState;
|
const AppState = @import("../core/app_state.zig").AppState;
|
||||||
const Observer = @import("../core/observable.zig").Observer;
|
const Observer = @import("../core/observable.zig").Observer;
|
||||||
|
const Arc = @import("zigrc").Arc;
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|||||||
@@ -124,8 +124,15 @@ const Model = struct {
|
|||||||
defer vm.app_common_model.current_items.mutex.unlock();
|
defer vm.app_common_model.current_items.mutex.unlock();
|
||||||
|
|
||||||
break :blk2 if (vm.app_common_model.current_items.data) |items| blk: {
|
break :blk2 if (vm.app_common_model.current_items.data) |items| blk: {
|
||||||
const children = try ctx.arena.alloc(*vxfw.Text, items.len);
|
const children = try ctx.arena.create(std.ArrayList(*vxfw.Text));
|
||||||
for (0.., items[0..children.len]) |i, child| {
|
children.* = std.ArrayList(*vxfw.Text).init(ctx.arena);
|
||||||
|
|
||||||
|
// const children = try ctx.arena.alloc(*vxfw.Text, items.len);
|
||||||
|
for (0.., items) |i, *weak_child| {
|
||||||
|
const arc_child = weak_child.upgrade() orelse continue;
|
||||||
|
defer if (arc_child.releaseUnwrap()) |item| item.deinit();
|
||||||
|
|
||||||
|
const child = arc_child.value.*;
|
||||||
const is_active = i == vm.current_items_view.cursor;
|
const is_active = i == vm.current_items_view.cursor;
|
||||||
|
|
||||||
const fg, const bg = colors: {
|
const fg, const bg = colors: {
|
||||||
@@ -162,14 +169,18 @@ const Model = struct {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
children[i] = text_element;
|
// children[i] = text_element;
|
||||||
|
try children.append(text_element);
|
||||||
}
|
}
|
||||||
break :blk children;
|
break :blk children;
|
||||||
} else &.{};
|
} else {
|
||||||
|
vm.current_items_view.children.slice = &.{};
|
||||||
|
return;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const widgets = try ctx.arena.alloc(vxfw.Widget, text_items.len);
|
const widgets = try ctx.arena.alloc(vxfw.Widget, text_items.items.len);
|
||||||
for (text_items, 0..) |t, i| {
|
for (text_items.items, 0..) |t, i| {
|
||||||
widgets[i] = t.widget();
|
widgets[i] = t.widget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
pub const Tab = struct {
|
pub const Tab = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
currentLocation: ?*Container,
|
currentLocation: ?*Container,
|
||||||
currentItems: locked(?std.ArrayList(*Item)),
|
currentItems: locked(?std.ArrayList(Arc(*Item))),
|
||||||
currentLocationChanged: Observable(?*Container),
|
currentLocationChanged: Observable(?*Container),
|
||||||
currentItemsChanged: bool = false,
|
currentItemsChanged: bool = false,
|
||||||
preCurrentItemsUnload: Observable(*Tab),
|
preCurrentItemsUnload: Observable(*Tab),
|
||||||
threadPool: *std.Thread.Pool,
|
threadPool: *std.Thread.Pool,
|
||||||
rootProvider: *RootProvider,
|
rootProvider: *RootProvider,
|
||||||
_private: Private,
|
|
||||||
|
|
||||||
const Private = struct {
|
|
||||||
currentItemsAllocator: std.heap.ArenaAllocator,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn init(
|
pub fn init(
|
||||||
self: *Tab,
|
self: *Tab,
|
||||||
@@ -27,9 +22,6 @@ pub const Tab = struct {
|
|||||||
.threadPool = threadPool,
|
.threadPool = threadPool,
|
||||||
.rootProvider = rootProvider,
|
.rootProvider = rootProvider,
|
||||||
.preCurrentItemsUnload = Observable(*Tab).init(allocator),
|
.preCurrentItemsUnload = Observable(*Tab).init(allocator),
|
||||||
._private = .{
|
|
||||||
.currentItemsAllocator = std.heap.ArenaAllocator.init(allocator),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,25 +62,21 @@ pub const Tab = struct {
|
|||||||
|
|
||||||
self.preCurrentItemsUnload.notify(self);
|
self.preCurrentItemsUnload.notify(self);
|
||||||
|
|
||||||
|
const data = self.currentItems.data;
|
||||||
self.currentItems.data = null;
|
self.currentItems.data = null;
|
||||||
|
if (data) |currentItems| {
|
||||||
|
for (currentItems.items) |*item| {
|
||||||
|
if (item.releaseUnwrap()) |i| i.deinit();
|
||||||
|
}
|
||||||
|
currentItems.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: half the capacity to prevent "leaking" after a huuuge container has been opened once
|
|
||||||
_ = self._private.currentItemsAllocator.reset(.retain_capacity);
|
|
||||||
const arena = self._private.currentItemsAllocator.allocator();
|
|
||||||
|
|
||||||
var threadSafeAllocator = std.heap.ThreadSafeAllocator{ .child_allocator = arena };
|
|
||||||
const allocator = threadSafeAllocator.allocator();
|
|
||||||
|
|
||||||
errdefer {
|
|
||||||
_ = self._private.currentItemsAllocator.reset(.free_all);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
self.currentItems.mutex.lock();
|
self.currentItems.mutex.lock();
|
||||||
defer self.currentItems.mutex.unlock();
|
defer self.currentItems.mutex.unlock();
|
||||||
|
|
||||||
self.currentItems.data = std.ArrayList(*Item).init(allocator);
|
self.currentItems.data = std.ArrayList(Arc(*Item)).init(self.allocator);
|
||||||
}
|
}
|
||||||
errdefer {
|
errdefer {
|
||||||
self.currentItems.data.?.deinit();
|
self.currentItems.data.?.deinit();
|
||||||
@@ -101,7 +89,7 @@ pub const Tab = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (location.children.items) |item| {
|
for (location.children.items) |item| {
|
||||||
const resolvedItem = location.item.provider.getItemByFullName(item, &.{ .skipChildInit = true }, allocator) catch |e| {
|
const resolvedItem = location.item.provider.getItemByFullName(item, &.{ .skipChildInit = true }, self.allocator) catch |e| {
|
||||||
//TODO: save error to container errors
|
//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;
|
continue;
|
||||||
@@ -110,7 +98,9 @@ pub const Tab = struct {
|
|||||||
self.currentItems.mutex.lock();
|
self.currentItems.mutex.lock();
|
||||||
defer self.currentItems.mutex.unlock();
|
defer self.currentItems.mutex.unlock();
|
||||||
|
|
||||||
try self.currentItems.data.?.append(resolvedItem);
|
// const arc = try Arc(*Item).init(self.allocator, resolvedItem);
|
||||||
|
// try self.currentItems.data.?.append(arc);
|
||||||
|
try self.currentItems.data.?.append(try Arc(*Item).init(self.allocator, resolvedItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -124,7 +114,18 @@ pub const Tab = struct {
|
|||||||
if (self.currentLocation) |c| {
|
if (self.currentLocation) |c| {
|
||||||
c.item.deinit();
|
c.item.deinit();
|
||||||
}
|
}
|
||||||
self._private.currentItemsAllocator.deinit();
|
|
||||||
|
const data = self.currentItems.data;
|
||||||
|
self.currentItems.data = null;
|
||||||
|
if (data) |currentItems| {
|
||||||
|
for (currentItems.items) |arc_item| {
|
||||||
|
if (arc_item.releaseUnwrap()) |item| {
|
||||||
|
item.deinit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentItems.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
self.allocator.destroy(self);
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -140,3 +141,4 @@ const Item = models.Item;
|
|||||||
const locked = @import("../sync.zig").locked;
|
const locked = @import("../sync.zig").locked;
|
||||||
const Observable = @import("../observable.zig").Observable;
|
const Observable = @import("../observable.zig").Observable;
|
||||||
const RootProvider = @import("../provider/root.zig").RootProvider;
|
const RootProvider = @import("../provider/root.zig").RootProvider;
|
||||||
|
const Arc = @import("zigrc").Arc;
|
||||||
|
|||||||
@@ -142,7 +142,12 @@ fn dvui_frame(model: *Model) !void {
|
|||||||
defer model.core_model.current_items.mutex.unlock();
|
defer model.core_model.current_items.mutex.unlock();
|
||||||
|
|
||||||
if (model.core_model.current_items.data) |current_items| {
|
if (model.core_model.current_items.data) |current_items| {
|
||||||
for (0.., current_items) |i, item| {
|
for (0.., current_items) |i, *weak_item| {
|
||||||
|
const arc_item = weak_item.upgrade() orelse continue;
|
||||||
|
defer if (arc_item.releaseUnwrap()) |item| item.deinit();
|
||||||
|
|
||||||
|
const item = arc_item.value.*;
|
||||||
|
|
||||||
const is_active = i == model.selected_item;
|
const is_active = i == model.selected_item;
|
||||||
const fg, const bg = colors: {
|
const fg, const bg = colors: {
|
||||||
var fg: dvui.Color = .{ .r = 100, .g = 100, .b = 100 };
|
var fg: dvui.Color = .{ .r = 100, .g = 100, .b = 100 };
|
||||||
|
|||||||
Reference in New Issue
Block a user