Files
FileTime3/src/core/app_state.zig
Ádám Kovács ba172cc8ed fix invalid free
2025-05-29 11:04:43 +02:00

74 lines
2.3 KiB
Zig

pub const UnknownTabError = error.UnknownTab;
pub const AppState = struct {
allocator: std.mem.Allocator,
currentTab: *Tab = undefined,
tabs: std.ArrayList(*Tab),
currentTabChanged: Observable(*Tab),
tabChildrenLoaded: Observable(*Tab),
pub fn init(allocator: std.mem.Allocator) AppState {
return .{
.allocator = allocator,
.tabs = std.ArrayList(*Tab).init(allocator),
.currentTabChanged = Observable(*Tab).init(allocator),
.tabChildrenLoaded = Observable(*Tab).init(allocator),
};
}
pub fn addTab(self: *AppState, tab: *Tab) !void {
try self.tabs.append(tab);
const tabChildrenLoadedHandlerObserver = try tab.childrenLoaded.allocator.create(Observer(*Tab));
tabChildrenLoadedHandlerObserver.* = Observer(*Tab){
.ctx = @ptrCast(@alignCast(self)),
.update = tabChildrenLoadedHandler,
};
try tab.childrenLoaded.attach(tabChildrenLoadedHandlerObserver);
}
pub fn setCurrentTab(self: *AppState, newTab: *Tab) !void {
blk: {
for (self.tabs.items) |item| {
if (item == newTab) break :blk;
}
return UnknownTabError;
}
self.currentTab = newTab;
self.currentTabChanged.notify(newTab);
}
pub fn removeTab(self: *AppState, tab: *Tab) void {
const index = for (tab.childrenLoaded.observers, 0..) |observer, i| {
if (observer.ctx == self) break i;
} else null;
if (index) |i| {
const removed = tab.childrenLoaded.observers.swapRemove(i);
self.allocator.destroy(removed);
}
//TODO: remove from tabs
}
pub fn deinit(self: *AppState) void {
self.tabChildrenLoaded.deinit();
self.currentTabChanged.deinit();
for (self.tabs.items) |tab| {
tab.deinit();
}
self.tabs.deinit();
}
fn tabChildrenLoadedHandler(ctx: *anyopaque, tab: *Tab) void {
const self: *AppState = @ptrCast(@alignCast(ctx));
self.tabChildrenLoaded.notify(tab);
}
};
const std = @import("std");
const Tab = @import("tab/tab.zig").Tab;
const Observable = @import("observable.zig").Observable;
const Observer = @import("observable.zig").Observer;