~mil/mepo-devel

mepo: Prefer name over @This() v1 PROPOSED

Nguyễn Gia Phong: 2
 Prefer name over @This()
 Remove some redundant code

 7 files changed, 88 insertions(+), 90 deletions(-)
Ah - so giving it a bit of thought I agree.

Having a bunch of function calls for @This(); even while trivial is
likely a bit harder to read then one Self assignment for @This().

My only caveat would be that the token for the struct we use in
this pattern should be consistent (e.g. both 'Self' in the case of
EvictionHashMap is used but then 'Mepo' and 'TileCache' are used for
Mepo/TileCache). We should follow one pattern or the other for naming. I'd
say using 'Self' in all instances would be a bit better?
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~mil/mepo-devel/patches/53777/mbox | git am -3
Learn more about email & git

[PATCH mepo 1/2] Prefer name over @This() Export this patch

---
 src/Mepo.zig                          | 71 ++++++++++++++-------------
 src/TileCache.zig                     | 41 ++++++++--------
 src/datastructure/EvictionHashMap.zig | 19 +++----
 src/datastructure/QueueHashMap.zig    | 27 +++++-----
 src/types.zig                         |  6 +--
 5 files changed, 84 insertions(+), 80 deletions(-)

diff --git a/src/Mepo.zig b/src/Mepo.zig
index b8f9fe3bc4a9..5d99229a01e2 100644
--- a/src/Mepo.zig
+++ b/src/Mepo.zig
@@ -15,6 +15,7 @@ const datastructure = @import("datastructure/datastructure.zig");
const zoom_relative = @import("./api/zoom_relative.zig").zoom_relative;
const FnTable = @import("./api/_FnTable.zig");

const Mepo = @This();
allocator: std.mem.Allocator,
async_shellpipe_threads: datastructure.QueueHashMap(i8, sdl.SDL_threadID),
blit_pinlayer_cache: datastructure.EvictionHashMap(types.XYZ, *sdl.SDL_Texture, evict_texture, &config.MaxTextures),
@@ -48,21 +49,21 @@ win_w: u32 = config.InitWindowW,
window: *sdl.SDL_Window = undefined,
quit_action: ?[]const u8 = null,

