- ambits en la consola
- verifica que la habitacio de debug.yaml existisca
This commit is contained in:
@@ -14,9 +14,12 @@
|
|||||||
# dynamic_completions - (optional) Completions generated at runtime (default: false)
|
# dynamic_completions - (optional) Completions generated at runtime (default: false)
|
||||||
# completions - (optional) Static TAB completion tree
|
# completions - (optional) Static TAB completion tree
|
||||||
# debug_extras - (optional) Overrides applied in debug builds
|
# debug_extras - (optional) Overrides applied in debug builds
|
||||||
|
# scope - (optional) Visibility scope: global, game, editor, debug (default: global)
|
||||||
|
# Can be a string or a list. Categories can set a default scope for all commands.
|
||||||
|
|
||||||
categories:
|
categories:
|
||||||
- name: VIDEO
|
- name: VIDEO
|
||||||
|
scope: game
|
||||||
commands:
|
commands:
|
||||||
- keyword: SS
|
- keyword: SS
|
||||||
handler: cmd_ss
|
handler: cmd_ss
|
||||||
@@ -86,6 +89,7 @@ categories:
|
|||||||
dynamic_completions: true
|
dynamic_completions: true
|
||||||
|
|
||||||
- name: AUDIO
|
- name: AUDIO
|
||||||
|
scope: game
|
||||||
commands:
|
commands:
|
||||||
- keyword: AUDIO
|
- keyword: AUDIO
|
||||||
handler: cmd_audio
|
handler: cmd_audio
|
||||||
@@ -109,6 +113,7 @@ categories:
|
|||||||
SOUND: [ON, OFF, VOL]
|
SOUND: [ON, OFF, VOL]
|
||||||
|
|
||||||
- name: GAME
|
- name: GAME
|
||||||
|
scope: game
|
||||||
commands:
|
commands:
|
||||||
- keyword: PLAYER
|
- keyword: PLAYER
|
||||||
handler: cmd_player
|
handler: cmd_player
|
||||||
@@ -137,6 +142,7 @@ categories:
|
|||||||
description: Quit application
|
description: Quit application
|
||||||
usage: EXIT
|
usage: EXIT
|
||||||
instant: true
|
instant: true
|
||||||
|
scope: global
|
||||||
|
|
||||||
- keyword: QUIT
|
- keyword: QUIT
|
||||||
handler: cmd_quit
|
handler: cmd_quit
|
||||||
@@ -144,8 +150,10 @@ categories:
|
|||||||
usage: QUIT
|
usage: QUIT
|
||||||
instant: true
|
instant: true
|
||||||
help_hidden: true
|
help_hidden: true
|
||||||
|
scope: global
|
||||||
|
|
||||||
- name: INFO
|
- name: INFO
|
||||||
|
scope: global
|
||||||
commands:
|
commands:
|
||||||
- keyword: SHOW
|
- keyword: SHOW
|
||||||
handler: cmd_show
|
handler: cmd_show
|
||||||
@@ -182,6 +190,7 @@ categories:
|
|||||||
|
|
||||||
- name: DEBUG
|
- name: DEBUG
|
||||||
debug_only: true
|
debug_only: true
|
||||||
|
scope: debug
|
||||||
commands:
|
commands:
|
||||||
- keyword: DEBUG
|
- keyword: DEBUG
|
||||||
handler: cmd_debug
|
handler: cmd_debug
|
||||||
@@ -202,6 +211,7 @@ categories:
|
|||||||
handler: cmd_room
|
handler: cmd_room
|
||||||
description: "Change to room number (GAME only)"
|
description: "Change to room number (GAME only)"
|
||||||
usage: "ROOM <1-60>|NEXT|PREV|LEFT|RIGHT|UP|DOWN"
|
usage: "ROOM <1-60>|NEXT|PREV|LEFT|RIGHT|UP|DOWN"
|
||||||
|
scope: [debug, editor]
|
||||||
completions:
|
completions:
|
||||||
ROOM: [NEXT, PREV, LEFT, RIGHT, UP, DOWN, NEW, DELETE]
|
ROOM: [NEXT, PREV, LEFT, RIGHT, UP, DOWN, NEW, DELETE]
|
||||||
ROOM NEW: [LEFT, RIGHT, UP, DOWN]
|
ROOM NEW: [LEFT, RIGHT, UP, DOWN]
|
||||||
@@ -216,30 +226,35 @@ categories:
|
|||||||
- keyword: EDIT
|
- keyword: EDIT
|
||||||
handler: cmd_edit
|
handler: cmd_edit
|
||||||
description: "Map editor mode (GAME only)"
|
description: "Map editor mode (GAME only)"
|
||||||
usage: "EDIT [ON|OFF|REVERT|SHOW|HIDE|MAPBG] [...]"
|
usage: "EDIT [ON|OFF|REVERT|SHOW|HIDE|MAPBG|MAPCONN] [...]"
|
||||||
|
scope: [debug, editor]
|
||||||
dynamic_completions: true
|
dynamic_completions: true
|
||||||
completions:
|
completions:
|
||||||
EDIT: [ON, OFF, REVERT, SHOW, HIDE, MAPBG, MAPCONN]
|
EDIT: [ON, OFF, REVERT, SHOW, HIDE, MAPBG, MAPCONN]
|
||||||
EDIT SHOW: [INFO, GRID]
|
EDIT SHOW: [INFO, GRID]
|
||||||
EDIT HIDE: [INFO, GRID]
|
EDIT HIDE: [INFO, GRID]
|
||||||
|
|
||||||
|
- name: EDITOR
|
||||||
|
debug_only: true
|
||||||
|
scope: editor
|
||||||
|
commands:
|
||||||
- keyword: ENEMY
|
- keyword: ENEMY
|
||||||
handler: cmd_enemy
|
handler: cmd_enemy
|
||||||
description: "Add, delete or duplicate enemy (editor)"
|
description: "Add, delete or duplicate enemy"
|
||||||
usage: "ENEMY <ADD|DELETE|DUPLICATE>"
|
usage: "ENEMY <ADD|DELETE|DUPLICATE>"
|
||||||
completions:
|
completions:
|
||||||
ENEMY: [ADD, DELETE, DUPLICATE]
|
ENEMY: [ADD, DELETE, DUPLICATE]
|
||||||
|
|
||||||
- keyword: ITEM
|
- keyword: ITEM
|
||||||
handler: cmd_item
|
handler: cmd_item
|
||||||
description: "Add, delete or duplicate item (editor)"
|
description: "Add, delete or duplicate item"
|
||||||
usage: "ITEM <ADD|DELETE|DUPLICATE>"
|
usage: "ITEM <ADD|DELETE|DUPLICATE>"
|
||||||
completions:
|
completions:
|
||||||
ITEM: [ADD, DELETE, DUPLICATE]
|
ITEM: [ADD, DELETE, DUPLICATE]
|
||||||
|
|
||||||
- keyword: SET
|
- keyword: SET
|
||||||
handler: cmd_set
|
handler: cmd_set
|
||||||
description: "Set property (enemy or room, editor mode)"
|
description: "Set property (enemy, item or room)"
|
||||||
usage: "SET <property> <value>"
|
usage: "SET <property> <value>"
|
||||||
dynamic_completions: true
|
dynamic_completions: true
|
||||||
completions:
|
completions:
|
||||||
@@ -249,6 +264,7 @@ categories:
|
|||||||
SET CONVEYOR: [LEFT, NONE, RIGHT]
|
SET CONVEYOR: [LEFT, NONE, RIGHT]
|
||||||
|
|
||||||
- name: CHEATS
|
- name: CHEATS
|
||||||
|
scope: [game, editor]
|
||||||
commands:
|
commands:
|
||||||
- keyword: CHEAT
|
- keyword: CHEAT
|
||||||
handler: cmd_cheat
|
handler: cmd_cheat
|
||||||
|
|||||||
@@ -204,6 +204,9 @@ void MapEditor::enter(std::shared_ptr<Room> room, std::shared_ptr<Player> player
|
|||||||
RenderInfo::get()->toggle();
|
RenderInfo::get()->toggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Activar scope de la consola para el editor
|
||||||
|
Console::get()->setScope("editor");
|
||||||
|
|
||||||
// Resetear enemigos a su posición inicial (pueden haberse movido durante el gameplay)
|
// Resetear enemigos a su posición inicial (pueden haberse movido durante el gameplay)
|
||||||
room_->resetEnemyPositions(room_data_.enemies);
|
room_->resetEnemyPositions(room_data_.enemies);
|
||||||
|
|
||||||
@@ -237,9 +240,10 @@ void MapEditor::exit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restaurar prompt de la consola y limpiar estado
|
// Restaurar prompt y scope de la consola
|
||||||
selected_enemy_ = -1;
|
selected_enemy_ = -1;
|
||||||
Console::get()->setPrompt("> ");
|
Console::get()->setPrompt("> ");
|
||||||
|
Console::get()->setScope("");
|
||||||
drag_ = {};
|
drag_ = {};
|
||||||
statusbar_.reset();
|
statusbar_.reset();
|
||||||
room_.reset();
|
room_.reset();
|
||||||
|
|||||||
@@ -50,6 +50,20 @@ Game::Game(Mode mode)
|
|||||||
current_room_(Defaults::Game::Room::INITIAL),
|
current_room_(Defaults::Game::Room::INITIAL),
|
||||||
spawn_data_(Player::SpawnData(Defaults::Game::Player::SPAWN_X, Defaults::Game::Player::SPAWN_Y, 0, 0, 0, Player::State::ON_GROUND, Defaults::Game::Player::SPAWN_FLIP)) {
|
spawn_data_(Player::SpawnData(Defaults::Game::Player::SPAWN_X, Defaults::Game::Player::SPAWN_Y, 0, 0, 0, Player::State::ON_GROUND, Defaults::Game::Player::SPAWN_FLIP)) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
// Validar que la room de debug existe; si no, fallback a la default
|
||||||
|
if (Resource::List::get()->get(current_room_).empty()) {
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Debug room %s not found, using default", current_room_.c_str());
|
||||||
|
current_room_ = Defaults::Game::Room::INITIAL;
|
||||||
|
spawn_data_ = Player::SpawnData(Defaults::Game::Player::SPAWN_X, Defaults::Game::Player::SPAWN_Y, 0, 0, 0, Player::State::ON_GROUND, Defaults::Game::Player::SPAWN_FLIP);
|
||||||
|
auto ss = Debug::get()->getSpawnSettings();
|
||||||
|
ss.room = current_room_;
|
||||||
|
Debug::get()->setSpawnSettings(ss);
|
||||||
|
Debug::get()->saveToFile();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Crea objetos e inicializa variables
|
// Crea objetos e inicializa variables
|
||||||
ItemTracker::init();
|
ItemTracker::init();
|
||||||
demoInit();
|
demoInit();
|
||||||
|
|||||||
@@ -444,3 +444,7 @@ auto Console::getVisibleHeight() -> int {
|
|||||||
if (status_ == Status::HIDDEN) { return 0; }
|
if (status_ == Status::HIDDEN) { return 0; }
|
||||||
return static_cast<int>(y_ + height_);
|
return static_cast<int>(y_ + height_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scope de comandos
|
||||||
|
void Console::setScope(const std::string& scope) { registry_.setScope(scope); }
|
||||||
|
auto Console::getScope() const -> std::string { return registry_.getScope(); }
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ class Console {
|
|||||||
// Prompt configurable (por defecto "> ")
|
// Prompt configurable (por defecto "> ")
|
||||||
void setPrompt(const std::string& prompt) { prompt_ = prompt; }
|
void setPrompt(const std::string& prompt) { prompt_ = prompt; }
|
||||||
|
|
||||||
|
// Scope de comandos (filtra help y tab completion)
|
||||||
|
void setScope(const std::string& scope);
|
||||||
|
[[nodiscard]] auto getScope() const -> std::string;
|
||||||
|
|
||||||
// Callback llamado al abrir (true) o cerrar (false) la consola
|
// Callback llamado al abrir (true) o cerrar (false) la consola
|
||||||
std::function<void(bool)> on_toggle;
|
std::function<void(bool)> on_toggle;
|
||||||
|
|
||||||
|
|||||||
@@ -1091,6 +1091,17 @@ void CommandRegistry::load(const std::string& yaml_path) {
|
|||||||
const std::string category = cat_node["name"].get_value<std::string>();
|
const std::string category = cat_node["name"].get_value<std::string>();
|
||||||
const bool cat_debug_only = cat_node.contains("debug_only") && cat_node["debug_only"].get_value<bool>();
|
const bool cat_debug_only = cat_node.contains("debug_only") && cat_node["debug_only"].get_value<bool>();
|
||||||
|
|
||||||
|
// Scopes por defecto de la categoría
|
||||||
|
std::vector<std::string> cat_scopes;
|
||||||
|
if (cat_node.contains("scope")) {
|
||||||
|
const auto& scope_node = cat_node["scope"];
|
||||||
|
if (scope_node.is_sequence()) {
|
||||||
|
for (const auto& s : scope_node) { cat_scopes.push_back(s.get_value<std::string>()); }
|
||||||
|
} else {
|
||||||
|
cat_scopes.push_back(scope_node.get_value<std::string>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!cat_node.contains("commands")) { continue; }
|
if (!cat_node.contains("commands")) { continue; }
|
||||||
|
|
||||||
for (const auto& cmd_node : cat_node["commands"]) {
|
for (const auto& cmd_node : cat_node["commands"]) {
|
||||||
@@ -1106,6 +1117,20 @@ void CommandRegistry::load(const std::string& yaml_path) {
|
|||||||
def.help_hidden = cmd_node.contains("help_hidden") && cmd_node["help_hidden"].get_value<bool>();
|
def.help_hidden = cmd_node.contains("help_hidden") && cmd_node["help_hidden"].get_value<bool>();
|
||||||
def.dynamic_completions = cmd_node.contains("dynamic_completions") && cmd_node["dynamic_completions"].get_value<bool>();
|
def.dynamic_completions = cmd_node.contains("dynamic_completions") && cmd_node["dynamic_completions"].get_value<bool>();
|
||||||
|
|
||||||
|
// Scopes: del comando, o hereda de la categoría, o "global" por defecto
|
||||||
|
if (cmd_node.contains("scope")) {
|
||||||
|
const auto& scope_node = cmd_node["scope"];
|
||||||
|
if (scope_node.is_sequence()) {
|
||||||
|
for (const auto& s : scope_node) { def.scopes.push_back(s.get_value<std::string>()); }
|
||||||
|
} else {
|
||||||
|
def.scopes.push_back(scope_node.get_value<std::string>());
|
||||||
|
}
|
||||||
|
} else if (!cat_scopes.empty()) {
|
||||||
|
def.scopes = cat_scopes;
|
||||||
|
} else {
|
||||||
|
def.scopes.push_back("global");
|
||||||
|
}
|
||||||
|
|
||||||
// Completions estáticas
|
// Completions estáticas
|
||||||
if (cmd_node.contains("completions")) {
|
if (cmd_node.contains("completions")) {
|
||||||
auto completions_node = cmd_node["completions"];
|
auto completions_node = cmd_node["completions"];
|
||||||
@@ -1208,13 +1233,40 @@ auto CommandRegistry::generateTerminalHelp() const -> std::string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto CommandRegistry::generateConsoleHelp() const -> std::string {
|
auto CommandRegistry::generateConsoleHelp() const -> std::string {
|
||||||
|
if (!active_scope_.empty()) {
|
||||||
|
// Con scope activo: listar solo los comandos de ese scope + global
|
||||||
|
std::string cmds;
|
||||||
|
std::string shortcuts;
|
||||||
|
|
||||||
|
for (const auto& cmd : commands_) {
|
||||||
|
if (cmd.help_hidden) { continue; }
|
||||||
|
if (!isCommandVisible(cmd)) { continue; }
|
||||||
|
|
||||||
|
std::string kw_lower = cmd.keyword;
|
||||||
|
std::ranges::transform(kw_lower, kw_lower.begin(), ::tolower);
|
||||||
|
|
||||||
|
if (!cmds.empty()) { cmds += ", "; }
|
||||||
|
cmds += kw_lower;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string result = active_scope_ + " commands:\n" + cmds + "\n";
|
||||||
|
|
||||||
|
// Atajos de teclado del editor
|
||||||
|
if (active_scope_ == "editor") {
|
||||||
|
result += "\nkeys: 9=editor 8=grid e=eraser m=map";
|
||||||
|
}
|
||||||
|
|
||||||
|
result += "\n-- more info on the terminal";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sin scope: formato original (release + debug)
|
||||||
std::string release_cmds;
|
std::string release_cmds;
|
||||||
std::string debug_cmds;
|
std::string debug_cmds;
|
||||||
|
|
||||||
for (const auto& cmd : commands_) {
|
for (const auto& cmd : commands_) {
|
||||||
if (cmd.help_hidden) { continue; }
|
if (cmd.help_hidden) { continue; }
|
||||||
|
|
||||||
// Convertir keyword a minúsculas para la lista
|
|
||||||
std::string kw_lower = cmd.keyword;
|
std::string kw_lower = cmd.keyword;
|
||||||
std::ranges::transform(kw_lower, kw_lower.begin(), ::tolower);
|
std::ranges::transform(kw_lower, kw_lower.begin(), ::tolower);
|
||||||
|
|
||||||
@@ -1247,10 +1299,22 @@ auto CommandRegistry::getCompletions(const std::string& path) const -> std::vect
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Comprueba si un comando es visible en el scope activo
|
||||||
|
auto CommandRegistry::isCommandVisible(const CommandDef& cmd) const -> bool {
|
||||||
|
if (cmd.hidden) { return false; }
|
||||||
|
if (active_scope_.empty()) { return true; } // Sin filtro, todo visible
|
||||||
|
|
||||||
|
// Un comando es visible si pertenece al scope activo o al scope "global"
|
||||||
|
for (const auto& s : cmd.scopes) {
|
||||||
|
if (s == active_scope_ || s == "global") { return true; }
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto CommandRegistry::getVisibleKeywords() const -> std::vector<std::string> {
|
auto CommandRegistry::getVisibleKeywords() const -> std::vector<std::string> {
|
||||||
std::vector<std::string> result;
|
std::vector<std::string> result;
|
||||||
for (const auto& cmd : commands_) {
|
for (const auto& cmd : commands_) {
|
||||||
if (!cmd.hidden) {
|
if (isCommandVisible(cmd)) {
|
||||||
result.push_back(cmd.keyword);
|
result.push_back(cmd.keyword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ struct CommandDef {
|
|||||||
bool debug_only{false};
|
bool debug_only{false};
|
||||||
bool help_hidden{false};
|
bool help_hidden{false};
|
||||||
bool dynamic_completions{false};
|
bool dynamic_completions{false};
|
||||||
|
std::vector<std::string> scopes; // Ámbitos: "global", "game", "editor", "debug"
|
||||||
std::unordered_map<std::string, std::vector<std::string>> completions;
|
std::unordered_map<std::string, std::vector<std::string>> completions;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,9 +41,11 @@ class CommandRegistry {
|
|||||||
[[nodiscard]] auto generateTerminalHelp() const -> std::string;
|
[[nodiscard]] auto generateTerminalHelp() const -> std::string;
|
||||||
[[nodiscard]] auto generateConsoleHelp() const -> std::string;
|
[[nodiscard]] auto generateConsoleHelp() const -> std::string;
|
||||||
|
|
||||||
|
// Scope activo (filtra comandos visibles en help y tab completion)
|
||||||
|
void setScope(const std::string& scope) { active_scope_ = scope; }
|
||||||
|
[[nodiscard]] auto getScope() const -> const std::string& { return active_scope_; }
|
||||||
|
|
||||||
// TAB completion
|
// TAB completion
|
||||||
// Devuelve las opciones de completado para un path dado (ej: "SHADER", "SHADER PRESET")
|
|
||||||
// Combina completions estáticas del YAML con dinámicas registradas en C++
|
|
||||||
[[nodiscard]] auto getCompletions(const std::string& path) const -> std::vector<std::string>;
|
[[nodiscard]] auto getCompletions(const std::string& path) const -> std::vector<std::string>;
|
||||||
[[nodiscard]] auto getVisibleKeywords() const -> std::vector<std::string>;
|
[[nodiscard]] auto getVisibleKeywords() const -> std::vector<std::string>;
|
||||||
|
|
||||||
@@ -51,6 +54,8 @@ class CommandRegistry {
|
|||||||
std::unordered_map<std::string, CommandHandler> handlers_;
|
std::unordered_map<std::string, CommandHandler> handlers_;
|
||||||
std::unordered_map<std::string, std::vector<std::string>> completions_map_;
|
std::unordered_map<std::string, std::vector<std::string>> completions_map_;
|
||||||
std::unordered_map<std::string, DynamicCompletionProvider> dynamic_providers_;
|
std::unordered_map<std::string, DynamicCompletionProvider> dynamic_providers_;
|
||||||
|
std::string active_scope_; // Scope activo ("" = sin filtro, muestra todo)
|
||||||
|
|
||||||
void registerHandlers();
|
void registerHandlers();
|
||||||
|
[[nodiscard]] auto isCommandVisible(const CommandDef& cmd) const -> bool;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user