Skip to content

Commit 3640688

Browse files
committed
assets: Implement asset:// and file:// handlers
1 parent 1bff24e commit 3640688

File tree

3 files changed

+39
-8
lines changed

3 files changed

+39
-8
lines changed
File renamed without changes.

examples/fade.zig

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ pub fn main() !void {
2626
try capy.backend.init();
2727

2828
var window = try capy.Window.init();
29-
const imageData = try capy.ImageData.fromBuffer(capy.internal.lasting_allocator, @embedFile("ziglogo.png"));
29+
// const imageData = try capy.ImageData.fromBuffer(capy.internal.lasting_allocator, @embedFile("ziglogo.png"));
3030

3131
try window.set(
3232
capy.Row(.{}, .{
3333
capy.Expanded((try capy.Row(.{}, .{
3434
capy.Label(.{ .text = "Hello Zig" }),
3535
capy.Expanded(
36-
capy.Image(.{ .data = imageData, .scaling = .Fit }),
36+
// capy.Image(.{ .url = "asset://examples/ziglogo.png", .scaling = .Fit }),
37+
capy.Image(.{ .url = "file:///media/randy/Données/home/randy/code/capy/assets/ziglogo.png", .scaling = .Fit }),
3738
),
3839
}))
3940
.bind("opacity", &opacity)),

src/assets.zig

+36-6
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,38 @@
11
//! URI based system for retrieving assets
22
const std = @import("std");
33
const http = @import("http.zig");
4+
const internal = @import("internal.zig");
5+
const log = std.log.scoped(.assets);
46
const Uri = std.Uri;
57

68
const GetError = Uri.ParseError || http.SendRequestError || error{UnsupportedScheme};
79

810
pub const AssetHandle = struct {
911
data: union(enum) {
1012
http: http.HttpResponse,
13+
file: std.fs.File,
1114
},
1215

1316
// TODO: intersection between file and http error
14-
pub const ReadError = http.HttpResponse.ReadError;
17+
pub const ReadError = http.HttpResponse.ReadError || std.fs.File.ReadError;
1518
pub const Reader = std.io.Reader(*AssetHandle, ReadError, read);
1619

1720
pub fn reader(self: *AssetHandle) Reader {
1821
return .{ .context = self };
1922
}
2023

24+
pub fn bufferedReader(self: *AssetHandle) std.io.BufferedReader(4096, Reader) {
25+
return std.io.bufferedReaderSize(4096, self.reader());
26+
}
27+
2128
pub fn read(self: *AssetHandle, dest: []u8) ReadError!usize {
2229
switch (self.data) {
2330
.http => |*resp| {
2431
return try resp.read(dest);
2532
},
33+
.file => |file| {
34+
return try file.read(dest);
35+
},
2636
}
2737
}
2838

@@ -31,23 +41,43 @@ pub const AssetHandle = struct {
3141
.http => |*resp| {
3242
resp.deinit();
3343
},
44+
.file => |file| {
45+
file.close();
46+
},
3447
}
3548
}
3649
};
3750

3851
pub fn get(url: []const u8) GetError!AssetHandle {
39-
const uri = try Uri.parse(url);
52+
// Normalize the URI for the file:// scheme
53+
var out_url: [4096]u8 = undefined;
54+
const new_size = std.mem.replacementSize(u8, url, "file:///", "file:/");
55+
_ = std.mem.replace(u8, url, "file:///", "file:/", &out_url);
56+
57+
const uri = try Uri.parse(out_url[0..new_size]);
58+
log.debug("Loading {s}", .{url});
59+
60+
if (std.mem.eql(u8, uri.scheme, "asset")) {
61+
// TODO: on wasm load from the web (in relative path)
62+
// TODO: on pc make assets into a bundle and use @embedFile ? this would ease loading times on windows which
63+
// notoriously BAD I/O performance
64+
var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
65+
const cwd_path = try std.fs.realpath(".", &buffer);
4066

41-
if (std.mem.eql(u8, uri.scheme, "assets")) {
42-
@panic("TODO: assets handler");
67+
const asset_path = try std.fs.path.join(internal.scratch_allocator, &.{ cwd_path, "assets/", uri.path });
68+
log.debug("-> {s}", .{asset_path});
69+
const file = try std.fs.openFileAbsolute(asset_path, .{ .mode = .read_only });
70+
return AssetHandle{ .data = .{ .file = file } };
4371
} else if (std.mem.eql(u8, uri.scheme, "file")) {
44-
@panic("TODO: file handler");
72+
log.debug("-> {s}", .{uri.path});
73+
const file = try std.fs.openFileAbsolute(uri.path, .{ .mode = .read_only });
74+
return AssetHandle{ .data = .{ .file = file } };
4575
} else if (std.mem.eql(u8, uri.scheme, "http") or std.mem.eql(u8, uri.scheme, "https")) {
4676
const request = http.HttpRequest.get(url);
4777
var response = try request.send();
4878

4979
while (!response.isReady()) {
50-
// TODO: suspend;
80+
// TODO: suspend; when async is back
5181
}
5282
try response.checkError();
5383

0 commit comments

Comments
 (0)