Working sync version of the game loop

Main problem here is that display() is blocked by update() and the update rate will slow down if the display rate slows below the update rate
This commit is contained in:
Skye Terran 2021-08-05 22:15:18 -07:00
parent 7159007154
commit cbd45ffc92
4 changed files with 274 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

181
Cargo.lock generated Normal file
View File

@ -0,0 +1,181 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "futures"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
name = "futures-core"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99"
[[package]]
name = "futures-executor"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582"
[[package]]
name = "futures-macro"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57"
dependencies = [
"autocfg",
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "futures-sink"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53"
[[package]]
name = "futures-task"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2"
[[package]]
name = "futures-util"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78"
dependencies = [
"autocfg",
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"proc-macro-hack",
"proc-macro-nested",
"slab",
]
[[package]]
name = "loopcore"
version = "0.1.0"
dependencies = [
"futures",
]
[[package]]
name = "memchr"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
[[package]]
name = "pin-project-lite"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro-nested"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
[[package]]
name = "proc-macro2"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "slab"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
[[package]]
name = "syn"
version = "1.0.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"

9
Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "loopcore"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
futures = "0.3.16"

83
src/main.rs Normal file
View File

@ -0,0 +1,83 @@
use std::time::Instant;
const UPDATE_INTERVAL: u32 = 40;
fn main() {
// track the update delay's exponential moving average (EMA)
let mut frame_delay_ema: f64 = 0.0;
// track the latest delays
let mut frame_delay: u32 = 0;
let mut tick_delay: u32 = 0;
loop {
// start per-loop delay timer
let timer = Instant::now();
// DEBUG - track if a tick has happened on this frame
let mut ticked: bool = false;
// update (game logic, etc.)
// executes every UPDATE_INTERVAL milliseconds at maximum
if tick_delay >= UPDATE_INTERVAL {
// perform all per-tick logic here
update();
// reset the tick delay
tick_delay = 0;
// DEBUG
ticked = true;
}
// display (rendering)
// executes as fast as possible
{
display();
}
// get the current frame delay, update the frame delay EMA and the tick delay
frame_delay = timer.elapsed().as_millis() as u32;
frame_delay_ema = lerp_1d(frame_delay_ema, frame_delay as f64, 0.1f64);
tick_delay += frame_delay;
// debug
let frame_rate = (1000.0f64 / frame_delay_ema as f64) as u32;
if ticked {
println!("Frame Delay: {}ms | Frame Rate: {}Hz | Ticked!", frame_delay, frame_rate);
} else {
println!("Frame Delay: {}ms | Frame Rate: {}Hz", frame_delay, frame_rate);
}
}
}
// update function
fn update() {
waste_time(64);
}
// render function
fn display() {
waste_time(16);
}
// 1D linear interpolation
fn lerp_1d(x: f64, y: f64, a: f64) -> f64 {
x + ((y - x) * a)
}
// busywork function
fn waste_time(repeat: u32) {
const BUFFER_RESOLUTION: usize = 512;
// create an RGBA buffer and change every pixel one-by-one
let mut rgba_buffer = vec![[[0.0f32; 4]; BUFFER_RESOLUTION]; BUFFER_RESOLUTION];
// change every pixel in the buffer (repeat) times
for _n in 0..repeat {
for u in 0..BUFFER_RESOLUTION {
for v in 0..BUFFER_RESOLUTION {
rgba_buffer[u][v] = [1.0f32; 4];
}
}
}
}