#pragma once #include "error.h" #include #include #include #include enum MoveDir { UP, RIGHT, DOWN, LEFT }; enum CommandArgType { STR, NUM, MOVDIR, STR_REST, NUM_ARR_REST }; struct NumArr { int* arr; int size; }; typedef union { char* str; int num; NumArr numArr; MoveDir dir; } CommandArg; struct Command { const std::string name; const std::function func; const std::function staticFunc; const int argc; CommandArgType* argTypes; std::any* module; }; class CommandsModule { private: std::vector commandList; std::vector splitCommand(std::string command); CommandArg* getCommandArgs(std::vector& args, const CommandArgType* argTypes, const int argc); const void echo(const CommandArg* argv); const void loadFile(const CommandArg* argv); std::string cwd; public: CommandsModule(); ~CommandsModule(); template void addCommand(std::string name, const void(T::*func)(const CommandArg*), const int argc, CommandArgType* argTypes, T* module); void addCommand(std::string name, const void(*func)(const CommandArg*), const int argc, CommandArgType* argTypes); template void addCommand(std::string name, const void(T::*func)(const CommandArg*), const int argc, std::vector argTypes, T* module); void addCommand(std::string name, const void(*func)(const CommandArg*), const int argc, std::vector argTypes); void addCommand(Command c); Command* lookupCommand(std::string name); void runCommand(std::string command); void runCommand(std::vector split); std::vector checkCommand(std::string command); Err checkCommand(std::vector split); }; // YES I KNOW THIS IS BAD // but it needs to be done this way template void CommandsModule::addCommand(std::string name, const void(T::*func)(const CommandArg*), const int argc, CommandArgType* argTypes, T* module) { Command c = {name, (const void*(std::any::*)(const CommandArg* argv)) func, nullptr, argc, argTypes, (std::any*)module}; addCommand(c); } template void CommandsModule::addCommand(std::string name, const void(T::*func)(const CommandArg*), const int argc, std::vector argTypes, T* module) { CommandArgType* argTypesArr = new CommandArgType[argc]; for(int i = 0; i < argc; i++) { argTypesArr[i] = argTypes[i]; } addCommand(name, func, argc, argTypesArr, module); }