gutter_runner/game/name/name.odin

63 lines
1.4 KiB
Odin

// String interning thingy
package name
import "core:mem"
import "core:strings"
import "core:sync"
Name :: distinct u32
NONE :: Name(0)
Container :: struct {
lock: sync.Atomic_RW_Mutex,
names_lookup: map[string]Name,
names_allocator: mem.Dynamic_Arena,
names_array: [dynamic]string,
}
@(private = "file")
global_container: ^Container
setup_global_container :: proc(cnt: ^Container) {
global_container = cnt
}
init :: proc(cnt: ^Container) {
mem.dynamic_arena_init(&cnt.names_allocator)
assert(len(cnt.names_array) == 0)
append(&cnt.names_array, "None")
}
destroy :: proc() {
assert(global_container != nil)
delete(global_container.names_array)
delete(global_container.names_lookup)
mem.dynamic_arena_destroy(&global_container.names_allocator)
global_container = nil
}
from_string :: proc(str: string) -> Name {
sync.atomic_rw_mutex_guard(&global_container.lock)
existing, ok := global_container.names_lookup[str]
if ok {
return existing
} else {
new_str := strings.clone(
str,
mem.dynamic_arena_allocator(&global_container.names_allocator),
)
idx := u32(len(global_container.names_array))
append(&global_container.names_array, new_str)
global_container.names_lookup[str] = Name(idx)
return Name(idx)
}
}
to_string :: proc(name: Name) -> string {
sync.atomic_rw_mutex_shared_guard(&global_container.lock)
return global_container.names_array[name]
}