Some minor changes
This commit is contained in:
parent
cb73d9df32
commit
e30c03029f
@ -237,6 +237,11 @@ namespace ts {
|
|||||||
details_ptr->extra_properties["extra_msg"] = message;
|
details_ptr->extra_properties["extra_msg"] = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
command_result(error::type error, const std::map<std::string, std::string>& properties) : command_result{error, ""} {
|
||||||
|
assert(this->is_detailed());
|
||||||
|
this->details()->extra_properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef _NDEBUG
|
#ifndef _NDEBUG
|
||||||
/* if we're not using any debug we dont have to use a deconstructor. A deconstructor prevent a direct uint64_t return as described above */
|
/* if we're not using any debug we dont have to use a deconstructor. A deconstructor prevent a direct uint64_t return as described above */
|
||||||
~command_result() {
|
~command_result() {
|
||||||
@ -259,7 +264,6 @@ namespace ts {
|
|||||||
ErrorType(const uint16_t errorId, const std::string &name, const std::string &message) : errorId(errorId), name(name), message(message) {}
|
ErrorType(const uint16_t errorId, const std::string &name, const std::string &message) : errorId(errorId), name(name), message(message) {}
|
||||||
|
|
||||||
ErrorType(const ErrorType& ref) : errorId(ref.errorId), name(ref.name), message(ref.message) {}
|
ErrorType(const ErrorType& ref) : errorId(ref.errorId), name(ref.name), message(ref.message) {}
|
||||||
ErrorType(ErrorType& ref) : errorId(ref.errorId), name(ref.name), message(ref.message) {}
|
|
||||||
ErrorType(ErrorType&& ref) : errorId(ref.errorId), name(std::move(ref.name)), message(std::move(ref.message)) {}
|
ErrorType(ErrorType&& ref) : errorId(ref.errorId), name(std::move(ref.name)), message(std::move(ref.message)) {}
|
||||||
|
|
||||||
uint16_t errorId;
|
uint16_t errorId;
|
||||||
|
@ -53,23 +53,23 @@ namespace ts {
|
|||||||
typedef uint32_t flag_type;
|
typedef uint32_t flag_type;
|
||||||
enum flag : flag_type {
|
enum flag : flag_type {
|
||||||
FLAG_BEGIN = 0b1,
|
FLAG_BEGIN = 0b1,
|
||||||
FLAG_INTERNAL = FLAG_BEGIN << 1, //Just for internal usage
|
FLAG_INTERNAL = FLAG_BEGIN << 1UL, //Just for internal usage
|
||||||
FLAG_GLOBAL = FLAG_INTERNAL << 1, //Not server bound
|
FLAG_GLOBAL = FLAG_INTERNAL << 1UL, //Not server bound
|
||||||
FLAG_SNAPSHOT = FLAG_GLOBAL << 1, //Saved within snapshots
|
FLAG_SNAPSHOT = FLAG_GLOBAL << 1UL, //Saved within snapshots
|
||||||
FLAG_SAVE = FLAG_SNAPSHOT << 1, //Saved to database
|
FLAG_SAVE = FLAG_SNAPSHOT << 1UL, //Saved to database
|
||||||
FLAG_SAVE_MUSIC = FLAG_SAVE << 1, //Saved to database
|
FLAG_SAVE_MUSIC = FLAG_SAVE << 1UL, //Saved to database
|
||||||
FLAG_NEW = FLAG_SAVE_MUSIC << 1, //Its a non TeamSpeak property
|
FLAG_NEW = FLAG_SAVE_MUSIC << 1UL, //Its a non TeamSpeak property
|
||||||
FLAG_SERVER_VARIABLE = FLAG_NEW << 1,
|
FLAG_SERVER_VARIABLE = FLAG_NEW << 1UL,
|
||||||
FLAG_SERVER_VIEW = FLAG_SERVER_VARIABLE << 1,
|
FLAG_SERVER_VIEW = FLAG_SERVER_VARIABLE << 1UL,
|
||||||
FLAG_CLIENT_VARIABLE = FLAG_SERVER_VIEW << 1,
|
FLAG_CLIENT_VARIABLE = FLAG_SERVER_VIEW << 1UL,
|
||||||
FLAG_CLIENT_VIEW = FLAG_CLIENT_VARIABLE << 1,
|
FLAG_CLIENT_VIEW = FLAG_CLIENT_VARIABLE << 1UL,
|
||||||
FLAG_CLIENT_INFO = FLAG_CLIENT_VIEW << 1,
|
FLAG_CLIENT_INFO = FLAG_CLIENT_VIEW << 1UL,
|
||||||
FLAG_CHANNEL_VARIABLE = FLAG_CLIENT_INFO << 1,
|
FLAG_CHANNEL_VARIABLE = FLAG_CLIENT_INFO << 1UL,
|
||||||
FLAG_CHANNEL_VIEW = FLAG_CHANNEL_VARIABLE << 1,
|
FLAG_CHANNEL_VIEW = FLAG_CHANNEL_VARIABLE << 1UL,
|
||||||
FLAG_GROUP_VIEW = FLAG_CHANNEL_VIEW << 1,
|
FLAG_GROUP_VIEW = FLAG_CHANNEL_VIEW << 1UL,
|
||||||
FLAG_INSTANCE_VARIABLE = FLAG_GROUP_VIEW << 1,
|
FLAG_INSTANCE_VARIABLE = FLAG_GROUP_VIEW << 1UL,
|
||||||
FLAG_USER_EDITABLE = FLAG_INSTANCE_VARIABLE << 1,
|
FLAG_USER_EDITABLE = FLAG_INSTANCE_VARIABLE << 1UL,
|
||||||
FLAG_PLAYLIST_VARIABLE = FLAG_USER_EDITABLE << 1,
|
FLAG_PLAYLIST_VARIABLE = FLAG_USER_EDITABLE << 1UL,
|
||||||
};
|
};
|
||||||
static constexpr const char *flag_names[sizeof(flag) * 8] =
|
static constexpr const char *flag_names[sizeof(flag) * 8] =
|
||||||
{"UNDEFINED", "FLAG_INTERNAL", "FLAG_GLOBAL", "FLAG_SNAPSHOT", "FLAG_SAVE", "FLAG_SAVE_MUSIC", "FLAG_NEW",
|
{"UNDEFINED", "FLAG_INTERNAL", "FLAG_GLOBAL", "FLAG_SNAPSHOT", "FLAG_SAVE", "FLAG_SAVE_MUSIC", "FLAG_NEW",
|
||||||
@ -773,12 +773,8 @@ namespace ts {
|
|||||||
Properties(const Properties&) = delete;
|
Properties(const Properties&) = delete;
|
||||||
Properties(Properties&&) = delete;
|
Properties(Properties&&) = delete;
|
||||||
|
|
||||||
std::vector<PropertyWrapper> list_properties(property::flag_type flagMask = ~0, property::flag_type negatedFlagMask = 0);
|
std::vector<PropertyWrapper> list_properties(property::flag_type flagMask = (property::flag_type) ~0UL, property::flag_type negatedFlagMask = 0);
|
||||||
std::vector<PropertyWrapper> all_properties();
|
std::vector<PropertyWrapper> all_properties();
|
||||||
/*
|
|
||||||
std::deque<std::shared_ptr<Property>> listProperties(property::flag_type flagMask = ~0, property::flag_type negatedFlagMask = 0);
|
|
||||||
std::deque<std::shared_ptr<Property>> allProperties();
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
bool register_property_type() {
|
bool register_property_type() {
|
||||||
@ -786,25 +782,6 @@ namespace ts {
|
|||||||
return this->register_property_type(type, property::impl::length(type), property::impl::offset(type));
|
return this->register_property_type(type, property::impl::length(type), property::impl::offset(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
template <typename PT>
|
|
||||||
std::shared_ptr<Property> registerProperty(PT property){
|
|
||||||
auto info = property::impl::info<PT>(property);
|
|
||||||
{
|
|
||||||
threads::MutexLock lock(this->propsLock);
|
|
||||||
for(const auto& elm : this->properties) {
|
|
||||||
if(*info == elm->type()){
|
|
||||||
std::cerr << "Double registration of " << elm->type().name << "\n";
|
|
||||||
return this->find(property::impl::type<PT>(), property);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
properties.push_back(std::make_shared<Property>(this, info));
|
|
||||||
}
|
|
||||||
return this->find(property::impl::type<PT>(), property);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool hasProperty(T type) { return this->has(property::impl::type<T>(), type); }
|
bool hasProperty(T type) { return this->has(property::impl::type<T>(), type); }
|
||||||
|
|
||||||
@ -846,11 +823,9 @@ namespace ts {
|
|||||||
|
|
||||||
bool save = true;
|
bool save = true;
|
||||||
std::vector<std::function<void(PropertyWrapper&)>> notifyFunctions{};
|
std::vector<std::function<void(PropertyWrapper&)>> notifyFunctions{};
|
||||||
std::recursive_mutex propsLock{};
|
|
||||||
//std::deque<std::shared_ptr<Property>> properties{};
|
|
||||||
|
|
||||||
size_t properties_count = 0;
|
size_t properties_count = 0;
|
||||||
std::deque<std::shared_ptr<PropertyBundle>> properties;
|
std::vector<std::shared_ptr<PropertyBundle>> properties;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ CONVERTER_ST(const_char__ , return str.c_str();, return std::string(std::any_cas
|
|||||||
|
|
||||||
command::command(const std::string& command, bool editable) {
|
command::command(const std::string& command, bool editable) {
|
||||||
this->handle = make_shared<impl::command_data>();
|
this->handle = make_shared<impl::command_data>();
|
||||||
this->handle->editiable = editable;
|
this->handle->editable = editable;
|
||||||
this->handle->command = command;
|
this->handle->command = command;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ void command::set_identifier(const std::string &command) {
|
|||||||
|
|
||||||
command_bulk command::bulk(size_t index) {
|
command_bulk command::bulk(size_t index) {
|
||||||
if(this->handle->bulks.size() <= index) {
|
if(this->handle->bulks.size() <= index) {
|
||||||
if(!this->handle->editiable)
|
if(!this->handle->editable)
|
||||||
throw command_bulk_exceed_index_exception();
|
throw command_bulk_exceed_index_exception();
|
||||||
|
|
||||||
while(this->handle->bulks.size() <= index) {
|
while(this->handle->bulks.size() <= index) {
|
||||||
@ -229,7 +229,7 @@ command_entry command_bulk::value(const std::string &key) {
|
|||||||
auto& values = this->handle->values;
|
auto& values = this->handle->values;
|
||||||
auto index = values.find(key);
|
auto index = values.find(key);
|
||||||
if(index == values.end()) {
|
if(index == values.end()) {
|
||||||
if(!this->handle->handle->editiable)
|
if(!this->handle->handle->editable)
|
||||||
throw command_value_missing_exception(this->bulk_index, key);
|
throw command_value_missing_exception(this->bulk_index, key);
|
||||||
|
|
||||||
auto result = make_shared<impl::command_value>();
|
auto result = make_shared<impl::command_value>();
|
||||||
|
@ -38,7 +38,7 @@ namespace ts {
|
|||||||
|
|
||||||
struct command_data {
|
struct command_data {
|
||||||
std::string command;
|
std::string command;
|
||||||
bool editiable;
|
bool editable;
|
||||||
std::deque<std::shared_ptr<command_bulk>> bulks;
|
std::deque<std::shared_ptr<command_bulk>> bulks;
|
||||||
std::deque<std::string> triggers;
|
std::deque<std::string> triggers;
|
||||||
};
|
};
|
||||||
@ -136,7 +136,7 @@ namespace ts {
|
|||||||
return this->string();
|
return this->string();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, std::enable_if_t<!std::is_same<T, std::string>::value && !std::is_same<T, std::string>::value, int> = 0>
|
template <typename T, std::enable_if_t<!std::is_same<T, std::string>::value, int> = 0>
|
||||||
T as() {
|
T as() {
|
||||||
static_assert(converter<T>::supported, "Target type isn't supported!");
|
static_assert(converter<T>::supported, "Target type isn't supported!");
|
||||||
static_assert(!converter<T>::supported || converter<T>::from_string, "Target type dosn't support parsing");
|
static_assert(!converter<T>::supported || converter<T>::from_string, "Target type dosn't support parsing");
|
||||||
@ -308,13 +308,20 @@ namespace ts {
|
|||||||
};
|
};
|
||||||
using default_options = options<false, false>;
|
using default_options = options<false, false>;
|
||||||
|
|
||||||
struct base { };
|
struct base {
|
||||||
|
virtual ~base() = default;
|
||||||
|
};
|
||||||
|
|
||||||
struct base_data {
|
struct base_data {
|
||||||
int type; /* 1 = field | 2 = switch | 3 = command handle */
|
int type; /* 1 = field | 2 = switch | 3 = command handle */
|
||||||
option_data options;
|
option_data options;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct field_base : public base {
|
||||||
|
virtual std::vector<command_entry>& ref_values() = 0;
|
||||||
|
virtual const std::vector<command_entry>& ref_values() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct field_data : public base_data {
|
struct field_data : public base_data {
|
||||||
const char* key;
|
const char* key;
|
||||||
const std::type_info& field_type;
|
const std::type_info& field_type;
|
||||||
@ -323,19 +330,12 @@ namespace ts {
|
|||||||
void* to_string;
|
void* to_string;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct field_base {
|
|
||||||
typedef std::vector<command_entry>&(*ref_values_fn)();
|
|
||||||
static inline std::vector<command_entry>& ref_values(const void* _this) {
|
|
||||||
void** vtable = *(void***) _this;
|
|
||||||
return ((ref_values_fn) vtable[0])();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class key_t, typename value_type_t, class options, class... extends>
|
template <class key_t, typename value_type_t, class options, class... extends>
|
||||||
struct field : public base, public options, public extends... {
|
struct field : public field_base, public options, public extends... {
|
||||||
friend struct command_parser<field<key_t, value_type_t, options, extends...>>;
|
friend struct command_parser<field<key_t, value_type_t, options, extends...>>;
|
||||||
static_assert(converter<value_type_t>::supported, "Target type isn't supported!");
|
static_assert(converter<value_type_t>::supported, "Target type isn't supported!");
|
||||||
static_assert(!converter<value_type_t>::supported || converter<value_type_t>::from_string, "Target type dosn't support parsing");
|
static_assert(!converter<value_type_t>::supported || converter<value_type_t>::from_string, "Target type dosn't support parsing");
|
||||||
|
static_assert(impl::templates::_or_<!std::is_empty<extends>::value...>::value == false, "Extensions could not have data members");
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using object_t = field_data;
|
using object_t = field_data;
|
||||||
@ -344,7 +344,6 @@ namespace ts {
|
|||||||
static constexpr auto from_string = converter<value_type_t>::from_string;
|
static constexpr auto from_string = converter<value_type_t>::from_string;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
template <bool flag = true /*, std::enable_if_t<!templates::_or_<std::is_same<extends, optional_extend>::value...>::value, int> = 0 */>
|
template <bool flag = true /*, std::enable_if_t<!templates::_or_<std::is_same<extends, optional_extend>::value...>::value, int> = 0 */>
|
||||||
using as_optional = field<key_t, value_type_t, impl::options<options::is_bulked, flag>, optional_extend, extends...>;
|
using as_optional = field<key_t, value_type_t, impl::options<options::is_bulked, flag>, optional_extend, extends...>;
|
||||||
|
|
||||||
@ -391,27 +390,32 @@ namespace ts {
|
|||||||
return this->as<T>();
|
return this->as<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<command_entry>& ref_values() final { return this->values; }
|
||||||
|
const std::vector<command_entry>& ref_values() const final { return this->values; }
|
||||||
protected:
|
protected:
|
||||||
/* ATTENTION: This must be placed at index 0 within the VTable */
|
|
||||||
virtual __attribute__used std::vector<command_entry>& _v_ref_values() {
|
|
||||||
return this->values;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<command_entry> values;
|
std::vector<command_entry> values;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct optional_extend {
|
struct optional_extend {
|
||||||
public:
|
public:
|
||||||
inline bool has_value() const {
|
inline bool has_value() const {
|
||||||
auto& values = field_base::ref_values(this);
|
auto base = dynamic_cast<field_base*>((struct base*) this);
|
||||||
|
assert(base);
|
||||||
|
|
||||||
|
const auto& values = base->ref_values();
|
||||||
return !values.empty() && !values[0].is_empty();
|
return !values.empty() && !values[0].is_empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T get_or(T&& value = T{}) const {
|
inline T get_or(T&& value = T{}) const {
|
||||||
if(this->has_value())
|
auto base = dynamic_cast<field_base*>((struct base*) this);
|
||||||
return field_base::ref_values(this).front().as<T>();
|
assert(base);
|
||||||
|
|
||||||
|
auto& values = base->ref_values();
|
||||||
|
if(values.empty() || values[0].is_empty())
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
|
return values.front().as<T>();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -421,10 +425,18 @@ namespace ts {
|
|||||||
return !this->at(index).is_empty();
|
return !this->at(index).is_empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t length() const { return field_base::ref_values(this).size(); }
|
inline size_t length() const {
|
||||||
|
auto base = dynamic_cast<field_base*>((struct base*) this);
|
||||||
|
assert(base);
|
||||||
|
|
||||||
|
return base->ref_values().size();
|
||||||
|
}
|
||||||
|
|
||||||
inline command_entry at(size_t index) const {
|
inline command_entry at(size_t index) const {
|
||||||
auto& values = field_base::ref_values(this);
|
auto base = dynamic_cast<field_base*>((struct base*) this);
|
||||||
|
assert(base);
|
||||||
|
|
||||||
|
auto& values = base->ref_values();
|
||||||
if(index > values.size())
|
if(index > values.size())
|
||||||
throw command_bulk_exceed_index_exception();
|
throw command_bulk_exceed_index_exception();
|
||||||
|
|
||||||
@ -436,16 +448,12 @@ namespace ts {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct trigger_data : public base_data {
|
struct trigger_base : public base {
|
||||||
const char* key;
|
virtual bool& ref_flag() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct trigger_base : public base {
|
struct trigger_data : public base_data {
|
||||||
typedef bool&(*ref_flag_fn)();
|
const char* key;
|
||||||
static inline bool& ref_flag(void* _this) {
|
|
||||||
void** vtable = *(void***) _this;
|
|
||||||
return ((ref_flag_fn) vtable[0])();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class key_t, class options>
|
template <class key_t, class options>
|
||||||
@ -468,109 +476,14 @@ namespace ts {
|
|||||||
inline bool is_set() const { return this->flag_set; }
|
inline bool is_set() const { return this->flag_set; }
|
||||||
operator bool() const { return this->flag_set; }
|
operator bool() const { return this->flag_set; }
|
||||||
|
|
||||||
private:
|
bool& ref_flag() override {
|
||||||
/* ATTENTION: This must be placed at index 0 within the VTable */
|
|
||||||
virtual __attribute__used bool& _v_ref_values() {
|
|
||||||
return this->flag_set;
|
return this->flag_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool flag_set;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct command_handle_data : public base_data { };
|
|
||||||
|
|
||||||
struct command_handle_base : public base {
|
|
||||||
typedef command&(*ref_flag_fn)();
|
|
||||||
static inline command& ref_command(void* _this) {
|
|
||||||
void** vtable = *(void***) _this;
|
|
||||||
return ((ref_flag_fn) vtable[0])();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class options>
|
|
||||||
struct command_handle : public command_handle_base, public options {
|
|
||||||
public:
|
|
||||||
using object_t = command_handle_data;
|
|
||||||
inline static std::shared_ptr<object_t> describe() {
|
|
||||||
return std::make_shared<object_t>(
|
|
||||||
command_handle_data {
|
|
||||||
3,
|
|
||||||
options::options_object()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline command get_command() { return this->_command; }
|
|
||||||
operator command() { return this->_command; }
|
|
||||||
|
|
||||||
inline command* operator->() const noexcept {
|
|
||||||
return (command*) &_command;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
template<class Arg>
|
|
||||||
auto operator[](Arg &&arg) -> decltype(get_command()[std::forward<Arg>(arg)]) {
|
|
||||||
return _command[std::forward<Arg>(arg)];
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
template<class Arg>
|
|
||||||
decltype(std::declval<command>()[std::forward<Arg>(Arg{})]) operator[](Arg &&arg) {
|
|
||||||
return _command[std::forward<Arg>(arg)];
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
/* ATTENTION: This must be placed at index 0 within the VTable */
|
bool flag_set = false;
|
||||||
virtual __attribute__used class command& _v_ref_values() {
|
|
||||||
return this->_command;
|
|
||||||
}
|
|
||||||
|
|
||||||
command _command;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<std::shared_ptr<impl::base_data>> function_descriptors_t;
|
|
||||||
|
|
||||||
template <typename...>
|
|
||||||
struct describe {
|
|
||||||
inline static void apply(function_descriptors_t& result) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
|
||||||
struct describe<T, Args...> {
|
|
||||||
inline static void apply(function_descriptors_t& result) {
|
|
||||||
result.push_back(T::describe());
|
|
||||||
describe<Args...>::apply(result);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void parse_field(const std::shared_ptr<field_data>& description, void* field, command& cmd) {
|
|
||||||
//if(!description->options.optional && !cmd.has_value(description->key))
|
|
||||||
// throw command_value_missing_exception();
|
|
||||||
|
|
||||||
auto& values = field_base::ref_values(field);
|
|
||||||
values.clear();
|
|
||||||
|
|
||||||
if(description->options.bulked) {
|
|
||||||
values.resize(cmd.bulk_count());
|
|
||||||
for(size_t bulk_index = 0; bulk_index < cmd.bulk_count(); bulk_index++) {
|
|
||||||
if(!cmd[bulk_index].has(description->key)) {
|
|
||||||
if(!description->options.optional)
|
|
||||||
throw command_value_missing_exception(bulk_index, description->key);
|
|
||||||
else
|
|
||||||
values[bulk_index] = command_entry::empty;
|
|
||||||
} else {
|
|
||||||
values[bulk_index] = cmd[bulk_index][description->key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(!cmd.has_value(description->key)) {
|
|
||||||
if(!description->options.optional)
|
|
||||||
throw command_value_missing_exception(0, description->key);
|
|
||||||
else
|
|
||||||
values.push_back(command_entry::empty);
|
|
||||||
} else
|
|
||||||
values.push_back(cmd[description->key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class key_t, class options, class... extends>
|
template <class key_t, class options, class... extends>
|
||||||
struct command_parser<field<key_t, options, extends...>> {
|
struct command_parser<field<key_t, options, extends...>> {
|
||||||
constexpr static bool supported = true;
|
constexpr static bool supported = true;
|
||||||
@ -586,7 +499,33 @@ namespace ts {
|
|||||||
assert(descriptor->type == 1);
|
assert(descriptor->type == 1);
|
||||||
|
|
||||||
field_t result{};
|
field_t result{};
|
||||||
parse_field(descriptor, (void*) &result, cmd);
|
|
||||||
|
//if(!description->options.optional && !cmd.has_value(description->key))
|
||||||
|
// throw command_value_missing_exception();
|
||||||
|
auto& values = result.ref_values();
|
||||||
|
values.clear();
|
||||||
|
|
||||||
|
if(descriptor->options.bulked) {
|
||||||
|
values.resize(cmd.bulk_count());
|
||||||
|
for(size_t bulk_index = 0; bulk_index < cmd.bulk_count(); bulk_index++) {
|
||||||
|
if(!cmd[bulk_index].has(descriptor->key)) {
|
||||||
|
if(!descriptor->options.optional)
|
||||||
|
throw command_value_missing_exception(bulk_index, descriptor->key);
|
||||||
|
else
|
||||||
|
values[bulk_index] = command_entry::empty;
|
||||||
|
} else {
|
||||||
|
values[bulk_index] = cmd[bulk_index][descriptor->key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(!cmd.has_value(descriptor->key)) {
|
||||||
|
if(!descriptor->options.optional)
|
||||||
|
throw command_value_missing_exception(0, descriptor->key);
|
||||||
|
else
|
||||||
|
values.push_back(command_entry::empty);
|
||||||
|
} else
|
||||||
|
values.push_back(cmd[descriptor->key]);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -607,37 +546,32 @@ namespace ts {
|
|||||||
assert(descriptor->type == 2);
|
assert(descriptor->type == 2);
|
||||||
|
|
||||||
trigger_t result{};
|
trigger_t result{};
|
||||||
trigger_base::ref_flag(&result) = cmd.has_trigger(descriptor->key);
|
result.ref_flag() = cmd.has_trigger(descriptor->key);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class options>
|
struct command_data : public base_data { };
|
||||||
struct command_parser<command_handle<options>> {
|
|
||||||
|
template <>
|
||||||
|
struct command_parser<command&> {
|
||||||
constexpr static bool supported = true;
|
constexpr static bool supported = true;
|
||||||
|
|
||||||
typedef command_handle<options> command_handle_t;
|
using descriptor_t = std::shared_ptr<command_data>;
|
||||||
using descriptor_t = std::shared_ptr<typename command_handle_t::object_t>;
|
|
||||||
|
|
||||||
inline static descriptor_t describe() {
|
inline static descriptor_t describe() { return std::make_shared<command_data>(command_data{{3, {false, false}}}); }
|
||||||
return command_handle_t::describe();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static command_handle_t apply(descriptor_t& descriptor, command& cmd) {
|
inline static command& apply(descriptor_t& descriptor, command& cmd) {
|
||||||
assert(descriptor->type == 3);
|
assert(descriptor->type == 3);
|
||||||
|
return cmd;
|
||||||
command_handle_t result{};
|
|
||||||
command_handle_base::ref_command(&result) = cmd;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename C>
|
template <typename C>
|
||||||
struct command_parser<C> {
|
struct command_parser<C> {
|
||||||
constexpr static bool supported = std::is_same<typename std::remove_reference<typename std::remove_cv<C>::type>::type, command>::value;
|
constexpr static bool supported = false;
|
||||||
static_assert(supported, "This type isn't supported!");
|
|
||||||
|
|
||||||
using descriptor_t = std::shared_ptr<void>;
|
using descriptor_t = std::shared_ptr<nullptr_t>;
|
||||||
|
|
||||||
inline static descriptor_t describe() {
|
inline static descriptor_t describe() {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -649,9 +583,6 @@ namespace ts {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* direct use of command is possible as well! */
|
|
||||||
using command_handle = impl::command_handle<impl::default_options>;
|
|
||||||
|
|
||||||
template <class key_t, typename value_type_t>
|
template <class key_t, typename value_type_t>
|
||||||
using field = impl::field<key_t, value_type_t, impl::default_options>;
|
using field = impl::field<key_t, value_type_t, impl::default_options>;
|
||||||
|
|
||||||
@ -659,16 +590,13 @@ namespace ts {
|
|||||||
using trigger = impl::trigger<key_t, impl::default_options>;
|
using trigger = impl::trigger<key_t, impl::default_options>;
|
||||||
|
|
||||||
template <typename... args_t>
|
template <typename... args_t>
|
||||||
inline impl::function_descriptors_t describe_function() {
|
inline std::array<std::shared_ptr<struct impl::base_data>, sizeof...(args_t)> describe_function(void(*)(args_t...)) {
|
||||||
impl::function_descriptors_t result;
|
static_assert(!impl::templates::_or_<!impl::command_parser<typename impl::templates::remove_cr<args_t>::type>::supported...>::value, "Not any function argument type is supported");
|
||||||
impl::describe<args_t...>::apply(result);
|
return {impl::command_parser<typename impl::templates::remove_cr<args_t>::type>::describe()...};
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct invocable_function {
|
struct invocable_function {
|
||||||
void operator()(command& command) {
|
void operator()(command& command) { this->invoke(command); }
|
||||||
this->invoke(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void invoke(command& command) = 0;
|
virtual void invoke(command& command) = 0;
|
||||||
};
|
};
|
||||||
@ -684,7 +612,7 @@ namespace ts {
|
|||||||
void(*function)(args_t...);
|
void(*function)(args_t...);
|
||||||
|
|
||||||
void invoke(command& command) override {
|
void invoke(command& command) override {
|
||||||
function(command_parser_t<args_t>::apply(std::get<impl::templates::tuple_index<args_t, args_tuple_t>::value>(descriptors), command)...);
|
this->function(command_parser_t<args_t>::apply(std::get<impl::templates::tuple_index<args_t, args_tuple_t>::value>(descriptors), command)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,11 +23,11 @@ using trigger = ts::descriptor::trigger<key_t>;
|
|||||||
|
|
||||||
void handleCommand(
|
void handleCommand(
|
||||||
ts::command& _cmd,
|
ts::command& _cmd,
|
||||||
cconstants::return_code::optional return_code,
|
const cconstants::return_code::optional& return_code,
|
||||||
field<tl("key_a"), int> key_a,
|
const field<tl("key_a"), int>& key_a,
|
||||||
field<tl("key_b"), string>::optional key_b,
|
const field<tl("key_b"), string>::optional& key_b,
|
||||||
field<tl("key_c"), uint64_t>::optional::bulked key_c,
|
const field<tl("key_c"), uint64_t>::optional::bulked& key_c,
|
||||||
trigger<tl("test")> switch_test
|
const trigger<tl("test")>& switch_test
|
||||||
) {
|
) {
|
||||||
if(key_a.value() < 10)
|
if(key_a.value() < 10)
|
||||||
cout << "ERROR" << endl;
|
cout << "ERROR" << endl;
|
||||||
@ -67,18 +67,6 @@ void eval_test(command_result x) {
|
|||||||
int main() {
|
int main() {
|
||||||
//for(const auto& error : avariableErrors)
|
//for(const auto& error : avariableErrors)
|
||||||
// cout << error.name << " = " << hex << "0x" << error.errorId << "," << endl;
|
// cout << error.name << " = " << hex << "0x" << error.errorId << "," << endl;
|
||||||
#if false
|
|
||||||
{
|
|
||||||
string error;
|
|
||||||
istringstream is(base64::decode("AQCvbHFTQDY/terPeilrp/ECU9xCH5U3xC92lYTNaY/0KQAJFueAazbsgAAAACVUZWFtU3BlYWsgU3lzdGVtcyBHbWJIAADCxw83PomiAdX11jLso/hdMVov4e8N79iq2NRhwkIjqgAKSyfbMFu6mwAAACRUZWFtU3BlYWsgc3lzdGVtcyBHbWJIAAA+kiuhufX/V96lZzq4MICxnYxFPkV/mG03Pu+VYgUISwIKU0+AC1RkAAQAAAIASmFuLU5pa2xhcyBLZXR0ZW5idXJnAADlcwyCViOfHJKYvWHHqyL9R1Ba5ZP+cL7MQ5nI7s1R2yAKnICdCp0pXQ=="));
|
|
||||||
auto chain = LicenseChain::parse(is, error);
|
|
||||||
chain->print();
|
|
||||||
cout << base64::encode(chain->generatePublicKey(public_root)) << endl;
|
|
||||||
cout << base64::encode(chain->generatePublicKey(public_root, 1)) << endl;
|
|
||||||
cout << base64::encode(chain->generatePublicKey(public_root, 2)) << endl;
|
|
||||||
cout << base64::encode(chain->generatePublicKey(public_root, 3)) << endl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
eval_test(test());
|
eval_test(test());
|
||||||
eval_test(test2());
|
eval_test(test2());
|
||||||
@ -127,7 +115,7 @@ int main() {
|
|||||||
cout << ts::command::parse("a=c", false).build(ts::command::format::BRACE_ESCAPED_QUERY) << endl;
|
cout << ts::command::parse("a=c", false).build(ts::command::format::BRACE_ESCAPED_QUERY) << endl;
|
||||||
cout << ts::command::parse("a=c | a=c -x", false).build(ts::command::format::BRACE_ESCAPED_QUERY) << endl;
|
cout << ts::command::parse("a=c | a=c -x", false).build(ts::command::format::BRACE_ESCAPED_QUERY) << endl;
|
||||||
cout << ts::command::parse("a a=c|a=c").build(ts::command::format::BRACE_ESCAPED_QUERY) << endl;
|
cout << ts::command::parse("a a=c|a=c").build(ts::command::format::BRACE_ESCAPED_QUERY) << endl;
|
||||||
cout << ts::command::parse("a a=c a=c2 -z | a=c").build(ts::command::format::BRACE_ESCAPED_QUERY) << endl;
|
cout << ts::command::parse("a a=c a=c2 -z | -? a=c").build(ts::command::format::BRACE_ESCAPED_QUERY) << endl;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
@ -147,6 +135,8 @@ int main() {
|
|||||||
cmd[1]["key_c"] = "key_c_value_1";
|
cmd[1]["key_c"] = "key_c_value_1";
|
||||||
cmd.set_trigger("test");
|
cmd.set_trigger("test");
|
||||||
|
|
||||||
|
auto result = ts::descriptor::describe_function(handleCommand);
|
||||||
|
|
||||||
auto cmd_handler = ts::descriptor::parse_function(handleCommand);
|
auto cmd_handler = ts::descriptor::parse_function(handleCommand);
|
||||||
cmd_handler->invoke(cmd);
|
cmd_handler->invoke(cmd);
|
||||||
cout << cmd.build() << endl;
|
cout << cmd.build() << endl;
|
||||||
|
Loading…
Reference in New Issue
Block a user