Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow resources to retrieve the invoking resource of commands #3012

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
3 changes: 2 additions & 1 deletion code/client/citicore/console/Console.CommandHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class ConsoleCommand
{
private:
int m_token;
std::string m_resource = "internal";
ConsoleCommandManager* m_manager;

public:
Expand All @@ -30,7 +31,7 @@ class ConsoleCommand

using ConsoleCommandFunction = internal::ConsoleCommandFunction<decltype(functionRef)>;

m_token = m_manager->Register(name, [=](ConsoleExecutionContext& context) {
m_token = m_manager->Register(name, m_resource, [=](ConsoleExecutionContext& context) {
return ConsoleCommandFunction::Call(functionRef, context);
}, ConsoleCommandFunction::kNumArguments);
}
Expand Down
12 changes: 6 additions & 6 deletions code/client/citicore/console/Console.Commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@
#include <IteratorView.h>

ConsoleCommandManager::ConsoleCommandManager(console::Context* parentContext)
: m_parentContext(parentContext), m_curToken(0)
: m_parentContext(parentContext), m_curToken(0)
{
}

ConsoleCommandManager::~ConsoleCommandManager()
{
}

int ConsoleCommandManager::Register(const std::string& name, const THandler& handler, size_t arity)
int ConsoleCommandManager::Register(const std::string& name, std::string resource, const THandler& handler, size_t arity)
{
std::unique_lock<std::shared_mutex> lock(m_mutex);

int token = m_curToken.fetch_add(1);
m_entries.insert({name, Entry{name, handler, token, arity}});
m_entries.insert({ name, Entry{ name, handler, resource, token, arity } });

return token;
}
Expand Down Expand Up @@ -55,7 +55,7 @@ void ConsoleCommandManager::Invoke(const std::string& commandString, const std::
return;
}

std::string command = arguments.Shift();
std::string command = arguments.Shift();

m_rawCommand = commandString;

Expand Down Expand Up @@ -98,7 +98,7 @@ void ConsoleCommandManager::InvokeDirect(const std::string& commandName, const P
// Don't print to the console if a remote client tried to execute an unknown command.
if (executionContext.empty())
{
console::Printf("cmd", "No such command %s.\n", commandName.c_str());
console::Printf("cmd", "No such command %s.\n", commandName.c_str());
}
return;
}
Expand Down Expand Up @@ -167,7 +167,7 @@ void ConsoleCommandManager::ForAllCommands2(const std::function<void(const conso
// loop through the commands
for (auto& command : m_entries)
{
console::CommandMetadata md{ command.first, command.second.arity };
console::CommandMetadata md{ command.first, command.second.resource, command.second.arity };
callback(md);
}
}
Expand Down
74 changes: 42 additions & 32 deletions code/client/citicore/console/Console.Commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ struct ConsoleExecutionContext
std::string contextRef;

inline ConsoleExecutionContext(const ProgramArguments&& arguments, const std::string& contextRef)
: arguments(arguments), contextRef(contextRef)
: arguments(arguments), contextRef(contextRef)
{
}
};
Expand All @@ -50,8 +50,8 @@ class CommandMetadata
{
}

inline CommandMetadata(const std::string& name, size_t arity)
: m_name(name), m_arity(arity)
inline CommandMetadata(const std::string& name, std::string resource, size_t arity)
: m_name(name), m_resource(resource), m_arity(arity)
{
}

Expand All @@ -65,13 +65,24 @@ class CommandMetadata
return m_name;
}

inline const auto GetResourceName() const
{
return m_resource;
}

inline const bool MatchResourceName(std::string resource) const
{
return m_resource == resource;
}

inline auto GetArity() const
{
return m_arity;
}

private:
std::string m_name;
std::string m_resource;
size_t m_arity = -1;
};
}
Expand All @@ -86,7 +97,7 @@ class ConsoleCommandManager

virtual ~ConsoleCommandManager();

virtual int Register(const std::string& name, const THandler& handler, size_t arity = -1);
virtual int Register(const std::string& name, std::string resource, const THandler& handler, size_t arity = -1);

virtual void Unregister(int token);

Expand Down Expand Up @@ -114,12 +125,13 @@ class ConsoleCommandManager
{
std::string name;
THandler function;
std::string resource;

int token;
size_t arity;

inline Entry(const std::string& name, const THandler& function, int token, size_t arity = -1)
: name(name), function(function), token(token), arity(arity)
inline Entry(const std::string& name, const THandler& function, std::string resource, int token, size_t arity = -1)
: name(name), function(function), resource(resource), token(token), arity(arity)
{
}
};
Expand All @@ -142,15 +154,15 @@ class ConsoleCommandManager
}
};

