#include "argsprocessor.h" #include "output_util.h" #include "filepath_util.h" #include #include ///////////////////////////////////////////////////////////////////////// static constexpr int DEFAULT_SCREEN_WIDTH = 1280; static constexpr int DEFAULT_SCREEN_HEIGHT = 720; static constexpr int DEFAULT_SPLITTING = 4; static const char * const DEFAULT_PATH = "."; ///////////////////////////////////////////////////////////////////////// ArgsProcessor::ArgsProcessor(int argc, char **argv) : image_splitting(DEFAULT_SPLITTING), game_resolution({DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT}), image_path(DEFAULT_PATH) { parse_result = tryConvertInput(argc, argv); } int ArgsProcessor::broken() const { return parse_result; } std::tuple ArgsProcessor::unpack() const { return {image_splitting, game_resolution, image_path}; } int ArgsProcessor::tryConvertInput(int argc, char **argv) { int error = iterateArgc(argc, argv); if (error) return error; if (image_path == DEFAULT_PATH && loaded_image_pathes.empty()) { // no path was given, loading random image from '.' const auto &[error, ret_path] = filepath::parsePath(image_path); if (error) return makeError(output::IMG_FAIL_MSG); loaded_image_pathes.insert(loaded_image_pathes.end(), ret_path.begin(), ret_path.end()); } image_path = filepath::randomChoice(loaded_image_pathes); return EXIT_SUCCESS; } bool ArgsProcessor::isFlag(const char *arg, const char *flag) const { return (strcmp(arg, flag) == 0); } int ArgsProcessor::iterateArgc(int argc, char **argv) { for (int current_arg = 1; current_arg < argc; ++current_arg) // current_arg = 0 is executable name { if (isFlag(argv[current_arg], output::HELP_FLAG)) return makeError(output::HELP_MSG); if (isFlag(argv[current_arg], output::SPLITTING_FLAG)) { int error = parseSplitting(current_arg, argc, argv); if (error) return error; ++current_arg; continue; } if (isFlag(argv[current_arg], output::RESOLUTION_FLAG)) { int error = parseResolution(current_arg, argc, argv); if (error) return error; ++current_arg; continue; } const auto &[error, ret_path] = filepath::parsePath(argv[current_arg]); if (error) continue; loaded_image_pathes.insert(loaded_image_pathes.end(), ret_path.begin(), ret_path.end()); } return EXIT_SUCCESS; } int ArgsProcessor::parseSplitting(int curr_arg, int argc, char **argv) { const int value_rg = curr_arg + 1; if (value_rg == argc) return makeError(output::SPLITTING_MSG); image_splitting = -1; if (std::isdigit(*argv[value_rg])) image_splitting = std::stoi(argv[value_rg]); if (image_splitting < 2) return makeError(output::SPLITTING_MSG); return EXIT_SUCCESS; } int ArgsProcessor::parseResolution(int curr_arg, int argc, char **argv) { const int value_rg = curr_arg + 1; if (value_rg == argc) return makeError(output::RESOLUTION_MSG); std::vector res = filepath::split(argv[value_rg], 'x'); // splitting argument by 'x' as in 600x900 if (res.size() < 2) return makeError(output::RESOLUTION_MSG); game_resolution = {-1, -1}; if (std::isdigit(*res[0].c_str()) && std::isdigit(*res[1].c_str())) game_resolution = {std::stoi(res[0].c_str()), std::stoi(res[1].c_str())}; if (game_resolution.x < 1 || game_resolution.y < 1) return makeError(output::RESOLUTION_MSG); return EXIT_SUCCESS; } int ArgsProcessor::makeError(const char* msg) const { std::cout << msg; return EXIT_FAILURE; }