Last active
July 2, 2022 09:59
-
-
Save DaseinPhaos/b47a600df2abb7d35ce2718e92d54a4c to your computer and use it in GitHub Desktop.
demonstrates how to hot reload config files on debug builds with odin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package hot_reload | |
when ODIN_DEBUG==true { | |
import "core:path/filepath" | |
import "core:os" | |
import "core:sync" | |
import "core:time" | |
import "core:strings" | |
import "core:thread" | |
} | |
import "core:fmt" | |
import "core:sys/windows" | |
foreign import kernel32 "system:Kernel32.lib" | |
@(default_calling_convention="std") | |
foreign kernel32 { | |
FindFirstChangeNotificationW :: proc(lpPathName: windows.LPCWSTR, bWatchSubtree: windows.BOOL, dwNotifyFilter: windows.DWORD) -> windows.HANDLE --- | |
FindNextChangeNotification :: proc(hChangeHandle: windows.HANDLE) -> windows.BOOL --- | |
FindCloseChangeNotification :: proc(hChangeHandle: windows.HANDLE) -> windows.BOOL --- | |
} | |
FILE_NOTIFY_CHANGE_LAST_WRITE :: 0x00000010 | |
main :: proc() { | |
cfg : string | |
for { | |
newCfg := read_config() | |
if newCfg != cfg { | |
fmt.printf("Config changed:\n\told: [%s]\n\tnew: [%s]\n", cfg, newCfg) | |
cfg = newCfg | |
} | |
} | |
} | |
read_config :: proc() -> string { | |
cfgPath :: `H:/projects/test/config` | |
when ODIN_DEBUG==true { | |
if _cfgDirHandle == nil { | |
// create cfg handle, spawn thread to monitor filesystem changes | |
cfgDir := filepath.dir(cfgPath, context.temp_allocator) | |
cfgDirW := windows.utf8_to_wstring(cfgDir, context.temp_allocator) | |
_cfgDirHandle = FindFirstChangeNotificationW(cfgDirW, false, FILE_NOTIFY_CHANGE_LAST_WRITE) | |
thread.run(proc() { | |
for { | |
windows.WaitForSingleObject(_cfgDirHandle, windows.INFINITE) | |
time.sleep(200*time.Millisecond) // wait for some time to make sure that content gets flushed | |
sync.atomic_store(&_cfgDirChanged, true) | |
FindNextChangeNotification(_cfgDirHandle) | |
} | |
}) | |
_cfgDirChanged = true | |
} | |
if sync.atomic_exchange(&_cfgDirChanged, false) { | |
// change detected, reload content | |
newContent, newContentOk := os.read_entire_file(cfgPath, context.allocator) | |
if newContentOk { | |
if _cfgContent != {} { | |
delete_string(_cfgContent, context.allocator) | |
} | |
_cfgContent = strings.string_from_ptr(&newContent[0], len(newContent)) | |
} | |
} | |
return _cfgContent | |
} else { | |
content :: string(#load(cfgPath)) | |
return content | |
} | |
} | |
when ODIN_DEBUG==true { | |
_cfgDirHandle : windows.HANDLE | |
_cfgDirChanged : bool | |
_cfgContent : string | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment