Start working on hot-reload functionality

This commit is contained in:
Riyyi
2026-09-06 16:37:49 +02:00
parent d353a43090
commit aea791fe2b
6 changed files with 92 additions and 17 deletions
+12
View File
@@ -36,3 +36,15 @@ vendor
- microui (temp)
- box3d?
- build.sh -> build.odin
## Hot Reload
build.sh -> hot reload enabled, debug mode enabled
build_release.sh -> hot reload disabled, debug mode disabled
build_debug.sh -> hot reload disabled, debug mode enabled
hot reload builds engine as .exe, then game as dynamic lib.
skips building the engine if its already running (pgrep).
no hot reload does not use game.dll, instead it imports the game source
as a normal Odin package during build.
+7 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
set -e
set -eu
PROJECT="sindri"
VERSION="dev-$(date -u '+%Y-%m-%d')-$(git rev-parse --short HEAD)"
@@ -14,6 +14,12 @@ VERSION="dev-$(date -u '+%Y-%m-%d')-$(git rev-parse --short HEAD)"
mkdir -p build
# Game.dll
odin build game/ -show-timings \
-collection:sindri=src \
-build-mode:dynamic \
-out:build/game -microarch:native -define:VERSION="$VERSION-debug" -debug "$@"
if [ "$1" = "debug" ]; then
shift
+20
View File
@@ -0,0 +1,20 @@
package game
import "core:time"
import "core:fmt"
@(export)
hello :: proc() {
fmt.println("hello from .dll!")
}
start := time.tick_now()
@(export)
should_close :: proc() -> bool {
elapsed := time.tick_since(start)
seconds := time.duration_seconds(elapsed)
if seconds > 4 do return true
return false
}
+10 -12
View File
@@ -1,6 +1,5 @@
package sindri
import "core:time"
import "vendor:glfw"
import "wgpu:wgpu"
@@ -27,20 +26,19 @@ os_init :: proc() {
glfw.SetFramebufferSizeCallback(state.os.window, size_callback)
}
os_run :: proc() {
dt: f32
for !glfw.WindowShouldClose(state.os.window) {
start := time.tick_now()
glfw.PollEvents()
frame(dt)
dt = f32(time.duration_seconds(time.tick_since(start)))
os_should_close :: proc() -> bool {
return bool(glfw.WindowShouldClose(state.os.window))
}
instance_destroy()
os_set_should_close :: proc(val: bool) {
glfw.SetWindowShouldClose(state.os.window, b32(val))
}
os_poll_events :: proc() {
glfw.PollEvents()
}
os_destroy :: proc() {
glfw.DestroyWindow(state.os.window)
glfw.Terminate()
}
+43
View File
@@ -1,13 +1,56 @@
package sindri
import "core:dynlib"
import "core:fmt"
import "core:time"
VERSION :: #config(VERSION, "dev")
// -----------------------------------------
instance_ready: bool
Game_API :: struct {
__handle: dynlib.Library,
hello: proc(),
should_close: proc() -> bool,
}
main :: proc() {
fmt.println("hello world!")
api: Game_API
load_game_api(&api)
api.hello()
// Initialize window
os_init()
// Initialize GPU resources
instance_init()
gt: f32
for !os_should_close() && !api.should_close() {
start := time.tick_now()
os_poll_events()
frame(gt)
gt = f32(time.duration_seconds(time.tick_since(start)))
}
// Cleanup GPU resources
instance_destroy()
// Cleanup window
os_destroy()
}
load_game_api :: proc(api: ^Game_API) {
// Match the names of the fields in Game_API to symbols in the game DLL
_, ok := dynlib.initialize_symbols(api, "build/game.dylib")
if !ok {
fmt.printfln("Failed initializing symbols: {0}", dynlib.last_error())
}
}
-4
View File
@@ -27,8 +27,6 @@ state: struct {
instance_init :: proc() {
state.ctx = context
os_init()
state.instance = wgpu.CreateInstance(nil)
if state.instance == nil {
panic("WebGPU is not supported")
@@ -130,8 +128,6 @@ instance_init :: proc() {
multisample = {count = 1, mask = 0xFFFFFFFF},
},
)
os_run()
}
}