89 lines
2.7 KiB
Odin
89 lines
2.7 KiB
Odin
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
|
|
} |