Backlog/engine/papyrus/src/localization.zig

112 lines
3.1 KiB
Zig

const std = @import("std");
const core = @import("core");
const Name = core.Name;
pub var gLocDbRef: ?*anyopaque = null;
pub var gLocDbInterface: *LocDbInterface = undefined;
pub const LocDbErrors = error{
OutOfMemory,
UnableToSetLocalization,
UnknownError,
};
pub const LocDbInterface = struct {
// Fetches the localized version of the string if it exists
setLocalization: *const fn (*anyopaque, Name) LocDbErrors!void,
getLocalized: *const fn (*anyopaque, u32) ?[]const u8,
createEntry: *const fn (*anyopaque, u32, []const u8) LocDbErrors!u32,
pub fn from(comptime TargetType: type) void {
const W = struct {
pub fn getLocalized(pointer: *anyopaque, key: u32) ?[]const u8 {
var ptr = @as(*TargetType, @ptrCast(@alignCast(pointer)));
return ptr.getLocalized(key);
}
pub fn createEntry(pointer: *anyopaque, key: u32, source: []const u8) LocDbErrors!u32 {
var ptr = @as(*TargetType, @ptrCast(@alignCast(pointer)));
try ptr.createEntry(key, source);
}
pub fn setLocalization(pointer: *anyopaque, name: Name) LocDbErrors!void {
var ptr = @as(*TargetType, @ptrCast(@alignCast(pointer)));
try ptr.setLocalization(name);
}
};
return @This(){
.getLocalized = W.getLocalized,
.createEntry = W.createEntry,
.setLocalization = W.setLocalization,
};
}
};
pub fn setupLocDb(ref: *anyopaque, interface: *LocDbInterface) void {
gLocDbRef = ref;
gLocDbInterface = interface;
}
// Anything display should probably be utilizing Text instead of just a normal []const u8,
pub const LocText = struct {
utf8: []const u8,
localized: ?[]const u8 = null,
locKey: u32 = 0,
pub fn getRead(self: @This()) []const u8 {
if (self.localized) |localized| {
return localized;
}
if (gLocDbRef) |locdb| {
return gLocDbInterface.getLocalized(locdb, self.locKey).?;
}
return self.utf8;
}
pub fn get(self: *@This()) []const u8 {
if (self.localized) |localized| {
return localized;
}
if (gLocDbRef) |locdb| {
self.localized = gLocDbInterface.getLocalized(locdb, self.locKey);
return self.localized.?;
}
return self.utf8;
}
pub fn fromUtf8(text: []const u8) @This() {
return .{
.utf8 = text,
};
}
pub fn fromUtf8Z(text: [:0]const u8) @This() {
for (text, 0..) |ch, i| {
if (ch == 0) {
var slice: []const u8 = undefined;
slice.ptr = text.ptr;
slice.len = i;
return .{
.utf8 = slice,
};
}
}
return .{
.utf8 = text,
};
}
};
// text construction macro
pub fn MakeText(comptime utf8: []const u8) LocText {
return LocText.fromUtf8(utf8);
}