lib/choir/src/composition/loaded/fragment.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 const composition = @import("../root.zig");
 3 const loaded = @import("root.zig");
 4 
 5 const Allocator = std.mem.Allocator;
 6 const abi = composition.abi;
 7 const model = composition.module;
 8 const source = composition.source;
 9 
10 pub const FragmentVTable = struct {
11     invoke: ?*const fn (*anyopaque, *const model.CallSite, *abi.Context, *abi.Frame) abi.Status = null,
12     lookup_export: ?*const fn (*anyopaque, []const u8) ?usize = null,
13     deinit: *const fn (*anyopaque, Allocator) void,
14 };
15 
16 pub const MaterializedFragment = struct {
17     state: *anyopaque,
18     vtable: *const FragmentVTable,
19 };
20 
21 pub const FragmentMaterializer = struct {
22     id: source.FragmentId,
23     context: *anyopaque,
24     materialize: *const fn (*anyopaque, Allocator, *const model.CompositionModule, *const model.Fragment) anyerror!MaterializedFragment,
25 };
26 
27 pub const LoadedFragment = struct {
28     id: source.FragmentId,
29     state: *anyopaque,
30     vtable: *const FragmentVTable,
31 };
32 
33 pub fn deinitUnique(
34     allocator: Allocator,
35     fragments: []const LoadedFragment,
36     observer: ?loaded.LifecycleObserver,
37 ) void {
38     var index = fragments.len;
39     while (index != 0) {
40         index -= 1;
41         const fragment_value = fragments[index];
42         var earlier_index: usize = 0;
43         var aliased = false;
44         while (earlier_index < index) : (earlier_index += 1) {
45             if (fragments[earlier_index].state == fragment_value.state) {
46                 aliased = true;
47                 break;
48             }
49         }
50         if (aliased) continue;
51         fragment_value.vtable.deinit(fragment_value.state, allocator);
52         if (observer) |value| value.record(.{ .fragment_destroyed = fragment_value.id });
53     }
54 }