Initial commit.
This commit is contained in:
89
console.odin
Normal file
89
console.odin
Normal file
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user