120 lines
2.9 KiB
Odin
120 lines
2.9 KiB
Odin
/*
|
|
This file implements logger and temp allocator for the web build. The logger
|
|
is based on the one found here: https://github.com/Aronicu/Raylib-WASM/tree/main
|
|
*/
|
|
|
|
#+build wasm32, wasm64p32
|
|
|
|
package main_web
|
|
|
|
import "base:runtime"
|
|
import "core:c"
|
|
import "core:fmt"
|
|
import "core:log"
|
|
import "core:strings"
|
|
|
|
|
|
// WASM logger
|
|
|
|
WASM_Logger_Opts :: log.Options{.Level, .Short_File_Path, .Line}
|
|
|
|
create_wasm_logger :: proc (lowest := log.Level.Debug, opt := WASM_Logger_Opts) -> log.Logger {
|
|
return log.Logger{data = nil, procedure = wasm_logger_proc, lowest_level = lowest, options = opt}
|
|
}
|
|
|
|
@(private="file")
|
|
wasm_logger_proc :: proc(
|
|
logger_data: rawptr,
|
|
level: log.Level,
|
|
text: string,
|
|
options: log.Options,
|
|
location := #caller_location
|
|
) {
|
|
b := strings.builder_make(context.temp_allocator)
|
|
strings.write_string(&b, Wasm_Logger_Level_Headers[level])
|
|
do_location_header(options, &b, location)
|
|
fmt.sbprint(&b, text)
|
|
puts(strings.to_cstring(&b))
|
|
}
|
|
|
|
@(private="file")
|
|
Wasm_Logger_Level_Headers := [?]string {
|
|
0 ..< 10 = "[DEBUG] --- ",
|
|
10 ..< 20 = "[INFO ] --- ",
|
|
20 ..< 30 = "[WARN ] --- ",
|
|
30 ..< 40 = "[ERROR] --- ",
|
|
40 ..< 50 = "[FATAL] --- ",
|
|
}
|
|
|
|
@(private="file")
|
|
do_location_header :: proc(opts: log.Options, buf: ^strings.Builder, location := #caller_location) {
|
|
if log.Location_Header_Opts & opts == nil {
|
|
return
|
|
}
|
|
fmt.sbprint(buf, "[")
|
|
file := location.file_path
|
|
if .Short_File_Path in opts {
|
|
last := 0
|
|
for r, i in location.file_path {
|
|
if r == '/' {
|
|
last = i + 1
|
|
}
|
|
}
|
|
file = location.file_path[last:]
|
|
}
|
|
|
|
if log.Location_File_Opts & opts != nil {
|
|
fmt.sbprint(buf, file)
|
|
}
|
|
if .Line in opts {
|
|
if log.Location_File_Opts & opts != nil {
|
|
fmt.sbprint(buf, ":")
|
|
}
|
|
fmt.sbprint(buf, location.line)
|
|
}
|
|
|
|
if .Procedure in opts {
|
|
if (log.Location_File_Opts | {.Line}) & opts != nil {
|
|
fmt.sbprint(buf, ":")
|
|
}
|
|
fmt.sbprintf(buf, "%s()", location.procedure)
|
|
}
|
|
|
|
fmt.sbprint(buf, "] ")
|
|
}
|
|
|
|
@(default_calling_convention = "c")
|
|
foreign {
|
|
puts :: proc(buffer: cstring) -> c.int ---
|
|
}
|
|
|
|
|
|
// Temp Allocator
|
|
// More or less a copy from base:runtime (that one is disabled in freestanding
|
|
// build mode).
|
|
|
|
WASM_Temp_Allocator :: struct {
|
|
arena: runtime.Arena,
|
|
}
|
|
|
|
wasm_temp_allocator_init :: proc(s: ^WASM_Temp_Allocator, size: int, backing_allocator := context.allocator) {
|
|
_ = runtime.arena_init(&s.arena, uint(size), backing_allocator)
|
|
}
|
|
|
|
wasm_temp_allocator_proc :: proc(
|
|
allocator_data: rawptr,
|
|
mode: runtime.Allocator_Mode,
|
|
size, alignment: int,
|
|
old_memory: rawptr,
|
|
old_size: int,
|
|
loc := #caller_location) -> (data: []byte, err: runtime.Allocator_Error) {
|
|
s := (^WASM_Temp_Allocator)(allocator_data)
|
|
return runtime.arena_allocator_proc(&s.arena, mode, size, alignment, old_memory, old_size, loc)
|
|
}
|
|
|
|
wasm_temp_allocator :: proc(allocator: ^WASM_Temp_Allocator) -> runtime.Allocator {
|
|
return runtime.Allocator{
|
|
procedure = wasm_temp_allocator_proc,
|
|
data = allocator,
|
|
}
|
|
} |