template <typename TArgument, typename TConstraint = void>
template<typename TArgument, typename TConstraint = void>
struct ConsoleArgumentTraits
{
using Less = std::less<TArgument>;
using Less = std::less<TArgument>;
using Greater = std::greater<TArgument>;
using Equal = std::equal_to<TArgument>;
using Equal = std::equal_to<TArgument>;
};

template <typename TArgument, typename TConstraint = void>
template<typename TArgument, typename TConstraint = void>
struct ConsoleArgumentName
{
inline static const char* Get()
Expand All @@ -159,23 +171,23 @@ struct ConsoleArgumentName
}
};

template <typename TArgument, typename TConstraint = void>
template<typename TArgument, typename TConstraint = void>
struct ConsoleArgumentType
{
static std::string Unparse(const TArgument& argument)
{
//static_assert(false, "Unknown ConsoleArgumentType unparse handler (try defining one?)");
// static_assert(false, "Unknown ConsoleArgumentType unparse handler (try defining one?)");
TArgument::__fatal();
}

static bool Parse(const std::string& input, TArgument* out)
{
//static_assert(false, "Unknown ConsoleArgumentType parse handler (try defining one?)");
// static_assert(false, "Unknown ConsoleArgumentType parse handler (try defining one?)");
TArgument::__fatal();
}
};

template <>
template<>
struct ConsoleArgumentType<std::string>
{
static std::string Unparse(const std::string& input)
Expand All @@ -190,7 +202,7 @@ struct ConsoleArgumentType<std::string>
}
};

template <>
template<>
struct ConsoleArgumentName<std::string>
{
inline static const char* Get()
Expand All @@ -199,7 +211,7 @@ struct ConsoleArgumentName<std::string>
}
};

template <typename TArgument>
template<typename TArgument>
struct ConsoleArgumentType<TArgument, typename std::enable_if<std::is_same<TArgument, bool>::value>::type>
{
static std::string Unparse(const TArgument& input)
Expand Down Expand Up @@ -247,7 +259,7 @@ struct ConsoleArgumentType<TArgument, typename std::enable_if<std::is_same<TArgu
}
};

template <typename TArgument>
template<typename TArgument>
struct ConsoleArgumentType<TArgument, std::enable_if_t<std::is_integral<TArgument>::value && !std::is_same<TArgument, bool>::value>>
{
static std::string Unparse(const TArgument& input)
Expand All @@ -271,7 +283,7 @@ struct ConsoleArgumentType<TArgument, std::enable_if_t<std::is_integral<TArgumen
}
};

template <typename TArgument>
template<typename TArgument>
struct ConsoleArgumentType<TArgument, std::enable_if_t<std::is_floating_point<TArgument>::value>>
{
static std::string Unparse(const TArgument& input)
Expand Down Expand Up @@ -301,7 +313,6 @@ class ExternalContext : public std::any
ExternalContext(const std::any& any)
: std::any(any)
{

}
};
#else
Expand All @@ -316,13 +327,13 @@ class ExternalContext

