Removed the leak, but still lost on the game update loop
This commit is contained in:
parent
7716ddf26a
commit
4b186784bc
src
@ -18,7 +18,7 @@ pub const GameStateController = struct {
|
|||||||
SCREEN_HEIGHT: u32 = 480,
|
SCREEN_HEIGHT: u32 = 480,
|
||||||
slime_factory_controller: sf.SlimeFactoryController = undefined,
|
slime_factory_controller: sf.SlimeFactoryController = undefined,
|
||||||
game_text_factory_controller: text.GameTextFactoryController = undefined,
|
game_text_factory_controller: text.GameTextFactoryController = undefined,
|
||||||
prev_game_state: *GameState = undefined,
|
prev_game_state: ?*GameState = null,
|
||||||
current_game_state: *GameState = undefined,
|
current_game_state: *GameState = undefined,
|
||||||
renderer: *sdl.struct_SDL_Renderer = undefined,
|
renderer: *sdl.struct_SDL_Renderer = undefined,
|
||||||
rng: std.Random = undefined,
|
rng: std.Random = undefined,
|
||||||
@ -51,6 +51,11 @@ pub const GameStateController = struct {
|
|||||||
|
|
||||||
pub fn deinit(self: *GameStateController) void {
|
pub fn deinit(self: *GameStateController) void {
|
||||||
self.slime_factory_controller.deinit();
|
self.slime_factory_controller.deinit();
|
||||||
|
|
||||||
|
self.allocator.destroy(self.current_game_state);
|
||||||
|
if (self.prev_game_state) |gs| {
|
||||||
|
self.allocator.destroy(gs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Physics main loop that processes variable time steps
|
// Physics main loop that processes variable time steps
|
||||||
@ -114,10 +119,12 @@ pub const GameStateController = struct {
|
|||||||
// sdl.SDL_Delay(100);
|
// sdl.SDL_Delay(100);
|
||||||
|
|
||||||
var game_state = try self.allocator.create(GameState);
|
var game_state = try self.allocator.create(GameState);
|
||||||
game_state.allocator = self.allocator;
|
if (self.prev_game_state) |prev_gs| {
|
||||||
|
self.allocator.destroy(prev_gs);
|
||||||
|
}
|
||||||
game_state.slime_factory = try self.slime_factory_controller.spawnFactory(self.allocator);
|
game_state.slime_factory = try self.slime_factory_controller.spawnFactory(self.allocator);
|
||||||
game_state.fps_timer = &self.fps_timer;
|
game_state.fps_timer = &self.fps_timer;
|
||||||
game_state.phys_ticks = @floatFromInt(self.phys_timer.getTicks());
|
game_state.phys_ticks = self.phys_timer.getTicks();
|
||||||
game_state.phys_updates_since_render = self.phys_updates_since_last_render;
|
game_state.phys_updates_since_render = self.phys_updates_since_last_render;
|
||||||
|
|
||||||
// self.allocator.destroy(self.prev_game_state);
|
// self.allocator.destroy(self.prev_game_state);
|
||||||
@ -145,7 +152,7 @@ pub const GameStateController = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn getFpsText(self: *GameStateController, buf: []u8) ![:0]const u8 {
|
fn getFpsText(self: *GameStateController, buf: []u8) ![:0]const u8 {
|
||||||
const ticks_f: f64 = @floatFromInt(self.fps_timer.getTicks());
|
const ticks_f: f64 = self.fps_timer.getTicks();
|
||||||
const frames_f: f64 = @floatFromInt(self.frames);
|
const frames_f: f64 = @floatFromInt(self.frames);
|
||||||
const avg_fps: f64 = @round(frames_f / (ticks_f / 1000.0));
|
const avg_fps: f64 = @round(frames_f / (ticks_f / 1000.0));
|
||||||
return try std.fmt.bufPrintZ(buf, "{d} fps", .{avg_fps});
|
return try std.fmt.bufPrintZ(buf, "{d} fps", .{avg_fps});
|
||||||
@ -153,38 +160,37 @@ pub const GameStateController = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const GameState = struct {
|
pub const GameState = struct {
|
||||||
allocator: std.mem.Allocator,
|
|
||||||
slime_factory: sf.SlimeFactory = undefined,
|
slime_factory: sf.SlimeFactory = undefined,
|
||||||
fps_timer: *Timer,
|
fps_timer: *Timer,
|
||||||
phys_ticks: f64,
|
phys_ticks: f64,
|
||||||
phys_updates_since_render: u32,
|
phys_updates_since_render: u32,
|
||||||
// Checks all struct fields in GameState and calls deinit
|
// Checks all struct fields in GameState and calls deinit
|
||||||
pub fn deinit(self: *const GameState) void {
|
// pub fn deinit(self: *const GameState) void {
|
||||||
const game_state_info = @typeInfo(GameState);
|
// const game_state_info = @typeInfo(GameState);
|
||||||
switch (game_state_info) {
|
// switch (game_state_info) {
|
||||||
.Struct => {
|
// .Struct => {
|
||||||
inline for (game_state_info.Struct.fields) |field| {
|
// inline for (game_state_info.Struct.fields) |field| {
|
||||||
switch (@typeInfo(field.type)) {
|
// switch (@typeInfo(field.type)) {
|
||||||
.Struct => {
|
// .Struct => {
|
||||||
// const inner_struct_info = @typeInfo(field.type);
|
// // const inner_struct_info = @typeInfo(field.type);
|
||||||
|
|
||||||
// Check if struct has `deinit` method
|
// // Check if struct has `deinit` method
|
||||||
if (@hasDecl(field.type, "deinit")) {
|
// if (@hasDecl(field.type, "deinit")) {
|
||||||
const field_ptr = @field(self, field.name);
|
// const field_ptr = @field(self, field.name);
|
||||||
field_ptr.deinit();
|
// field_ptr.deinit();
|
||||||
std.debug.print("Deinit called on {s}\n", .{field.name});
|
// std.debug.print("Deinit called on {s}\n", .{field.name});
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
else => {},
|
// else => {},
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
|
|
||||||
else => {},
|
// else => {},
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Loop over fields of `GameState`
|
// Loop over fields of `GameState`
|
||||||
|
|
||||||
self.allocator.destroy(self);
|
// self.allocator.destroy(self);
|
||||||
}
|
// }
|
||||||
};
|
};
|
||||||
|
36
src/main.zig
36
src/main.zig
@ -38,6 +38,9 @@ pub fn main() !void {
|
|||||||
|
|
||||||
var quit = false;
|
var quit = false;
|
||||||
|
|
||||||
|
var game_timer = Timer{};
|
||||||
|
game_timer.start();
|
||||||
|
|
||||||
var frame_time = Timer{};
|
var frame_time = Timer{};
|
||||||
frame_time.start();
|
frame_time.start();
|
||||||
|
|
||||||
@ -72,9 +75,10 @@ pub fn main() !void {
|
|||||||
// Wait for time to render screen, keep running physics
|
// Wait for time to render screen, keep running physics
|
||||||
accumulator = accumulator + SCREEN_TICKS_PER_FRAME;
|
accumulator = accumulator + SCREEN_TICKS_PER_FRAME;
|
||||||
const total_phys_ticks: u32 = @intFromFloat(PHYS_TICKS_PER_UPDATE * PHYS_UPDATES_PER_RENDER);
|
const total_phys_ticks: u32 = @intFromFloat(PHYS_TICKS_PER_UPDATE * PHYS_UPDATES_PER_RENDER);
|
||||||
const phys_done_at_ticks: u32 = sdl.SDL_GetTicks() + total_phys_ticks;
|
const game_time_ms: u32 = @intFromFloat(game_timer.getTicks());
|
||||||
|
const phys_done_at_ticks: u32 = game_time_ms + total_phys_ticks;
|
||||||
var phys_ticks_used: f64 = 0;
|
var phys_ticks_used: f64 = 0;
|
||||||
std.debug.print("phys ticks/upd: {d}, Acc: {d}\nTotal phys ticks {d}ms\nPhys done at {d}ms\n", .{ PHYS_TICKS_PER_UPDATE, accumulator, total_phys_ticks, phys_done_at_ticks });
|
std.debug.print("Phys ticks/upd: {d}\nAcc: {d}\nTotal phys ticks {d}ms\nPhys done at {d}ms\n", .{ PHYS_TICKS_PER_UPDATE, accumulator, total_phys_ticks, phys_done_at_ticks });
|
||||||
// Run a physics update
|
// Run a physics update
|
||||||
while (accumulator >= PHYS_TICKS_PER_UPDATE) {
|
while (accumulator >= PHYS_TICKS_PER_UPDATE) {
|
||||||
// Control loop here
|
// Control loop here
|
||||||
@ -86,6 +90,7 @@ pub fn main() !void {
|
|||||||
},
|
},
|
||||||
sdl.SDL_KEYDOWN => {
|
sdl.SDL_KEYDOWN => {
|
||||||
switch (event.key.keysym.sym) {
|
switch (event.key.keysym.sym) {
|
||||||
|
sdl.SDLK_RETURN => {},
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
log("Got key event: %i\n", event.key.keysym.sym);
|
log("Got key event: %i\n", event.key.keysym.sym);
|
||||||
@ -96,23 +101,24 @@ pub fn main() !void {
|
|||||||
prev_game_state = current_game_state;
|
prev_game_state = current_game_state;
|
||||||
current_game_state = try game_state_controller.update_tick();
|
current_game_state = try game_state_controller.update_tick();
|
||||||
const phys_ticks_this_update: f64 = current_game_state.?.phys_ticks - phys_ticks_used;
|
const phys_ticks_this_update: f64 = current_game_state.?.phys_ticks - phys_ticks_used;
|
||||||
|
accumulator -= phys_ticks_this_update;
|
||||||
|
|
||||||
std.debug.print(" PU in {d}ms ", .{phys_ticks_this_update});
|
// std.debug.print(" PU in {d}ms ", .{phys_ticks_this_update});
|
||||||
std.debug.print(" Acc:{d} - ", .{accumulator});
|
// std.debug.print(" Acc:{d} - ", .{accumulator});
|
||||||
|
|
||||||
// TODO dont turn it into an int, take the extra phys_frames and do a partial render
|
// TODO dont turn it into an int, take the extra phys_frames and do a partial render
|
||||||
if (phys_ticks_this_update < PHYS_TICKS_PER_UPDATE) {
|
// if (phys_ticks_this_update < PHYS_TICKS_PER_UPDATE) {
|
||||||
const ticks: u32 = @intFromFloat(PHYS_TICKS_PER_UPDATE - phys_ticks_this_update);
|
// const ticks: u32 = @intFromFloat(PHYS_TICKS_PER_UPDATE - phys_ticks_this_update);
|
||||||
sdl.SDL_Delay(ticks);
|
// sdl.SDL_Delay(ticks);
|
||||||
accumulator -= PHYS_TICKS_PER_UPDATE;
|
// const ticksf: f64 = @floatFromInt(ticks);
|
||||||
} else {
|
// accumulator -= (phys_ticks_this_update + ticksf);
|
||||||
std.debug.print("\nPHYSICS JANK\nPhysics Update took {d}ms, target: {d}ms\n", .{ phys_ticks_this_update, PHYS_TICKS_PER_UPDATE });
|
// } else {
|
||||||
accumulator -= phys_ticks_this_update;
|
// // std.debug.print("PHYSICS JANK: Physics Update took {d}ms, target: {d}ms\n", .{ phys_ticks_this_update, PHYS_TICKS_PER_UPDATE });
|
||||||
}
|
// accumulator -= phys_ticks_this_update;
|
||||||
|
// }
|
||||||
phys_ticks_used = current_game_state.?.phys_ticks;
|
phys_ticks_used = current_game_state.?.phys_ticks;
|
||||||
std.debug.print(" PhyTicks this render: {d} ", .{current_game_state.?.phys_ticks});
|
// std.debug.print(" PhyTicks this render: {d} ", .{current_game_state.?.phys_ticks});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO lerp together prev and current states
|
// TODO lerp together prev and current states
|
||||||
// Otherwise will have physics jank
|
// Otherwise will have physics jank
|
||||||
|
|
||||||
@ -120,7 +126,7 @@ pub fn main() !void {
|
|||||||
std.debug.print("Took {d} phys frames\n", .{current_game_state.?.phys_updates_since_render});
|
std.debug.print("Took {d} phys frames\n", .{current_game_state.?.phys_updates_since_render});
|
||||||
try game_state_controller.render(current_game_state.?);
|
try game_state_controller.render(current_game_state.?);
|
||||||
|
|
||||||
prev_frame_ms = @floatFromInt(frame_time.getTicks());
|
prev_frame_ms = frame_time.getTicks();
|
||||||
std.debug.print("Rendered to screen in {d}ms\n***\n***\n", .{prev_frame_ms});
|
std.debug.print("Rendered to screen in {d}ms\n***\n***\n", .{prev_frame_ms});
|
||||||
frame_time.reset();
|
frame_time.reset();
|
||||||
// const frame_time_ticks = frame_time.getTicks();
|
// const frame_time_ticks = frame_time.getTicks();
|
||||||
|
@ -1,57 +1,62 @@
|
|||||||
const sdl = @import("./../sdl.zig").c;
|
const sdl = @import("./../sdl.zig").c;
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
pub const TimerStatus = enum { started, stopped, paused };
|
pub const TimerStatus = enum { started, stopped, paused };
|
||||||
|
|
||||||
pub const Timer = struct {
|
pub const Timer = struct {
|
||||||
start_ticks_ms: u32 = 0,
|
start_ticks_ns: f64 = 0.0,
|
||||||
pause_ticks_ms: u32 = 0,
|
pause_ticks_ns: f64 = 0.0,
|
||||||
status: TimerStatus = TimerStatus.stopped,
|
status: TimerStatus = TimerStatus.stopped,
|
||||||
|
|
||||||
pub fn start(self: *Timer) void {
|
pub fn start(self: *Timer) void {
|
||||||
if (self.status == .started) return;
|
if (self.status == .started) return;
|
||||||
self.status = .started;
|
self.status = .started;
|
||||||
self.start_ticks_ms = sdl.SDL_GetTicks();
|
self.start_ticks_ns = @floatFromInt(std.time.nanoTimestamp());
|
||||||
self.pause_ticks_ms = 0;
|
self.pause_ticks_ns = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stop(self: *Timer) void {
|
pub fn stop(self: *Timer) void {
|
||||||
if (self.status == .stopped) return;
|
if (self.status == .stopped) return;
|
||||||
self.status = .stopped;
|
self.status = .stopped;
|
||||||
self.start_ticks_ms = 0;
|
self.start_ticks_ns = 0;
|
||||||
self.pause_ticks_ms = 0;
|
self.pause_ticks_ns = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resets the timer to 0 and starts it
|
// Resets the timer to 0 and starts it
|
||||||
pub fn reset(self: *Timer) void {
|
pub fn reset(self: *Timer) void {
|
||||||
self.status = .started;
|
self.status = .started;
|
||||||
self.start_ticks_ms = sdl.SDL_GetTicks();
|
self.start_ticks_ns = @floatFromInt(std.time.nanoTimestamp());
|
||||||
self.pause_ticks_ms = 0;
|
self.pause_ticks_ns = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pause(self: *Timer) void {
|
pub fn pause(self: *Timer) void {
|
||||||
if (self.status == .paused or self.status == .stopped) return;
|
if (self.status == .paused or self.status == .stopped) return;
|
||||||
self.status = .paused;
|
self.status = .paused;
|
||||||
self.pause_ticks_ms = sdl.SDL_GetTicks();
|
const ns_stampf: f64 = @floatFromInt(std.time.nanoTimestamp());
|
||||||
|
self.pause_ticks_ns = (ns_stampf - self.start_ticks_ns) / 1_000_000;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpause(self: *Timer) void {
|
pub fn unpause(self: *Timer) void {
|
||||||
if (self.status == .started or self.status == .stopped) return;
|
if (self.status == .started or self.status == .stopped) return;
|
||||||
self.status = .started;
|
self.status = .started;
|
||||||
self.start_ticks_ms = sdl.SDL_GetTicks() - self.pause_ticks_ms;
|
const ns_stampf: f64 = @floatFromInt(std.time.nanoTimestamp());
|
||||||
self.pause_ticks_ms = 0;
|
const diff_ns: f64 = ns_stampf - self.pause_ticks_ns;
|
||||||
|
self.start_ticks_ns = self.start_ticks_ns + diff_ns;
|
||||||
|
self.pause_ticks_ns = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the current tick/ms of the timer
|
// Gets the current tick/ms of the timer
|
||||||
pub fn getTicks(self: *Timer) u32 {
|
pub fn getTicks(self: *Timer) f64 {
|
||||||
switch (self.status) {
|
switch (self.status) {
|
||||||
.stopped => {
|
.stopped => {
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
.paused => {
|
.paused => {
|
||||||
return self.pause_ticks_ms;
|
return self.pause_ticks_ns / 1_000_000;
|
||||||
},
|
},
|
||||||
.started => {
|
.started => {
|
||||||
return sdl.SDL_GetTicks() - self.start_ticks_ms;
|
const ns_stampf: f64 = @floatFromInt(std.time.nanoTimestamp());
|
||||||
|
return (ns_stampf - self.start_ticks_ns) / 1_000_000;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user