feat(core): load parent's children
This commit is contained in:
@@ -64,6 +64,7 @@ pub const Tab = struct {
|
|||||||
|
|
||||||
//TODO: Proper error handling
|
//TODO: Proper error handling
|
||||||
std.Thread.Pool.spawn(self.threadPool, loadItemsWrapper, .{ self, newLocationContainer }) catch unreachable;
|
std.Thread.Pool.spawn(self.threadPool, loadItemsWrapper, .{ self, newLocationContainer }) catch unreachable;
|
||||||
|
std.Thread.Pool.spawn(self.threadPool, loadParentItemsWrapper, .{ self, newLocationContainer }) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn selectItem(self: *Tab, requested_selected: models.FullName) !void {
|
pub fn selectItem(self: *Tab, requested_selected: models.FullName) !void {
|
||||||
@@ -171,73 +172,33 @@ pub const Tab = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn loadItemsWrapper(self: *Tab, location: *Container) void {
|
fn loadItemsWrapper(self: *Tab, location: *Container) void {
|
||||||
loadItems(self, location) catch return;
|
loadItems(*Tab, self, location, &self.currentItems, updateCurrentItemCallback, self.allocator) catch {};
|
||||||
}
|
}
|
||||||
fn loadItems(self: *Tab, location: *Container) !void {
|
fn updateCurrentItemCallback(self: *Tab) void {
|
||||||
{
|
|
||||||
self.currentItems.mutex.lock();
|
|
||||||
defer self.currentItems.mutex.unlock();
|
|
||||||
|
|
||||||
const data = self.currentItems.data;
|
|
||||||
self.currentItems.data = null;
|
|
||||||
if (data) |currentItems| {
|
|
||||||
for (currentItems.items) |*item| {
|
|
||||||
if (item.releaseUnwrap()) |i| i.deinit();
|
|
||||||
}
|
|
||||||
currentItems.deinit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
self.currentItems.mutex.lock();
|
|
||||||
defer self.currentItems.mutex.unlock();
|
|
||||||
|
|
||||||
self.currentItems.data = std.ArrayList(Arc(*Item)).init(self.allocator);
|
|
||||||
}
|
|
||||||
errdefer {
|
|
||||||
self.currentItems.data.?.deinit();
|
|
||||||
self.currentItems.data = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: add async
|
|
||||||
//NOTE: also we should
|
|
||||||
var processed_number: usize = 0;
|
|
||||||
while (true) {
|
|
||||||
std.Thread.sleep(100 * std.time.ns_per_ms);
|
|
||||||
|
|
||||||
location.children.mutex.lock();
|
|
||||||
defer location.children.mutex.unlock();
|
|
||||||
|
|
||||||
std.debug.assert(processed_number <= location.children.data.items.len);
|
|
||||||
|
|
||||||
if (!location.childrenLoading and processed_number == location.children.data.items.len) break;
|
|
||||||
if (processed_number == location.children.data.items.len) continue;
|
|
||||||
|
|
||||||
defer processed_number = location.children.data.items.len;
|
|
||||||
for (location.children.data.items[processed_number..]) |item_fullname| {
|
|
||||||
const resolvedItem = location.item.provider.getItemByFullName(item_fullname, &.{ .skipChildInit = true }, self.allocator) catch |e| {
|
|
||||||
//TODO: save error to container errors
|
|
||||||
std.debug.print("error {} {s}\r\n", .{ e, item_fullname.path });
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
self.currentItems.mutex.lock();
|
|
||||||
defer self.currentItems.mutex.unlock();
|
|
||||||
|
|
||||||
const insertIndex = for (self.currentItems.data.?.items, 0..) |*item, i| {
|
|
||||||
if (order.orderByDisplayName(resolvedItem, item.value.*) == .lt) break i;
|
|
||||||
} else null;
|
|
||||||
|
|
||||||
const arc = try Arc(*Item).init(self.allocator, resolvedItem);
|
|
||||||
if (insertIndex) |i| {
|
|
||||||
try self.currentItems.data.?.insert(i, arc);
|
|
||||||
} else {
|
|
||||||
try self.currentItems.data.?.append(arc);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.updateCurrentItem() catch {};
|
self.updateCurrentItem() catch {};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
fn loadParentItemsWrapper(self: *Tab, location: *Container) void {
|
||||||
|
const parentAbsolutePath = location.item.parent orelse return;
|
||||||
|
var arena = std.heap.ArenaAllocator.init(self.allocator);
|
||||||
|
defer arena.deinit();
|
||||||
|
const allocator = arena.allocator();
|
||||||
|
|
||||||
|
const parentFullName = models.FullName{
|
||||||
|
.path = allocator.dupe(u8, parentAbsolutePath.path.path) catch return,
|
||||||
|
};
|
||||||
|
|
||||||
|
const resolvedParent = location.item.provider.getItemByFullName(parentFullName, &.{ .skipChildInit = true }, allocator) catch |e| {
|
||||||
|
std.debug.print("error {} {s}\r\n", .{ e, parentFullName.path });
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
const parentContainer = switch (resolvedParent.item) {
|
||||||
|
.container => |c| c,
|
||||||
|
else => return,
|
||||||
|
};
|
||||||
|
loadItems(*Tab, self, parentContainer, &self.currentParentItems, (struct {
|
||||||
|
fn a(_: *Tab) void {}
|
||||||
|
}).a, self.allocator) catch {};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Tab) void {
|
pub fn deinit(self: *Tab) void {
|
||||||
@@ -276,6 +237,79 @@ pub const Tab = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn loadItems(
|
||||||
|
comptime T: type,
|
||||||
|
ctx: T,
|
||||||
|
location: *Container,
|
||||||
|
sourceItems: *locked(?std.ArrayList(Arc(*Item))),
|
||||||
|
itemLoadedCallback: *const fn (T) void,
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
) !void {
|
||||||
|
{
|
||||||
|
sourceItems.mutex.lock();
|
||||||
|
defer sourceItems.mutex.unlock();
|
||||||
|
|
||||||
|
const data = sourceItems.data;
|
||||||
|
sourceItems.data = null;
|
||||||
|
if (data) |currentItems| {
|
||||||
|
for (currentItems.items) |*item| {
|
||||||
|
if (item.releaseUnwrap()) |i| i.deinit();
|
||||||
|
}
|
||||||
|
currentItems.deinit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
sourceItems.mutex.lock();
|
||||||
|
defer sourceItems.mutex.unlock();
|
||||||
|
|
||||||
|
sourceItems.data = std.ArrayList(Arc(*Item)).init(allocator);
|
||||||
|
}
|
||||||
|
errdefer {
|
||||||
|
sourceItems.data.?.deinit();
|
||||||
|
sourceItems.data = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: add async
|
||||||
|
var processed_number: usize = 0;
|
||||||
|
while (true) {
|
||||||
|
std.Thread.sleep(100 * std.time.ns_per_ms);
|
||||||
|
|
||||||
|
location.children.mutex.lock();
|
||||||
|
defer location.children.mutex.unlock();
|
||||||
|
|
||||||
|
std.debug.assert(processed_number <= location.children.data.items.len);
|
||||||
|
|
||||||
|
if (!location.childrenLoading and processed_number == location.children.data.items.len) break;
|
||||||
|
if (processed_number == location.children.data.items.len) continue;
|
||||||
|
|
||||||
|
defer processed_number = location.children.data.items.len;
|
||||||
|
for (location.children.data.items[processed_number..]) |item_fullname| {
|
||||||
|
const resolvedItem = location.item.provider.getItemByFullName(item_fullname, &.{ .skipChildInit = true }, allocator) catch |e| {
|
||||||
|
//TODO: save error to container errors
|
||||||
|
std.debug.print("error {} {s}\r\n", .{ e, item_fullname.path });
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
sourceItems.mutex.lock();
|
||||||
|
defer sourceItems.mutex.unlock();
|
||||||
|
|
||||||
|
const insertIndex = for (sourceItems.data.?.items, 0..) |*item, i| {
|
||||||
|
if (order.orderByDisplayName(resolvedItem, item.value.*) == .lt) break i;
|
||||||
|
} else null;
|
||||||
|
|
||||||
|
const arc = try Arc(*Item).init(allocator, resolvedItem);
|
||||||
|
if (insertIndex) |i| {
|
||||||
|
try sourceItems.data.?.insert(i, arc);
|
||||||
|
} else {
|
||||||
|
try sourceItems.data.?.append(arc);
|
||||||
|
}
|
||||||
|
|
||||||
|
itemLoadedCallback(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Mutex = std.Thread.Mutex;
|
const Mutex = std.Thread.Mutex;
|
||||||
|
|||||||
Reference in New Issue
Block a user