130 lines
5.1 KiB
C++
130 lines
5.1 KiB
C++
//! \~\file piparsehelper.h
|
||
//! \~\ingroup IO-Utils
|
||
//! \~\brief
|
||
//! \~english Key-dispatch helper for deserializing packets into callbacks
|
||
//! \~russian Вспомогательный класс диспетчеризации по ключу для десериализации пакетов в обработчики
|
||
/*
|
||
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"
|
||
|
||
|
||
//! \~\ingroup IO-Utils
|
||
//! \~\brief
|
||
//! \~english Maps packet keys to handlers and deserializes payloads before invocation.
|
||
//! \~russian Связывает ключи пакетов с обработчиками и десериализует полезную нагрузку перед вызовом.
|
||
//! \~\details
|
||
//! \~english
|
||
//! %PIParseHelper helps replace manual switch-based packet dispatch with a set of
|
||
//! \a assign() calls. Handlers may be plain callbacks, functors or object member functions.
|
||
//! Payload types are restored from %PIByteArray by the selected handler signature.
|
||
//! \n
|
||
//! \n Example:
|
||
//! \~russian
|
||
//! %PIParseHelper помогает заменить ручную диспетчеризацию пакетов через switch
|
||
//! набором вызовов \a assign(). Обработчиками могут быть обычные callback-функции,
|
||
//! функторы или методы объекта. Тип полезной нагрузки восстанавливается из %PIByteArray
|
||
//! по сигнатуре выбранного обработчика.
|
||
//! \n
|
||
//! \n Пример:
|
||
//!
|
||
//! \~\snippet piparsehelper.cpp 0
|
||
//! \~\snippet piparsehelper.cpp 1
|
||
template<typename Key>
|
||
class PIParseHelper {
|
||
public:
|
||
//! \~english Constructs empty parser helper.
|
||
//! \~russian Создает пустой вспомогательный парсер.
|
||
PIParseHelper() {}
|
||
|
||
|
||
//! \~english Assigns key "key" to callback "func" without payload arguments.
|
||
//! \~russian Связывает ключ "key" с callback-функцией "func" без аргументов полезной нагрузки.
|
||
void assign(Key key, std::function<void()> func) {
|
||
auto lf = [func](PIByteArray) { func(); };
|
||
functions[key] << std::move(lf);
|
||
}
|
||
|
||
|
||
//! \~english Assigns key "key" to callback "func" with one deserialized argument.
|
||
//! \~russian Связывает ключ "key" с callback-функцией "func" с одним десериализуемым аргументом.
|
||
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] << std::move(lf);
|
||
}
|
||
|
||
|
||
//! \~english Assigns key "key" to zero-argument member function of object "obj".
|
||
//! \~russian Связывает ключ "key" с методом объекта "obj" без аргументов.
|
||
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 Assigns key "key" to member function of object "obj" with one deserialized argument.
|
||
//! \~russian Связывает ключ "key" с методом объекта "obj" с одним десериализуемым аргументом.
|
||
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 Assigns key "key" to functor or lambda with zero or one argument.
|
||
//! \~russian Связывает ключ "key" с функтором или lambda с нулем или одним аргументом.
|
||
template<typename L>
|
||
void assign(Key key, L func) {
|
||
return assign(key, toStdFunction(func));
|
||
}
|
||
|
||
|
||
//! \~english Deserializes payload "ba" and invokes handlers assigned to "key".
|
||
//! \~russian Десериализует полезную нагрузку "ba" и вызывает обработчики, назначенные ключу "key".
|
||
void parse(Key key, PIByteArray ba) {
|
||
auto fl = functions.value(key);
|
||
for (auto f: fl)
|
||
f(ba);
|
||
}
|
||
|
||
private:
|
||
PIMap<Key, PIVector<std::function<void(PIByteArray)>>> functions;
|
||
};
|
||
|
||
|
||
#endif // PIPARSEHELPER_H
|