Finally working hot reload again
This commit is contained in:
parent
8b8ab8c6bc
commit
33cffe95a2
@ -1,2 +1,2 @@
|
||||
vim.opt_global.makeprg = "./build_hot_reload.sh"
|
||||
vim.opt_global.makeprg = "./build.sh"
|
||||
vim.opt.errorformat = "%f(%l:%c)\\ %m"
|
||||
|
@ -199,20 +199,24 @@ setup_emsdk_env :: proc() {
|
||||
set_env("EMSDK", absolute_path("./libs/emsdk"))
|
||||
}
|
||||
|
||||
setup_bin_dir :: proc(path: string, files_to_copy: []string) {
|
||||
setup_bin_dir :: proc(opts: Options, path: string, files_to_copy: []string) {
|
||||
mkdir_all(path)
|
||||
|
||||
for file in files_to_copy {
|
||||
copy_file(file, temp_path_join(path, filepath.base(file)))
|
||||
dst := temp_path_join(path, filepath.base(file))
|
||||
|
||||
if !os.is_file(dst) || opts.force {
|
||||
copy_file(file, dst)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
context.logger = log.create_console_logger()
|
||||
opts := Options {
|
||||
tracy = true,
|
||||
debug = true,
|
||||
run = true,
|
||||
tracy = true,
|
||||
debug = true,
|
||||
optimize = true,
|
||||
}
|
||||
flags.parse_or_exit(&opts, os.args, .Unix, context.temp_allocator)
|
||||
if opts.variant == .Web {
|
||||
@ -230,10 +234,10 @@ main :: proc() {
|
||||
|
||||
switch opts.variant {
|
||||
case .Hot_Reload:
|
||||
setup_bin_dir("./build/hotreload", shared_dep_paths)
|
||||
setup_bin_dir(opts, "./build/hotreload", shared_dep_paths)
|
||||
|
||||
is_main_built := os.is_file("./build/hotreload/game.bin")
|
||||
if !is_main_built || opts.force {
|
||||
is_running := process_exists("game.bin")
|
||||
if !is_running {
|
||||
run_cmd(
|
||||
temp_concat(
|
||||
[]string {
|
||||
@ -244,72 +248,32 @@ main :: proc() {
|
||||
},
|
||||
debug_flag,
|
||||
tracy_flag,
|
||||
optimize_flag,
|
||||
COMMON_FLAGS,
|
||||
),
|
||||
"",
|
||||
)
|
||||
}
|
||||
build_game_cmd := temp_concat(
|
||||
[]string {
|
||||
"odin",
|
||||
"build",
|
||||
"game",
|
||||
"-define:RAYLIB_SHARED=true",
|
||||
"-define:PHYSFS_SHARED=true",
|
||||
"-build-mode:dll",
|
||||
"-out:./build/hotreload/game_tmp.so",
|
||||
},
|
||||
tracy_flag,
|
||||
debug_flag,
|
||||
optimize_flag,
|
||||
COMMON_FLAGS,
|
||||
build_game_cmd := run_cmd(
|
||||
temp_concat(
|
||||
[]string {
|
||||
"odin",
|
||||
"build",
|
||||
"game",
|
||||
"-define:RAYLIB_SHARED=true",
|
||||
"-define:PHYSFS_SHARED=true",
|
||||
"-build-mode:dll",
|
||||
"-out:./build/hotreload/game_tmp.so",
|
||||
},
|
||||
tracy_flag,
|
||||
debug_flag,
|
||||
optimize_flag,
|
||||
COMMON_FLAGS,
|
||||
),
|
||||
"",
|
||||
)
|
||||
build_game_lib :: proc(build_cmd: []string) {
|
||||
run_cmd(build_cmd, "")
|
||||
rename("./build/hotreload/game_tmp.so", "./build/hotreload/game.so")
|
||||
}
|
||||
build_game_lib(build_game_cmd)
|
||||
|
||||
if opts.run && !process_exists("game.bin") {
|
||||
Watcher_Context :: struct {
|
||||
run: bool,
|
||||
build_game_cmd: []string,
|
||||
}
|
||||
watcher_ctx := Watcher_Context {
|
||||
run = true,
|
||||
build_game_cmd = build_game_cmd,
|
||||
}
|
||||
thread_ctx := context
|
||||
thread_ctx.user_ptr = &watcher_ctx
|
||||
thrd := thread.create_and_start(proc() {
|
||||
watcher_ctx := (cast(^Watcher_Context)context.user_ptr)
|
||||
input := os.to_reader(os.stdin)
|
||||
|
||||
buf: [1024]u8
|
||||
for {
|
||||
n, err := io.read(input, buf[:])
|
||||
|
||||
for cmd in buf[0:n] {
|
||||
switch cmd {
|
||||
case 'r', 'R':
|
||||
build_game_lib(watcher_ctx.build_game_cmd)
|
||||
case:
|
||||
}
|
||||
}
|
||||
|
||||
if err == .EOF {
|
||||
break
|
||||
}
|
||||
|
||||
handle_error(err)
|
||||
}
|
||||
}, thread_ctx)
|
||||
|
||||
run_cmd({"./build/hotreload/game.bin"}, "")
|
||||
}
|
||||
rename("./build/hotreload/game_tmp.so", "./build/hotreload/game.so")
|
||||
case .Desktop:
|
||||
setup_bin_dir("./build/desktop", shared_dep_paths)
|
||||
setup_bin_dir(opts, "./build/desktop", shared_dep_paths)
|
||||
|
||||
cmd := slice.concatenate(
|
||||
[][]string {
|
||||
|
@ -20,9 +20,11 @@ Run_Error :: union #shared_nil {
|
||||
os.Error,
|
||||
}
|
||||
|
||||
@(private = "file")
|
||||
run_cmd_internal :: proc(
|
||||
cmd: []string,
|
||||
cwd: string,
|
||||
capture: bool,
|
||||
loc := #caller_location,
|
||||
) -> (
|
||||
result: string,
|
||||
@ -70,7 +72,9 @@ run_cmd_internal :: proc(
|
||||
buf: [1024]u8
|
||||
if has_data {
|
||||
n = handle_error1(os.read(r, buf[:]))
|
||||
strings.write_bytes(&b, buf[0:n])
|
||||
if capture {
|
||||
strings.write_bytes(&b, buf[0:n])
|
||||
}
|
||||
handle_error1(os.write(os.stderr, buf[0:n]))
|
||||
}
|
||||
|
||||
@ -106,10 +110,11 @@ run_cmd_internal :: proc(
|
||||
run_cmd :: proc(
|
||||
cmd: []string,
|
||||
cwd: string,
|
||||
capture := true,
|
||||
expr := #caller_expression,
|
||||
loc := #caller_location,
|
||||
) -> string {
|
||||
result, err := run_cmd_internal(cmd, cwd, loc)
|
||||
result, err := run_cmd_internal(cmd, cwd, capture, loc)
|
||||
handle_error(err, "", expr, loc)
|
||||
return result
|
||||
}
|
||||
|
@ -577,8 +577,6 @@ get_convex :: proc(assetman: ^Asset_Manager, path: cstring) -> (result: Loaded_C
|
||||
}
|
||||
}
|
||||
|
||||
log.debugf("num verts: %v", len(vertices))
|
||||
|
||||
center := (max_pos + min_pos) * 0.5
|
||||
extent := (max_pos - min_pos) * 0.5
|
||||
|
||||
|
@ -1302,6 +1302,7 @@ game_init :: proc() {
|
||||
g_mem.ui_context.default_style.font_size = 20
|
||||
g_mem.ui_context.text_size = ui.rl_measure_text_2d
|
||||
|
||||
log.debugf("game_init")
|
||||
game_hot_reloaded(g_mem)
|
||||
}
|
||||
|
||||
@ -1340,6 +1341,7 @@ game_hot_reloaded :: proc(mem: rawptr) {
|
||||
ui.rl_init()
|
||||
|
||||
g_mem.runtime_world.orbit_camera.distance = 4
|
||||
log.debugf("hot reloaded")
|
||||
}
|
||||
|
||||
@(export)
|
||||
|
@ -52,8 +52,14 @@ Game_API :: struct {
|
||||
api_version: int,
|
||||
}
|
||||
|
||||
load_game_api :: proc(api_version: int) -> (api: Game_API, ok: bool) {
|
||||
mod_time, mod_time_error := os.last_write_time_by_name("game" + DLL_EXT)
|
||||
load_game_api :: proc(bin_dir: string, api_version: int) -> (api: Game_API, ok: bool) {
|
||||
// NOTE: this needs to be a relative path for Linux to work.
|
||||
game_dll_name := fmt.tprintf("game_{0}" + DLL_EXT, api_version)
|
||||
game_dll_path := filepath.join({bin_dir, game_dll_name}, context.temp_allocator)
|
||||
|
||||
mod_time, mod_time_error := os.last_write_time_by_name(
|
||||
filepath.join({bin_dir, "game" + DLL_EXT}, context.temp_allocator),
|
||||
)
|
||||
if mod_time_error != os.ERROR_NONE {
|
||||
fmt.printfln(
|
||||
"Failed getting last write time of game" + DLL_EXT + ", error code: {1}",
|
||||
@ -62,14 +68,9 @@ load_game_api :: proc(api_version: int) -> (api: Game_API, ok: bool) {
|
||||
return
|
||||
}
|
||||
|
||||
// NOTE: this needs to be a relative path for Linux to work.
|
||||
game_dll_name := fmt.tprintf("game_{0}" + DLL_EXT, api_version)
|
||||
bin_dir := filepath.dir(os.args[0], context.temp_allocator)
|
||||
|
||||
copy_dll(bin_dir, game_dll_name) or_return
|
||||
|
||||
game_dll_path := filepath.join({bin_dir, game_dll_name}, context.temp_allocator)
|
||||
|
||||
// This proc matches the names of the fields in Game_API to symbols in the
|
||||
// game DLL. It actually looks for symbols starting with `game_`, which is
|
||||
// why the argument `"game_"` is there.
|
||||
@ -85,15 +86,13 @@ load_game_api :: proc(api_version: int) -> (api: Game_API, ok: bool) {
|
||||
return
|
||||
}
|
||||
|
||||
unload_game_api :: proc(api: ^Game_API) {
|
||||
unload_game_api :: proc(bin_dir: string, api: ^Game_API) {
|
||||
if api.lib != nil {
|
||||
if !dynlib.unload_library(api.lib) {
|
||||
fmt.printfln("Failed unloading lib: {0}", dynlib.last_error())
|
||||
}
|
||||
}
|
||||
|
||||
bin_dir := filepath.dir(os.args[0], context.temp_allocator)
|
||||
|
||||
game_dll_path := filepath.join(
|
||||
{bin_dir, fmt.tprintf("game_{0}" + DLL_EXT, api.api_version)},
|
||||
context.temp_allocator,
|
||||
@ -137,7 +136,7 @@ main :: proc() {
|
||||
}
|
||||
|
||||
game_api_version := 0
|
||||
game_api, game_api_ok := load_game_api(game_api_version)
|
||||
game_api, game_api_ok := load_game_api(bin_dir, game_api_version)
|
||||
|
||||
if !game_api_ok {
|
||||
fmt.println("Failed to load Game API")
|
||||
@ -165,7 +164,7 @@ main :: proc() {
|
||||
}
|
||||
|
||||
if reload {
|
||||
new_game_api, new_game_api_ok := load_game_api(game_api_version)
|
||||
new_game_api, new_game_api_ok := load_game_api(bin_dir, game_api_version)
|
||||
|
||||
if new_game_api_ok {
|
||||
force_restart =
|
||||
@ -194,11 +193,11 @@ main :: proc() {
|
||||
reset_tracking_allocator(&tracking_allocator)
|
||||
|
||||
for &g in old_game_apis {
|
||||
unload_game_api(&g)
|
||||
unload_game_api(bin_dir, &g)
|
||||
}
|
||||
|
||||
clear(&old_game_apis)
|
||||
unload_game_api(&game_api)
|
||||
unload_game_api(bin_dir, &game_api)
|
||||
game_api = new_game_api
|
||||
game_api.init()
|
||||
}
|
||||
@ -232,13 +231,13 @@ main :: proc() {
|
||||
}
|
||||
|
||||
for &g in old_game_apis {
|
||||
unload_game_api(&g)
|
||||
unload_game_api(bin_dir, &g)
|
||||
}
|
||||
|
||||
delete(old_game_apis)
|
||||
|
||||
game_api.shutdown_window()
|
||||
unload_game_api(&game_api)
|
||||
unload_game_api(bin_dir, &game_api)
|
||||
mem.tracking_allocator_destroy(&tracking_allocator)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user