namespace internal
{
template <typename TArgument>
template<typename TArgument>
inline bool ParseArgument(const std::string& input, TArgument* out)
{
return ConsoleArgumentType<TArgument>::Parse(input, out);
}

template <typename TArgument>
template<typename TArgument>
inline bool ParseArgument(const ConsoleExecutionContext& context, int argInput, TArgument* out)
{
return ConsoleArgumentType<TArgument>::Parse(context.arguments[argInput], out);
Expand Down Expand Up @@ -351,25 +362,25 @@ inline bool ParseArgument<ExternalContext>(const ConsoleExecutionContext& contex
return true;
}

template <typename TArgument, int Iterator>
template<typename TArgument, int Iterator>
constexpr int AddOneArg = Iterator + 1;

template <int Iterator>
template<int Iterator>
int AddOneArg<ExternalContext, Iterator> = Iterator;

template <typename TArgument>
template<typename TArgument>
std::string UnparseArgument(const TArgument& input)
{
return ConsoleArgumentType<TArgument>::Unparse(input);
}

template <class TFunc>
template<class TFunc>
struct ConsoleCommandFunction
{
constexpr static const size_t kNumArguments = -1;
};

template <typename... Args>
template<typename... Args>
struct ConsoleCommandFunction<std::function<void(Args...)>>
{
using TFunc = std::function<void(Args...)>;
Expand Down Expand Up @@ -409,9 +420,8 @@ struct ConsoleCommandFunction<std::function<void(Args...)>>
}

public:

// non-terminator iterator
template <size_t Iterator, size_t ArgIterator, typename TupleType>
template<size_t Iterator, size_t ArgIterator, typename TupleType>
static std::enable_if_t<(Iterator < sizeof...(Args)), bool> CallInternal(TFunc func, ConsoleExecutionContext& context, TupleType tuple)
{
// the type of the current argument
Expand All @@ -421,9 +431,9 @@ struct ConsoleCommandFunction<std::function<void(Args...)>>
if (ParseArgument(context, ArgIterator, &argument))
{
return CallInternal<Iterator + 1, AddOneArg<ArgType, ArgIterator>>(
func,
context,
std::tuple_cat(std::move(tuple), std::forward_as_tuple(std::forward<ArgType>(argument))));
func,
context,
std::tuple_cat(std::move(tuple), std::forward_as_tuple(std::forward<ArgType>(argument))));
}

context.errorBuffer << "Could not convert argument " << std::to_string(Iterator) << " (" << context.arguments[Iterator] << ") to " << typeid(ArgType).name() << std::endl;
Expand All @@ -432,7 +442,7 @@ struct ConsoleCommandFunction<std::function<void(Args...)>>
}

// terminator
template <size_t Iterator, size_t ArgIterator, typename TupleType>
template<size_t Iterator, size_t ArgIterator, typename TupleType>
static std::enable_if_t<(Iterator == sizeof...(Args)), bool> CallInternal(TFunc func, ConsoleExecutionContext& context, TupleType tuple)
{
apply(func, std::move(tuple));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@
struct CommandObject
{
std::string name;
std::string resource;
int32_t arity;

CommandObject(const std::string& name, size_t arity)
: name(name), arity(arity)
CommandObject(const std::string& name, std::string resource, size_t arity)
: name(name), resource(resource), arity(arity)
{

}

MSGPACK_DEFINE_MAP(name, arity);
MSGPACK_DEFINE_MAP(name, resource, arity);
};

static InitFunction initFunction([] ()
Expand Down Expand Up @@ -125,6 +125,7 @@ static InitFunction initFunction([] ()
{
auto resourceManager = resource->GetManager();
auto consoleCxt = resourceManager->GetComponent<console::Context>();
std::string resourceName = resource->GetName();

outerRefs[commandName] = commandRef;

Expand All @@ -139,7 +140,7 @@ static InitFunction initFunction([] ()
seGetCurrentContext()->AddAccessControlEntry(se::Principal{ "builtin.everyone" }, se::Object{ "command." + commandName }, se::AccessType::Allow);
}

int commandToken = consoleCxt->GetCommandManager()->Register(commandName, [=](ConsoleExecutionContext& context)
int commandToken = consoleCxt->GetCommandManager()->Register(commandName, resourceName, [=](ConsoleExecutionContext& context)
{
try
{
Expand All @@ -159,7 +160,7 @@ static InitFunction initFunction([] ()
resource->OnStop.Connect([consoleCxt, commandToken]()
{
consoleCxt->GetCommandManager()->Unregister(commandToken);
}, INT32_MAX);
},INT32_MAX);
}
}
});
Expand All @@ -181,14 +182,38 @@ static InitFunction initFunction([] ()

consoleCxt->GetCommandManager()->ForAllCommands2([&commandList](const console::CommandMetadata& command)
{
commandList.emplace_back(command.GetName(), (command.GetArity() == -1) ? -1 : int32_t(command.GetArity()));
commandList.emplace_back(command.GetName(), command.GetResourceName(), (command.GetArity() == -1) ? -1 : int32_t(command.GetArity()));
});

context.SetResult(fx::SerializeObject(commandList));
}
}
});

fx::ScriptEngine::RegisterNativeHandler("GET_RESOURCE_COMMANDS", [](fx::ScriptContext& context)
{
std::string resourceName = context.CheckArgument<const char*>(0);
std::vector<CommandObject> commandList;

// find the resource
fx::ResourceManager* resourceManager = fx::ResourceManager::GetCurrent();
fwRefContainer<fx::Resource> resource = resourceManager->GetResource(resourceName);
auto consoleCxt = resourceManager->GetComponent<console::Context>();

if (resource.GetRef())
{
consoleCxt->GetCommandManager()->ForAllCommands2([&commandList, &resourceName](const console::CommandMetadata& command)
{
if (command.MatchResourceName(resourceName))
{
commandList.emplace_back(command.GetName(), command.GetResourceName(), (command.GetArity() == -1) ? -1 : int32_t(command.GetArity()));
}
});
}

context.SetResult(fx::SerializeObject(commandList));
});

fx::ScriptEngine::RegisterNativeHandler("GET_INSTANCE_ID", [](fx::ScriptContext& context)
{
fx::OMPtr<IScriptRuntime> runtime;
Expand Down
Loading
Loading