How did I get here?

This commit is contained in:
2025-09-19 22:01:48 -05:00
parent 2049a6f7b9
commit 96fcddea30
20 changed files with 962 additions and 30 deletions

146
src/console/Console.cpp Normal file
View File

@@ -0,0 +1,146 @@
// Copyright (c) 2025 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Console.hpp"
#include "assert/Assert.hpp"
using namespace Dawn;
Console::Console(void) :
commands(),
variables(),
buffer()
{
}
void Console::registerCommand(
const std::string &cmd,
const std::function<void(std::vector<std::string>&)> &callback
) {
assertTrue(cmd.length() > 0, "cmd length must be > 0");
assertTrue(callback != nullptr, "callback must not be null");
this->commands[cmd] = callback;
}
template<typename T>
void Console::registerVariable(
const std::string &var,
const std::function<T()> &getter,
const std::function<void(const T &)> &setter
) {
assertTrue(var.length() > 0, "var length must be > 0");
assertTrue(getter != nullptr, "getter must not be null");
assertTrue(setter != nullptr, "setter must not be null");
this->variables[var] = std::make_pair(getter, setter);
}
void Console::update() {
enum class ParseState { FIND_CMD, FIND_ARG, COMMAND, ARG, ARG_QUOTED };
for (const auto &cmd : buffer) {
std::string cmdName;
std::vector<std::string> args;
ParseState state = ParseState::FIND_CMD;
std::string buff;
for(size_t i = 0; i < cmd.length(); i++) {
char_t c = cmd[i];
switch(state) {
case ParseState::FIND_CMD:
if(isspace(c)) continue;
state = ParseState::COMMAND;
buff += c;
break;
case ParseState::FIND_ARG:
if(isspace(c)) continue;
if(c == '\"') {
state = ParseState::ARG_QUOTED;
break;
}
state = ParseState::ARG;
buff += c;
break;
case ParseState::COMMAND:
if(isspace(c)) {
cmdName = buff;
buff.clear();
state = ParseState::FIND_ARG;
break;
}
buff += c;
break;
case ParseState::ARG:
if(isspace(c)) {
args.push_back(buff);
buff.clear();
state = ParseState::FIND_ARG;
break;
}
buff += c;
break;
case ParseState::ARG_QUOTED:
if(c == '\"') {
args.push_back(buff);
buff.clear();
state = ParseState::FIND_ARG;
break;
}
buff += c;
break;
}
}
if(buff.length() > 0) {
if(state == ParseState::COMMAND) {
cmdName = buff;
} else {
args.push_back(buff);
}
}
// Find command
auto itCmd = commands.find(cmdName);
if(itCmd == commands.end()) {
// Find variable
auto itVar = variables.find(cmdName);
if(itVar == variables.end()) {
std::cout << "Console: Unknown command or variable '" << cmdName << "'" << std::endl;
continue;
}
// Variable get/set
printf("Console: Variable '%s' ", cmdName.c_str());
continue;
}
itCmd->second(args);
}
buffer.clear();
}
void Console::exec(const std::string &str) {
// Split strings by command seperator
std::istringstream iss(str);
std::string token;
while(std::getline(iss, token, COMMAND_SEPARATOR)) {
// Seperate by newlines too
std::istringstream lineIss(token);
std::string lineToken;
while(std::getline(lineIss, lineToken)) {
if(lineToken.length() == 0) continue;
buffer.push_back(lineToken);
}
}
}
Console::~Console(void) {
}