diff --git a/src/example/simple/plugin.zig b/src/example/simple/plugin.zig index 32eb504..dfce6df 100644 --- a/src/example/simple/plugin.zig +++ b/src/example/simple/plugin.zig @@ -8,6 +8,7 @@ const stage = @import("stage.zig"); pub const plugin: App.plugin.Plugin = .{ .name = "Simple", .description = "Simple plugin example", + .dependencies = &.{}, .build = build, }; diff --git a/src/plugin/plugin.zig b/src/plugin/plugin.zig index 3fc52fd..fafb9af 100644 --- a/src/plugin/plugin.zig +++ b/src/plugin/plugin.zig @@ -7,6 +7,7 @@ const Self = @This(); // --- ID --- name: []const u8, +dependencies: []const []const u8 = &.{}, description: []const u8 = "", version: [3]u8 = .{ 0, 0, 0 }, diff --git a/src/plugin/storage.zig b/src/plugin/storage.zig index 0996539..76618d8 100644 --- a/src/plugin/storage.zig +++ b/src/plugin/storage.zig @@ -55,7 +55,54 @@ pub fn build( self: *Self, ctx: Context, ) !void { - for (self.data.items) |*plugin| { - try plugin.build(plugin, ctx); + // --- # --- + var built: std.StringHashMap(void) = .init(self.alloc); + defer built.deinit(); + + // --- # --- + var progress = true; + while (progress) { + progress = false; + + for (self.data.items) |*plugin| { + // --- SKIP SELF --- + if (built.contains(plugin.name)) continue; + + // --- CHECK IF DEP ARE [READY OR NOT] + var ready: bool = true; + for (plugin.dependencies) |dep| { + if (!built.contains(dep)) { + ready = false; + break; + } + } + + // --- IF YE, BUILD --- + if (ready) { + try plugin.build(plugin, ctx); + try built.put(plugin.name, {}); + progress = true; + } + } + } + + // --- # --- + var missing = false; + for (self.data.items) |plugin| { + if (!built.contains(plugin.name)) { + std.debug.print("[PLUGIN] Failed to build \"{s}\". Missing dependencies:\n", .{plugin.name}); + + for (plugin.dependencies) |dep| { + if (!built.contains(dep)) { + std.debug.print(" - {s}\n", .{dep}); + } + } + missing = true; + } + } + + // --- # --- + if (missing) { + return error.PluginDependencyError; } }