Compare commits
3
Commits
master
...
be516d39a3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be516d39a3 | ||
|
|
e7cc935035 | ||
|
|
416b42c27e |
@@ -0,0 +1,52 @@
|
|||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$PROJECT = "sindri"
|
||||||
|
$COMMIT = git rev-parse --short HEAD
|
||||||
|
$VERSION = "dev-$(Get-Date -Format 'yyyy-MM-dd')-$COMMIT"
|
||||||
|
|
||||||
|
$OPTION = $args[0]
|
||||||
|
if ($args) { $args = $args[1..($args.Length - 1)] } else { $args = @() }
|
||||||
|
|
||||||
|
# ------------------------------------------
|
||||||
|
# Game compile
|
||||||
|
|
||||||
|
New-Item -ItemType Directory -Force -Path build | Out-Null
|
||||||
|
|
||||||
|
# Game.dll
|
||||||
|
odin build game/ -show-timings `
|
||||||
|
-collection:sindri=src `
|
||||||
|
-build-mode:dynamic `
|
||||||
|
-out:build/game_tmp -microarch:native "-define:VERSION=$VERSION-debug" -debug @args
|
||||||
|
|
||||||
|
# Need to use a temp file on Windows because it first writes an empty file,
|
||||||
|
# which the engine will load before it is actually fully written.
|
||||||
|
if (-not (Test-Path "build/game_tmp.dll")) {
|
||||||
|
Write-Error "error: build produced no game lib.dll"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
Move-Item -Force "build/game_tmp.dll" "build/game.dll"
|
||||||
|
|
||||||
|
# ------------------------------------------
|
||||||
|
# Engine compile
|
||||||
|
|
||||||
|
# If the executable is already running, then don't try to build and start it.
|
||||||
|
$proc = Get-Process -Name $PROJECT -ErrorAction SilentlyContinue
|
||||||
|
if ($proc) {
|
||||||
|
Write-Output "Hot reloading..."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($OPTION -eq "debug") {
|
||||||
|
odin build src/ -show-timings `
|
||||||
|
-collection:sindri=src `
|
||||||
|
-collection:gram=vendor/gram/src `
|
||||||
|
-collection:wgpu=vendor `
|
||||||
|
-out:build/$PROJECT -microarch:native -use-separate-modules "-define:VERSION=$VERSION-debug" -debug @args
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
odin build src/ -show-timings `
|
||||||
|
-collection:sindri=src `
|
||||||
|
-collection:gram=vendor/gram/src `
|
||||||
|
-collection:wgpu=vendor `
|
||||||
|
-out:build/$PROJECT -microarch:native -o:speed "-define:VERSION=$VERSION" @args
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# Odin
|
||||||
|
|
||||||
|
This document contains specifics about the workings of the Odin programming
|
||||||
|
language, dynamic linking and state management design patterns. These are
|
||||||
|
tested and validated findings, for continued reference by me.
|
||||||
|
|
||||||
|
## Dynamic Library Memory
|
||||||
|
|
||||||
|
When a program loads in a dynamic library, what happens with package globals?
|
||||||
|
|
||||||
|
Findings (macOS):
|
||||||
|
- The package globals are shared between the host and the lib
|
||||||
|
- After hot reloading the lib, the memory of the packge is not refreshed,
|
||||||
|
it keeps pointing to the package global of the host
|
||||||
|
|
||||||
|
The clanker states this is due to "flat-namespace symbol interposition".
|
||||||
|
|
||||||
|
Linux "ELF has symbol preemption: when resolving references, ld.so searches
|
||||||
|
globals scope in order — executable first, then loaded shared objects".
|
||||||
|
|
||||||
|
Windows PE has no interposition at all, every module (exe and each DLL) has its
|
||||||
|
own symbol table.
|
||||||
+14
-6
@@ -5,11 +5,12 @@ import "core:time"
|
|||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
|
|
||||||
import "sindri:core"
|
import "sindri:core"
|
||||||
|
import "sindri:test"
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
Game_Memory :: struct {
|
Game_Memory :: struct {
|
||||||
should_close: bool
|
should_close: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
g: ^Game_Memory
|
g: ^Game_Memory
|
||||||
@@ -54,6 +55,8 @@ settings :: proc() -> core.Settings {
|
|||||||
@(export)
|
@(export)
|
||||||
init_once :: proc() {
|
init_once :: proc() {
|
||||||
fmt.println("init once")
|
fmt.println("init once")
|
||||||
|
|
||||||
|
test.test_proc = proc() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@(export)
|
@(export)
|
||||||
@@ -61,6 +64,9 @@ init :: proc() {
|
|||||||
fmt.println("hello from .dll!")
|
fmt.println("hello from .dll!")
|
||||||
|
|
||||||
g = new(Game_Memory)
|
g = new(Game_Memory)
|
||||||
|
memory_set(g)
|
||||||
|
|
||||||
|
test.test_proc = proc() { asd := 2 }
|
||||||
}
|
}
|
||||||
|
|
||||||
@(export)
|
@(export)
|
||||||
@@ -70,6 +76,10 @@ update :: proc(dt: f32) {
|
|||||||
if input.key_state(.Key_Escape) == .Press {
|
if input.key_state(.Key_Escape) == .Press {
|
||||||
g.should_close = true
|
g.should_close = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.println("GAME:", test.test)
|
||||||
|
fmt.printf("pointer: %p | %p\n", &test.test, &test.test_proc)
|
||||||
|
test.test += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@(export)
|
@(export)
|
||||||
@@ -83,19 +93,17 @@ start := time.tick_now()
|
|||||||
should_close :: proc() -> bool {
|
should_close :: proc() -> bool {
|
||||||
elapsed := time.tick_since(start)
|
elapsed := time.tick_since(start)
|
||||||
seconds := time.duration_seconds(elapsed)
|
seconds := time.duration_seconds(elapsed)
|
||||||
if seconds > 4 do return true
|
// if seconds > 4 do return true
|
||||||
|
|
||||||
return g.should_close
|
return g.should_close
|
||||||
}
|
}
|
||||||
|
|
||||||
@(export)
|
@(export)
|
||||||
force_reload :: proc() -> bool {
|
force_reload :: proc() -> bool {
|
||||||
// TODO: read keypress
|
return input.key_state(.Key_F5) == .Press
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@(export)
|
@(export)
|
||||||
force_restart :: proc() -> bool {
|
force_restart :: proc() -> bool {
|
||||||
// TODO: read keypress
|
return input.key_state(.Key_F6) == .Press
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ import "core:fmt"
|
|||||||
import "sindri:input"
|
import "sindri:input"
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
// Types
|
||||||
|
|
||||||
// event category, bitfield (?)
|
// event category, bitfield (?)
|
||||||
|
|
||||||
|
// Event_Data :: union {
|
||||||
Event :: union {
|
Event :: union {
|
||||||
Window_Close_Event,
|
Window_Close_Event,
|
||||||
Window_Resize_Event,
|
Window_Resize_Event,
|
||||||
@@ -22,6 +24,11 @@ Event :: union {
|
|||||||
Mouse_Scroll_Event,
|
Mouse_Scroll_Event,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Event :: struct {
|
||||||
|
// data: Event_Data,
|
||||||
|
// handled: bool,
|
||||||
|
// }
|
||||||
|
|
||||||
Window_Close_Event :: struct {
|
Window_Close_Event :: struct {
|
||||||
handled: bool,
|
handled: bool,
|
||||||
}
|
}
|
||||||
@@ -85,6 +92,13 @@ Mouse_Scroll_Event :: struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
// Variables
|
||||||
|
|
||||||
|
// I want to have a list of Listeners per Event type, but this is state
|
||||||
|
// listeners: map[typeid][dynamic]Listener
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
// Public functions
|
||||||
|
|
||||||
// Dispatcher(Event) -> forwards to the right function
|
// Dispatcher(Event) -> forwards to the right function
|
||||||
on_event :: proc(event: Event) {
|
on_event :: proc(event: Event) {
|
||||||
@@ -116,3 +130,9 @@ on_event :: proc(event: Event) {
|
|||||||
fmt.println("Joy dis:", e.id)
|
fmt.println("Joy dis:", e.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
Have the events queued up into a frame buffer that gets drained at a specific time.
|
||||||
|
*/
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package sindri
|
|||||||
|
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
import "core:time"
|
import "core:time"
|
||||||
|
import "sindri:test"
|
||||||
|
|
||||||
import "sindri:hot_reload"
|
import "sindri:hot_reload"
|
||||||
import "sindri:platform"
|
import "sindri:platform"
|
||||||
@@ -41,6 +42,9 @@ main :: proc() {
|
|||||||
platform.os_poll_events()
|
platform.os_poll_events()
|
||||||
api.update(dt)
|
api.update(dt)
|
||||||
|
|
||||||
|
fmt.println("MAIN:", test.test)
|
||||||
|
fmt.printf("pointer: %p | %p\n", &test.test, &test.test_proc)
|
||||||
|
|
||||||
platform.frame(dt)
|
platform.frame(dt)
|
||||||
|
|
||||||
dt = f32(time.duration_seconds(time.tick_since(start)))
|
dt = f32(time.duration_seconds(time.tick_since(start)))
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
test: int = 0
|
||||||
|
|
||||||
|
test_proc: proc()
|
||||||
Reference in New Issue
Block a user