From e30913b0184a267fbba36b2eda284934aecaf4bd Mon Sep 17 00:00:00 2001 From: modeco80 Date: Wed, 15 Jan 2025 19:25:31 -0500 Subject: [PATCH] tools/eupak: Refactor InfoTask to ITask pattern --- src/tools/eupak/main.cpp | 20 +++---------- src/tools/eupak/tasks/InfoTask.cpp | 48 +++++++++++++++++++++++++++++- src/tools/eupak/tasks/InfoTask.hpp | 33 +++++++++++++------- src/tools/eupak/tasks/Task.cpp | 2 +- src/tools/eupak/tasks/Task.hpp | 5 +++- 5 files changed, 78 insertions(+), 30 deletions(-) diff --git a/src/tools/eupak/main.cpp b/src/tools/eupak/main.cpp index 485a25d..9e237e4 100644 --- a/src/tools/eupak/main.cpp +++ b/src/tools/eupak/main.cpp @@ -25,16 +25,6 @@ int main(int argc, char** argv) { argparse::ArgumentParser parser("eupak", EUPAK_VERSION_STR); parser.add_description("Eupak (Europa Package Multi-Tool) v" EUPAK_VERSION_STR); - argparse::ArgumentParser infoParser("info", EUPAK_VERSION_STR, argparse::default_arguments::help); - infoParser.add_description("Print information about a package file."); - infoParser.add_argument("input") - .help("Input archive") - .metavar("ARCHIVE"); - - infoParser.add_argument("--verbose") - .help("Increase information output verbosity (print a list of files).") - .default_value(false) - .implicit_value(true); argparse::ArgumentParser extractParser("extract", EUPAK_VERSION_STR, argparse::default_arguments::help); extractParser.add_description("Extract a package file."); @@ -51,11 +41,11 @@ int main(int argc, char** argv) { .default_value(false) .implicit_value(true); - parser.add_subparser(infoParser); parser.add_subparser(extractParser); auto tasks = std::vector { - eupak::tasks::TaskFactory::CreateNamed("create", parser) + eupak::tasks::TaskFactory::CreateNamed("create", parser), + eupak::tasks::TaskFactory::CreateNamed("info", parser) }; try { @@ -82,7 +72,7 @@ int main(int argc, char** argv) { if(task->ShouldRun(parser)) { if(auto res = task->Parse(); res != 0) return res; - + return task->Run(); } } @@ -115,9 +105,7 @@ int main(int argc, char** argv) { eupak::tasks::InfoTask task; eupak::tasks::InfoTask::Arguments args; - args.verbose = infoParser.get("--verbose"); - args.inputPath = eupak::fs::path(infoParser.get("input")); - + return task.Run(std::move(args)); } diff --git a/src/tools/eupak/tasks/InfoTask.cpp b/src/tools/eupak/tasks/InfoTask.cpp index d7ae8a6..d65e5b3 100644 --- a/src/tools/eupak/tasks/InfoTask.cpp +++ b/src/tools/eupak/tasks/InfoTask.cpp @@ -6,19 +6,63 @@ // SPDX-License-Identifier: MIT // +#include #include #include #include #include #include +#include "argparse/argparse.hpp" #include "europa/structs/Pak.hpp" namespace eupak::tasks { constexpr static auto DATE_FORMAT = "%m/%d/%Y %r"; - int InfoTask::Run(Arguments&& args) { + InfoTask::InfoTask() + : parser("info", EUPAK_VERSION_STR, argparse::default_arguments::help) { + // clang-format off + parser + .add_description("Print information about a package file."); + parser + .add_argument("input") + .help("Input archive") + .metavar("ARCHIVE"); + + // FIXME: Probably just print this always, in a thinner format, but use + // the existing thicker format for verbosity. + parser + .add_argument("--verbose") + .help("Increase information output verbosity (print a list of files).") + .default_value(false) + .implicit_value(true); + // clang-format on + } + + void InfoTask::Init(argparse::ArgumentParser& parentParser) { + parentParser.add_subparser(parser); + } + + int InfoTask::Parse() { + auto& args = currentArgs; + + try { + args.verbose = parser.get("--verbose"); + args.inputPath = eupak::fs::path(parser.get("input")); + } catch(...) { + return 1; + } + + return 0; + } + + bool InfoTask::ShouldRun(argparse::ArgumentParser& parentParser) const { + return parentParser.is_subcommand_used("info"); + } + + int InfoTask::Run() { + const auto& args = currentArgs; std::ifstream ifs(args.inputPath.string(), std::ifstream::binary); if(!ifs) { @@ -72,4 +116,6 @@ namespace eupak::tasks { return 0; } + EUPAK_REGISTER_TASK("info", InfoTask); + } // namespace eupak::tasks \ No newline at end of file diff --git a/src/tools/eupak/tasks/InfoTask.hpp b/src/tools/eupak/tasks/InfoTask.hpp index 6021dce..20fa0ed 100644 --- a/src/tools/eupak/tasks/InfoTask.hpp +++ b/src/tools/eupak/tasks/InfoTask.hpp @@ -11,20 +11,31 @@ #include +#include "tasks/Task.hpp" + namespace eupak::tasks { - struct InfoTask { - - struct Arguments { - fs::path inputPath; - bool verbose; - }; - - - - int Run(Arguments&& args); + struct InfoTask : ITask { + struct Arguments { + fs::path inputPath; + bool verbose; }; -} + InfoTask(); + + void Init(argparse::ArgumentParser& parentParser) override; + + bool ShouldRun(argparse::ArgumentParser& parentParser) const override; + + int Parse() override; + + int Run() override; + + private: + argparse::ArgumentParser parser; + Arguments currentArgs; + }; + +} // namespace eupak::tasks #endif // EUROPA_EUPAK_TASKS_INFOTASK_HPP diff --git a/src/tools/eupak/tasks/Task.cpp b/src/tools/eupak/tasks/Task.cpp index 1ec511d..e7ae4a9 100644 --- a/src/tools/eupak/tasks/Task.cpp +++ b/src/tools/eupak/tasks/Task.cpp @@ -1,5 +1,5 @@ -#pragma once #include "Task.hpp" + #include namespace eupak::tasks { diff --git a/src/tools/eupak/tasks/Task.hpp b/src/tools/eupak/tasks/Task.hpp index 0aaa5e7..e2ae55a 100644 --- a/src/tools/eupak/tasks/Task.hpp +++ b/src/tools/eupak/tasks/Task.hpp @@ -32,7 +32,7 @@ namespace eupak::tasks { virtual int Run() = 0; }; - /// Creates tasks. + /// Creates ITask instances for clients. struct TaskFactory { using FactoryMethod = std::shared_ptr (*)(); @@ -49,6 +49,7 @@ namespace eupak::tasks { } }; + /// Helper template to register into the [TaskFactory]. template struct TaskFactoryRegister { TaskFactoryRegister(const std::string& name) { @@ -60,6 +61,8 @@ namespace eupak::tasks { } }; + /// Registers a task. Should be put in the .cpp implementation source file of the + /// task object itself. #define EUPAK_REGISTER_TASK(Name, TTask) \ static ::eupak::tasks::TaskFactoryRegister __register__##TTask(Name)