refactor(cli): migrate command management to CommandRegistry

- Replaced direct command handling in ModernCLI with a centralized CommandRegistry singleton.
- Removed SetupCommands method and associated command handler logic, simplifying command execution and registration.
- Updated ShowHelp and ShowCommandSummary methods to utilize CommandRegistry for fetching command metadata and descriptions.

Benefits:
- Streamlined command management, enhancing maintainability and clarity in the CLI structure.
- Improved command registration and execution consistency through a unified registry approach.
This commit is contained in:
scawful
2025-10-12 01:41:24 -04:00
parent 55a28661af
commit 2ccd49f9e6
2 changed files with 54 additions and 36 deletions

View File

@@ -1,5 +1,5 @@
#include "cli/cli.h" #include "cli/cli.h"
#include "cli/handlers/command_handlers.h" #include "cli/service/command_registry.h"
#include "cli/z3ed_ascii_logo.h" #include "cli/z3ed_ascii_logo.h"
#include "absl/strings/str_join.h" #include "absl/strings/str_join.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
@@ -11,14 +11,12 @@ namespace yaze {
namespace cli { namespace cli {
ModernCLI::ModernCLI() { ModernCLI::ModernCLI() {
SetupCommands(); // Commands are now managed by CommandRegistry singleton
// SetupCommands() is no longer needed
} }
void ModernCLI::SetupCommands() { void ModernCLI::SetupCommands() {
auto handlers = handlers::CreateAllCommandHandlers(); // No-op: CommandRegistry handles this automatically
for (auto& handler : handlers) {
commands_[handler->GetName()] = std::move(handler);
}
} }
absl::Status ModernCLI::Run(int argc, char* argv[]) { absl::Status ModernCLI::Run(int argc, char* argv[]) {
@@ -56,13 +54,17 @@ absl::Status ModernCLI::Run(int argc, char* argv[]) {
return absl::OkStatus(); return absl::OkStatus();
} }
auto it = commands_.find(args[0]); // Use CommandRegistry for unified command execution
if (it != commands_.end()) { auto& registry = CommandRegistry::Instance();
std::string command_name = args[0];
std::vector<std::string> command_args(args.begin() + 1, args.end()); std::vector<std::string> command_args(args.begin() + 1, args.end());
return it->second->Run(command_args, nullptr);
if (registry.HasCommand(command_name)) {
return registry.Execute(command_name, command_args, nullptr);
} }
return absl::NotFoundError(absl::StrCat("Unknown command: ", args[0])); return absl::NotFoundError(absl::StrCat("Unknown command: ", command_name));
} }
void ModernCLI::ShowHelp() { void ModernCLI::ShowHelp() {
@@ -97,19 +99,26 @@ void ModernCLI::ShowHelp() {
void ModernCLI::ShowCategoryHelp(const std::string& category) const { void ModernCLI::ShowCategoryHelp(const std::string& category) const {
using namespace ftxui; using namespace ftxui;
std::vector<std::vector<std::string>> rows; auto& registry = CommandRegistry::Instance();
rows.push_back({"Subcommand", "Summary", "TODO/Reference"});
auto it = commands_.find(category); std::vector<std::vector<std::string>> rows;
if (it != commands_.end()) { rows.push_back({"Command", "Description", "Requirements"});
const auto& metadata = it->second->Describe();
for (const auto& entry : metadata.entries) { auto commands = registry.GetCommandsInCategory(category);
rows.push_back({entry.name, entry.description, entry.todo_reference}); for (const auto& cmd_name : commands) {
auto* metadata = registry.GetMetadata(cmd_name);
if (metadata) {
std::string requirements;
if (metadata->requires_rom) requirements += "ROM ";
if (metadata->requires_grpc) requirements += "gRPC ";
if (requirements.empty()) requirements = "";
rows.push_back({cmd_name, metadata->description, requirements});
} }
} }
if (rows.size() == 1) { if (rows.size() == 1) {
rows.push_back({"", "No metadata registered", ""}); rows.push_back({"", "No commands in this category", ""});
} }
Table detail(rows); Table detail(rows);
@@ -121,7 +130,7 @@ void ModernCLI::ShowCategoryHelp(const std::string& category) const {
separator(), separator(),
detail.Render(), detail.Render(),
separator(), separator(),
text("Command handlers can expose TODO references via Describe().") | dim | center text("Commands are auto-registered from CommandRegistry") | dim | center
}); });
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(layout)); auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(layout));
@@ -131,24 +140,37 @@ void ModernCLI::ShowCategoryHelp(const std::string& category) const {
void ModernCLI::ShowCommandSummary() const { void ModernCLI::ShowCommandSummary() const {
using namespace ftxui; using namespace ftxui;
std::vector<Element> tiles; auto& registry = CommandRegistry::Instance();
for (const auto& [name, handler] : commands_) {
const auto summary = handler->Describe(); std::vector<std::vector<std::string>> rows;
tiles.push_back( rows.push_back({"Command", "Category", "Description"});
vbox({
text(summary.display_name.empty() ? name : summary.display_name) | bold, auto categories = registry.GetCategories();
separator(), for (const auto& category : categories) {
text(summary.summary), auto commands = registry.GetCommandsInCategory(category);
text(absl::StrCat("TODO: ", summary.todo_reference)) | dim for (const auto& cmd_name : commands) {
}) | borderRounded); auto* metadata = registry.GetMetadata(cmd_name);
if (metadata) {
rows.push_back({cmd_name, metadata->category, metadata->description});
} }
}
}
if (rows.size() == 1) {
rows.push_back({"", "", "No commands registered"});
}
Table command_table(rows);
command_table.SelectAll().Border(LIGHT);
command_table.SelectRow(0).Decorate(bold);
auto layout = vbox({ auto layout = vbox({
text("Z3ED Command Summary") | bold | center, text("Z3ED Command Summary") | bold | center,
separator(), separator(),
tiles.empty() ? text("No commands registered.") | dim | center command_table.Render(),
: vbox(tiles),
separator(), separator(),
text(absl::StrFormat("Total: %zu commands across %zu categories",
registry.Count(), categories.size())) | center | dim,
text("Use `z3ed --tui` for interactive command palette.") | center | dim text("Use `z3ed --tui` for interactive command palette.") | center | dim
}); });

View File

@@ -13,10 +13,6 @@
#include "app/snes.h" #include "app/snes.h"
#include "util/macro.h" #include "util/macro.h"
#include "cli/service/resources/command_handler.h"
#include <map>
#include <memory>
// Forward declarations // Forward declarations
namespace ftxui { namespace ftxui {
class ScreenInteractive; class ScreenInteractive;
@@ -42,7 +38,7 @@ class ModernCLI {
void ShowCategoryHelp(const std::string& category) const; void ShowCategoryHelp(const std::string& category) const;
void ShowCommandSummary() const; void ShowCommandSummary() const;
std::map<std::string, std::unique_ptr<resources::CommandHandler>> commands_; // Commands are now managed by CommandRegistry singleton (no member needed)
}; };
} // namespace cli } // namespace cli