175 lines
8.3 KiB
C++
175 lines
8.3 KiB
C++
//! \addtogroup IO
|
||
//! \{
|
||
//! \file piparsehelper.h
|
||
//! \brief
|
||
//! \~english Template helper class to automate structs receive and data packet deserialization
|
||
//! \~russian Шаблонный класс для автоматизации приема структур и десериализации пакетов данных
|
||
//! \details
|
||
//! \~english The PIParseHelper class provides a mechanism to deserialize data packets and automatically invoke assigned handler methods. It
|
||
//! supports member functions, lambda functions, and functors with 0 or 1 arguments.
|
||
//! \~russian Класс PIParseHelper предоставляет механизм для десериализации пакетов данных и автоматического вызова назначаемых
|
||
//! обработчиков. Поддерживаются member-функции, lambda-функции и функторы с 0 или 1 аргументами.
|
||
//! \~\}
|
||
|
||
/*
|
||
PIP - Platform Independent Primitives
|
||
Helper class to automate structs receive
|
||
Ivan Pelipenko peri4ko@yandex.ru
|
||
|
||
This program is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef PIPARSEHELPER_H
|
||
#define PIPARSEHELPER_H
|
||
|
||
#include "piobject.h"
|
||
#include "pip_io_utils_export.h"
|
||
|
||
|
||
//! \class PIParseHelper
|
||
//! \~english Template helper class to automate structs receive and data packet deserialization
|
||
//! \~russian Шаблонный класс для автоматизации приема структур и десериализации пакетов данных
|
||
//! \details
|
||
//! \~english The PIParseHelper class provides a mechanism to deserialize data packets and automatically invoke assigned handler methods. It
|
||
//! supports member functions, lambda functions, and functors with 0 or 1 arguments. The class eliminates the need for switch-case
|
||
//! statements by mapping keys to event handlers via assign() calls. Data type extraction is automatically performed from the handler
|
||
//! signature.
|
||
//! \~russian Класс PIParseHelper предоставляет механизм для десериализации пакетов данных и автоматического вызова назначаемых
|
||
//! обработчиков. Поддерживаются member-функции, lambda-функции и функторы с 0 или 1 аргументами. Класс устраняет необходимость операторов
|
||
//! switch-case, сопоставляя ключи с обработчиками событий через вызовы assign(). Извлечение типа данных автоматически выполняется из
|
||
//! сигнатуры обработчика.
|
||
|
||
template<typename Key>
|
||
class PIParseHelper {
|
||
public:
|
||
//! \~english Construct PIParseHelper
|
||
//! \~russian Создать PIParseHelper
|
||
PIParseHelper() {}
|
||
|
||
|
||
//! \~english Assign key to lambda-function without arguments
|
||
//! \~russian Сопоставить ключ с lambda-функцией без аргументов
|
||
//! \param key The key to assign
|
||
//! \param func The lambda function to call when key is parsed
|
||
//! \~english \param key Ключ для сопоставления
|
||
//! \~russian \param key Ключ для сопоставления
|
||
//! \~english \param func Lambda-функция, вызываемая при разборе ключа
|
||
//! \~russian \param func Lambda-функция, вызываемая при разборе ключа
|
||
void assign(Key key, std::function<void()> func) {
|
||
auto lf = [func](PIByteArray) { func(); };
|
||
functions[key] << lf;
|
||
}
|
||
|
||
|
||
//! \~english Assign key to lambda-function with 1 argument
|
||
//! \~russian Сопоставить ключ с lambda-функцией с 1 аргументом
|
||
//! \param key The key to assign
|
||
//! \param func The lambda function to call when key is parsed
|
||
//! \~english \param key Ключ для сопоставления
|
||
//! \~russian \param key Ключ для сопоставления
|
||
//! \~english \param func Lambda-функция, вызываемая при разборе ключа
|
||
//! \~russian \param func Lambda-функция, вызываемая при разборе ключа
|
||
template<typename T>
|
||
void assign(Key key, std::function<void(const T &)> func) {
|
||
auto lf = [func](PIByteArray data) {
|
||
if (!data.isEmpty()) {
|
||
T v;
|
||
data >> v;
|
||
func(v);
|
||
}
|
||
};
|
||
functions[key] << lf;
|
||
}
|
||
|
||
|
||
//! \~english Assign key to member function of object without arguments
|
||
//! \~russian Сопоставить ключ с member-функцией объекта без аргументов
|
||
//! \param key The key to assign
|
||
//! \param obj Pointer to the object
|
||
//! \param member_func Pointer to the member function
|
||
//! \~english \param key Ключ для сопоставления
|
||
//! \~russian \param key Ключ для сопоставления
|
||
//! \~english \param obj Указатель на объект
|
||
//! \~russian \param obj Указатель на объект
|
||
//! \~english \param member_func Указатель на member-функцию
|
||
//! \~russian \param member_func Указатель на member-функцию
|
||
template<typename O>
|
||
void assign(Key key, O * obj, void (O::*member_func)()) {
|
||
auto lf = [member_func, obj](PIByteArray) { (obj->*member_func)(); };
|
||
functions[key] << lf;
|
||
}
|
||
|
||
|
||
//! \~english Assign key to member function of object with 1 argument
|
||
//! \~russian Сопоставить ключ с member-функцией объекта с 1 аргументом
|
||
//! \param key The key to assign
|
||
//! \param obj Pointer to the object
|
||
//! \param member_func Pointer to the member function
|
||
//! \~english \param key Ключ для сопоставления
|
||
//! \~russian \param key Ключ для сопоставления
|
||
//! \~english \param obj Указатель на объект
|
||
//! \~russian \param obj Указатель на объект
|
||
//! \~english \param member_func Указатель на member-функцию
|
||
//! \~russian \param member_func Указатель на member-функцию
|
||
template<typename T, typename O>
|
||
void assign(Key key, O * obj, void (O::*member_func)(const T &)) {
|
||
auto lf = [member_func, obj](PIByteArray data) {
|
||
if (!data.isEmpty()) {
|
||
T v;
|
||
data >> v;
|
||
(obj->*member_func)(v);
|
||
}
|
||
};
|
||
functions[key] << lf;
|
||
}
|
||
|
||
|
||
//! \~english Assign key to functor with 0 or 1 argument
|
||
//! \~russian Сопоставить ключ с функтором с 0 или 1 аргументом
|
||
//! \param key The key to assign
|
||
//! \param func The functor to call when key is parsed
|
||
//! \~english \param key Ключ для сопоставления
|
||
//! \~russian \param key Ключ для сопоставления
|
||
//! \~english \param func Функтор, вызываемый при разборе ключа
|
||
//! \~russian \param func Функтор, вызываемый при разборе ключа
|
||
template<typename L>
|
||
void assign(Key key, L func) {
|
||
return assign(key, toStdFunction(func));
|
||
}
|
||
|
||
|
||
//! \~english Deserialize data and invoke assigned methods
|
||
//! \~russian Десериализовать данные и вызвать назначенные методы
|
||
//! \param key The key to look up
|
||
//! \param ba The byte array to deserialize
|
||
//! \~english \param key Ключ для поиска
|
||
//! \~russian \param key Ключ для поиска
|
||
//! \~english \param ba Байтовый массив для десериализации
|
||
//! \~russian \param ba Байтовый массив для десериализации
|
||
void parse(Key key, PIByteArray ba) {
|
||
auto fl = functions.value(key);
|
||
for (auto f: fl)
|
||
f(ba);
|
||
}
|
||
|
||
private:
|
||
//! \~english Map of assigned functions
|
||
//! \~russian Карта назначенных функций
|
||
PIMap<Key, PIVector<std::function<void(PIByteArray)>>> functions;
|
||
};
|
||
//! \}
|
||
|
||
|
||
#endif // PIPARSEHELPER_H
|