commit 071a4c48e5355271d560d8d7d8b85180d9a2af69 Author: samstalhandske Date: Mon Feb 9 11:51:28 2026 +0100 Initial commit. diff --git a/console.odin b/console.odin new file mode 100644 index 0000000..febf097 --- /dev/null +++ b/console.odin @@ -0,0 +1,89 @@ +package console + +import "core:strings" +import "core:log" +MAX_COMMANDS_IN_REGISTRY :: #config(CONSOLE_MAX_COMMANDS_IN_REGISTRY, 2048) + +Console :: struct { + command_registry: Command_Registry, +} + +Command_Registry :: map[string]Command + +Command :: struct { + description: string, + userdata: rawptr, + callback: Commmand_Callback, +} + +Commmand_Callback :: proc(c: ^Console, userdata: rawptr, arguments: []string) -> bool // TODO: SS - Return an enum? 'Success', 'Not enough arguments', 'Invalid arguments' etc. + +init :: proc(console: ^Console) { + assert(console.command_registry == nil) + console.command_registry = make(Command_Registry, MAX_COMMANDS_IN_REGISTRY) +} + +// TODO: SS - Support routing logs to somewhere else? Maybe add a 'log_callback' procedure? + +register_command :: proc(console: ^Console, name, description: string, userdata: rawptr, callback: Commmand_Callback) -> bool { + elem, ok := &console.command_registry[name] + if ok { + log.warnf("Command with name '%v' has already been registered.", name) + return false + } + + console.command_registry[name] = {} + + cmd := &console.command_registry[name] + cmd.description = description + cmd.userdata = userdata + cmd.callback = callback + + log.infof("Registered command with name '%v'.", name) + return true +} + +log_available_commands :: proc(console: ^Console) { + assert(console != nil) + + log.infof("Available commands (%v):", len(console.command_registry)) + for key, value in console.command_registry { + log.infof("- '%v', '%v'.", key, value.description) + } +} + +send_input :: proc(console: ^Console, input: string, loc := #caller_location) { // TODO: SS - Decide on a nice name for this. 'run'? 'send_input' is probably alright too. + input_strings, err := strings.split(input, " ") + if err != .None { + log.infof("No input.") + return + } + defer delete(input_strings) + + command_name := input_strings[0] + arguments := input_strings[1:] + + // log.infof("Command '%v', arguments: '%v'", command_name, arguments) + + cmd, command_exists := &console.command_registry[command_name] + if !command_exists { + log.warnf("Command '%v' was not found in registry.", command_name) + return + } + + if cmd.callback == nil { + log.errorf("Command '%v' is missing a callback.") + return + } + + result := cmd.callback(console, cmd.userdata, arguments) + if !result { + log.warnf("Command '%v' failed. Command description: '%v'. Location: %v", command_name, cmd.description, loc) + return + } +} + +shutdown :: proc(console: ^Console) { + delete(console.command_registry) + console.command_registry = nil +} \ No newline at end of file