feat(core): incrementally load items

This commit is contained in:
2025-05-27 17:48:47 +02:00
parent ae8ead1e5d
commit 1c0004a5d5
3 changed files with 49 additions and 30 deletions

View File

@@ -1,7 +1,3 @@
const std = @import("std");
const Provider = @import("provider/provider.zig").Provider;
const consts = @import("consts.zig");
pub const Item = struct { pub const Item = struct {
allocator: std.mem.Allocator, allocator: std.mem.Allocator,
provider: Provider, provider: Provider,
@@ -52,13 +48,13 @@ pub const Element = struct {
pub const Container = struct { pub const Container = struct {
item: Item, item: Item,
children: std.ArrayList(FullName), children: locked(std.ArrayList(FullName)),
childrenLoading: bool, childrenLoading: bool,
fn deinit(self: *Container) void { fn deinit(self: *Container) void {
for (self.children.items) |itemFullName| { for (self.children.data.items) |itemFullName| {
self.item.allocator.free(itemFullName.path); self.item.allocator.free(itemFullName.path);
} }
self.children.deinit(); self.children.data.deinit();
self.item.allocator.destroy(self); self.item.allocator.destroy(self);
} }
}; };
@@ -103,3 +99,8 @@ pub const AbsolutePathType = union(enum) {
container, container,
item, item,
}; };
const std = @import("std");
const Provider = @import("provider/provider.zig").Provider;
const consts = @import("consts.zig");
const locked = @import("./sync.zig").locked;

View File

@@ -18,7 +18,9 @@ fn loadChildren(container: *Container) void {
while (it.next() catch return) |entry| { while (it.next() catch return) |entry| {
const child = container.item.fullName.getChild(entry.name, container.item.allocator) catch return; const child = container.item.fullName.getChild(entry.name, container.item.allocator) catch return;
container.children.append(child) catch return; container.children.mutex.lock();
defer container.children.mutex.unlock();
container.children.data.append(child) catch return;
} }
} }
@@ -108,7 +110,9 @@ pub const LocalContentProvider = struct {
.directory => blk: { .directory => blk: {
const container = try allocator.create(Container); const container = try allocator.create(Container);
container.* = Container{ container.* = Container{
.children = std.ArrayList(FullName).init(allocator), .children = locked(std.ArrayList(FullName)){
.data = std.ArrayList(FullName).init(allocator),
},
.childrenLoading = true, .childrenLoading = true,
.item = undefined, .item = undefined,
}; };
@@ -214,3 +218,4 @@ const ItemEnum = models.ItemEnum;
const Element = models.Element; const Element = models.Element;
const Container = models.Container; const Container = models.Container;
const native_os = @import("builtin").os.tag; const native_os = @import("builtin").os.tag;
const locked = @import("../sync.zig").locked;

View File

@@ -2,6 +2,7 @@ pub const Tab = struct {
allocator: std.mem.Allocator, allocator: std.mem.Allocator,
currentLocation: ?*Container, currentLocation: ?*Container,
currentItems: locked(?std.ArrayList(Arc(*Item))), currentItems: locked(?std.ArrayList(Arc(*Item))),
currentParentItems: locked(?std.ArrayList(Arc(*Item))),
currentLocationChanged: Observable(?*Container), currentLocationChanged: Observable(?*Container),
currentItemFullName: ?models.FullName, currentItemFullName: ?models.FullName,
currentItem: ?Arc(*models.Item), currentItem: ?Arc(*models.Item),
@@ -19,6 +20,7 @@ pub const Tab = struct {
self.* = Tab{ self.* = Tab{
.allocator = allocator, .allocator = allocator,
.currentItems = .{ .data = null }, .currentItems = .{ .data = null },
.currentParentItems = .{ .data = null },
.currentLocationChanged = Observable(?*Container).init(allocator), .currentLocationChanged = Observable(?*Container).init(allocator),
.currentLocation = null, .currentLocation = null,
.currentRequested = null, .currentRequested = null,
@@ -198,32 +200,43 @@ pub const Tab = struct {
} }
//TODO: add async //TODO: add async
while (location.childrenLoading) { //NOTE: also we should
std.Thread.sleep(1 * std.time.ns_per_ms); var processed_number: usize = 0;
} while (true) {
std.Thread.sleep(100 * std.time.ns_per_ms);
for (location.children.items) |item_fullname| { location.children.mutex.lock();
const resolvedItem = location.item.provider.getItemByFullName(item_fullname, &.{ .skipChildInit = true }, self.allocator) catch |e| { defer location.children.mutex.unlock();
//TODO: save error to container errors
std.debug.print("error {} {s}\r\n", .{ e, item_fullname.path });
continue;
};
self.currentItems.mutex.lock(); std.debug.assert(processed_number <= location.children.data.items.len);
defer self.currentItems.mutex.unlock();
const insertIndex = for (self.currentItems.data.?.items, 0..) |*item, i| { if (!location.childrenLoading and processed_number == location.children.data.items.len) break;
if (order.orderByDisplayName(resolvedItem, item.value.*) == .lt) break i; if (processed_number == location.children.data.items.len) continue;
} else null;
const arc = try Arc(*Item).init(self.allocator, resolvedItem); defer processed_number = location.children.data.items.len;
if (insertIndex) |i| { for (location.children.data.items[processed_number..]) |item_fullname| {
try self.currentItems.data.?.insert(i, arc); const resolvedItem = location.item.provider.getItemByFullName(item_fullname, &.{ .skipChildInit = true }, self.allocator) catch |e| {
} else { //TODO: save error to container errors
try self.currentItems.data.?.append(arc); 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 {};
} }
} }