~mil/mepo

4bb3b55aac499ba4f85180006c6b69976c6c0a14 — Miles Alan a month ago c9af5f4
Move prefrences into global / utilprefs rather then object structure

To allow for usages within TileCache and additional by debug / debug_stderr
7 files changed, 70 insertions(+), 113 deletions(-)

M src/Mepo.zig
M src/TileCache.zig
M src/api/prefinc.zig
M src/api/prefset_n.zig
M src/api/preftoggle.zig
M src/util/utildbg.zig
R src/{Prefs.zig => util/utilprefs.zig}
M src/Mepo.zig => src/Mepo.zig +22 -24
@@ 7,11 7,11 @@ const TileCache = @import("./TileCache.zig");
const utilconversion = @import("./util/utilconversion.zig");
const utilmepolang = @import("util/utilmepolang.zig");
const utilplatform = @import("util/utilplatform.zig");
const utilprefs = @import("util/utilprefs.zig");
const utildbg = @import("util/utildbg.zig");
const utilsdl = @import("util/utilsdl.zig");
const zoom_relative = @import("./api/zoom_relative.zig").zoom_relative;
const FnTable = @import("./api/_FnTable.zig");
const Prefs = @import("./Prefs.zig");

var pending_signal: ?u6 = null;
allocator: std.mem.Allocator,


@@ 47,23 47,22 @@ win_h: u32 = config.InitWindowH,
win_w: u32 = config.InitWindowW,
window: *sdl.SDL_Window = undefined,
zoom: u8 = 14,
prefs: Prefs,

fn blit_crosshair(mepo: *@This()) errors.SDLError!void {
    try utilsdl.sdl_renderer_set_draw_color(mepo.renderer, .{ .value = 0x000000 });
    try utilsdl.errorcheck(sdl.SDL_RenderDrawLine(
        mepo.renderer,
        @intCast(c_int, mepo.win_w / 2 - (mepo.prefs.get("crosshair_size").u / 2)),
        @intCast(c_int, mepo.win_w / 2 - (utilprefs.get("crosshair_size").u / 2)),
        @intCast(c_int, mepo.win_h / 2),
        @intCast(c_int, mepo.win_w / 2 + (mepo.prefs.get("crosshair_size").u / 2)),
        @intCast(c_int, mepo.win_w / 2 + (utilprefs.get("crosshair_size").u / 2)),
        @intCast(c_int, mepo.win_h / 2),
    ));
    try utilsdl.errorcheck(sdl.SDL_RenderDrawLine(
        mepo.renderer,
        @intCast(c_int, mepo.win_w / 2),
        @intCast(c_int, mepo.win_h / 2 - (mepo.prefs.get("crosshair_size").u / 2)),
        @intCast(c_int, mepo.win_h / 2 - (utilprefs.get("crosshair_size").u / 2)),
        @intCast(c_int, mepo.win_w / 2),
        @intCast(c_int, mepo.win_h / 2 + (mepo.prefs.get("crosshair_size").u / 2)),
        @intCast(c_int, mepo.win_h / 2 + (utilprefs.get("crosshair_size").u / 2)),
    ));
}



@@ 103,7 102,7 @@ pub fn blit_tiles_all(mepo: *@This(), bbox: sdl.SDL_Rect, zoom: u8) !void {
}

