diff --git a/src/assets.zig b/src/assets.zig index 2b9135b8..5fbd445d 100644 --- a/src/assets.zig +++ b/src/assets.zig @@ -11,10 +11,11 @@ const NeverFailingAllocator = main.utils.NeverFailingAllocator; var arena: main.utils.NeverFailingArenaAllocator = undefined; var arenaAllocator: NeverFailingAllocator = undefined; var commonBlocks: std.StringHashMap(ZonElement) = undefined; -var commonBlocksMigrations: std.StringHashMap(ZonElement) = undefined; -var commonBiomes: std.StringHashMap(ZonElement) = undefined; +var commonBlockMigrations: std.StringHashMap(ZonElement) = undefined; var commonItems: std.StringHashMap(ZonElement) = undefined; var commonTools: std.StringHashMap(ZonElement) = undefined; +var commonBiomes: std.StringHashMap(ZonElement) = undefined; +var commonBiomeMigrations: std.StringHashMap(ZonElement) = undefined; var commonRecipes: std.StringHashMap(ZonElement) = undefined; var commonModels: std.StringHashMap([]const u8) = undefined; @@ -25,10 +26,11 @@ pub fn init() void { arena = .init(main.globalAllocator); arenaAllocator = arena.allocator(); commonBlocks = .init(arenaAllocator.allocator); - commonBlocksMigrations = .init(arenaAllocator.allocator); + commonBlockMigrations = .init(arenaAllocator.allocator); commonItems = .init(arenaAllocator.allocator); commonTools = .init(arenaAllocator.allocator); commonBiomes = .init(arenaAllocator.allocator); + commonBiomeMigrations = .init(arenaAllocator.allocator); commonRecipes = .init(arenaAllocator.allocator); commonModels = .init(arenaAllocator.allocator); @@ -36,17 +38,18 @@ pub fn init() void { arenaAllocator, "assets/", &commonBlocks, - &commonBlocksMigrations, + &commonBlockMigrations, &commonItems, &commonTools, &commonBiomes, + &commonBlockMigrations, &commonRecipes, &commonModels, ); std.log.info( - "Finished assets init with {} blocks ({} migrations), {} items, {} tools. {} biomes, {} recipes", - .{commonBlocks.count(), commonBlocksMigrations.count(), commonItems.count(), commonTools.count(), commonBiomes.count(), commonRecipes.count()}, + "Finished assets init with {} blocks ({} migrations), {} items, {} tools. {} biomes ({} migrations), {} recipes", + .{commonBlocks.count(), commonBlockMigrations.count(), commonItems.count(), commonTools.count(), commonBiomes.count(), commonBiomeMigrations.count(), commonRecipes.count()}, ); } @@ -207,7 +210,18 @@ pub fn readAllObjFilesInAddonsHashmap( } } -pub fn readAssets(externalAllocator: NeverFailingAllocator, assetPath: []const u8, blocks: *std.StringHashMap(ZonElement), blocksMigrations: *std.StringHashMap(ZonElement), items: *std.StringHashMap(ZonElement), tools: *std.StringHashMap(ZonElement), biomes: *std.StringHashMap(ZonElement), recipes: *std.StringHashMap(ZonElement), models: *std.StringHashMap([]const u8)) void { +pub fn readAssets( + externalAllocator: NeverFailingAllocator, + assetPath: []const u8, + blocks: *std.StringHashMap(ZonElement), + blockMigrations: *std.StringHashMap(ZonElement), + items: *std.StringHashMap(ZonElement), + tools: *std.StringHashMap(ZonElement), + biomes: *std.StringHashMap(ZonElement), + biomeMigrations: *std.StringHashMap(ZonElement), + recipes: *std.StringHashMap(ZonElement), + models: *std.StringHashMap([]const u8), +) void { var addons = main.List(std.fs.Dir).init(main.stackAllocator); defer addons.deinit(); var addonNames = main.List([]const u8).init(main.stackAllocator); @@ -238,10 +252,10 @@ pub fn readAssets(externalAllocator: NeverFailingAllocator, assetPath: []const u main.stackAllocator.free(addonName); }; - readAllZonFilesInAddons(externalAllocator, addons, addonNames, "blocks", true, blocks, blocksMigrations); + readAllZonFilesInAddons(externalAllocator, addons, addonNames, "blocks", true, blocks, blockMigrations); readAllZonFilesInAddons(externalAllocator, addons, addonNames, "items", true, items, null); readAllZonFilesInAddons(externalAllocator, addons, addonNames, "tools", true, tools, null); - readAllZonFilesInAddons(externalAllocator, addons, addonNames, "biomes", true, biomes, null); + readAllZonFilesInAddons(externalAllocator, addons, addonNames, "biomes", true, biomes, biomeMigrations); readAllZonFilesInAddons(externalAllocator, addons, addonNames, "recipes", false, recipes, null); readAllObjFilesInAddonsHashmap(externalAllocator, addons, addonNames, "models", models); } @@ -347,14 +361,16 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, biomePal var blocks = commonBlocks.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable; defer blocks.clearAndFree(); - var blocksMigrations = commonBlocksMigrations.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable; - defer blocksMigrations.clearAndFree(); + var blockMigrations = commonBlockMigrations.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable; + defer blockMigrations.clearAndFree(); var items = commonItems.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable; defer items.clearAndFree(); var tools = commonTools.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable; defer tools.clearAndFree(); var biomes = commonBiomes.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable; defer biomes.clearAndFree(); + var biomeMigrations = commonBiomeMigrations.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable; + defer biomeMigrations.clearAndFree(); var recipes = commonRecipes.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable; defer recipes.clearAndFree(); var models = commonModels.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable; @@ -364,17 +380,21 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, biomePal arenaAllocator, assetFolder, &blocks, - &blocksMigrations, + &blockMigrations, &items, &tools, &biomes, + &biomeMigrations, &recipes, &models, ); errdefer unloadAssets(); - migrations_zig.registerBlockMigrations(&commonBlocksMigrations); - migrations_zig.applyBlockPaletteMigrations(blockPalette); + migrations_zig.registerAll(.block, &blockMigrations); + migrations_zig.apply(.block, blockPalette); + + migrations_zig.registerAll(.biome, &biomeMigrations); + migrations_zig.apply(.biome, biomePalette); // models: var modelIterator = models.iterator(); @@ -465,8 +485,8 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, biomePal } std.log.info( - "Finished registering assets with {} blocks ({} migrations), {} items {} tools. {} biomes, {} recipes and {} models", - .{blocks.count(), blocksMigrations.count(), items.count(), tools.count(), biomes.count(), recipes.count(), models.count()}, + "Finished registering assets with {} blocks ({} migrations), {} items {} tools. {} biomes ({} migrations), {} recipes and {} models", + .{blocks.count(), blockMigrations.count(), items.count(), tools.count(), biomes.count(), biomeMigrations.count(), recipes.count(), models.count()}, ); } diff --git a/src/migrations.zig b/src/migrations.zig index 69c491e9..3c70b561 100644 --- a/src/migrations.zig +++ b/src/migrations.zig @@ -8,24 +8,41 @@ var arenaAllocator = main.utils.NeverFailingArenaAllocator.init(main.globalAlloc const migrationAllocator = arenaAllocator.allocator(); var blockMigrations: std.StringHashMap([]const u8) = .init(migrationAllocator.allocator); +var biomeMigrations: std.StringHashMap([]const u8) = .init(migrationAllocator.allocator); -pub fn registerBlockMigrations(migrations: *std.StringHashMap(ZonElement)) void { - std.log.info("Registering {} block migrations", .{migrations.count()}); +const MigrationType = enum { + block, + biome, +}; +pub fn registerAll(comptime typ: MigrationType, migrations: *std.StringHashMap(ZonElement)) void { + std.log.info("Registering {} {s} migrations", .{migrations.count(), @tagName(typ)}); + const collection = switch(typ) { + .block => &blockMigrations, + .biome => &biomeMigrations, + }; var migrationIterator = migrations.iterator(); while(migrationIterator.next()) |migration| { - register(&blockMigrations, "block", migration.key_ptr.*, migration.value_ptr.*); + register(typ, collection, migration.key_ptr.*, migration.value_ptr.*); } } fn register( + comptime typ: MigrationType, collection: *std.StringHashMap([]const u8), - assetType: []const u8, addonName: []const u8, migrationZon: ZonElement, ) void { - if((migrationZon.toSlice().len == 0)) { - std.log.err("Skipping incorrect {s} migration data structure from addon {s}", .{assetType, addonName}); + if(migrationZon != .array) { + if(migrationZon == .object and migrationZon.object.count() == 0) { + std.log.warn("Skipping empty {s} migration data structure from addon {s}", .{@tagName(typ), addonName}); + return; + } + std.log.err("Skipping incorrect {s} migration data structure from addon {s}", .{@tagName(typ), addonName}); + return; + } + if(migrationZon.array.items.len == 0) { + std.log.warn("Skipping empty {s} migration data structure from addon {s}", .{@tagName(typ), addonName}); return; } @@ -34,7 +51,7 @@ fn register( const newZonOpt = migration.get(?[]const u8, "new", null); if(oldZonOpt == null or newZonOpt == null) { - std.log.err("Skipping incomplete migration in {s} migrations: '{s}:{s}' -> '{s}:{s}'", .{assetType, addonName, oldZonOpt orelse "", addonName, newZonOpt orelse ""}); + std.log.err("Skipping incomplete migration in {s} migrations: '{s}:{s}' -> '{s}:{s}'", .{@tagName(typ), addonName, oldZonOpt orelse "", addonName, newZonOpt orelse ""}); continue; } @@ -42,7 +59,7 @@ fn register( const newZon = newZonOpt orelse unreachable; if(std.mem.eql(u8, oldZon, newZon)) { - std.log.err("Skipping identity migration in {s} migrations: '{s}:{s}' -> '{s}:{s}'", .{assetType, addonName, oldZon, addonName, newZon}); + std.log.err("Skipping identity migration in {s} migrations: '{s}:{s}' -> '{s}:{s}'", .{@tagName(typ), addonName, oldZon, addonName, newZon}); continue; } @@ -50,7 +67,7 @@ fn register( const result = collection.getOrPut(oldAssetId) catch unreachable; if(result.found_existing) { - std.log.err("Skipping name collision in {s} migration: '{s}' -> '{s}:{s}'", .{assetType, oldAssetId, addonName, newZon}); + std.log.err("Skipping name collision in {s} migration: '{s}' -> '{s}:{s}'", .{@tagName(typ), oldAssetId, addonName, newZon}); const existingMigration = collection.get(oldAssetId) orelse unreachable; std.log.err("Already mapped to '{s}'", .{existingMigration}); @@ -60,23 +77,28 @@ fn register( result.key_ptr.* = oldAssetId; result.value_ptr.* = newAssetId; - std.log.info("Registered {s} migration: '{s}' -> '{s}'", .{assetType, oldAssetId, newAssetId}); + std.log.info("Registered {s} migration: '{s}' -> '{s}'", .{@tagName(typ), oldAssetId, newAssetId}); } } } -pub fn applyBlockPaletteMigrations(palette: *Palette) void { - std.log.info("Applying {} migrations to block palette", .{blockMigrations.count()}); +pub fn apply(comptime typ: MigrationType, palette: *Palette) void { + const migrations = switch(typ) { + .block => blockMigrations, + .biome => biomeMigrations, + }; + std.log.info("Applying {} migrations to {s} palette", .{migrations.count(), @tagName(typ)}); for(palette.palette.items, 0..) |assetName, i| { - const newAssetName = blockMigrations.get(assetName) orelse continue; - std.log.info("Migrating block {s} -> {s}", .{assetName, newAssetName}); + const newAssetName = migrations.get(assetName) orelse continue; + std.log.info("Migrating {s} {s} -> {s}", .{@tagName(typ), assetName, newAssetName}); palette.replaceEntry(i, newAssetName); } } pub fn reset() void { blockMigrations.clearAndFree(); + biomeMigrations.clearAndFree(); _ = arenaAllocator.reset(.free_all); }