Modified methods to take separate arguments instead of a vector of args

This commit is contained in:
Malcolm Roberts 2024-05-14 16:25:06 -05:00
parent 0c06151b0b
commit 94b877e87d
7 changed files with 86 additions and 40 deletions

Binary file not shown.

View File

@ -53,44 +53,46 @@ unsigned long MrBotApiType::GetActorIdByName(const std::string &actorName, bool
// Members
bool MrBotApiType::Version(const std::vector<std::string> &args, LSOBJECT &dest)
{
dest.ConstCharPtr = "0.1.0";
constexpr const char *version = "0.1.0";
log << "MrBotApiType::Version: " << version << std::endl;
dest.ConstCharPtr = version;
dest.Type = pStringType;
return true;
}
// Methods
bool MrBotApiType::ClickActorByName(const std::vector<std::string> &args)
bool MrBotApiType::ClickActorByName(const std::string name)
{
if (args.size() != 1)
if (name.empty())
{
logw << "MrBotApiType::ClickActorByName: Expected 1 argument, got " << args.size() << std::endl;
logw << "MrBotApiType::ClickActorByName: Actor name is empty" << std::endl;
return false;
}
const auto actorId = GetActorIdByName(args[0]);
const auto actorId = GetActorIdByName(name);
if (actorId == -1)
{
logw << "MrBotApiType::ClickActorByName: Actor not found: " << args[0] << std::endl;
logw << "MrBotApiType::ClickActorByName: Actor not found: " << name << std::endl;
return false;
}
return ClickActorById({std::to_string(actorId)});
}
bool MrBotApiType::ClickActorById(const std::vector<std::string> &args)
bool MrBotApiType::ClickActorById(const string id)
{
if (args.size() != 1)
if (id.empty())
{
logw << "MrBotApiType::ClickActorById: Expected 1 argument, got " << args.size() << std::endl;
logw << "MrBotApiType::ClickActorById: Actor id is empty" << std::endl;
return false;
}
log << "MrBotApiType::ClickActorById " << args[0] << std::endl;
const auto actor = ExtensionTLOs::Actor().GetActorById(std::stoul(args[0]));
log << "MrBotApiType::ClickActorById " << id << std::endl;
const auto actor = ExtensionTLOs::Actor().GetActorById(std::stoul(id));
if (!actor.has_value())
{
logw << "MrBotApiType::ClickActorById: Actor not found: " << args[0] << std::endl;
logw << "MrBotApiType::ClickActorById: Actor not found: " << id << std::endl;
return false;
}
@ -100,26 +102,29 @@ bool MrBotApiType::ClickActorById(const std::vector<std::string> &args)
return true;
}
bool MrBotApiType::ApplyVerb(const std::vector<std::string> &args)
bool MrBotApiType::ApplyVerb(const string actorName, const string verb)
{
if (args.size() != 2)
if (actorName.empty() || verb.empty())
{
logw << "MrBotApiType::ApplyVerb: Expected 2 arguments, got " << args.size() << std::endl;
logw << "MrBotApiType::ApplyVerb: Actor name or verb is empty" << std::endl;
return false;
}
const auto actorId = GetActorIdByName(args[0]);
const auto actorId = GetActorIdByName(actorName);
if (actorId == -1)
{
logw << "MrBotApiType::ApplyVerb: Actor not found: " << args[0] << std::endl;
logw << "MrBotApiType::ApplyVerb: Actor not found: " << actorName << std::endl;
return false;
}
const auto verb = args[1];
const auto command = "eq2execute apply_verb " + std::to_string(actorId) + " \"" + verb + "\"";
log << "MrBotApiType::ApplyVerb: " << command << std::endl;
const auto response = pISInterface->ExecuteCommand(command.c_str());
return response == 0;
}
bool MrBotApiType::ConversationBubble(const string option)
{
return false;
}

View File

@ -2,9 +2,63 @@
#include <ISXDK.h>
#include <memory>
#include <tuple>
#include <vector>
#include <string>
#include <sstream>
#include <functional>
#include <type_traits>
#include <unordered_map>
#include "../isxeq2/ExtensionTLOs.h"
// Helper to get the number of arguments of a method
template <typename T>
struct function_traits;
template <typename R, typename C, typename... Args>
struct function_traits<R (C::*)(Args...)>
{
static constexpr std::size_t arity = sizeof...(Args);
using arg_tuple = std::tuple<Args...>;
};
template <typename R, typename C, typename... Args>
struct function_traits<R (C::*)(Args...) const>
{
static constexpr std::size_t arity = sizeof...(Args);
using arg_tuple = std::tuple<Args...>;
};
// A helper function to convert an array of C-strings to a tuple of strings.
template <typename Tuple, std::size_t... I>
Tuple array_to_tuple_impl(char *argv[], std::index_sequence<I...>)
{
return Tuple{std::string(argv[I])...};
}
template <typename Tuple>
Tuple array_to_tuple(char *argv[])
{
return array_to_tuple_impl<Tuple>(argv, std::make_index_sequence<std::tuple_size<Tuple>::value>{});
}
#define ADD_METHOD_TO_MAP(EnumType, methodName) \
AddMethod(static_cast<DWORD>(EnumType::methodName), const_cast<char *>(#methodName)); \
methodMap[EnumType::methodName] = [this](int argc, char *argv[]) { \
constexpr auto expectedArgc = function_traits<decltype(&std::remove_pointer_t<decltype(this)>::methodName)>::arity; \
if (argc != expectedArgc) \
{ \
logw << "MrBotApiType::GetMethod: " #methodName ": Expected " << expectedArgc \
<< " argument(s), got " << argc << std::endl; \
return false; \
} \
log << "MrBotApiType::GetMethod: " #methodName << std::endl; \
using ArgsTuple = typename function_traits<decltype(&std::remove_pointer_t<decltype(this)>::methodName)>::arg_tuple; \
auto args_tuple = array_to_tuple<ArgsTuple>(argv); \
return std::apply([this](auto &&...args) { return this->methodName(std::forward<decltype(args)>(args)...); }, args_tuple); \
}
#define ADD_MEMBER_TO_MAP(EnumType, memberName, expectedArgc) \
AddMember(static_cast<DWORD>(EnumType::memberName), const_cast<char *>(#memberName)); \
memberMap[EnumType::memberName] = [this](int argc, char *argv[], LSOBJECT &dest) { \
@ -19,26 +73,12 @@
return memberName(args, dest); \
}
#define ADD_METHOD_TO_MAP(EnumType, methodName, expectedArgc) \
AddMethod(static_cast<DWORD>(EnumType::methodName), const_cast<char *>(#methodName)); \
methodMap[EnumType::methodName] = [this](int argc, char *argv[]) { \
if (argc != expectedArgc) \
{ \
logw << "MrBotApiType::GetMethod: " #methodName ": Expected " << expectedArgc \
<< " argument(s), got " << argc << std::endl; \
return false; \
} \
log << "MrBotApiType::GetMethod: " #methodName << std::endl; \
std::vector<std::string> args(argv, argv + argc); \
return methodName(args); \
}
class MrBotApiType : public LSTypeDefinition
{
public:
enum class MrBotApiTypeMembers
{
Version
Version,
};
enum class MrBotApiTypeMethods
@ -51,9 +91,9 @@ public:
MrBotApiType() : LSTypeDefinition(const_cast<char *>("mrbotapi"))
{
ADD_MEMBER_TO_MAP(MrBotApiTypeMembers, Version, 0);
ADD_METHOD_TO_MAP(MrBotApiTypeMethods, ClickActorByName, 1);
ADD_METHOD_TO_MAP(MrBotApiTypeMethods, ClickActorById, 1);
ADD_METHOD_TO_MAP(MrBotApiTypeMethods, ApplyVerb, 2);
ADD_METHOD_TO_MAP(MrBotApiTypeMethods, ClickActorByName);
ADD_METHOD_TO_MAP(MrBotApiTypeMethods, ClickActorById);
ADD_METHOD_TO_MAP(MrBotApiTypeMethods, ApplyVerb);
}
virtual bool GetMember(LSOBJECTDATA ObjectData, PLSTYPEMEMBER pMember, int argc, char *argv[], LSOBJECT &Dest);
@ -94,9 +134,10 @@ private:
// Members
bool Version(const std::vector<std::string> &args, LSOBJECT &dest);
// Methods
bool ClickActorByName(const std::vector<std::string> &args);
bool ClickActorById(const std::vector<std::string> &args);
bool ApplyVerb(const std::vector<std::string> &args);
bool ClickActorByName(const string name);
bool ClickActorById(const string id);
bool ApplyVerb(const string actorName, const string verb);
bool ConversationBubble(const string option);
static unique_ptr<MrBotApiType> pMrBotApi;
using MethodFunc = std::function<bool(int argc, char *argv[])>;