Compare commits

...

4 commits

4 changed files with 106 additions and 14 deletions

View file

@ -23,23 +23,32 @@ fn fetchThread(state: *AppState) !void {
defer state.departure_screen_state.fetch_thread = null; defer state.departure_screen_state.fetch_thread = null;
const allocator = state.allocator; const allocator = state.allocator;
var station_id_buf = std.BoundedArray(u8, 10){}; var station_id_buf = std.BoundedArray(u8, 10){};
var include_tram = false; var transport_means = state.departure_screen_state.transport_means;
var curl = Curl.init() orelse return; var curl = Curl.init() orelse return;
defer curl.deinit(); defer curl.deinit();
while (state.departure_screen_state.fetch_thread != null) { while (true) {
{
state.departure_screen_state.mutex.lock();
defer state.departure_screen_state.mutex.unlock();
if (state.departure_screen_state.fetch_thread == null) {
break;
}
}
var fetch_anyway = state.departure_screen_state.should_refresh; var fetch_anyway = state.departure_screen_state.should_refresh;
if (state.departure_screen_state.last_refresh_time + 30000 < std.time.milliTimestamp()) { if (state.departure_screen_state.last_refresh_time + 30000 < std.time.milliTimestamp()) {
fetch_anyway = true; fetch_anyway = true;
} }
if (!fetch_anyway and std.mem.eql(u8, station_id_buf.slice(), state.departure_screen_state.station_id.items) and include_tram == state.departure_screen_state.include_tram) { const same_station = std.mem.eql(u8, station_id_buf.slice(), state.departure_screen_state.station_id.items);
const same_transport_means = std.meta.eql(transport_means, state.departure_screen_state.transport_means);
if (!fetch_anyway and same_station and same_transport_means) {
std.time.sleep(100 * 1000); std.time.sleep(100 * 1000);
continue; continue;
} }
station_id_buf.resize(state.departure_screen_state.station_id.items.len) catch continue; station_id_buf.resize(state.departure_screen_state.station_id.items.len) catch continue;
std.mem.copyForwards(u8, station_id_buf.slice(), state.departure_screen_state.station_id.items); std.mem.copyForwards(u8, station_id_buf.slice(), state.departure_screen_state.station_id.items);
include_tram = state.departure_screen_state.include_tram; transport_means = state.departure_screen_state.transport_means;
std.debug.print("[departure/fetchThread] Detected update: {s}\n", .{station_id_buf.slice()}); std.debug.print("[departure/fetchThread] Detected update: {s}\n", .{station_id_buf.slice()});
curl.reset(); curl.reset();
@ -51,9 +60,20 @@ fn fetchThread(state: *AppState) !void {
) catch continue; ) catch continue;
defer allocator.free(departures_base); defer allocator.free(departures_base);
var departures_uri = std.Uri.parse(departures_base) catch unreachable; var departures_uri = std.Uri.parse(departures_base) catch unreachable;
const query = std.fmt.allocPrint(allocator, "duration=300&bus=false&ferry=false&taxi=false&pretty=false{s}", .{if (include_tram) "" else "&tram=false&subway=false"}) catch continue; var queryBuilder = std.ArrayList(u8).init(allocator);
defer allocator.free(query); defer queryBuilder.deinit();
departures_uri.query = query; queryBuilder.appendSlice("duration=300&pretty=false") catch continue;
if (!transport_means.ice) queryBuilder.appendSlice("&nationalExpress=false") catch continue;
if (!transport_means.ic) queryBuilder.appendSlice("&national=false") catch continue;
if (!transport_means.ir) queryBuilder.appendSlice("&regionalExpress=false") catch continue;
if (!transport_means.r) queryBuilder.appendSlice("&regional=false") catch continue;
if (!transport_means.s) queryBuilder.appendSlice("&suburban=false") catch continue;
if (!transport_means.bus) queryBuilder.appendSlice("&bus=false") catch continue;
if (!transport_means.ferry) queryBuilder.appendSlice("&ferry=false") catch continue;
if (!transport_means.u) queryBuilder.appendSlice("&subway=false") catch continue;
if (!transport_means.tram) queryBuilder.appendSlice("&tram=false") catch continue;
if (!transport_means.taxi) queryBuilder.appendSlice("&taxi=false") catch continue;
departures_uri.query = queryBuilder.items;
defer departures_uri.query = null; defer departures_uri.query = null;
std.debug.print("[departure/fetchThread] Making request to: {}\n", .{departures_uri}); std.debug.print("[departure/fetchThread] Making request to: {}\n", .{departures_uri});
@ -622,6 +642,9 @@ pub fn render(state: *AppState) !void {
switch (key) { switch (key) {
rl.KEY_LEFT => { rl.KEY_LEFT => {
state.screen = .home; state.screen = .home;
ds.mutex.lock();
defer ds.mutex.unlock();
ds.fetch_thread = null;
}, },
rl.KEY_R => { rl.KEY_R => {
ds.should_refresh = true; ds.should_refresh = true;
@ -635,7 +658,8 @@ pub fn render(state: *AppState) !void {
ds.max_next_trains = @min(ds.max_next_trains + 1, if (ds.fetch_result) |fr| @as(c_int, @intCast(fr.value.object.get("departures").?.array.items.len)) else 5); ds.max_next_trains = @min(ds.max_next_trains + 1, if (ds.fetch_result) |fr| @as(c_int, @intCast(fr.value.object.get("departures").?.array.items.len)) else 5);
}, },
rl.KEY_T => { rl.KEY_T => {
ds.include_tram = !ds.include_tram; ds.transport_means.u = !ds.transport_means.u;
ds.transport_means.tram = !ds.transport_means.tram;
}, },
rl.KEY_ONE => { rl.KEY_ONE => {
ds.render_style = .db1; ds.render_style = .db1;
@ -652,7 +676,10 @@ pub fn render(state: *AppState) !void {
{ {
ds.mutex.lock(); ds.mutex.lock();
defer ds.mutex.unlock(); defer {
ds.mutex.unlock();
_ = std.Thread.yield() catch null;
}
switch (ds.render_style) { switch (ds.render_style) {
.db1 => try draw_db1(state), .db1 => try draw_db1(state),
.ns => try draw_ns(state), .ns => try draw_ns(state),

View file

@ -57,6 +57,7 @@ fn fetchThread(state: *AppState) !void {
continue; continue;
}; };
defer parsed.deinit(); defer parsed.deinit();
std.debug.print("[home/fetchThread] Parsed data\n", .{});
var results = std.ArrayList(AppState.HSSuggestion).init(allocator); var results = std.ArrayList(AppState.HSSuggestion).init(allocator);
for (parsed.value) |station| { for (parsed.value) |station| {
@ -72,9 +73,11 @@ fn fetchThread(state: *AppState) !void {
} }
} }
} }
std.debug.print("[home/fetchThread] Created results: {} stations\n", .{results.items.len});
state.home_screen_state.mutex.lock(); state.home_screen_state.mutex.lock();
defer state.home_screen_state.mutex.unlock(); defer state.home_screen_state.mutex.unlock();
if (state.home_screen_state.suggestions.len > 0) { if (state.home_screen_state.suggestions.len > 0) {
std.debug.print("[home/fetchThread] Deallocating previous data\n", .{});
for (state.home_screen_state.suggestions) |suggestion| { for (state.home_screen_state.suggestions) |suggestion| {
allocator.free(suggestion.id); allocator.free(suggestion.id);
allocator.free(suggestion.name); allocator.free(suggestion.name);
@ -82,6 +85,7 @@ fn fetchThread(state: *AppState) !void {
allocator.free(state.home_screen_state.suggestions); allocator.free(state.home_screen_state.suggestions);
} }
state.home_screen_state.suggestions = results.toOwnedSlice() catch continue; state.home_screen_state.suggestions = results.toOwnedSlice() catch continue;
std.debug.print("[home/fetchThread] Replaced suggestions\n", .{});
} }
} }
@ -102,7 +106,10 @@ pub fn render(state: *AppState) !void {
} }
state.home_screen_state.mutex.lock(); state.home_screen_state.mutex.lock();
defer state.home_screen_state.mutex.unlock(); defer {
state.home_screen_state.mutex.unlock();
_ = std.Thread.yield() catch null;
}
while (raylib.GetKeyPressed()) |key| { while (raylib.GetKeyPressed()) |key| {
switch (key) { switch (key) {

View file

@ -27,9 +27,9 @@ pub fn main() !void {
var station_id_buffer: [10]u8 = .{0} ** 10; var station_id_buffer: [10]u8 = .{0} ** 10;
var appState = AppState{ var appState = AppState{
.allocator = allocator, .allocator = allocator,
.font = rl.LoadFontFromMemory(".ttf", noto, noto.len, 64, cp, cp_cnt), .font = rl.LoadFontFromMemory(".ttf", noto, noto.len, 100, cp, cp_cnt),
.db_font = raylib.LoadFontEx("./private/db.ttf", 64, cp, cp_cnt), .db_font = raylib.LoadFontEx("./private/db.ttf", 100, cp, cp_cnt),
.ns_font = raylib.LoadFontEx("./private/ns.ttf", 64, cp, cp_cnt), .ns_font = raylib.LoadFontEx("./private/ns.ttf", 100, cp, cp_cnt),
.home_screen_state = .{ .home_screen_state = .{
.station_name = std.ArrayListUnmanaged(u8).initBuffer(&station_name_buffer), .station_name = std.ArrayListUnmanaged(u8).initBuffer(&station_name_buffer),
.station_name_max_len = station_name_buffer.len - 1, .station_name_max_len = station_name_buffer.len - 1,

View file

@ -26,6 +26,64 @@ pub const RenderStyle = enum(u8) {
ns = 3, ns = 3,
}; };
pub const TransportationMethodFlags = packed struct {
ice: bool = false,
ic: bool = false,
ir: bool = false,
r: bool = false,
s: bool = false,
bus: bool = false,
tram: bool = false,
u: bool = false,
taxi: bool = false,
ferry: bool = false,
fn all() @This() {
return .{
.ice = true,
.ic = true,
.ir = true,
.r = true,
.s = true,
.bus = true,
.tram = true,
.u = true,
.taxi = true,
.ferry = true,
};
}
fn only_trains() @This() {
return .{
.ice = true,
.ic = true,
.ir = true,
.r = true,
.s = true,
};
}
fn only_long_distance() @This() {
return .{
.ice = true,
.ic = true,
.ir = true,
};
}
fn only_regional() @This() {
return .{
.r = true,
.s = true,
.bus = true,
.tram = true,
.u = true,
.taxi = true,
.ferry = true,
};
}
};
pub const DepartureScreenState = struct { pub const DepartureScreenState = struct {
mutex: std.Thread.Mutex = .{}, mutex: std.Thread.Mutex = .{},
station_id: std.ArrayListUnmanaged(u8), station_id: std.ArrayListUnmanaged(u8),
@ -36,7 +94,7 @@ pub const DepartureScreenState = struct {
fetch_result: ?std.json.Parsed(std.json.Value) = null, fetch_result: ?std.json.Parsed(std.json.Value) = null,
should_refresh: bool = false, should_refresh: bool = false,
max_next_trains: c_int = 5, max_next_trains: c_int = 5,
include_tram: bool = false, transport_means: TransportationMethodFlags = TransportationMethodFlags.only_trains(),
render_style: RenderStyle = .db1, render_style: RenderStyle = .db1,
}; };