地圖 (Jido) is a lightweight Unix TUI file explorer designed for speed and simplicity.
at main 100 lines 3.4 kB view raw
1const std = @import("std"); 2 3const vaxis = @import("vaxis"); 4 5const App = @import("app.zig"); 6 7pub const Cache = struct { 8 mutex: std.Thread.Mutex = .{}, 9 cache: std.StringHashMap(Image), 10}; 11 12const Status = enum { 13 ready, 14 processing, 15 failed, 16}; 17 18const Image = @This(); 19 20///Only use on first transmission. Subsequent draws should use 21///`Image.image`. 22data: ?vaxis.zigimg.Image = null, 23image: ?vaxis.Image = null, 24path: ?[]const u8 = null, 25status: Status = .processing, 26 27pub fn deinit(self: Image, alloc: std.mem.Allocator, vx: vaxis.Vaxis, tty: *vaxis.Tty) void { 28 if (self.image) |image| { 29 vx.freeImage(tty.writer(), image.id); 30 } 31 if (self.data) |data| { 32 var d = data; 33 d.deinit(alloc); 34 } 35 if (self.path) |path| alloc.free(path); 36} 37 38pub fn processImage(alloc: std.mem.Allocator, app: *App, path: []const u8) error{ Unsupported, OutOfMemory }!void { 39 app.images.cache.put(path, .{ .path = path, .status = .processing }) catch { 40 const message = try std.fmt.allocPrint(alloc, "Failed to load image '{s}' - error occurred while attempting to add image to cache.", .{path}); 41 defer alloc.free(message); 42 app.notification.write(message, .err) catch {}; 43 if (app.file_logger) |file_logger| file_logger.write(message, .err) catch {}; 44 return error.Unsupported; 45 }; 46 47 const load_img_thread = std.Thread.spawn(.{}, loadImage, .{ 48 alloc, 49 app, 50 path, 51 }) catch { 52 app.images.mutex.lock(); 53 if (app.images.cache.getPtr(path)) |entry| { 54 entry.status = .failed; 55 } 56 app.images.mutex.unlock(); 57 58 const message = try std.fmt.allocPrint(alloc, "Failed to load image '{s}' - error occurred while attempting to spawn processing thread.", .{path}); 59 defer alloc.free(message); 60 app.notification.write(message, .err) catch {}; 61 if (app.file_logger) |file_logger| file_logger.write(message, .err) catch {}; 62 63 return error.Unsupported; 64 }; 65 load_img_thread.detach(); 66} 67 68fn loadImage(alloc: std.mem.Allocator, app: *App, path: []const u8) error{OutOfMemory}!void { 69 var buf: [(1024 * 1024) * 5]u8 = undefined; // 5mb 70 const data = vaxis.zigimg.Image.fromFilePath(alloc, path, &buf) catch { 71 app.images.mutex.lock(); 72 if (app.images.cache.getPtr(path)) |entry| { 73 entry.status = .failed; 74 } 75 app.images.mutex.unlock(); 76 77 const message = try std.fmt.allocPrint(alloc, "Failed to load image '{s}' - error occurred while attempting to read image from path.", .{path}); 78 defer alloc.free(message); 79 app.notification.write(message, .err) catch {}; 80 if (app.file_logger) |file_logger| file_logger.write(message, .err) catch {}; 81 82 return; 83 }; 84 85 app.images.mutex.lock(); 86 if (app.images.cache.getPtr(path)) |entry| { 87 entry.status = .ready; 88 entry.data = data; 89 entry.path = path; 90 } else { 91 const message = try std.fmt.allocPrint(alloc, "Failed to load image '{s}' - error occurred while attempting to add image to cache.", .{path}); 92 defer alloc.free(message); 93 app.notification.write(message, .err) catch {}; 94 if (app.file_logger) |file_logger| file_logger.write(message, .err) catch {}; 95 return; 96 } 97 app.images.mutex.unlock(); 98 99 app.loop.postEvent(.image_ready); 100}