pub fn blit_tile_text(mepo: *@This(), tile_x: u32, tile_y: u32, zoom: u8, x_off: i32, y_off: i32) !void {
    if (!mepo.prefs.get("debug_tiles").b) return;
    if (!utilprefs.get("debug_tiles").b) return;
    var dl_now: c_long = 0;
    var dl_total: c_long = 0;



@@ 192,9 191,9 @@ pub fn blit_tile_surface(mepo: *@This(), tile_x: u32, tile_y: u32, zoom: u8, x_o
}

fn blit_overlay_pindetails(mepo: *@This()) !void {
    if (!mepo.prefs.get("overlay_pindetails").b) return;
    if (!utilprefs.get("overlay_pindetails").b) return;

    const d_unit_km = mepo.prefs.get("distance_unit_tf_km_mi").b;
    const d_unit_km = utilprefs.get("distance_unit_tf_km_mi").b;
    const d_unit = if (d_unit_km) "km" else "mi";

    var arena = std.heap.ArenaAllocator.init(mepo.allocator);


@@ 242,8 241,8 @@ fn blit_overlay_pindetails(mepo: *@This()) !void {
}

fn blit_debugmessage(mepo: *@This()) !void {
    if (mepo.prefs.get("debug_message_enabled").b and mepo.debug_message != null) {
        const bottom_off: u32 = if (mepo.prefs.get("overlay_debugbar").b) mepo.prefs.get("fontsize_ui").u + 10 else 5;
    if (utilprefs.get("debug_message_enabled").b and mepo.debug_message != null) {
        const bottom_off: u32 = if (utilprefs.get("overlay_debugbar").b) utilprefs.get("fontsize_ui").u + 10 else 5;
        try mepo.blit_multiline_text(
            0xff0000,
            null,


@@ 349,8 348,8 @@ fn blit_pins(mepo: *@This()) !void {
}

fn blit_overlay_debugbar(mepo: *@This()) !void {
    if (!mepo.prefs.get("overlay_debugbar").b) return;
    const bottombar_height = mepo.prefs.get("fontsize_ui").u + 5;
    if (!utilprefs.get("overlay_debugbar").b) return;
    const bottombar_height = utilprefs.get("fontsize_ui").u + 5;

    const bg: types.Color = color: {
        if (mepo.tile_cache.thread_download == null) {


@@ 410,7 409,7 @@ fn blit_overlay_debugbar(mepo: *@This()) !void {
}

fn blit_help(mepo: *@This()) !void {
    if (!mepo.prefs.get("help").b) return;
    if (!utilprefs.get("help").b) return;

    var msg = msg: {
        var acc = std.ArrayList([]const u8).init(mepo.allocator);


@@ 456,7 455,7 @@ fn blit_uibuttons(mepo: *@This(), determine_click_target: ?sdl.SDL_MouseButtonEv
    var btn_i = mepo.uibuttons.items.len;
    const pad: c_int = 5;
    var right_pad: c_int = 10;
    const pad_bottom: c_int = mepo.prefs.get("fontsize_ui").u + 10;
    const pad_bottom: c_int = utilprefs.get("fontsize_ui").u + 10;

    while (btn_i > 0) {
        btn_i -= 1;


@@ 466,7 465,7 @@ fn blit_uibuttons(mepo: *@This(), determine_click_target: ?sdl.SDL_MouseButtonEv

        const surf = try utilsdl.errorcheck_ptr(
            sdl.SDL_Surface,
            sdl.TTF_RenderText_Blended(mepo.fonts_bold[mepo.prefs.get("fontsize_ui").u], @ptrCast([*c]const u8, mepo.uibuttons.items[btn_i].text), (types.Color{ .value = 0x000000 }).to_sdl()),
            sdl.TTF_RenderText_Blended(mepo.fonts_bold[utilprefs.get("fontsize_ui").u], @ptrCast([*c]const u8, mepo.uibuttons.items[btn_i].text), (types.Color{ .value = 0x000000 }).to_sdl()),
        );
        defer sdl.SDL_FreeSurface(surf);



@@ 713,8 712,8 @@ fn event_mousemotion(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
        mepo.drag.?.point.y = e.motion.y;
        mepo.drag.?.delta_x += std.math.absInt(e.motion.xrel) catch unreachable;
        mepo.drag.?.delta_y += std.math.absInt(e.motion.yrel) catch unreachable;
        mepo.set_x(mepo.get_x() - (e.motion.xrel * mepo.prefs.get("drag_scale").u));
        mepo.set_y(mepo.get_y() - (e.motion.yrel * mepo.prefs.get("drag_scale").u));
        mepo.set_x(mepo.get_x() - (e.motion.xrel * utilprefs.get("drag_scale").u));
        mepo.set_y(mepo.get_y() - (e.motion.yrel * utilprefs.get("drag_scale").u));
        return .Drag;
    } else {
        mepo.drag = null;


@@ 1010,12 1009,12 @@ fn blit_table(mepo: *@This(), x: i32, y: i32, padding: c_int, rows: []const [2][
    for (rows) |row| {
        const surf_lab = try utilsdl.errorcheck_ptr(
            sdl.SDL_Surface,
            sdl.TTF_RenderText_Blended(mepo.fonts_bold[mepo.prefs.get("fontsize_ui").u], @ptrCast([*c]const u8, row[0]), (types.Color{ .value = 0x000000 }).to_sdl()),
            sdl.TTF_RenderText_Blended(mepo.fonts_bold[utilprefs.get("fontsize_ui").u], @ptrCast([*c]const u8, row[0]), (types.Color{ .value = 0x000000 }).to_sdl()),
        );
        defer sdl.SDL_FreeSurface(surf_lab);
        const surf_val = try utilsdl.errorcheck_ptr(
            sdl.SDL_Surface,
            sdl.TTF_RenderText_Blended(mepo.fonts_normal[mepo.prefs.get("fontsize_ui").u], @ptrCast([*c]const u8, row[1]), (types.Color{ .value = 0x000000 }).to_sdl()),
            sdl.TTF_RenderText_Blended(mepo.fonts_normal[utilprefs.get("fontsize_ui").u], @ptrCast([*c]const u8, row[1]), (types.Color{ .value = 0x000000 }).to_sdl()),
        );
        defer sdl.SDL_FreeSurface(surf_val);
        width_label = std.math.max(width_label, surf_lab.w);


@@ 1049,7 1048,7 @@ fn blit_table(mepo: *@This(), x: i32, y: i32, padding: c_int, rows: []const [2][
        // Label
        const surf_lab = try utilsdl.errorcheck_ptr(
            sdl.SDL_Surface,
            sdl.TTF_RenderText_Blended(mepo.fonts_bold[mepo.prefs.get("fontsize_ui").u], @ptrCast([*c]const u8, row[0]), (types.Color{ .value = 0x000000 }).to_sdl()),
            sdl.TTF_RenderText_Blended(mepo.fonts_bold[utilprefs.get("fontsize_ui").u], @ptrCast([*c]const u8, row[0]), (types.Color{ .value = 0x000000 }).to_sdl()),
        );
        const text_lab = try utilsdl.errorcheck_ptr(sdl.SDL_Texture, sdl.SDL_CreateTextureFromSurface(mepo.renderer, surf_lab));
        defer sdl.SDL_FreeSurface(surf_lab);


@@ 1064,7 1063,7 @@ fn blit_table(mepo: *@This(), x: i32, y: i32, padding: c_int, rows: []const [2][
        // Value
        const surf_value = try utilsdl.errorcheck_ptr(
            sdl.SDL_Surface,
            sdl.TTF_RenderText_Blended(mepo.fonts_normal[mepo.prefs.get("fontsize_ui").u], @ptrCast([*c]const u8, row[1]), (types.Color{ .value = 0x000000 }).to_sdl()),
            sdl.TTF_RenderText_Blended(mepo.fonts_normal[utilprefs.get("fontsize_ui").u], @ptrCast([*c]const u8, row[1]), (types.Color{ .value = 0x000000 }).to_sdl()),
        );
        const text_value = try utilsdl.errorcheck_ptr(sdl.SDL_Texture, sdl.SDL_CreateTextureFromSurface(mepo.renderer, surf_value));
        defer sdl.SDL_FreeSurface(surf_value);


@@ 1105,7 1104,7 @@ pub fn blit_multiline_text(
        if (font_size_opt) |font_size| {
            if (font_size > mepo.fonts_normal.len) return error.FontTooBig else break :font_size font_size;
        } else {
            break :font_size mepo.prefs.get("fontsize_ui").u;
            break :font_size utilprefs.get("fontsize_ui").u;
        }
    };



@@ 1390,6 1389,5 @@ pub fn init(allocator: std.mem.Allocator, tile_cache: *TileCache, use_config: []
        .uibuttons = std.ArrayList(types.UIButton).init(allocator),
        .async_shellpipe_threads = std.ArrayList(*sdl.SDL_Thread).init(allocator),
        .renderer_sw = use_sw_renderer,
        .prefs = Prefs.init(),
    });
}

M src/TileCache.zig => src/TileCache.zig +5 -4
@@ 12,6 12,7 @@ const utilsdl = @import("./util/utilsdl.zig");
const utilconversion = @import("./util/utilconversion.zig");
const utilfile = @import("./util/utilfile.zig");
const utildbg = @import("./util/utildbg.zig");
const utilprefs = @import("./util/utilprefs.zig");
const datastructure = @import("./datastructure/datastructure.zig");

pub const DownloadBBoxRequest = struct {


@@ 47,7 48,6 @@ byte_counter: u64 = 0,
cache_dir: ?std.fs.Dir = null,
curl_multi: *curl.CURLM,
expiry_seconds: i32 = -1,
max_n_transfers: u8 = 20,
queue_lifo_ui: datastructure.QueueHashMap(types.XYZ, void),
queue_lifo_bg: datastructure.QueueHashMap(types.XYZ, void),
renderer: ?*sdl.SDL_Renderer = null,


@@ 83,13 83,13 @@ pub fn download_loop(tile_cache: *@This(), graphical_mode: bool) !void {
        }

        // 2. Transfer from UI LIFO into transfers
        while (tile_cache.queue_lifo_ui.count() > 0 and tile_cache.transfer_map.count() < tile_cache.max_n_transfers) {
        while (tile_cache.queue_lifo_ui.count() > 0 and tile_cache.transfer_map.count() < utilprefs.get("tile_cache_max_n_transfers").u) {
            var coords = tile_cache.queue_lifo_ui.pop();
            try tile_cache.curl_add_to_multi_and_register_transfer(coords.key, true);
        }

        // 3. Transfer from BG LIFO into transfers
        while (tile_cache.queue_lifo_bg.count() > 0 and tile_cache.transfer_map.count() < tile_cache.max_n_transfers) {
        while (tile_cache.queue_lifo_bg.count() > 0 and tile_cache.transfer_map.count() < utilprefs.get("tile_cache_max_n_transfers").u) {
            var coords = tile_cache.queue_lifo_bg.pop();
            try tile_cache.curl_add_to_multi_and_register_transfer(coords.key, false);
        }


@@ 486,7 486,8 @@ fn tile_exists_in_fs_and_non_expired(tile_cache: *@This(), coords: types.XYZ) !b
        defer tile_cache.allocator.free(png);
        const tile_file = cache_dir.openFile(png, .{}) catch return false;
        defer tile_file.close();
        if (tile_cache.expiry_seconds < 0 or std.time.timestamp() < (try tile_file.stat()).ctime + tile_cache.expiry_seconds) {
        const expiry_seconds = @floatToInt(i32, utilprefs.get("tile_cache_expiry_seconds").f);
        if (expiry_seconds < 0 or std.time.timestamp() < (try tile_file.stat()).ctime + expiry_seconds) {
            return true;
        }
    }

M src/api/prefinc.zig => src/api/prefinc.zig +4 -3
@@ 2,6 2,7 @@ const Mepo = @import("../Mepo.zig");
const types = @import("../types.zig");
const std = @import("std");
const utildbg = @import("../util/utildbg.zig");
const utilprefs = @import("../util/utilprefs.zig");

pub const spec = .{
    .name = "prefinc",


@@ 13,12 14,12 @@ pub const spec = .{
    .execute = execute,
};

fn execute(mepo: *Mepo, args: [types.MepoFnNargs]types.MepoArg) !void {
fn execute(_: *Mepo, args: [types.MepoFnNargs]types.MepoArg) !void {
    const name = args[0].Text;
    const delta = args[1].Number;

    const val = mepo.prefs.get(name).u;
    mepo.prefs.set_n(name, @intToFloat(f64, val) + delta);
    const val = utilprefs.get(name).u;
    utilprefs.set_n(name, @intToFloat(f64, val) + delta);

    //for (&[_]struct { prop: []const u8, ptr: *u8 }{
    //    .{ .prop = "fontsize_ui", .ptr = &mepo.fontsize_ui },

M src/api/prefset_n.zig => src/api/prefset_n.zig +3 -33
@@ 2,6 2,7 @@ const Mepo = @import("../Mepo.zig");
const types = @import("../types.zig");
const std = @import("std");
const utildbg = @import("../util/utildbg.zig");
const utilprefs = @import("../util/utilprefs.zig");

pub const spec = .{
    .name = "prefset_n",


@@ 14,42 15,11 @@ pub const spec = .{
    .execute = execute,
};

fn execute(mepo: *Mepo, args: [types.MepoFnNargs]types.MepoArg) !void {
fn execute(_: *Mepo, args: [types.MepoFnNargs]types.MepoArg) !void {
    const name = args[0].Text;
    const value = args[1].Number;

    mepo.prefs.set_n(name, value);

    // Bools
    //for (&[_]struct { prop: []const u8, ptr: *bool }{
    //    .{ .prop = "debug_message_enabled", .ptr = &mepo.debug_message_enabled },
    //    .{ .prop = "debug_stderr", .ptr = &utildbg.debug_stderr },
    //    .{ .prop = "debug_tiles", .ptr = &mepo.debug_tiles },
    //    .{ .prop = "distance_unit_tf_km_mi", .ptr = &mepo.distance_unit_tf_km_mi },
    //    .{ .prop = "overlay_debugbar", .ptr = &mepo.overlay_debugbar },
    //    .{ .prop = "overlay_pindetails", .ptr = &mepo.overlay_pindetails },
    //    .{ .prop = "help", .ptr = &mepo.help },
    //}) |stg| {
    //    if (std.mem.eql(u8, stg.prop, name)) stg.ptr.* = value == 1;
    //}

    // U8 Ints
    //for (&[_]struct { prop: []const u8, ptr: *u8 }{
    //    .{ .prop = "fontsize_ui", .ptr = &mepo.fontsize_ui },
    //    .{ .prop = "drag_scale", .ptr = &mepo.drag_scale },
    //    .{ .prop = "zoom", .ptr = &mepo.zoom },
    //    .{ .prop = "crosshair_size", .ptr = &mepo.crosshair_size },
    //    .{ .prop = "tile_cache_max_n_transfers", .ptr = &mepo.tile_cache.max_n_transfers },
    //}) |stg| {
    //    if (std.mem.eql(u8, stg.prop, name)) stg.ptr.* = @floatToInt(u8, value);
    //}

    // I32 Ints
    //for (&[_]struct { prop: []const u8, ptr: *i32 }{
    //    .{ .prop = "tile_cache_expiry_seconds", .ptr = &mepo.tile_cache.expiry_seconds },
    //}) |stg| {
    //    if (std.mem.eql(u8, stg.prop, name)) stg.ptr.* = @floatToInt(i32, value);
    //}
    utilprefs.set_n(name, value);

    //if (std.mem.eql(u8, "tile_cache_network", name)) {
    //    mepo.tile_cache.set_network(value == 1);

M src/api/preftoggle.zig => src/api/preftoggle.zig +3 -13
@@ 2,6 2,7 @@ const Mepo = @import("../Mepo.zig");
const types = @import("../types.zig");
const std = @import("std");
const utildbg = @import("../util/utildbg.zig");
const utilprefs = @import("../util/utilprefs.zig");

pub const spec = .{
    .name = "preftoggle",


@@ 13,21 14,10 @@ pub const spec = .{
    .execute = execute,
};

fn execute(mepo: *Mepo, args: [types.MepoFnNargs]types.MepoArg) !void {
fn execute(_: *Mepo, args: [types.MepoFnNargs]types.MepoArg) !void {
    const name = args[0].Text;

    mepo.prefs.toggle_bool(name);

    //for (&[_]struct { prop: []const u8, ptr: *bool }{
    //    .{ .prop = "help", .ptr = &mepo.help },
    //    .{ .prop = "overlay_debugbar", .ptr = &mepo.overlay_debugbar },
    //    .{ .prop = "overlay_pindetails", .ptr = &mepo.overlay_pindetails },
    //    .{ .prop = "debug_message_enabled", .ptr = &mepo.debug_message_enabled },
    //    .{ .prop = "debug_tiles", .ptr = &mepo.debug_tiles },
    //    .{ .prop = "debug_stderr", .ptr = &utildbg.debug_stderr },
    //}) |stg| {
    //    if (std.mem.eql(u8, stg.prop, name)) stg.ptr.* = !stg.ptr.*;
    //}
    utilprefs.toggle_bool(name);

    //if (std.mem.eql(u8, "tile_cache_network", name)) {
    //    mepo.tile_cache.set_network(!(mepo.tile_cache.thread_download != null));

M src/util/utildbg.zig => src/util/utildbg.zig +2 -3
@@ 1,7 1,6 @@
const std = @import("std");

pub var debug_stderr: bool = true;
const utilprefs = @import("./utilprefs.zig");

pub fn log(comptime msg: []const u8, args: anytype) void {
    if (debug_stderr) std.debug.print(msg, args);
    if (utilprefs.get("debug_stderr").b) std.debug.print(msg, args);
}

R src/Prefs.zig => src/util/utilprefs.zig +31 -33
@@ 1,23 1,40 @@
const std = @import("std");

const PrefValueEnum = enum { b, t, n, u };
const PrefValueUnion = union(PrefValueEnum) { b: bool, t: []const u8, n: f64, u: u8 };
const PrefValueEnum = enum { b, t, f, u };
const PrefValueUnion = union(PrefValueEnum) { b: bool, t: []const u8, f: f64, u: u8 };
const PrefMapping = struct {
    name: []const u8,
    value: PrefValueUnion,
};

prefs_mapping: [10]PrefMapping = undefined,
const n_prefs = 13;
var prefs_mapping: [n_prefs]PrefMapping = mapping: {
    var mapping: [n_prefs]PrefMapping = undefined;
    mapping[0] = .{ .name = "debug_message_enabled", .value = .{ .b = true } };
    mapping[1] = .{ .name = "distance_unit_tf_km_mi", .value = .{ .b = false } };
    mapping[2] = .{ .name = "overlay_debugbar", .value = .{ .b = true } };
    mapping[3] = .{ .name = "help", .value = .{ .b = false } };
    mapping[4] = .{ .name = "overlay_pindetails", .value = .{ .b = true } };
    mapping[5] = .{ .name = "crosshair_size", .value = .{ .u = 15 } };
    mapping[6] = .{ .name = "drag_scale", .value = .{ .u = 2 } };
    mapping[7] = .{ .name = "fontsize_ui", .value = .{ .u = 20 } };
    mapping[8] = .{ .name = "zoom", .value = .{ .u = 14 } };
    mapping[9] = .{ .name = "debug_tiles", .value = .{ .b = false } };
    mapping[10] = .{ .name = "debug_stderr", .value = .{ .b = false } };
    mapping[11] = .{ .name = "tile_cache_max_n_transfers", .value = .{ .u = 20 } };
    mapping[12] = .{ .name = "tile_cache_expiry_seconds", .value = .{ .f = -1 } };
    break :mapping mapping;
};

pub fn get_u8(prefs: *@This(), prefname: []const u8) f64 {
    for (prefs.prefs_mapping) |pref| {
pub fn get_u8(prefname: []const u8) f64 {
    for (prefs_mapping) |pref| {
        if (std.mem.eql(u8, pref.name, prefname)) return pref.value.u;
    }
    return 0;
}

pub fn get(prefs: *@This(), prefname: []const u8) PrefValueUnion {
    for (prefs.prefs_mapping) |pref| {
pub fn get(prefname: []const u8) PrefValueUnion {
    for (prefs_mapping) |pref| {
        if (std.mem.eql(u8, pref.name, prefname)) {
            return pref.value;
        }


@@ 25,8 42,8 @@ pub fn get(prefs: *@This(), prefname: []const u8) PrefValueUnion {
    return .{ .b = false };
}

pub fn set_n(prefs: *@This(), prefname: []const u8, value: f64) void {
    for (prefs.prefs_mapping) |*pref| {
pub fn set_n(prefname: []const u8, value: f64) void {
    for (prefs_mapping) |*pref| {
        if (std.mem.eql(u8, pref.name, prefname)) {
            switch (pref.value) {
                .b => {


@@ 35,8 52,8 @@ pub fn set_n(prefs: *@This(), prefname: []const u8, value: f64) void {
                .u => {
                    pref.value = .{ .u = @floatToInt(u8, value) };
                },
                .n => {
                    pref.value = .{ .n = value };
                .f => {
                    pref.value = .{ .f = value };
                },
                .t => {},
            }


@@ 44,8 61,8 @@ pub fn set_n(prefs: *@This(), prefname: []const u8, value: f64) void {
    }
}

pub fn toggle_bool(prefs: *@This(), prefname: []const u8) void {
    for (prefs.prefs_mapping) |*pref| {
pub fn toggle_bool(prefname: []const u8) void {
    for (prefs_mapping) |*pref| {
        if (std.mem.eql(u8, pref.name, prefname)) {
            switch (pref.value) {
                .b => {


@@ 55,23 72,4 @@ pub fn toggle_bool(prefs: *@This(), prefname: []const u8) void {
            }
        }
    }
}

pub fn init() @This() {
    return @as(@This(), .{
        .prefs_mapping = mapping: {
            var prefs_mapping: [10]PrefMapping = undefined;
            prefs_mapping[0] = .{ .name = "debug_message_enabled", .value = .{ .b = true } };
            prefs_mapping[1] = .{ .name = "distance_unit_tf_km_mi", .value = .{ .b = false } };
            prefs_mapping[2] = .{ .name = "overlay_debugbar", .value = .{ .b = true } };
            prefs_mapping[3] = .{ .name = "help", .value = .{ .b = false } };
            prefs_mapping[4] = .{ .name = "overlay_pindetails", .value = .{ .b = true } };
            prefs_mapping[5] = .{ .name = "crosshair_size", .value = .{ .u = 15 } };
            prefs_mapping[6] = .{ .name = "drag_scale", .value = .{ .u = 2 } };
            prefs_mapping[7] = .{ .name = "fontsize_ui", .value = .{ .u = 20 } };
            prefs_mapping[8] = .{ .name = "zoom", .value = .{ .u = 14 } };
            prefs_mapping[9] = .{ .name = "debug_tiles", .value = .{ .b = false } };
            break :mapping prefs_mapping;
        },
    });
}
}
\ No newline at end of file