lib/choir/src/composition/loaded/lifecycle.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const sys = @import("sys");
2 const composition = @import("../root.zig");
3
4 const source = composition.source;
5
6 pub const LifecycleEvent = union(enum) {
7 invocation_destroyed: u64,
8 fragment_destroyed: source.FragmentId,
9 composition_destroyed,
10 };
11
12 pub const LifecycleObserver = struct {
13 ptr: *anyopaque,
14 record_fn: *const fn (*anyopaque, LifecycleEvent) void,
15
16 pub fn record(self: LifecycleObserver, event: LifecycleEvent) void {
17 self.record_fn(self.ptr, event);
18 }
19 };
20
21 pub const Recorder = struct {
22 mutex: sys.thread.Mutex = .{},
23 target: ?LifecycleObserver,
24
25 pub fn init(target: ?LifecycleObserver) Recorder {
26 return .{ .target = target };
27 }
28
29 pub fn record(self: *Recorder, event: LifecycleEvent) void {
30 const target = self.target orelse return;
31 self.mutex.lock();
32 defer self.mutex.unlock();
33 target.record(event);
34 }
35
36 pub fn serialized(self: *Recorder) ?LifecycleObserver {
37 if (self.target == null) return null;
38 return .{
39 .ptr = self,
40 .record_fn = recordSerialized,
41 };
42 }
43
44 fn recordSerialized(ptr: *anyopaque, event: LifecycleEvent) void {
45 const self: *Recorder = @ptrCast(@alignCast(ptr));
46 self.record(event);
47 }
48 };