mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-09-08 03:29:48 -04:00
Add biome migrations to mitigate damage after biome renames (#1157)
* Add biomes migrations * Fix error on empty migration file * Fix migrations_zig.applyBiomePaletteMigrations call * Fix formatting issues * Rename thingsMigrations to thingMigrations * Change log type for incorrect migrations * Use comptime enum for migration selection * Fix formatting issues * Update src/migrations.zig * Update src/migrations.zig * Update src/migrations.zig
This commit is contained in:
parent
b497133967
commit
ac43b7128e
@ -11,10 +11,11 @@ const NeverFailingAllocator = main.utils.NeverFailingAllocator;
|
|||||||
var arena: main.utils.NeverFailingArenaAllocator = undefined;
|
var arena: main.utils.NeverFailingArenaAllocator = undefined;
|
||||||
var arenaAllocator: NeverFailingAllocator = undefined;
|
var arenaAllocator: NeverFailingAllocator = undefined;
|
||||||
var commonBlocks: std.StringHashMap(ZonElement) = undefined;
|
var commonBlocks: std.StringHashMap(ZonElement) = undefined;
|
||||||
var commonBlocksMigrations: std.StringHashMap(ZonElement) = undefined;
|
var commonBlockMigrations: std.StringHashMap(ZonElement) = undefined;
|
||||||
var commonBiomes: std.StringHashMap(ZonElement) = undefined;
|
|
||||||
var commonItems: std.StringHashMap(ZonElement) = undefined;
|
var commonItems: std.StringHashMap(ZonElement) = undefined;
|
||||||
var commonTools: 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 commonRecipes: std.StringHashMap(ZonElement) = undefined;
|
||||||
var commonModels: std.StringHashMap([]const u8) = undefined;
|
var commonModels: std.StringHashMap([]const u8) = undefined;
|
||||||
|
|
||||||
@ -25,10 +26,11 @@ pub fn init() void {
|
|||||||
arena = .init(main.globalAllocator);
|
arena = .init(main.globalAllocator);
|
||||||
arenaAllocator = arena.allocator();
|
arenaAllocator = arena.allocator();
|
||||||
commonBlocks = .init(arenaAllocator.allocator);
|
commonBlocks = .init(arenaAllocator.allocator);
|
||||||
commonBlocksMigrations = .init(arenaAllocator.allocator);
|
commonBlockMigrations = .init(arenaAllocator.allocator);
|
||||||
commonItems = .init(arenaAllocator.allocator);
|
commonItems = .init(arenaAllocator.allocator);
|
||||||
commonTools = .init(arenaAllocator.allocator);
|
commonTools = .init(arenaAllocator.allocator);
|
||||||
commonBiomes = .init(arenaAllocator.allocator);
|
commonBiomes = .init(arenaAllocator.allocator);
|
||||||
|
commonBiomeMigrations = .init(arenaAllocator.allocator);
|
||||||
commonRecipes = .init(arenaAllocator.allocator);
|
commonRecipes = .init(arenaAllocator.allocator);
|
||||||
commonModels = .init(arenaAllocator.allocator);
|
commonModels = .init(arenaAllocator.allocator);
|
||||||
|
|
||||||
@ -36,17 +38,18 @@ pub fn init() void {
|
|||||||
arenaAllocator,
|
arenaAllocator,
|
||||||
"assets/",
|
"assets/",
|
||||||
&commonBlocks,
|
&commonBlocks,
|
||||||
&commonBlocksMigrations,
|
&commonBlockMigrations,
|
||||||
&commonItems,
|
&commonItems,
|
||||||
&commonTools,
|
&commonTools,
|
||||||
&commonBiomes,
|
&commonBiomes,
|
||||||
|
&commonBlockMigrations,
|
||||||
&commonRecipes,
|
&commonRecipes,
|
||||||
&commonModels,
|
&commonModels,
|
||||||
);
|
);
|
||||||
|
|
||||||
std.log.info(
|
std.log.info(
|
||||||
"Finished assets init with {} blocks ({} migrations), {} items, {} tools. {} biomes, {} recipes",
|
"Finished assets init with {} blocks ({} migrations), {} items, {} tools. {} biomes ({} migrations), {} recipes",
|
||||||
.{commonBlocks.count(), commonBlocksMigrations.count(), commonItems.count(), commonTools.count(), commonBiomes.count(), commonRecipes.count()},
|
.{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);
|
var addons = main.List(std.fs.Dir).init(main.stackAllocator);
|
||||||
defer addons.deinit();
|
defer addons.deinit();
|
||||||
var addonNames = main.List([]const u8).init(main.stackAllocator);
|
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);
|
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, "items", true, items, null);
|
||||||
readAllZonFilesInAddons(externalAllocator, addons, addonNames, "tools", true, tools, 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);
|
readAllZonFilesInAddons(externalAllocator, addons, addonNames, "recipes", false, recipes, null);
|
||||||
readAllObjFilesInAddonsHashmap(externalAllocator, addons, addonNames, "models", models);
|
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;
|
var blocks = commonBlocks.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
||||||
defer blocks.clearAndFree();
|
defer blocks.clearAndFree();
|
||||||
var blocksMigrations = commonBlocksMigrations.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
var blockMigrations = commonBlockMigrations.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
||||||
defer blocksMigrations.clearAndFree();
|
defer blockMigrations.clearAndFree();
|
||||||
var items = commonItems.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
var items = commonItems.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
||||||
defer items.clearAndFree();
|
defer items.clearAndFree();
|
||||||
var tools = commonTools.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
var tools = commonTools.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
||||||
defer tools.clearAndFree();
|
defer tools.clearAndFree();
|
||||||
var biomes = commonBiomes.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
var biomes = commonBiomes.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
||||||
defer biomes.clearAndFree();
|
defer biomes.clearAndFree();
|
||||||
|
var biomeMigrations = commonBiomeMigrations.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
||||||
|
defer biomeMigrations.clearAndFree();
|
||||||
var recipes = commonRecipes.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
var recipes = commonRecipes.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
||||||
defer recipes.clearAndFree();
|
defer recipes.clearAndFree();
|
||||||
var models = commonModels.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
var models = commonModels.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
||||||
@ -364,17 +380,21 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, biomePal
|
|||||||
arenaAllocator,
|
arenaAllocator,
|
||||||
assetFolder,
|
assetFolder,
|
||||||
&blocks,
|
&blocks,
|
||||||
&blocksMigrations,
|
&blockMigrations,
|
||||||
&items,
|
&items,
|
||||||
&tools,
|
&tools,
|
||||||
&biomes,
|
&biomes,
|
||||||
|
&biomeMigrations,
|
||||||
&recipes,
|
&recipes,
|
||||||
&models,
|
&models,
|
||||||
);
|
);
|
||||||
errdefer unloadAssets();
|
errdefer unloadAssets();
|
||||||
|
|
||||||
migrations_zig.registerBlockMigrations(&commonBlocksMigrations);
|
migrations_zig.registerAll(.block, &blockMigrations);
|
||||||
migrations_zig.applyBlockPaletteMigrations(blockPalette);
|
migrations_zig.apply(.block, blockPalette);
|
||||||
|
|
||||||
|
migrations_zig.registerAll(.biome, &biomeMigrations);
|
||||||
|
migrations_zig.apply(.biome, biomePalette);
|
||||||
|
|
||||||
// models:
|
// models:
|
||||||
var modelIterator = models.iterator();
|
var modelIterator = models.iterator();
|
||||||
@ -465,8 +485,8 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, biomePal
|
|||||||
}
|
}
|
||||||
|
|
||||||
std.log.info(
|
std.log.info(
|
||||||
"Finished registering assets with {} blocks ({} migrations), {} items {} tools. {} biomes, {} recipes and {} models",
|
"Finished registering assets with {} blocks ({} migrations), {} items {} tools. {} biomes ({} migrations), {} recipes and {} models",
|
||||||
.{blocks.count(), blocksMigrations.count(), items.count(), tools.count(), biomes.count(), recipes.count(), models.count()},
|
.{blocks.count(), blockMigrations.count(), items.count(), tools.count(), biomes.count(), biomeMigrations.count(), recipes.count(), models.count()},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,24 +8,41 @@ var arenaAllocator = main.utils.NeverFailingArenaAllocator.init(main.globalAlloc
|
|||||||
const migrationAllocator = arenaAllocator.allocator();
|
const migrationAllocator = arenaAllocator.allocator();
|
||||||
|
|
||||||
var blockMigrations: std.StringHashMap([]const u8) = .init(migrationAllocator.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 {
|
const MigrationType = enum {
|
||||||
std.log.info("Registering {} block migrations", .{migrations.count()});
|
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();
|
var migrationIterator = migrations.iterator();
|
||||||
while(migrationIterator.next()) |migration| {
|
while(migrationIterator.next()) |migration| {
|
||||||
register(&blockMigrations, "block", migration.key_ptr.*, migration.value_ptr.*);
|
register(typ, collection, migration.key_ptr.*, migration.value_ptr.*);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register(
|
fn register(
|
||||||
|
comptime typ: MigrationType,
|
||||||
collection: *std.StringHashMap([]const u8),
|
collection: *std.StringHashMap([]const u8),
|
||||||
assetType: []const u8,
|
|
||||||
addonName: []const u8,
|
addonName: []const u8,
|
||||||
migrationZon: ZonElement,
|
migrationZon: ZonElement,
|
||||||
) void {
|
) void {
|
||||||
if((migrationZon.toSlice().len == 0)) {
|
if(migrationZon != .array) {
|
||||||
std.log.err("Skipping incorrect {s} migration data structure from addon {s}", .{assetType, addonName});
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,7 +51,7 @@ fn register(
|
|||||||
const newZonOpt = migration.get(?[]const u8, "new", null);
|
const newZonOpt = migration.get(?[]const u8, "new", null);
|
||||||
|
|
||||||
if(oldZonOpt == null or newZonOpt == null) {
|
if(oldZonOpt == null or newZonOpt == null) {
|
||||||
std.log.err("Skipping incomplete migration in {s} migrations: '{s}:{s}' -> '{s}:{s}'", .{assetType, addonName, oldZonOpt orelse "<null>", addonName, newZonOpt orelse "<null>"});
|
std.log.err("Skipping incomplete migration in {s} migrations: '{s}:{s}' -> '{s}:{s}'", .{@tagName(typ), addonName, oldZonOpt orelse "<null>", addonName, newZonOpt orelse "<null>"});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +59,7 @@ fn register(
|
|||||||
const newZon = newZonOpt orelse unreachable;
|
const newZon = newZonOpt orelse unreachable;
|
||||||
|
|
||||||
if(std.mem.eql(u8, oldZon, newZon)) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +67,7 @@ fn register(
|
|||||||
const result = collection.getOrPut(oldAssetId) catch unreachable;
|
const result = collection.getOrPut(oldAssetId) catch unreachable;
|
||||||
|
|
||||||
if(result.found_existing) {
|
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;
|
const existingMigration = collection.get(oldAssetId) orelse unreachable;
|
||||||
std.log.err("Already mapped to '{s}'", .{existingMigration});
|
std.log.err("Already mapped to '{s}'", .{existingMigration});
|
||||||
|
|
||||||
@ -60,23 +77,28 @@ fn register(
|
|||||||
|
|
||||||
result.key_ptr.* = oldAssetId;
|
result.key_ptr.* = oldAssetId;
|
||||||
result.value_ptr.* = newAssetId;
|
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 {
|
pub fn apply(comptime typ: MigrationType, palette: *Palette) void {
|
||||||
std.log.info("Applying {} migrations to block palette", .{blockMigrations.count()});
|
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| {
|
for(palette.palette.items, 0..) |assetName, i| {
|
||||||
const newAssetName = blockMigrations.get(assetName) orelse continue;
|
const newAssetName = migrations.get(assetName) orelse continue;
|
||||||
std.log.info("Migrating block {s} -> {s}", .{assetName, newAssetName});
|
std.log.info("Migrating {s} {s} -> {s}", .{@tagName(typ), assetName, newAssetName});
|
||||||
palette.replaceEntry(i, newAssetName);
|
palette.replaceEntry(i, newAssetName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset() void {
|
pub fn reset() void {
|
||||||
blockMigrations.clearAndFree();
|
blockMigrations.clearAndFree();
|
||||||
|
biomeMigrations.clearAndFree();
|
||||||
_ = arenaAllocator.reset(.free_all);
|
_ = arenaAllocator.reset(.free_all);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user