mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 19:28:49 -04:00
Refactor common*
variables from assets.zig
into struct (#1289)
## Description This pull request moves all of the `common*` variables into `Assets` struct. As a bonus change `Managed` was special cased in `refAllDeclsRecursiveExceptCImports` to avoid infinite recursion for `*HashMap*` aliases. ## Links Resolves: #1205 Resolves: #1204 Related to: #1181
This commit is contained in:
parent
cbe400c9a4
commit
a15f1a96bc
607
src/assets.zig
607
src/assets.zig
@ -10,154 +10,285 @@ const main = @import("main");
|
|||||||
const biomes_zig = main.server.terrain.biomes;
|
const biomes_zig = main.server.terrain.biomes;
|
||||||
const sbb = main.server.terrain.structure_building_blocks;
|
const sbb = main.server.terrain.structure_building_blocks;
|
||||||
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
||||||
|
const NeverFailingArenaAllocator = main.heap.NeverFailingArenaAllocator;
|
||||||
|
const ListUnmanaged = main.ListUnmanaged;
|
||||||
|
const files = main.files;
|
||||||
|
|
||||||
var arena: main.heap.NeverFailingArenaAllocator = undefined;
|
var commonAssetArena: NeverFailingArenaAllocator = undefined;
|
||||||
var arenaAllocator: NeverFailingAllocator = undefined;
|
var commonAssetAllocator: NeverFailingAllocator = undefined;
|
||||||
var commonBlocks: std.StringHashMap(ZonElement) = undefined;
|
var common: Assets = 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;
|
|
||||||
var commonStructureBuildingBlocks: std.StringHashMap(ZonElement) = undefined;
|
|
||||||
var commonBlueprints: std.StringHashMap([]u8) = undefined;
|
|
||||||
|
|
||||||
pub fn init() void {
|
pub const Assets = struct {
|
||||||
biomes_zig.init();
|
pub const ZonHashMap = std.StringHashMapUnmanaged(ZonElement);
|
||||||
blocks_zig.init();
|
pub const BytesHashMap = std.StringHashMapUnmanaged([]const u8);
|
||||||
|
pub const AddonNameToZonMap = std.StringHashMapUnmanaged(ZonElement);
|
||||||
|
|
||||||
arena = .init(main.globalAllocator);
|
blocks: ZonHashMap,
|
||||||
arenaAllocator = arena.allocator();
|
blockMigrations: AddonNameToZonMap,
|
||||||
commonBlocks = .init(arenaAllocator.allocator);
|
items: ZonHashMap,
|
||||||
commonBlockMigrations = .init(arenaAllocator.allocator);
|
tools: ZonHashMap,
|
||||||
commonItems = .init(arenaAllocator.allocator);
|
biomes: ZonHashMap,
|
||||||
commonTools = .init(arenaAllocator.allocator);
|
biomeMigrations: AddonNameToZonMap,
|
||||||
commonBiomes = .init(arenaAllocator.allocator);
|
recipes: ZonHashMap,
|
||||||
commonBiomeMigrations = .init(arenaAllocator.allocator);
|
models: BytesHashMap,
|
||||||
commonRecipes = .init(arenaAllocator.allocator);
|
structureBuildingBlocks: ZonHashMap,
|
||||||
commonModels = .init(arenaAllocator.allocator);
|
blueprints: BytesHashMap,
|
||||||
commonStructureBuildingBlocks = .init(arenaAllocator.allocator);
|
|
||||||
commonBlueprints = .init(arenaAllocator.allocator);
|
|
||||||
|
|
||||||
readAssets(
|
fn init() Assets {
|
||||||
arenaAllocator,
|
return .{
|
||||||
"assets/",
|
.blocks = .{},
|
||||||
&commonBlocks,
|
.blockMigrations = .{},
|
||||||
&commonBlockMigrations,
|
.items = .{},
|
||||||
&commonItems,
|
.tools = .{},
|
||||||
&commonTools,
|
.biomes = .{},
|
||||||
&commonBiomes,
|
.biomeMigrations = .{},
|
||||||
&commonBiomeMigrations,
|
.recipes = .{},
|
||||||
&commonRecipes,
|
.models = .{},
|
||||||
&commonModels,
|
.structureBuildingBlocks = .{},
|
||||||
&commonStructureBuildingBlocks,
|
.blueprints = .{},
|
||||||
&commonBlueprints,
|
|
||||||
);
|
|
||||||
|
|
||||||
std.log.info(
|
|
||||||
"Finished assets init with {} blocks ({} migrations), {} items, {} tools, {} biomes ({} migrations), {} recipes, {} structure building blocks and {} blueprints",
|
|
||||||
.{commonBlocks.count(), commonBlockMigrations.count(), commonItems.count(), commonTools.count(), commonBiomes.count(), commonBiomeMigrations.count(), commonRecipes.count(), commonStructureBuildingBlocks.count(), commonBlueprints.count()},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn readDefaultFile(allocator: NeverFailingAllocator, dir: std.fs.Dir) !ZonElement {
|
|
||||||
if(main.files.Dir.init(dir).readToZon(allocator, "_defaults.zig.zon")) |zon| {
|
|
||||||
return zon;
|
|
||||||
} else |err| {
|
|
||||||
if(err != error.FileNotFound) return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(main.files.Dir.init(dir).readToZon(allocator, "_defaults.zon")) |zon| {
|
|
||||||
return zon;
|
|
||||||
} else |err| {
|
|
||||||
if(err != error.FileNotFound) return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return .null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads all asset `.zig.zon` files recursively from all sub folders.
|
|
||||||
///
|
|
||||||
/// Files red are stored in output hashmap with asset ID as key.
|
|
||||||
/// Asset ID are constructed as `{addonName}:{relativePathNoSuffix}`.
|
|
||||||
/// relativePathNoSuffix is always unix style path with all extensions removed.
|
|
||||||
pub fn readAllZonFilesInAddons(
|
|
||||||
externalAllocator: NeverFailingAllocator,
|
|
||||||
addons: main.List(std.fs.Dir),
|
|
||||||
addonNames: main.List([]const u8),
|
|
||||||
subPath: []const u8,
|
|
||||||
defaults: bool,
|
|
||||||
output: *std.StringHashMap(ZonElement),
|
|
||||||
migrations: ?*std.StringHashMap(ZonElement),
|
|
||||||
) void {
|
|
||||||
for(addons.items, addonNames.items) |addon, addonName| {
|
|
||||||
var dir = addon.openDir(subPath, .{.iterate = true}) catch |err| {
|
|
||||||
if(err != error.FileNotFound) {
|
|
||||||
std.log.err("Could not open addon directory {s}: {s}", .{subPath, @errorName(err)});
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
};
|
};
|
||||||
defer dir.close();
|
}
|
||||||
|
fn deinit(self: *Assets, allocator: NeverFailingAllocator) void {
|
||||||
|
self.blocks.deinit(allocator.allocator);
|
||||||
|
self.blockMigrations.deinit(allocator.allocator);
|
||||||
|
self.items.deinit(allocator.allocator);
|
||||||
|
self.tools.deinit(allocator.allocator);
|
||||||
|
self.biomes.deinit(allocator.allocator);
|
||||||
|
self.biomeMigrations.deinit(allocator.allocator);
|
||||||
|
self.recipes.deinit(allocator.allocator);
|
||||||
|
self.models.deinit(allocator.allocator);
|
||||||
|
self.structureBuildingBlocks.deinit(allocator.allocator);
|
||||||
|
self.blueprints.deinit(allocator.allocator);
|
||||||
|
}
|
||||||
|
fn clone(self: Assets, allocator: NeverFailingAllocator) Assets {
|
||||||
|
return .{
|
||||||
|
.blocks = self.blocks.clone(allocator.allocator) catch unreachable,
|
||||||
|
.blockMigrations = self.blockMigrations.clone(allocator.allocator) catch unreachable,
|
||||||
|
.items = self.items.clone(allocator.allocator) catch unreachable,
|
||||||
|
.tools = self.tools.clone(allocator.allocator) catch unreachable,
|
||||||
|
.biomes = self.biomes.clone(allocator.allocator) catch unreachable,
|
||||||
|
.biomeMigrations = self.biomeMigrations.clone(allocator.allocator) catch unreachable,
|
||||||
|
.recipes = self.recipes.clone(allocator.allocator) catch unreachable,
|
||||||
|
.models = self.models.clone(allocator.allocator) catch unreachable,
|
||||||
|
.structureBuildingBlocks = self.structureBuildingBlocks.clone(allocator.allocator) catch unreachable,
|
||||||
|
.blueprints = self.blueprints.clone(allocator.allocator) catch unreachable,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
fn read(self: *Assets, allocator: NeverFailingAllocator, assetPath: []const u8) void {
|
||||||
|
const addons = Addon.discoverAll(main.stackAllocator, assetPath);
|
||||||
|
defer addons.deinit(main.stackAllocator);
|
||||||
|
defer for(addons.items) |*addon| addon.deinit(main.stackAllocator);
|
||||||
|
|
||||||
var defaultsArena: main.heap.NeverFailingArenaAllocator = .init(main.stackAllocator);
|
for(addons.items) |addon| {
|
||||||
defer defaultsArena.deinit();
|
addon.readAllZon(allocator, "blocks", true, &self.blocks, &self.blockMigrations);
|
||||||
|
addon.readAllZon(allocator, "items", true, &self.items, null);
|
||||||
|
addon.readAllZon(allocator, "tools", true, &self.tools, null);
|
||||||
|
addon.readAllZon(allocator, "biomes", true, &self.biomes, &self.biomeMigrations);
|
||||||
|
addon.readAllZon(allocator, "recipes", false, &self.recipes, null);
|
||||||
|
addon.readAllZon(allocator, "sbb", true, &self.structureBuildingBlocks, null);
|
||||||
|
addon.readAllBlueprints(allocator, &self.blueprints);
|
||||||
|
addon.readAllModels(allocator, &self.models);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn log(self: *Assets, typ: enum {common, world}) void {
|
||||||
|
std.log.info(
|
||||||
|
"Finished {s} assets reading with {} blocks ({} migrations), {} items, {} tools, {} biomes ({} migrations), {} recipes, {} structure building blocks and {} blueprints",
|
||||||
|
.{@tagName(typ), self.blocks.count(), self.blockMigrations.count(), self.items.count(), self.tools.count(), self.biomes.count(), self.biomeMigrations.count(), self.recipes.count(), self.structureBuildingBlocks.count(), self.blueprints.count()},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const defaultsArenaAllocator = defaultsArena.allocator();
|
const Addon = struct {
|
||||||
|
name: []const u8,
|
||||||
|
dir: std.fs.Dir,
|
||||||
|
|
||||||
var defaultMap = std.StringHashMap(ZonElement).init(defaultsArenaAllocator.allocator);
|
fn discoverAll(allocator: NeverFailingAllocator, path: []const u8) main.ListUnmanaged(Addon) {
|
||||||
|
var addons: main.ListUnmanaged(Addon) = .{};
|
||||||
|
|
||||||
var walker = dir.walk(main.stackAllocator.allocator) catch unreachable;
|
var dir = std.fs.cwd().openDir(path, .{.iterate = true}) catch |err| {
|
||||||
defer walker.deinit();
|
std.log.err("Can't open asset path {s}: {s}", .{path, @errorName(err)});
|
||||||
|
return addons;
|
||||||
|
};
|
||||||
|
defer dir.close();
|
||||||
|
|
||||||
while(walker.next() catch |err| blk: {
|
var iterator = dir.iterate();
|
||||||
std.log.err("Got error while iterating addon directory {s}: {s}", .{subPath, @errorName(err)});
|
while(iterator.next() catch |err| blk: {
|
||||||
break :blk null;
|
std.log.err("Got error while iterating over asset path {s}: {s}", .{path, @errorName(err)});
|
||||||
}) |entry| {
|
break :blk null;
|
||||||
if(entry.kind == .file and
|
}) |addon| {
|
||||||
!std.ascii.startsWithIgnoreCase(entry.basename, "_defaults") and
|
if(addon.kind != .directory) continue;
|
||||||
std.ascii.endsWithIgnoreCase(entry.basename, ".zon") and
|
|
||||||
!std.ascii.startsWithIgnoreCase(entry.path, "textures") and
|
|
||||||
!std.ascii.eqlIgnoreCase(entry.basename, "_migrations.zig.zon"))
|
|
||||||
{
|
|
||||||
const id = createAssetStringID(externalAllocator, addonName, entry.path);
|
|
||||||
|
|
||||||
const zon = main.files.Dir.init(dir).readToZon(externalAllocator, entry.path) catch |err| {
|
const directory = dir.openDir(addon.name, .{}) catch |err| {
|
||||||
|
std.log.err("Got error while reading addon {s} from {s}: {s}", .{addon.name, path, @errorName(err)});
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
addons.append(allocator, .{.name = allocator.dupe(u8, addon.name), .dir = directory});
|
||||||
|
}
|
||||||
|
return addons;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deinit(self: *Addon, allocator: NeverFailingAllocator) void {
|
||||||
|
self.dir.close();
|
||||||
|
allocator.free(self.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Defaults = struct {
|
||||||
|
localArena: NeverFailingArenaAllocator = undefined,
|
||||||
|
localAllocator: NeverFailingAllocator = undefined,
|
||||||
|
defaults: std.StringHashMapUnmanaged(ZonElement) = .{},
|
||||||
|
|
||||||
|
fn init(self: *Defaults, allocator: NeverFailingAllocator) void {
|
||||||
|
self.localArena = .init(allocator);
|
||||||
|
self.localAllocator = self.localArena.allocator();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deinit(self: *Defaults) void {
|
||||||
|
self.localArena.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(self: *Defaults, dir: std.fs.Dir) ZonElement {
|
||||||
|
const path = dir.realpathAlloc(main.stackAllocator.allocator, ".") catch unreachable;
|
||||||
|
defer main.stackAllocator.free(path);
|
||||||
|
|
||||||
|
const result = self.defaults.getOrPut(self.localAllocator.allocator, path) catch unreachable;
|
||||||
|
|
||||||
|
if(!result.found_existing) {
|
||||||
|
result.key_ptr.* = self.localAllocator.dupe(u8, path);
|
||||||
|
const default: ZonElement = self.read(dir) catch |err| blk: {
|
||||||
|
std.log.err("Failed to read default file: {s}", .{@errorName(err)});
|
||||||
|
break :blk .null;
|
||||||
|
};
|
||||||
|
|
||||||
|
result.value_ptr.* = default;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.value_ptr.*;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read(self: *Defaults, dir: std.fs.Dir) !ZonElement {
|
||||||
|
if(main.files.Dir.init(dir).readToZon(self.localAllocator, "_defaults.zig.zon")) |zon| {
|
||||||
|
return zon;
|
||||||
|
} else |err| {
|
||||||
|
if(err != error.FileNotFound) return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(main.files.Dir.init(dir).readToZon(self.localAllocator, "_defaults.zon")) |zon| {
|
||||||
|
return zon;
|
||||||
|
} else |err| {
|
||||||
|
if(err != error.FileNotFound) return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn readAllZon(addon: Addon, allocator: NeverFailingAllocator, assetType: []const u8, hasDefaults: bool, output: *ZonHashMap, migrations: ?*AddonNameToZonMap) void {
|
||||||
|
var assetsDirectory = addon.dir.openDir(assetType, .{.iterate = true}) catch |err| {
|
||||||
|
if(err != error.FileNotFound) {
|
||||||
|
std.log.err("Could not open addon directory {s}: {s}", .{assetType, @errorName(err)});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
defer assetsDirectory.close();
|
||||||
|
|
||||||
|
var defaultsStorage: Defaults = .{};
|
||||||
|
defaultsStorage.init(main.stackAllocator);
|
||||||
|
defer defaultsStorage.deinit();
|
||||||
|
|
||||||
|
var walker = assetsDirectory.walk(main.stackAllocator.allocator) catch unreachable;
|
||||||
|
defer walker.deinit();
|
||||||
|
|
||||||
|
while(walker.next() catch |err| blk: {
|
||||||
|
std.log.err("Got error while iterating addon directory {s}: {s}", .{assetType, @errorName(err)});
|
||||||
|
break :blk null;
|
||||||
|
}) |entry| {
|
||||||
|
if(entry.kind != .file) continue;
|
||||||
|
if(std.ascii.startsWithIgnoreCase(entry.basename, "_defaults")) continue;
|
||||||
|
if(!std.ascii.endsWithIgnoreCase(entry.basename, ".zon")) continue;
|
||||||
|
if(std.ascii.startsWithIgnoreCase(entry.path, "textures")) continue;
|
||||||
|
if(std.ascii.eqlIgnoreCase(entry.basename, "_migrations.zig.zon")) continue;
|
||||||
|
|
||||||
|
const id = createAssetStringID(allocator, addon.name, entry.path);
|
||||||
|
|
||||||
|
const zon = files.Dir.init(assetsDirectory).readToZon(allocator, entry.path) catch |err| {
|
||||||
|
std.log.err("Could not open {s}/{s}: {s}", .{assetType, entry.path, @errorName(err)});
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if(hasDefaults) {
|
||||||
|
zon.join(defaultsStorage.get(entry.dir));
|
||||||
|
}
|
||||||
|
output.put(allocator.allocator, id, zon) catch unreachable;
|
||||||
|
}
|
||||||
|
if(migrations != null) blk: {
|
||||||
|
const zon = files.Dir.init(assetsDirectory).readToZon(allocator, "_migrations.zig.zon") catch |err| {
|
||||||
|
if(err != error.FileNotFound) std.log.err("Cannot read {s} migration file for addon {s}", .{assetType, addon.name});
|
||||||
|
break :blk;
|
||||||
|
};
|
||||||
|
migrations.?.put(allocator.allocator, allocator.dupe(u8, addon.name), zon) catch unreachable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn readAllBlueprints(addon: Addon, allocator: NeverFailingAllocator, output: *BytesHashMap) void {
|
||||||
|
const subPath = "blueprints";
|
||||||
|
var assetsDirectory = addon.dir.openDir(subPath, .{.iterate = true}) catch |err| {
|
||||||
|
if(err != error.FileNotFound) {
|
||||||
|
std.log.err("Could not open addon directory {s}: {s}", .{subPath, @errorName(err)});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
defer assetsDirectory.close();
|
||||||
|
|
||||||
|
var walker = assetsDirectory.walk(main.stackAllocator.allocator) catch unreachable;
|
||||||
|
defer walker.deinit();
|
||||||
|
|
||||||
|
while(walker.next() catch |err| blk: {
|
||||||
|
std.log.err("Got error while iterating addon directory {s}: {s}", .{subPath, @errorName(err)});
|
||||||
|
break :blk null;
|
||||||
|
}) |entry| {
|
||||||
|
if(entry.kind != .file) continue;
|
||||||
|
if(std.ascii.startsWithIgnoreCase(entry.basename, "_defaults")) continue;
|
||||||
|
if(!std.ascii.endsWithIgnoreCase(entry.basename, ".blp")) continue;
|
||||||
|
if(std.ascii.startsWithIgnoreCase(entry.basename, "_migrations")) continue;
|
||||||
|
|
||||||
|
const id = createAssetStringID(allocator, addon.name, entry.path);
|
||||||
|
|
||||||
|
const data = files.Dir.init(assetsDirectory).read(allocator, entry.path) catch |err| {
|
||||||
std.log.err("Could not open {s}/{s}: {s}", .{subPath, entry.path, @errorName(err)});
|
std.log.err("Could not open {s}/{s}: {s}", .{subPath, entry.path, @errorName(err)});
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
output.put(allocator.allocator, id, data) catch unreachable;
|
||||||
if(defaults) {
|
|
||||||
const path = entry.dir.realpathAlloc(main.stackAllocator.allocator, ".") catch unreachable;
|
|
||||||
defer main.stackAllocator.free(path);
|
|
||||||
|
|
||||||
const result = defaultMap.getOrPut(path) catch unreachable;
|
|
||||||
|
|
||||||
if(!result.found_existing) {
|
|
||||||
result.key_ptr.* = defaultsArenaAllocator.dupe(u8, path);
|
|
||||||
const default: ZonElement = readDefaultFile(defaultsArenaAllocator, entry.dir) catch |err| blk: {
|
|
||||||
std.log.err("Failed to read default file: {s}", .{@errorName(err)});
|
|
||||||
break :blk .null;
|
|
||||||
};
|
|
||||||
|
|
||||||
result.value_ptr.* = default;
|
|
||||||
}
|
|
||||||
|
|
||||||
zon.join(result.value_ptr.*);
|
|
||||||
}
|
|
||||||
output.put(id, zon) catch unreachable;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(migrations != null) blk: {
|
|
||||||
const zon = main.files.Dir.init(dir).readToZon(externalAllocator, "_migrations.zig.zon") catch |err| {
|
pub fn readAllModels(addon: Addon, allocator: NeverFailingAllocator, output: *BytesHashMap) void {
|
||||||
if(err != error.FileNotFound) std.log.err("Cannot read {s} migration file for addon {s}", .{subPath, addonName});
|
const subPath = "models";
|
||||||
break :blk;
|
var assetsDirectory = addon.dir.openDir(subPath, .{.iterate = true}) catch |err| {
|
||||||
|
if(err != error.FileNotFound) {
|
||||||
|
std.log.err("Could not open addon directory {s}: {s}", .{subPath, @errorName(err)});
|
||||||
|
}
|
||||||
|
return;
|
||||||
};
|
};
|
||||||
migrations.?.put(externalAllocator.dupe(u8, addonName), zon) catch unreachable;
|
defer assetsDirectory.close();
|
||||||
|
var walker = assetsDirectory.walk(main.stackAllocator.allocator) catch unreachable;
|
||||||
|
defer walker.deinit();
|
||||||
|
|
||||||
|
while(walker.next() catch |err| blk: {
|
||||||
|
std.log.err("Got error while iterating addon directory {s}: {s}", .{subPath, @errorName(err)});
|
||||||
|
break :blk null;
|
||||||
|
}) |entry| {
|
||||||
|
if(entry.kind != .file) continue;
|
||||||
|
if(!std.ascii.endsWithIgnoreCase(entry.basename, ".obj")) continue;
|
||||||
|
|
||||||
|
const id = createAssetStringID(allocator, addon.name, entry.path);
|
||||||
|
|
||||||
|
const string = assetsDirectory.readFileAlloc(allocator.allocator, entry.path, std.math.maxInt(usize)) catch |err| {
|
||||||
|
std.log.err("Could not open {s}/{s}: {s}", .{subPath, entry.path, @errorName(err)});
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
output.put(allocator.allocator, id, string) catch unreachable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
fn createAssetStringID(
|
fn createAssetStringID(
|
||||||
externalAllocator: NeverFailingAllocator,
|
externalAllocator: NeverFailingAllocator,
|
||||||
@ -184,133 +315,16 @@ fn createAssetStringID(
|
|||||||
return assetId;
|
return assetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn readAllBlueprintFilesInAddons(
|
pub fn init() void {
|
||||||
externalAllocator: NeverFailingAllocator,
|
biomes_zig.init();
|
||||||
addons: main.List(std.fs.Dir),
|
blocks_zig.init();
|
||||||
addonNames: main.List([]const u8),
|
|
||||||
subPath: []const u8,
|
|
||||||
output: *std.StringHashMap([]u8),
|
|
||||||
) void {
|
|
||||||
for(addons.items, addonNames.items) |addon, addonName| {
|
|
||||||
var dir = addon.openDir(subPath, .{.iterate = true}) catch |err| {
|
|
||||||
if(err != error.FileNotFound) {
|
|
||||||
std.log.err("Could not open addon directory {s}: {s}", .{subPath, @errorName(err)});
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
defer dir.close();
|
|
||||||
|
|
||||||
var walker = dir.walk(main.stackAllocator.allocator) catch unreachable;
|
commonAssetArena = .init(main.globalAllocator);
|
||||||
defer walker.deinit();
|
commonAssetAllocator = commonAssetArena.allocator();
|
||||||
|
|
||||||
while(walker.next() catch |err| blk: {
|
common = .init();
|
||||||
std.log.err("Got error while iterating addon directory {s}: {s}", .{subPath, @errorName(err)});
|
common.read(commonAssetAllocator, "assets/");
|
||||||
break :blk null;
|
common.log(.common);
|
||||||
}) |entry| {
|
|
||||||
if(entry.kind != .file) continue;
|
|
||||||
if(std.ascii.startsWithIgnoreCase(entry.basename, "_defaults")) continue;
|
|
||||||
if(!std.ascii.endsWithIgnoreCase(entry.basename, ".blp")) continue;
|
|
||||||
if(std.ascii.startsWithIgnoreCase(entry.basename, "_migrations")) continue;
|
|
||||||
|
|
||||||
const stringId: []u8 = createAssetStringID(externalAllocator, addonName, entry.path);
|
|
||||||
const data = main.files.Dir.init(dir).read(externalAllocator, entry.path) catch |err| {
|
|
||||||
std.log.err("Could not open {s}/{s}: {s}", .{subPath, entry.path, @errorName(err)});
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
output.put(stringId, data) catch unreachable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads obj files recursively from all subfolders.
|
|
||||||
pub fn readAllObjFilesInAddonsHashmap(
|
|
||||||
externalAllocator: NeverFailingAllocator,
|
|
||||||
addons: main.List(std.fs.Dir),
|
|
||||||
addonNames: main.List([]const u8),
|
|
||||||
subPath: []const u8,
|
|
||||||
output: *std.StringHashMap([]const u8),
|
|
||||||
) void {
|
|
||||||
for(addons.items, addonNames.items) |addon, addonName| {
|
|
||||||
var dir = addon.openDir(subPath, .{.iterate = true}) catch |err| {
|
|
||||||
if(err != error.FileNotFound) {
|
|
||||||
std.log.err("Could not open addon directory {s}: {s}", .{subPath, @errorName(err)});
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
defer dir.close();
|
|
||||||
|
|
||||||
var walker = dir.walk(main.stackAllocator.allocator) catch unreachable;
|
|
||||||
defer walker.deinit();
|
|
||||||
|
|
||||||
while(walker.next() catch |err| blk: {
|
|
||||||
std.log.err("Got error while iterating addon directory {s}: {s}", .{subPath, @errorName(err)});
|
|
||||||
break :blk null;
|
|
||||||
}) |entry| {
|
|
||||||
if(entry.kind == .file and std.ascii.endsWithIgnoreCase(entry.basename, ".obj")) {
|
|
||||||
const id: []u8 = createAssetStringID(externalAllocator, addonName, entry.path);
|
|
||||||
|
|
||||||
const string = dir.readFileAlloc(externalAllocator.allocator, entry.path, std.math.maxInt(usize)) catch |err| {
|
|
||||||
std.log.err("Could not open {s}/{s}: {s}", .{subPath, entry.path, @errorName(err)});
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
output.put(id, string) catch unreachable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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),
|
|
||||||
structureBuildingBlocks: *std.StringHashMap(ZonElement),
|
|
||||||
blueprints: *std.StringHashMap([]u8),
|
|
||||||
) void {
|
|
||||||
var addons = main.List(std.fs.Dir).init(main.stackAllocator);
|
|
||||||
defer addons.deinit();
|
|
||||||
var addonNames = main.List([]const u8).init(main.stackAllocator);
|
|
||||||
defer addonNames.deinit();
|
|
||||||
|
|
||||||
{ // Find all the sub-directories to the assets folder.
|
|
||||||
var dir = std.fs.cwd().openDir(assetPath, .{.iterate = true}) catch |err| {
|
|
||||||
std.log.err("Can't open asset path {s}: {s}", .{assetPath, @errorName(err)});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
defer dir.close();
|
|
||||||
var iterator = dir.iterate();
|
|
||||||
while(iterator.next() catch |err| blk: {
|
|
||||||
std.log.err("Got error while iterating over asset path {s}: {s}", .{assetPath, @errorName(err)});
|
|
||||||
break :blk null;
|
|
||||||
}) |addon| {
|
|
||||||
if(addon.kind == .directory) {
|
|
||||||
addons.append(dir.openDir(addon.name, .{}) catch |err| {
|
|
||||||
std.log.err("Got error while reading addon {s} from {s}: {s}", .{addon.name, assetPath, @errorName(err)});
|
|
||||||
continue;
|
|
||||||
});
|
|
||||||
addonNames.append(main.stackAllocator.dupe(u8, addon.name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
defer for(addons.items, addonNames.items) |*dir, addonName| {
|
|
||||||
dir.close();
|
|
||||||
main.stackAllocator.free(addonName);
|
|
||||||
};
|
|
||||||
|
|
||||||
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, biomeMigrations);
|
|
||||||
readAllZonFilesInAddons(externalAllocator, addons, addonNames, "recipes", false, recipes, null);
|
|
||||||
readAllObjFilesInAddonsHashmap(externalAllocator, addons, addonNames, "models", models);
|
|
||||||
readAllZonFilesInAddons(externalAllocator, addons, addonNames, "sbb", true, structureBuildingBlocks, null);
|
|
||||||
readAllBlueprintFilesInAddons(externalAllocator, addons, addonNames, "blueprints", blueprints);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn registerItem(assetFolder: []const u8, id: []const u8, zon: ZonElement) !void {
|
fn registerItem(assetFolder: []const u8, id: []const u8, zon: ZonElement) !void {
|
||||||
@ -463,51 +477,23 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, itemPale
|
|||||||
if(loadedAssets) return; // The assets already got loaded by the server.
|
if(loadedAssets) return; // The assets already got loaded by the server.
|
||||||
loadedAssets = true;
|
loadedAssets = true;
|
||||||
|
|
||||||
var blocks = commonBlocks.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
var worldArena: NeverFailingArenaAllocator = .init(main.stackAllocator);
|
||||||
defer blocks.clearAndFree();
|
defer worldArena.deinit();
|
||||||
var blockMigrations = commonBlockMigrations.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
const worldAllocator = worldArena.allocator();
|
||||||
defer blockMigrations.clearAndFree();
|
|
||||||
var items = commonItems.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
var worldAssets = common.clone(worldAllocator);
|
||||||
defer items.clearAndFree();
|
worldAssets.read(worldAllocator, assetFolder);
|
||||||
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;
|
|
||||||
defer models.clearAndFree();
|
|
||||||
var structureBuildingBlocks = commonStructureBuildingBlocks.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
|
||||||
defer structureBuildingBlocks.clearAndFree();
|
|
||||||
var blueprints = commonBlueprints.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable;
|
|
||||||
defer blueprints.clearAndFree();
|
|
||||||
|
|
||||||
readAssets(
|
|
||||||
arenaAllocator,
|
|
||||||
assetFolder,
|
|
||||||
&blocks,
|
|
||||||
&blockMigrations,
|
|
||||||
&items,
|
|
||||||
&tools,
|
|
||||||
&biomes,
|
|
||||||
&biomeMigrations,
|
|
||||||
&recipes,
|
|
||||||
&models,
|
|
||||||
&structureBuildingBlocks,
|
|
||||||
&blueprints,
|
|
||||||
);
|
|
||||||
errdefer unloadAssets();
|
errdefer unloadAssets();
|
||||||
|
|
||||||
migrations_zig.registerAll(.block, &blockMigrations);
|
migrations_zig.registerAll(.block, &worldAssets.blockMigrations);
|
||||||
migrations_zig.apply(.block, blockPalette);
|
migrations_zig.apply(.block, blockPalette);
|
||||||
|
|
||||||
migrations_zig.registerAll(.biome, &biomeMigrations);
|
migrations_zig.registerAll(.biome, &worldAssets.biomeMigrations);
|
||||||
migrations_zig.apply(.biome, biomePalette);
|
migrations_zig.apply(.biome, biomePalette);
|
||||||
|
|
||||||
// models:
|
// models:
|
||||||
var modelIterator = models.iterator();
|
var modelIterator = worldAssets.models.iterator();
|
||||||
while(modelIterator.next()) |entry| {
|
while(modelIterator.next()) |entry| {
|
||||||
_ = main.models.registerModel(entry.key_ptr.*, entry.value_ptr.*);
|
_ = main.models.registerModel(entry.key_ptr.*, entry.value_ptr.*);
|
||||||
}
|
}
|
||||||
@ -517,11 +503,11 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, itemPale
|
|||||||
// Blocks:
|
// Blocks:
|
||||||
// First blocks from the palette to enforce ID values.
|
// First blocks from the palette to enforce ID values.
|
||||||
for(blockPalette.palette.items) |stringId| {
|
for(blockPalette.palette.items) |stringId| {
|
||||||
try registerBlock(assetFolder, stringId, blocks.get(stringId) orelse .null);
|
try registerBlock(assetFolder, stringId, worldAssets.blocks.get(stringId) orelse .null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then all the blocks that were missing in palette but are present in the game.
|
// Then all the blocks that were missing in palette but are present in the game.
|
||||||
var iterator = blocks.iterator();
|
var iterator = worldAssets.blocks.iterator();
|
||||||
while(iterator.next()) |entry| {
|
while(iterator.next()) |entry| {
|
||||||
const stringId = entry.key_ptr.*;
|
const stringId = entry.key_ptr.*;
|
||||||
const zon = entry.value_ptr.*;
|
const zon = entry.value_ptr.*;
|
||||||
@ -538,16 +524,16 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, itemPale
|
|||||||
std.debug.assert(!items_zig.hasRegistered(stringId));
|
std.debug.assert(!items_zig.hasRegistered(stringId));
|
||||||
|
|
||||||
// Some items are created automatically from blocks.
|
// Some items are created automatically from blocks.
|
||||||
if(blocks.get(stringId)) |zon| {
|
if(worldAssets.blocks.get(stringId)) |zon| {
|
||||||
if(!zon.get(bool, "hasItem", true)) continue;
|
if(!zon.get(bool, "hasItem", true)) continue;
|
||||||
try registerItem(assetFolder, stringId, zon.getChild("item"));
|
try registerItem(assetFolder, stringId, zon.getChild("item"));
|
||||||
if(items.get(stringId) != null) {
|
if(worldAssets.items.get(stringId) != null) {
|
||||||
std.log.err("Item {s} appears as standalone item and as block item.", .{stringId});
|
std.log.err("Item {s} appears as standalone item and as block item.", .{stringId});
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Items not related to blocks should appear in items hash map.
|
// Items not related to blocks should appear in items hash map.
|
||||||
if(items.get(stringId)) |zon| {
|
if(worldAssets.items.get(stringId)) |zon| {
|
||||||
try registerItem(assetFolder, stringId, zon);
|
try registerItem(assetFolder, stringId, zon);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -557,7 +543,7 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, itemPale
|
|||||||
|
|
||||||
// Then missing block-items to keep backwards compatibility of ID order.
|
// Then missing block-items to keep backwards compatibility of ID order.
|
||||||
for(blockPalette.palette.items) |stringId| {
|
for(blockPalette.palette.items) |stringId| {
|
||||||
const zon = blocks.get(stringId) orelse .null;
|
const zon = worldAssets.blocks.get(stringId) orelse .null;
|
||||||
|
|
||||||
if(!zon.get(bool, "hasItem", true)) continue;
|
if(!zon.get(bool, "hasItem", true)) continue;
|
||||||
if(items_zig.hasRegistered(stringId)) continue;
|
if(items_zig.hasRegistered(stringId)) continue;
|
||||||
@ -567,7 +553,7 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, itemPale
|
|||||||
}
|
}
|
||||||
|
|
||||||
// And finally normal items.
|
// And finally normal items.
|
||||||
iterator = items.iterator();
|
iterator = worldAssets.items.iterator();
|
||||||
while(iterator.next()) |entry| {
|
while(iterator.next()) |entry| {
|
||||||
const stringId = entry.key_ptr.*;
|
const stringId = entry.key_ptr.*;
|
||||||
const zon = entry.value_ptr.*;
|
const zon = entry.value_ptr.*;
|
||||||
@ -581,7 +567,7 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, itemPale
|
|||||||
|
|
||||||
// After we have registered all items and all blocks, we can assign block references to those that come from blocks.
|
// After we have registered all items and all blocks, we can assign block references to those that come from blocks.
|
||||||
for(blockPalette.palette.items) |stringId| {
|
for(blockPalette.palette.items) |stringId| {
|
||||||
const zon = blocks.get(stringId) orelse .null;
|
const zon = worldAssets.blocks.get(stringId) orelse .null;
|
||||||
|
|
||||||
if(!zon.get(bool, "hasItem", true)) continue;
|
if(!zon.get(bool, "hasItem", true)) continue;
|
||||||
std.debug.assert(items_zig.hasRegistered(stringId));
|
std.debug.assert(items_zig.hasRegistered(stringId));
|
||||||
@ -590,29 +576,29 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, itemPale
|
|||||||
}
|
}
|
||||||
|
|
||||||
// tools:
|
// tools:
|
||||||
iterator = tools.iterator();
|
iterator = worldAssets.tools.iterator();
|
||||||
while(iterator.next()) |entry| {
|
while(iterator.next()) |entry| {
|
||||||
registerTool(assetFolder, entry.key_ptr.*, entry.value_ptr.*);
|
registerTool(assetFolder, entry.key_ptr.*, entry.value_ptr.*);
|
||||||
}
|
}
|
||||||
|
|
||||||
// block drops:
|
// block drops:
|
||||||
blocks_zig.finishBlocks(blocks);
|
blocks_zig.finishBlocks(worldAssets.blocks);
|
||||||
|
|
||||||
iterator = recipes.iterator();
|
iterator = worldAssets.recipes.iterator();
|
||||||
while(iterator.next()) |entry| {
|
while(iterator.next()) |entry| {
|
||||||
registerRecipesFromZon(entry.value_ptr.*);
|
registerRecipesFromZon(entry.value_ptr.*);
|
||||||
}
|
}
|
||||||
|
|
||||||
try sbb.registerBlueprints(&blueprints);
|
try sbb.registerBlueprints(&worldAssets.blueprints);
|
||||||
try sbb.registerSBB(&structureBuildingBlocks);
|
try sbb.registerSBB(&worldAssets.structureBuildingBlocks);
|
||||||
|
|
||||||
// Biomes:
|
// Biomes:
|
||||||
var nextBiomeNumericId: u32 = 0;
|
var nextBiomeNumericId: u32 = 0;
|
||||||
for(biomePalette.palette.items) |id| {
|
for(biomePalette.palette.items) |id| {
|
||||||
registerBiome(nextBiomeNumericId, id, biomes.get(id) orelse .null);
|
registerBiome(nextBiomeNumericId, id, worldAssets.biomes.get(id) orelse .null);
|
||||||
nextBiomeNumericId += 1;
|
nextBiomeNumericId += 1;
|
||||||
}
|
}
|
||||||
iterator = biomes.iterator();
|
iterator = worldAssets.biomes.iterator();
|
||||||
while(iterator.next()) |entry| {
|
while(iterator.next()) |entry| {
|
||||||
if(biomes_zig.hasRegistered(entry.key_ptr.*)) continue;
|
if(biomes_zig.hasRegistered(entry.key_ptr.*)) continue;
|
||||||
registerBiome(nextBiomeNumericId, entry.key_ptr.*, entry.value_ptr.*);
|
registerBiome(nextBiomeNumericId, entry.key_ptr.*, entry.value_ptr.*);
|
||||||
@ -640,10 +626,7 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, itemPale
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std.log.info(
|
worldAssets.log(.world);
|
||||||
"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()},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unloadAssets() void { // MARK: unloadAssets()
|
pub fn unloadAssets() void { // MARK: unloadAssets()
|
||||||
@ -680,7 +663,7 @@ pub fn unloadAssets() void { // MARK: unloadAssets()
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit() void {
|
pub fn deinit() void {
|
||||||
arena.deinit();
|
commonAssetArena.deinit();
|
||||||
biomes_zig.deinit();
|
biomes_zig.deinit();
|
||||||
blocks_zig.deinit();
|
blocks_zig.deinit();
|
||||||
migrations_zig.deinit();
|
migrations_zig.deinit();
|
||||||
|
@ -23,6 +23,7 @@ const block_entity = @import("block_entity.zig");
|
|||||||
const BlockEntityType = block_entity.BlockEntityType;
|
const BlockEntityType = block_entity.BlockEntityType;
|
||||||
const sbb = main.server.terrain.structure_building_blocks;
|
const sbb = main.server.terrain.structure_building_blocks;
|
||||||
const blueprint = main.blueprint;
|
const blueprint = main.blueprint;
|
||||||
|
const Assets = main.assets.Assets;
|
||||||
|
|
||||||
var arena = main.heap.NeverFailingArenaAllocator.init(main.globalAllocator);
|
var arena = main.heap.NeverFailingArenaAllocator.init(main.globalAllocator);
|
||||||
const allocator = arena.allocator();
|
const allocator = arena.allocator();
|
||||||
@ -212,7 +213,7 @@ fn registerOpaqueVariant(typ: u16, zon: ZonElement) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finishBlocks(zonElements: std.StringHashMap(ZonElement)) void {
|
pub fn finishBlocks(zonElements: Assets.ZonHashMap) void {
|
||||||
var i: u16 = 0;
|
var i: u16 = 0;
|
||||||
while(i < size) : (i += 1) {
|
while(i < size) : (i += 1) {
|
||||||
registerBlockDrop(i, zonElements.get(_id[i]) orelse continue);
|
registerBlockDrop(i, zonElements.get(_id[i]) orelse continue);
|
||||||
|
@ -170,7 +170,7 @@ pub const Blueprint = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn load(allocator: NeverFailingAllocator, inputBuffer: []u8) !Blueprint {
|
pub fn load(allocator: NeverFailingAllocator, inputBuffer: []const u8) !Blueprint {
|
||||||
var compressedReader = BinaryReader.init(inputBuffer);
|
var compressedReader = BinaryReader.init(inputBuffer);
|
||||||
const version = try compressedReader.readInt(u16);
|
const version = try compressedReader.readInt(u16);
|
||||||
|
|
||||||
|
@ -739,6 +739,8 @@ pub fn refAllDeclsRecursiveExceptCImports(comptime T: type) void {
|
|||||||
if(comptime std.mem.eql(u8, decl.name, "c")) continue;
|
if(comptime std.mem.eql(u8, decl.name, "c")) continue;
|
||||||
if(comptime std.mem.eql(u8, decl.name, "hbft")) break :blk;
|
if(comptime std.mem.eql(u8, decl.name, "hbft")) break :blk;
|
||||||
if(comptime std.mem.eql(u8, decl.name, "stb_image")) break :blk;
|
if(comptime std.mem.eql(u8, decl.name, "stb_image")) break :blk;
|
||||||
|
// TODO: Remove this after Zig removes Managed hashmap PixelGuys/Cubyz#308
|
||||||
|
if(comptime std.mem.eql(u8, decl.name, "Managed")) continue;
|
||||||
if(@TypeOf(@field(T, decl.name)) == type) {
|
if(@TypeOf(@field(T, decl.name)) == type) {
|
||||||
switch(@typeInfo(@field(T, decl.name))) {
|
switch(@typeInfo(@field(T, decl.name))) {
|
||||||
.@"struct", .@"enum", .@"union", .@"opaque" => refAllDeclsRecursiveExceptCImports(@field(T, decl.name)),
|
.@"struct", .@"enum", .@"union", .@"opaque" => refAllDeclsRecursiveExceptCImports(@field(T, decl.name)),
|
||||||
|
@ -3,6 +3,7 @@ const std = @import("std");
|
|||||||
const main = @import("main");
|
const main = @import("main");
|
||||||
const ZonElement = @import("zon.zig").ZonElement;
|
const ZonElement = @import("zon.zig").ZonElement;
|
||||||
const Palette = @import("assets.zig").Palette;
|
const Palette = @import("assets.zig").Palette;
|
||||||
|
const Assets = main.assets.Assets;
|
||||||
|
|
||||||
var arenaAllocator = main.heap.NeverFailingArenaAllocator.init(main.globalAllocator);
|
var arenaAllocator = main.heap.NeverFailingArenaAllocator.init(main.globalAllocator);
|
||||||
const migrationAllocator = arenaAllocator.allocator();
|
const migrationAllocator = arenaAllocator.allocator();
|
||||||
@ -15,7 +16,7 @@ const MigrationType = enum {
|
|||||||
biome,
|
biome,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn registerAll(comptime typ: MigrationType, migrations: *std.StringHashMap(ZonElement)) void {
|
pub fn registerAll(comptime typ: MigrationType, migrations: *Assets.AddonNameToZonMap) void {
|
||||||
std.log.info("Registering {} {s} migrations", .{migrations.count(), @tagName(typ)});
|
std.log.info("Registering {} {s} migrations", .{migrations.count(), @tagName(typ)});
|
||||||
const collection = switch(typ) {
|
const collection = switch(typ) {
|
||||||
.block => &blockMigrations,
|
.block => &blockMigrations,
|
||||||
|
@ -11,6 +11,7 @@ const Neighbor = main.chunk.Neighbor;
|
|||||||
const Block = main.blocks.Block;
|
const Block = main.blocks.Block;
|
||||||
const Degrees = main.rotation.Degrees;
|
const Degrees = main.rotation.Degrees;
|
||||||
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
||||||
|
const Assets = main.assets.Assets;
|
||||||
|
|
||||||
var arena = main.heap.NeverFailingArenaAllocator.init(main.globalAllocator);
|
var arena = main.heap.NeverFailingArenaAllocator.init(main.globalAllocator);
|
||||||
const arenaAllocator = arena.allocator();
|
const arenaAllocator = arena.allocator();
|
||||||
@ -175,7 +176,7 @@ const Child = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn registerSBB(structures: *std.StringHashMap(ZonElement)) !void {
|
pub fn registerSBB(structures: *Assets.ZonHashMap) !void {
|
||||||
std.debug.assert(structureCache.capacity() == 0);
|
std.debug.assert(structureCache.capacity() == 0);
|
||||||
structureCache.ensureTotalCapacity(arenaAllocator.allocator, structures.count()) catch unreachable;
|
structureCache.ensureTotalCapacity(arenaAllocator.allocator, structures.count()) catch unreachable;
|
||||||
childrenToResolve = .init(main.stackAllocator);
|
childrenToResolve = .init(main.stackAllocator);
|
||||||
@ -217,7 +218,7 @@ pub fn registerChildBlock(numericId: u16, stringId: []const u8) void {
|
|||||||
childBlockStringId.append(arenaAllocator, arenaAllocator.dupe(u8, colorName));
|
childBlockStringId.append(arenaAllocator, arenaAllocator.dupe(u8, colorName));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn registerBlueprints(blueprints: *std.StringHashMap([]u8)) !void {
|
pub fn registerBlueprints(blueprints: *Assets.BytesHashMap) !void {
|
||||||
std.debug.assert(blueprintCache.capacity() == 0);
|
std.debug.assert(blueprintCache.capacity() == 0);
|
||||||
|
|
||||||
originBlockNumericId = main.blocks.parseBlock(originBlockStringId).typ;
|
originBlockNumericId = main.blocks.parseBlock(originBlockStringId).typ;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user