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;
const allocator = state.allocator;
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;
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;
if (state.departure_screen_state.last_refresh_time + 30000 < std.time.milliTimestamp()) {
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);
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);
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()});
curl.reset();
@ -51,9 +60,20 @@ fn fetchThread(state: *AppState) !void {
) catch continue;
defer allocator.free(departures_base);
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;
defer allocator.free(query);
departures_uri.query = query;
var queryBuilder = std.ArrayList(u8).init(allocator);
defer queryBuilder.deinit();
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;
std.debug.print("[departure/fetchThread] Making request to: {}\n", .{departures_uri});
@ -622,6 +642,9 @@ pub fn render(state: *AppState) !void {
switch (key) {
rl.KEY_LEFT => {
state.screen = .home;
ds.mutex.lock();
defer ds.mutex.unlock();
ds.fetch_thread = null;
},
rl.KEY_R => {
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);
},
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 => {
ds.render_style = .db1;
@ -652,7 +676,10 @@ pub fn render(state: *AppState) !void {
{
ds.mutex.lock();
defer ds.mutex.unlock();
defer {
ds.mutex.unlock();
_ = std.Thread.yield() catch null;
}
switch (ds.render_style) {
.db1 => try draw_db1(state),
.ns => try draw_ns(state),

View file

@ -57,6 +57,7 @@ fn fetchThread(state: *AppState) !void {
continue;
};
defer parsed.deinit();
std.debug.print("[home/fetchThread] Parsed data\n", .{});
var results = std.ArrayList(AppState.HSSuggestion).init(allocator);
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();
defer state.home_screen_state.mutex.unlock();
if (state.home_screen_state.suggestions.len > 0) {
std.debug.print("[home/fetchThread] Deallocating previous data\n", .{});
for (state.home_screen_state.suggestions) |suggestion| {
allocator.free(suggestion.id);
allocator.free(suggestion.name);
@ -82,6 +85,7 @@ fn fetchThread(state: *AppState) !void {
allocator.free(state.home_screen_state.suggestions);
}
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();
defer state.home_screen_state.mutex.unlock();
defer {
state.home_screen_state.mutex.unlock();
_ = std.Thread.yield() catch null;
}
while (raylib.GetKeyPressed()) |key| {
switch (key) {

View file

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

View file

@ -26,6 +26,64 @@ pub const RenderStyle = enum(u8) {
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 {
mutex: std.Thread.Mutex = .{},
station_id: std.ArrayListUnmanaged(u8),
@ -36,7 +94,7 @@ pub const DepartureScreenState = struct {
fetch_result: ?std.json.Parsed(std.json.Value) = null,
should_refresh: bool = false,
max_next_trains: c_int = 5,
include_tram: bool = false,
transport_means: TransportationMethodFlags = TransportationMethodFlags.only_trains(),
render_style: RenderStyle = .db1,
};