pub fn convert_latlon_to_xy(mepo: *@This(), lat_or_lon: enum { LonToX, LatToY }, lat_lon_value: f64) i32 {
pub fn convert_latlon_to_xy(mepo: *Mepo, lat_or_lon: enum { LonToX, LatToY }, lat_lon_value: f64) i32 {
    return switch (lat_or_lon) {
        .LonToX => -1 * (mepo.get_x() - @as(i32, @intCast(mepo.win_w / 2)) - utilconversion.lon_to_px_x(lat_lon_value, p.get(p.pref.zoom).u)),
        .LatToY => -1 * (mepo.get_y() - @as(i32, @intCast(mepo.win_h / 2)) - utilconversion.lat_to_px_y(lat_lon_value, p.get(p.pref.zoom).u)),
    };
}

fn event_fingerdown(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_fingerdown(mepo: *Mepo, e: sdl.SDL_Event) types.Pending {
    for (mepo.fingers.items) |f| if (e.tfinger.fingerId == f) return .None;
    mepo.fingers.append(e.tfinger.fingerId) catch unreachable;
    if (mepo.fingers.items.len > 1) mepo.fingers_gesture_delta = 0;
    return .None;
}

fn event_fingerup(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_fingerup(mepo: *Mepo, e: sdl.SDL_Event) types.Pending {
    for (mepo.fingers.items, 0..) |f, i| {
        if (e.tfinger.fingerId == f) {
            _ = mepo.fingers.orderedRemove(i);
@@ -73,7 +74,7 @@ fn event_fingerup(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
    return .None;
}

fn event_textinput(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_textinput(mepo: *Mepo, e: sdl.SDL_Event) types.Pending {
    var idx: usize = 0;
    var pending: types.Pending = .None;
    const text = e.text.text;
@@ -92,7 +93,7 @@ fn event_textinput(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
    return pending;
}

fn event_multigesture(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_multigesture(mepo: *Mepo, e: sdl.SDL_Event) types.Pending {
    const threshold_pan_dist = 0.004;
    const threshold_rotate_radians = 0.015;

@@ -124,7 +125,7 @@ fn event_multigesture(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
    return .None;
}

fn event_mousebuttondown(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_mousebuttondown(mepo: *Mepo, e: sdl.SDL_Event) types.Pending {
    if (mepo.fingers.items.len > 1) return .None;

    const cursor = mepo.scaled_mouse_position();
@@ -140,7 +141,7 @@ fn event_mousebuttondown(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
    return .Redraw;
}

fn event_mousebuttonup(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_mousebuttonup(mepo: *Mepo, e: sdl.SDL_Event) types.Pending {
    if (mepo.fingers.items.len > 1) return .None;
    defer mepo.drag = null;

@@ -205,7 +206,7 @@ fn event_mousebuttonup(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
    return .None;
}

fn event_mousemotion(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_mousemotion(mepo: *Mepo, e: sdl.SDL_Event) types.Pending {
    if (mepo.fingers.items.len > 1) return .None;

    const cursor = mepo.scaled_mouse_position();
@@ -223,16 +224,16 @@ fn event_mousemotion(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
    return .None;
}

fn within_touch_bounds(mepo: *@This(), x: c_int, y: c_int) bool {
fn within_touch_bounds(mepo: *Mepo, x: c_int, y: c_int) bool {
    return x > 0 and y > 0 and x < mepo.win_w and y < mepo.win_h;
}

fn event_mousewheel(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_mousewheel(mepo: *Mepo, e: sdl.SDL_Event) types.Pending {
    zoom_relative(mepo, e.wheel.y);
    return .Redraw;
}

fn event_keyup(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_keyup(mepo: *Mepo, e: sdl.SDL_Event) types.Pending {
    if (sdl.SDL_TRUE == sdl.SDL_IsTextInputActive() and
        e.key.keysym.mod == 0) return .None;
    const key = sdl.SDL_GetScancodeName(e.key.keysym.scancode);
@@ -268,7 +269,7 @@ fn event_keyup(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
    return .None;
}

fn event_signal(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_signal(mepo: *Mepo, e: sdl.SDL_Event) types.Pending {
    if (mepo.table_signals.get(@intCast(e.user.code))) |run_expression| {
        utildbg.log("Got signals table function {s}\n", .{run_expression});
        mepo.mepolang_execute(run_expression) catch unreachable;
@@ -277,7 +278,7 @@ fn event_signal(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
    return .None;
}

fn event_windowevent(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_windowevent(mepo: *Mepo, e: sdl.SDL_Event) types.Pending {
    // Fix for certain platforms like Phosh like open keyboard on winevents
    defer if (utilplatform.supports_osk()) sdl.SDL_StopTextInput();

@@ -303,7 +304,7 @@ fn event_windowevent(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
    return .Redraw;
}

fn event_mepolangexecution(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_mepolangexecution(mepo: *Mepo, e: sdl.SDL_Event) types.Pending {
    const heap_str = std.mem.sliceTo(@as([*c]u8, @ptrCast(e.user.data1)), 0);
    utildbg.log("SDL mepolang event proccessing: <{s}>\n", .{heap_str});
    mepo.mepolang_execute(heap_str) catch |err| {
@@ -313,7 +314,7 @@ fn event_mepolangexecution(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
    return .Redraw;
}

pub fn event_quit(mepo: *@This(), _: sdl.SDL_Event) types.Pending {
pub fn event_quit(mepo: *Mepo, _: sdl.SDL_Event) types.Pending {
    if (mepo.quit_action) |quit_action| {
        mepo.mepolang_execute(quit_action) catch |err| {
            utildbg.log("Error with running mepolang quit action: {}\n", .{err});
@@ -323,7 +324,7 @@ pub fn event_quit(mepo: *@This(), _: sdl.SDL_Event) types.Pending {
    return .None;
}

fn event_unhandled(_: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_unhandled(_: *Mepo, e: sdl.SDL_Event) types.Pending {
    //utildbg.log("Unhandled SDL Event: {s}\n", .{@tagName(@intToEnum(sdl.SDL_EventType, @intCast(c_int, e.type)))});
    _ = e;
    return .None;
@@ -333,7 +334,7 @@ fn evict_texture(_: types.XYZ, texture: *sdl.SDL_Texture) void {
    sdl.SDL_DestroyTexture(texture);
}

pub fn mepolang_execute(mepo: *@This(), mepolang_text: []const u8) !void {
pub fn mepolang_execute(mepo: *Mepo, mepolang_text: []const u8) !void {
    var arena = std.heap.ArenaAllocator.init(mepo.allocator);
    defer arena.deinit();

@@ -413,7 +414,7 @@ fn mepolang_execute_validate_args(spec: types.MepoFnSpec, args: []types.MepoArg)
    return true;
}

fn dispatch_check_click_hold(mepo: *@This()) void {
fn dispatch_check_click_hold(mepo: *Mepo) void {
    if (mepo.drag == null or mepo.fingers.items.len > 1) {
        mepo.drag = null;
        return;
@@ -445,7 +446,7 @@ fn dispatch_check_click_hold(mepo: *@This()) void {
    }
}

fn dispatch_check_timers(mepo: *@This()) !void {
fn dispatch_check_timers(mepo: *Mepo) !void {
    var it = mepo.table_timers.iterator();
    while (it.next()) |kv| {
        const timer_input = kv.key_ptr.*;
@@ -462,7 +463,7 @@ fn dispatch_check_timers(mepo: *@This()) !void {
    }
}

pub fn init_video_and_sdl_stdin_loop(mepo: *@This(), enable_stdin_mepolang_repl: bool) !void {
pub fn init_video_and_sdl_stdin_loop(mepo: *Mepo, enable_stdin_mepolang_repl: bool) !void {
    if (enable_stdin_mepolang_repl) {
        const thread = sdl.SDL_CreateThread(
            mepo_sdl_loop_thread_boot,
@@ -485,14 +486,14 @@ pub fn init_video_and_sdl_stdin_loop(mepo: *@This(), enable_stdin_mepolang_repl:
}

fn mepo_sdl_loop_thread_boot(userdata: ?*anyopaque) callconv(.C) c_int {
    const mepo: *@This() = @alignCast(@ptrCast(userdata.?));
    const mepo: *Mepo = @alignCast(@ptrCast(userdata.?));
    video_init(mepo) catch unreachable;
    mepo.mepolang_execute(mepo.config) catch unreachable;
    sdl_event_loop(mepo) catch unreachable;
    return 0;
}

pub fn sdl_event_loop(mepo: *@This()) !void {
pub fn sdl_event_loop(mepo: *Mepo) !void {
    var pending: types.Pending = .None;
    var e: sdl.SDL_Event = undefined;

@@ -536,7 +537,7 @@ pub fn sdl_event_loop(mepo: *@This()) !void {
    }
}

pub fn update_debug_message(mepo: *@This(), new_msg_opt: ?[]const u8) !void {
pub fn update_debug_message(mepo: *Mepo, new_msg_opt: ?[]const u8) !void {
    if (mepo.debug_message) |dbg_msg| mepo.allocator.free(dbg_msg);
    if (new_msg_opt) |new_msg| {
        mepo.debug_message = try mepo.allocator.dupe(u8, new_msg);
@@ -553,7 +554,7 @@ pub fn update_debug_message(mepo: *@This(), new_msg_opt: ?[]const u8) !void {
// This is used in several places as its more reliable then motion/button
// events which seem to have some issue with SetLogicalSize in certain
// platforms as of SDL 2.0.22
pub fn scaled_mouse_position(mepo: *@This()) sdl.SDL_Point {
pub fn scaled_mouse_position(mepo: *Mepo) sdl.SDL_Point {
    var cursor_x: c_int = undefined;
    var cursor_y: c_int = undefined;
    var gl_w: c_int = undefined;
@@ -570,7 +571,7 @@ pub fn scaled_mouse_position(mepo: *@This()) sdl.SDL_Point {
    return .{ .x = @intFromFloat(scaled_x), .y = @intFromFloat(scaled_y) };
}

pub fn cursor_latlon(mepo: *@This()) struct { Lat: f64, Lon: f64 } {
pub fn cursor_latlon(mepo: *Mepo) struct { Lat: f64, Lon: f64 } {
    const cursor = mepo.scaled_mouse_position();

    const cursor_lat = utilconversion.px_y_to_lat(
@@ -588,23 +589,23 @@ pub fn cursor_latlon(mepo: *@This()) struct { Lat: f64, Lon: f64 } {
    };
}

pub fn get_x(_: *@This()) i32 {
pub fn get_x(_: *Mepo) i32 {
    return utilconversion.lon_to_px_x(p.get(p.pref.lon).f, p.get(p.pref.zoom).u);
}

pub fn get_y(_: *@This()) i32 {
pub fn get_y(_: *Mepo) i32 {
    return utilconversion.lat_to_px_y(p.get(p.pref.lat).f, p.get(p.pref.zoom).u);
}

pub fn set_x(_: *@This(), x: i32) void {
pub fn set_x(_: *Mepo, x: i32) void {
    p.set_n(p.pref.lon, utilconversion.px_x_to_lon(x, p.get(p.pref.zoom).u));
}

pub fn set_y(_: *@This(), y: i32) void {
pub fn set_y(_: *Mepo, y: i32) void {
    p.set_n(p.pref.lat, utilconversion.px_y_to_lat(y, p.get(p.pref.zoom).u));
}

pub fn bounding_box(mepo: *@This()) types.LatLonBox {
pub fn bounding_box(mepo: *Mepo) types.LatLonBox {
    return .{
        .topleft_lat = utilconversion.px_y_to_lat(mepo.get_y() - @as(i32, @intCast(mepo.win_h / 2)), p.get(p.pref.zoom).u),
        .topleft_lon = utilconversion.px_x_to_lon(mepo.get_x() - @as(i32, @intCast(mepo.win_w / 2)), p.get(p.pref.zoom).u),
@@ -727,11 +728,11 @@ fn setup_sdl_video_and_window(allocator: std.mem.Allocator) !*sdl.SDL_Window {
    };
}

pub fn blit(mepo: *@This()) !void {
pub fn blit(mepo: *Mepo) !void {
    return blitfns.blit(mepo);
}

pub fn video_init(mepo: *@This()) !void {
pub fn video_init(mepo: *Mepo) !void {
    mepo.window = try setup_sdl_video_and_window(mepo.allocator);
    mepo.renderer = renderer: {
        const r = try utilsdl.errorcheck_ptr(sdl.SDL_Renderer, sdl.SDL_CreateRenderer(
@@ -770,8 +771,8 @@ fn init_create_fonts_array(bold: bool) ![50]*sdl.TTF_Font {
    return fonts;
}

pub fn init(allocator: std.mem.Allocator, tile_cache: *TileCache, use_config: []const u8, renderer_type: types.RendererType) anyerror!@This() {
    return @as(@This(), .{
pub fn init(allocator: std.mem.Allocator, tile_cache: *TileCache, use_config: []const u8, renderer_type: types.RendererType) anyerror!Mepo {
    return Mepo{
        .allocator = allocator,
        .blit_pinlayer_cache = datastructure.EvictionHashMap(
            types.XYZ,
@@ -797,5 +798,5 @@ pub fn init(allocator: std.mem.Allocator, tile_cache: *TileCache, use_config: []
        .tile_cache = tile_cache,
        .uibuttons = std.ArrayList(types.UIButton).init(allocator),
        .renderer_type = renderer_type,
    });
    };
}
diff --git a/src/TileCache.zig b/src/TileCache.zig
index 17e662c22c44..a490191db053 100644
--- a/src/TileCache.zig
+++ b/src/TileCache.zig
@@ -40,6 +40,7 @@ const TileData = union(TileDataTag) {
const TileDataTag = enum { transfer_datum, texture, queued_position, error_type };
const QueuedInfo = struct { n_queued: usize, n_cached: usize };

const TileCache = @This();
allocator: std.mem.Allocator,
dev_null_fd: ?*cstdio.FILE,
thread_download: ?*sdl.SDL_Thread = null,
@@ -57,7 +58,7 @@ transfer_map: datastructure.QueueHashMap(types.XYZ, *TransferDatum),
/// Downloads tiles continuously
/// If graphical_mode is true, will idle even when queue_lifo is empty.
/// If graphical_mode is false, will terminate once queue_lifo is empty.
pub fn download_loop(tile_cache: *@This(), graphical_mode: bool) !void {
pub fn download_loop(tile_cache: *TileCache, graphical_mode: bool) !void {
    const initial_queue_bg_size = tile_cache.queue_lifo_bg.count();
    var ui_last_update_ticks = sdl.SDL_GetTicks();
    var running: c_int = undefined;
@@ -117,7 +118,7 @@ pub fn download_loop(tile_cache: *@This(), graphical_mode: bool) !void {

/// Sets the cache URL, making copy of str
/// Caller passed ptr url may be safely freed
pub fn set_cache_url(tile_cache: *@This(), url: [:0]const u8) !void {
pub fn set_cache_url(tile_cache: *TileCache, url: [:0]const u8) !void {
    if (tile_cache.thread_download != null) {
        // Set's network off (cancels inprogress transfers, resumes on switch)
        tile_cache.set_network(false);
@@ -134,7 +135,7 @@ pub fn set_cache_url(tile_cache: *@This(), url: [:0]const u8) !void {
    try p.set_t(tile_cache.allocator, p.pref.tile_cache_url, url);
}

pub fn set_cache_dir(tile_cache: *@This(), path: [:0]const u8) !void {
pub fn set_cache_dir(tile_cache: *TileCache, path: [:0]const u8) !void {
    try p.set_t(tile_cache.allocator, p.pref.tile_cache_dir, path);

    const expanded_path = try utilfile.wordexp_filepath(tile_cache.allocator, p.get(p.pref.tile_cache_dir).t.?);
@@ -145,7 +146,7 @@ pub fn set_cache_dir(tile_cache: *@This(), path: [:0]const u8) !void {

/// E.g. esentially the one function responsibel for launching/termination
/// of the download thread
pub fn set_network(tile_cache: *@This(), enable: bool) void {
pub fn set_network(tile_cache: *TileCache, enable: bool) void {
    tile_cache.set_queue(null);
    if (!enable and tile_cache.thread_download != null) {
        const orphan_thread = tile_cache.thread_download.?;
@@ -162,7 +163,7 @@ pub fn set_network(tile_cache: *@This(), enable: bool) void {

/// E.g. essentially the one function responsible for launching/termination
/// of the queuer thread
pub fn set_queue(tile_cache: *@This(), dl_req_opt: ?DownloadBBoxRequest) void {
pub fn set_queue(tile_cache: *TileCache, dl_req_opt: ?DownloadBBoxRequest) void {
    // Cancel any existing queueing thread
    if (tile_cache.thread_queuebbox) |thread_queuebbox| {
        const orphan_thread = thread_queuebbox;
@@ -185,7 +186,7 @@ pub fn set_queue(tile_cache: *@This(), dl_req_opt: ?DownloadBBoxRequest) void {
    }
}

pub fn tile_bg_bbox_queue(tile_cache: *@This(), dl_req: DownloadBBoxRequest, cancellable: bool) !QueuedInfo {
pub fn tile_bg_bbox_queue(tile_cache: *TileCache, dl_req: DownloadBBoxRequest, cancellable: bool) !QueuedInfo {
    if (cancellable and tile_cache.thread_download == null) return error.NoDownloadThread;

    const lat_min = if (dl_req.a_lat < dl_req.b_lat) dl_req.a_lat else dl_req.b_lat;
@@ -239,7 +240,7 @@ pub fn tile_bg_bbox_queue(tile_cache: *@This(), dl_req: DownloadBBoxRequest, can
/// thread and thus is safe to use renderer functions within (e.g. we transfer
/// the SDL surface into a texture here)
/// TODO: maybe just move this fn/code wholesale into Mepo.zig?
pub fn tile_ui_retreive_or_queue(tile_cache: *@This(), coords: types.XYZ) !TileData {
pub fn tile_ui_retreive_or_queue(tile_cache: *TileCache, coords: types.XYZ) !TileData {
    var file_cached_png_opt: ?[]u8 = null;

    if (tile_cache.texture_map.get(coords)) |texture| {
@@ -282,7 +283,7 @@ pub fn tile_ui_retreive_or_queue(tile_cache: *@This(), coords: types.XYZ) !TileD
// ////////////////////////////////////////////////////////////////////////////
// Private

fn curl_add_to_multi_and_register_transfer(tile_cache: *@This(), coords: types.XYZ, load_to_texture: bool) !void {
fn curl_add_to_multi_and_register_transfer(tile_cache: *TileCache, coords: types.XYZ, load_to_texture: bool) !void {
    if (tile_cache.transfer_map.get(coords)) |_| return;

    const transfer_datum: *TransferDatum = datum: {
@@ -361,7 +362,7 @@ fn curl_errorcheck(response: curl.CURLMcode) !void {
    return error.CurlMultiFail;
}

fn curl_client_to_coords(tile_cache: *@This(), client: ?*curl.CURL) ?types.XYZ {
fn curl_client_to_coords(tile_cache: *TileCache, client: ?*curl.CURL) ?types.XYZ {
    var it = tile_cache.transfer_map.iterator();
    while (it.next()) |kv| {
        if (kv.value_ptr.*.client == client) {
@@ -377,7 +378,7 @@ fn curl_setopt(client: *curl.CURL, opt: c_int, value: anytype) !void {
}

/// Show progress indicator for the download loop (for non interactive downloading)
fn download_loop_progress_indicator(tile_cache: *@This(), initial_queue_size: usize) void {
fn download_loop_progress_indicator(tile_cache: *TileCache, initial_queue_size: usize) void {
    std.debug.print("\x1b[1;1H\x1b[2J", .{});
    std.debug.print(
        \\Mepo - download mode
@@ -397,13 +398,13 @@ fn download_loop_progress_indicator(tile_cache: *@This(), initial_queue_size: us

/// Determine whether the download loop should continue based on either
/// if in graphical mode or non-empty queu
fn download_loop_should_continue(tile_cache: *@This(), graphical_mode: bool) bool {
fn download_loop_should_continue(tile_cache: *TileCache, graphical_mode: bool) bool {
    const graphical_and_online = (graphical_mode and tile_cache.thread_download != null);
    const nongraphical_and_pending = (!graphical_mode and (tile_cache.queue_lifo_bg.count() > 0 or tile_cache.transfer_map.count() > 0));
    return graphical_and_online or nongraphical_and_pending;
}

fn download_loop_transfer_complete(tile_cache: *@This(), msg: *curl.CURLMsg) !void {
fn download_loop_transfer_complete(tile_cache: *TileCache, msg: *curl.CURLMsg) !void {
    switch (msg.data.result) {
        curl.CURLE_OPERATION_TIMEDOUT => {
            utildbg.log("Curl timed out for msg: {}\n", .{msg});
@@ -448,7 +449,7 @@ fn download_loop_transfer_complete(tile_cache: *@This(), msg: *curl.CURLMsg) !vo
/// SDL resize (refresh event). By effect, if tile is loaded in texture
/// map rendering thread fetches and updates it; if CURLE_OK wasn't
/// there - the item will get repushed back into queue
fn download_loop_transfer_cleanup(tile_cache: *@This(), client: ?*curl.CURL) !void {
fn download_loop_transfer_cleanup(tile_cache: *TileCache, client: ?*curl.CURL) !void {
    if (tile_cache.curl_client_to_coords(client)) |coords| {
        const transfer_datum = tile_cache.transfer_map.get(coords).?;
        tile_cache.transfer_map.get(coords).?.data_arraylist.deinit();
@@ -464,7 +465,7 @@ fn evict_texture(_: types.XYZ, texture: *sdl.SDL_Texture) void {
    sdl.SDL_DestroyTexture(texture);
}

fn load_data_to_surface(_: *@This(), data: []u8) !*sdl.SDL_Surface {
fn load_data_to_surface(_: *TileCache, data: []u8) !*sdl.SDL_Surface {
    if (data.len == 0) return error.LoadToSurfaceFailEmptyData;

    const memory = try utilsdl.errorcheck_ptr(sdl.SDL_RWops, sdl.SDL_RWFromConstMem(@ptrCast(&data[0]), @intCast(data.len)));
@@ -483,7 +484,7 @@ fn png_path(allocator: std.mem.Allocator, source: []const u8, coords: types.XYZ)

/// Check whether tile is already in the filesystem and not expired according
/// to creation time & expiry seconds setting
fn tile_exists_in_fs_and_non_expired(tile_cache: *@This(), coords: types.XYZ) !bool {
fn tile_exists_in_fs_and_non_expired(tile_cache: *TileCache, coords: types.XYZ) !bool {
    if (tile_cache.cache_dir) |cache_dir| {
        const png = try png_path(tile_cache.allocator, p.get(p.pref.tile_cache_url).t.?, coords);
        defer tile_cache.allocator.free(png);
@@ -498,7 +499,7 @@ fn tile_exists_in_fs_and_non_expired(tile_cache: *@This(), coords: types.XYZ) !b
}

fn threadable_tile_bg_bbox_queue(userdata: ?*anyopaque) callconv(.C) c_int {
    const tile_cache: *@This() = @alignCast(@ptrCast(userdata.?));
    const tile_cache: *TileCache = @alignCast(@ptrCast(userdata.?));
    if (tile_cache.tile_bg_bbox_queue(tile_cache.bbox_queue.?, true)) |q| {
        utildbg.log("Done: {}\n", .{q});
    } else |err| {
@@ -509,16 +510,16 @@ fn threadable_tile_bg_bbox_queue(userdata: ?*anyopaque) callconv(.C) c_int {
}

fn threadable_download_loop_sdl(userdata: ?*anyopaque) callconv(.C) c_int {
    const tile_cache: *@This() = @alignCast(@ptrCast(userdata.?));
    const tile_cache: *TileCache = @alignCast(@ptrCast(userdata.?));
    tile_cache.download_loop(true) catch |e| {
        utildbg.log("Error running download loop: {}\n", .{e});
    };
    return 0;
}

pub fn init(allocator: std.mem.Allocator) anyerror!@This() {
pub fn init(allocator: std.mem.Allocator) anyerror!TileCache {
    if (curl.curl_multi_init()) |_| {
        var tc = @as(@This(), .{
        var tc = TileCache{
            .allocator = allocator,
            .dev_null_fd = cstdio.fopen("/dev/null", "wb"),
            .curl_multi = curl.curl_multi_init().?,
@@ -526,7 +527,7 @@ pub fn init(allocator: std.mem.Allocator) anyerror!@This() {
            .queue_lifo_bg = datastructure.QueueHashMap(types.XYZ, void).init(allocator),
            .texture_map = datastructure.EvictionHashMap(types.XYZ, *sdl.SDL_Texture, evict_texture, &config.MaxTextures).init(allocator),
            .transfer_map = datastructure.QueueHashMap(types.XYZ, *TransferDatum).init(allocator),
        });
        };
        try tc.set_cache_url(try allocator.dupeZ(u8, "https://tile.openstreetmap.org/%3$d/%1$d/%2$d.png"));
        return tc;
    } else {
diff --git a/src/datastructure/EvictionHashMap.zig b/src/datastructure/EvictionHashMap.zig
index 9ee65c0a0889..ee3246ca7945 100644
--- a/src/datastructure/EvictionHashMap.zig
+++ b/src/datastructure/EvictionHashMap.zig
@@ -2,29 +2,30 @@ const std = @import("std");

pub fn EvictionHashMap(comptime key_type: type, comptime metadata_type: type, comptime eviction_function: fn (key_type, metadata_type) void, comptime size: *usize) type {
    return struct {
        const Self = @This();
        array_hash_map: std.array_hash_map.AutoArrayHashMap(key_type, metadata_type),
        size: *usize,
        mutex: std.Thread.Mutex,

        pub fn count(self: *@This()) usize {
        pub fn count(self: *Self) usize {
            self.mutex.lock();
            defer self.mutex.unlock();
            return self.array_hash_map.count();
        }

        pub fn get(self: *@This(), key: key_type) ?metadata_type {
        pub fn get(self: *Self, key: key_type) ?metadata_type {
            self.mutex.lock();
            defer self.mutex.unlock();
            return self.array_hash_map.get(key);
        }

        pub fn values(self: *@This()) []metadata_type {
        pub fn values(self: *Self) []metadata_type {
            self.mutex.lock();
            defer self.mutex.unlock();
            return self.array_hash_map.values();
        }

        pub fn put(self: *@This(), k: key_type, v: metadata_type) !?metadata_type {
        pub fn put(self: *Self, k: key_type, v: metadata_type) !?metadata_type {
            self.mutex.lock();
            defer self.mutex.unlock();

@@ -32,7 +33,7 @@ pub fn EvictionHashMap(comptime key_type: type, comptime metadata_type: type, co
            return if (self.array_hash_map.count() > self.size.*) return self.shift() else null;
        }

        fn shift(self: *@This()) !metadata_type {
        fn shift(self: *Self) !metadata_type {
            const shifted_key = self.array_hash_map.keys()[0];
            const shifted_val = self.array_hash_map.values()[0];
            self.array_hash_map.orderedRemoveAt(0);
@@ -40,7 +41,7 @@ pub fn EvictionHashMap(comptime key_type: type, comptime metadata_type: type, co
            return shifted_val;
        }

        pub fn clearAndFree(self: *@This()) void {
        pub fn clearAndFree(self: *Self) void {
            self.mutex.lock();
            defer self.mutex.unlock();
            var it = self.array_hash_map.iterator();
@@ -48,12 +49,12 @@ pub fn EvictionHashMap(comptime key_type: type, comptime metadata_type: type, co
            self.array_hash_map.clearAndFree();
        }

        pub fn init(allocator: std.mem.Allocator) @This() {
            return @as(@This(), .{
        pub fn init(allocator: std.mem.Allocator) Self {
            return .{
                .size = size,
                .mutex = std.Thread.Mutex{},
                .array_hash_map = std.array_hash_map.AutoArrayHashMap(key_type, metadata_type).init(allocator),
            });
            };
        }
    };
}
diff --git a/src/datastructure/QueueHashMap.zig b/src/datastructure/QueueHashMap.zig
index a76b64926979..9cb7996a6123 100644
--- a/src/datastructure/QueueHashMap.zig
+++ b/src/datastructure/QueueHashMap.zig
@@ -10,31 +10,32 @@ const std = @import("std");
//      running put() and then pop() ensures the same item is referenced
pub fn QueueHashMap(comptime key_type: type, comptime metadata_type: type) type {
    return struct {
        const Self = @This();
        array_hash_map: std.array_hash_map.AutoArrayHashMap(key_type, metadata_type),
        mutex: std.Thread.Mutex,

        pub fn count(self: *@This()) usize {
        pub fn count(self: *Self) usize {
            self.mutex.lock();
            defer self.mutex.unlock();

            return self.array_hash_map.count();
        }

        pub fn get(self: *@This(), key: key_type) ?metadata_type {
        pub fn get(self: *Self, key: key_type) ?metadata_type {
            self.mutex.lock();
            defer self.mutex.unlock();

            return self.array_hash_map.get(key);
        }

        pub fn getPtr(self: *@This(), key: key_type) ?*metadata_type {
        pub fn getPtr(self: *Self, key: key_type) ?*metadata_type {
            self.mutex.lock();
            defer self.mutex.unlock();

            return self.array_hash_map.getPtr(key);
        }

        pub fn pop(self: *@This()) struct { key: key_type, value: metadata_type } {
        pub fn pop(self: *Self) struct { key: key_type, value: metadata_type } {
            self.mutex.lock();
            defer self.mutex.unlock();

@@ -42,35 +43,35 @@ pub fn QueueHashMap(comptime key_type: type, comptime metadata_type: type) type
            return .{ .key = popped.key, .value = popped.value };
        }

        pub fn getIndex(self: *@This(), key: key_type) ?usize {
        pub fn getIndex(self: *Self, key: key_type) ?usize {
            self.mutex.lock();
            defer self.mutex.unlock();

            return self.array_hash_map.getIndex(key);
        }

        pub fn swapRemove(self: *@This(), key: key_type) bool {
        pub fn swapRemove(self: *Self, key: key_type) bool {
            self.mutex.lock();
            defer self.mutex.unlock();

            return self.array_hash_map.swapRemove(key);
        }

        pub fn values(self: *@This()) []metadata_type {
        pub fn values(self: *Self) []metadata_type {
            self.mutex.lock();
            defer self.mutex.unlock();

            return self.array_hash_map.values();
        }

        pub fn iterator(self: *@This()) std.array_hash_map.AutoArrayHashMap(key_type, metadata_type).Iterator {
        pub fn iterator(self: *Self) std.array_hash_map.AutoArrayHashMap(key_type, metadata_type).Iterator {
            self.mutex.lock();
            defer self.mutex.unlock();

            return self.array_hash_map.iterator();
        }

        pub fn put(self: *@This(), k: key_type, v: metadata_type) !void {
        pub fn put(self: *Self, k: key_type, v: metadata_type) !void {
            self.mutex.lock();
            defer self.mutex.unlock();

@@ -82,18 +83,18 @@ pub fn QueueHashMap(comptime key_type: type, comptime metadata_type: type) type
            try self.array_hash_map.put(k, v);
        }

        pub fn clearAndFree(self: *@This()) void {
        pub fn clearAndFree(self: *Self) void {
            self.mutex.lock();
            defer self.mutex.unlock();

            self.array_hash_map.clearAndFree();
        }

        pub fn init(allocator: std.mem.Allocator) @This() {
            return @as(@This(), .{
        pub fn init(allocator: std.mem.Allocator) Self {
            return .{
                .mutex = std.Thread.Mutex{},
                .array_hash_map = std.array_hash_map.AutoArrayHashMap(key_type, metadata_type).init(allocator),
            });
            };
        }
    };
}
diff --git a/src/types.zig b/src/types.zig
index 7e2a47eb9ef7..610142b922b7 100644
--- a/src/types.zig
+++ b/src/types.zig
@@ -64,7 +64,7 @@ pub const Color = struct {

    const RGBA = packed struct { r: u8, g: u8, b: u8, a: u8 };

    fn to_rgba(self: @This()) RGBA {
    fn to_rgba(self: Color) RGBA {
        return .{
            .r = @intCast(self.value >> 16),
            .g = @intCast(self.value >> 8 & 0xff),
@@ -73,12 +73,12 @@ pub const Color = struct {
        };
    }

    pub fn to_sdl(self: @This()) sdl.SDL_Color {
    pub fn to_sdl(self: Color) sdl.SDL_Color {
        const rgba = self.to_rgba();
        return .{ .r = rgba.r, .g = rgba.g, .b = rgba.b, .a = rgba.a };
    }

    pub fn to_u32(self: @This()) u32 {
    pub fn to_u32(self: Color) u32 {
        return @bitCast(self.to_rgba());
    }
};
-- 
2.45.1







      
      

[PATCH mepo 2/2] Remove some redundant code Export this patch

---
 src/Mepo.zig                |  3 +--
 src/api/shellpipe_async.zig | 11 +++--------
 2 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/src/Mepo.zig b/src/Mepo.zig
index 5d99229a01e2..c2610fb3029d 100644
--- a/src/Mepo.zig
+++ b/src/Mepo.zig
@@ -324,9 +324,8 @@ pub fn event_quit(mepo: *Mepo, _: sdl.SDL_Event) types.Pending {
    return .None;
}

fn event_unhandled(_: *Mepo, e: sdl.SDL_Event) types.Pending {
fn event_unhandled(_: *Mepo, _: sdl.SDL_Event) types.Pending {
    //utildbg.log("Unhandled SDL Event: {s}\n", .{@tagName(@intToEnum(sdl.SDL_EventType, @intCast(c_int, e.type)))});
    _ = e;
    return .None;
}

diff --git a/src/api/shellpipe_async.zig b/src/api/shellpipe_async.zig
index e0f722ef8ddf..29ed26d7e3e4 100644
--- a/src/api/shellpipe_async.zig
+++ b/src/api/shellpipe_async.zig
@@ -74,18 +74,14 @@ fn async_shellpipe_run_catch_errors(mepo: *Mepo, unique_handle_id: i8, cmd: []co
    };
    const bump_amt = 512;

    var continue_reading = true;
    while (continue_reading) {
    while (true) {
        const events = try std.posix.poll(&poll_fds, std.math.maxInt(i32));
        if (events == 0) continue;
        if (poll_fds[0].revents & std.posix.POLL.IN != 0) {
            try stdout.ensureTotalCapacity(@min(stdout.items.len + bump_amt, max_output_bytes));
            if (stdout.unusedCapacitySlice().len == 0) return error.StdoutStreamTooLong;
            const nread = try std.posix.read(poll_fds[0].fd, stdout.unusedCapacitySlice());
            if (nread == 0) {
                continue_reading = false;
                continue;
            }
            if (nread == 0) break;
            stdout.items.len += nread;
            if (std.mem.lastIndexOf(u8, stdout.items, ";")) |mepolang_statement_end_index| {
                const statement = stdout.items[0 .. mepolang_statement_end_index + 1];
@@ -95,8 +91,7 @@ fn async_shellpipe_run_catch_errors(mepo: *Mepo, unique_handle_id: i8, cmd: []co
                try stdout.replaceRange(0, mepolang_statement_end_index + 1, &[_]u8{});
            }
        } else if (poll_fds[0].revents & (std.posix.POLL.ERR | std.posix.POLL.NVAL | std.posix.POLL.HUP) != 0) {
            continue_reading = false;
            continue;
            break;
        }
    }
    _ = try child.kill();
-- 
2.45.1