Core/ChatCommands: Properly handle single-argument handlers (argument string discarded). Add special handling for on/off booleans.

This commit is contained in:
Treeston
2018-09-08 19:46:12 +02:00
committed by Aokromes
parent 6815c24be1
commit 76d8fdba9c
3 changed files with 29 additions and 7 deletions

View File

@@ -118,7 +118,7 @@ struct CommandArgsConsumerMulti
static char const* TryConsumeTo(Tuple& tuple, char const* args)
{
if (char const* next = CommandArgsConsumerSingle<NextType>::TryConsumeTo(std::get<offset>(tuple), args))
return CommandArgsConsumerNext<Tuple, offset>::GoNext(tuple, next);
return CommandArgsConsumerNext<Tuple, offset+1>::GoNext(tuple, next);
else
return nullptr;
}
@@ -133,11 +133,11 @@ struct CommandArgsConsumerMulti<Tuple, Optional<NestedNextType>, offset>
auto& myArg = std::get<offset>(tuple);
myArg.emplace();
if (char const* next = CommandArgsConsumerSingle<NestedNextType>::TryConsumeTo(*(myArg.get_ptr()), args))
if ((next = CommandArgsConsumerNext<Tuple, offset>::GoNext(tuple, next)))
if ((next = CommandArgsConsumerNext<Tuple, offset+1>::GoNext(tuple, next)))
return next;
// try again omitting the argument
myArg = boost::none;
if (char const* next = CommandArgsConsumerNext<Tuple, offset>::GoNext(tuple, args))
if (char const* next = CommandArgsConsumerNext<Tuple, offset+1>::GoNext(tuple, args))
return next;
return nullptr;
}
@@ -148,13 +148,13 @@ struct CommandArgsConsumerNext<std::tuple<Ts...>, offset>
{
using tuple_type = std::tuple<Ts...>;
template <bool C = (offset + 1 < sizeof...(Ts))>
template <bool C = (offset < sizeof...(Ts))>
static std::enable_if_t<C, char const*> GoNext(tuple_type& tuple, char const* args)
{
return CommandArgsConsumerMulti<tuple_type, std::tuple_element_t<offset + 1, tuple_type>, offset + 1>::TryConsumeTo(tuple, args);
return CommandArgsConsumerMulti<tuple_type, std::tuple_element_t<offset, tuple_type>, offset>::TryConsumeTo(tuple, args);
}
template <bool C = (offset + 1 < sizeof...(Ts))>
template <bool C = (offset < sizeof...(Ts))>
static std::enable_if_t<!C, char const*> GoNext(tuple_type&, char const* args)
{
return args;
@@ -192,7 +192,7 @@ class TC_GAME_API CommandArgs
template <size_t offset = 0, typename T>
bool TryConsumeToTuple(T& tuple)
{
if (char const* next = CommandArgsConsumerMulti<T, std::tuple_element_t<offset, T>, offset>::TryConsumeTo(tuple, _args))
if (char const* next = CommandArgsConsumerNext<T, offset>::GoNext(tuple, _args))
{
_args = next;
return true;

View File

@@ -35,3 +35,18 @@ char const* Trinity::ChatCommands::ArgInfo<GameTele const*>::TryConsume(GameTele
data = boost::apply_visitor(GameTeleVisitor(), val);
return args;
}
struct BoolVisitor
{
using value_type = bool;
value_type operator()(uint32 i) const { return !!i; }
value_type operator()(ExactSequence<'o', 'n'>) const { return true; }
value_type operator()(ExactSequence<'o', 'f', 'f'>) const { return false; }
};
char const* Trinity::ChatCommands::ArgInfo<bool>::TryConsume(bool& data, char const* args)
{
Variant<uint32, ExactSequence<'o', 'n'>, ExactSequence<'o', 'f', 'f'>> val;
if ((args = CommandArgsConsumerSingle<decltype(val)>::TryConsumeTo(val, args)))
data = boost::apply_visitor(BoolVisitor(), val);
return args;
}

View File

@@ -115,6 +115,13 @@ struct TC_GAME_API ArgInfo<GameTele const*>
static char const* TryConsume(GameTele const*&, char const*);
};
// bool from 1/0 or on/off
template <>
struct TC_GAME_API ArgInfo<bool>
{
static char const* TryConsume(bool&, char const*);
};
}}
#endif