From 6ed7befa47e23ab4b46f5d2dd7aa4c36c96a2505 Mon Sep 17 00:00:00 2001 From: "andrey.bychkov" Date: Sat, 28 Feb 2026 18:32:00 +0300 Subject: [PATCH] Doxygen generated by local qwen3-coder-next --- .gitignore | 2 +- CMakeLists.txt | 2 + libs/main/core/piobject.h | 78 +++- libs/main/io_devices/pibinarylog.h | 209 +++++---- libs/main/io_utils/piconnection.h | 366 +++++++++++----- libs/main/io_utils/pidiagnostics.h | 181 ++++++-- libs/main/io_utils/pipacketextractor.h | 84 +++- libs/main/io_utils/piparsehelper.h | 137 +++--- libs/main/math/pievaluator.h | 435 ++++++++++++++----- libs/main/math/pimathsolver.h | 95 ++-- libs/main/math/pimathvector.h | 578 ++++++++++++++++++++++++- libs/main/math/pirect.h | 16 +- 12 files changed, 1696 insertions(+), 487 deletions(-) diff --git a/.gitignore b/.gitignore index 1c093651..d13a06d6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ +/.* /src_main/piversion.h -/.svn /doc/rtf _unsused CMakeLists.txt.user* diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e4740bd..4e6131a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,9 +72,11 @@ option(COVERAGE "Build project with coverage info" OFF) option(PIP_FFTW_F "Support fftw module for float" ON) option(PIP_FFTW_L "Support fftw module for long double" ON) option(PIP_FFTW_Q "Support fftw module for quad double" OFF) + set(PIP_UTILS 1) set(CMAKE_CXX_STANDARD_REQUIRED TRUE) set(CMAKE_CXX_STANDARD 11) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) shstk_is_parent_exists(_pe) if (_pe) diff --git a/libs/main/core/piobject.h b/libs/main/core/piobject.h index 1998c886..8d8b10ea 100644 --- a/libs/main/core/piobject.h +++ b/libs/main/core/piobject.h @@ -1,9 +1,15 @@ -/*! \file piobject.h - * \ingroup Core - * \~\brief - * \~english Base object - * \~russian Базовый класс - */ +//! \addtogroup Core +//! \{ +//! \file piobject.h +//! \brief +//! \~english Base object class providing event -> handler mechanism +//! \~russian Базовый класс объектов, обеспечивающий механизм событий -> обработчиков +//! \details +//! \~english PIObject is the base class for all PIP classes that need event-driven communication. +//! It provides signal-slot mechanism, property system, and object lifetime management. +//! \~russian PIObject является базовым классом для всех классов PIP, которым необходима событийная коммуникация. +//! Он обеспечивает механизм сигналов-слотов, систему свойств и управление жизненным циклом объектов. +//! \~ /* PIP - Platform Independent Primitives Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism @@ -34,10 +40,8 @@ #include "pivariant.h" #include "pivariantsimple.h" -//! \ingroup Core -//! \~\brief -//! \~english This is base class for any classes which use events -> handlers mechanism. -//! \~russian Этот класс является базовым для использования механизма события -> обработчики. +//! \~english Base class for classes using event -> handler mechanism +//! \~russian Базовый класс для классов, использующих механизм событий -> обработчиков class PIP_EXPORT PIObject { #ifndef MICRO_PIP friend class PIObjectManager; @@ -50,7 +54,7 @@ class PIP_EXPORT PIObject { public: NO_COPY_CLASS(PIObject); - //! \~english Contructs %PIObject with name "name" + //! \~english Constructs %PIObject with name "name" //! \~russian Создает %PIObject с именем "name" explicit PIObject(const PIString & name = PIString()); @@ -93,7 +97,7 @@ public: int args_count; public: - //! \~english Contructs invalid %Connection + //! \~english Constructs invalid %Connection //! \~russian Создает недействительный %Connection Connection(); @@ -179,15 +183,27 @@ public: //! \~russian Возвращает является ли объект потокобезопасным bool isThreadSafe() const { return thread_safe_; } + //! \~english Executes method with specified arguments + //! \~russian Выполняет метод с указанными аргументами bool execute(const PIString & method, const PIVector & vl); + //! \~english Executes method without arguments + //! \~russian Выполняет метод без аргументов bool execute(const PIString & method) { return execute(method, PIVector()); } + //! \~english Executes method with one argument + //! \~russian Выполняет метод с одним аргументом bool execute(const PIString & method, const PIVariantSimple & v0) { return execute(method, PIVector() << v0); } + //! \~english Executes method with two arguments + //! \~russian Выполняет метод с двумя аргументами bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) { return execute(method, PIVector() << v0 << v1); } + //! \~english Executes method with three arguments + //! \~russian Выполняет метод с тремя аргументами bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) { return execute(method, PIVector() << v0 << v1 << v2); } + //! \~english Executes method with four arguments + //! \~russian Выполняет метод с четырьмя аргументами bool execute(const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, @@ -196,16 +212,26 @@ public: return execute(method, PIVector() << v0 << v1 << v2 << v3); } + //! \~english Executes method queued with performer + //! \~russian Выполняет метод в очереди с исполнителем bool executeQueued(PIObject * performer, const PIString & method, const PIVector & vl); + //! \~english Executes method without arguments queued with performer + //! \~russian Выполняет метод без аргументов в очереди с исполнителем bool executeQueued(PIObject * performer, const PIString & method) { return executeQueued(performer, method, PIVector()); } + //! \~english Executes method with one argument queued with performer + //! \~russian Выполняет метод с одним аргументом в очереди с исполнителем bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0) { return executeQueued(performer, method, PIVector() << v0); } + //! \~english Executes method with two arguments queued with performer + //! \~russian Выполняет метод с двумя аргументами в очереди с исполнителем bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) { return executeQueued(performer, method, PIVector() << v0 << v1); } + //! \~english Executes method with three arguments queued with performer + //! \~russian Выполняет метод с тремя аргументами в очереди с исполнителем bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, @@ -213,6 +239,8 @@ public: const PIVariantSimple & v2) { return executeQueued(performer, method, PIVector() << v0 << v1 << v2); } + //! \~english Executes method with four arguments queued with performer + //! \~russian Выполняет метод с четырьмя аргументами в очереди с исполнителем bool executeQueued(PIObject * performer, const PIString & method, const PIVariantSimple & v0, @@ -222,18 +250,30 @@ public: return executeQueued(performer, method, PIVector() << v0 << v1 << v2 << v3); } + //! \~english Executes method on object with specified arguments + //! \~russian Выполняет метод на объекте с указанными аргументами static bool execute(PIObject * o, const PIString & method, const PIVector & vl) { return o->execute(method, vl); } + //! \~english Executes method on object without arguments + //! \~russian Выполняет метод на объекте без аргументов static bool execute(PIObject * o, const PIString & method) { return execute(o, method, PIVector()); } + //! \~english Executes method on object with one argument + //! \~russian Выполняет метод на объекте с одним аргументом static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0) { return execute(o, method, PIVector() << v0); } + //! \~english Executes method on object with two arguments + //! \~russian Выполняет метод на объекте с двумя аргументами static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) { return execute(o, method, PIVector() << v0 << v1); } + //! \~english Executes method on object with three arguments + //! \~russian Выполняет метод на объекте с тремя аргументами static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) { return execute(o, method, PIVector() << v0 << v1 << v2); } + //! \~english Executes method on object with four arguments + //! \~russian Выполняет метод на объекте с четырьмя аргументами static bool execute(PIObject * o, const PIString & method, const PIVariantSimple & v0, @@ -243,19 +283,29 @@ public: return execute(o, method, PIVector() << v0 << v1 << v2 << v3); } + //! \~english Executes method on object queued with performer + //! \~russian Выполняет метод на объекте в очереди с исполнителем static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVector & vl) { return o->executeQueued(performer, method, vl); } + //! \~english Executes method on object without arguments queued with performer + //! \~russian Выполняет метод на объекте без аргументов в очереди с исполнителем static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method) { return executeQueued(o, performer, method, PIVector()); } + //! \~english Executes method on object with one argument queued with performer + //! \~russian Выполняет метод на объекте с одним аргументом в очереди с исполнителем static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0) { return executeQueued(o, performer, method, PIVector() << v0); } + //! \~english Executes method on object with two arguments queued with performer + //! \~russian Выполняет метод на объекте с двумя аргументами в очереди с исполнителем static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, const PIVariantSimple & v0, const PIVariantSimple & v1) { return executeQueued(o, performer, method, PIVector() << v0 << v1); } + //! \~english Executes method on object with three arguments queued with performer + //! \~russian Выполняет метод на объекте с тремя аргументами в очереди с исполнителем static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, @@ -264,6 +314,8 @@ public: const PIVariantSimple & v2) { return executeQueued(o, performer, method, PIVector() << v0 << v1 << v2); } + //! \~english Executes method on object with four arguments queued with performer + //! \~russian Выполняет метод на объекте с четырьмя аргументами в очереди с исполнителем static bool executeQueued(PIObject * o, PIObject * performer, const PIString & method, @@ -274,6 +326,8 @@ public: return executeQueued(o, performer, method, PIVector() << v0 << v1 << v2 << v3); } + //! \~english Dumps object information + //! \~russian Выводит информацию об объекте void dump(const PIString & line_prefix = PIString()) const; diff --git a/libs/main/io_devices/pibinarylog.h b/libs/main/io_devices/pibinarylog.h index 03af587d..33aada04 100644 --- a/libs/main/io_devices/pibinarylog.h +++ b/libs/main/io_devices/pibinarylog.h @@ -1,9 +1,13 @@ -/*! \file pibinarylog.h - * \ingroup IO - * \~\brief - * \~english Binary log - * \~russian Бинарный лог - */ +//! \addtogroup IO +//! \{ +//! \file pibinarylog.h +//! \brief +//! \~english Binary log +//! \~russian Бинарный лог +//! \details +//! \~english Class for writing and reading binary data to/from log files, with support for playback in different modes +//! \~russian Класс для записи и чтения бинарных данных в/из файлов логов с поддержкой воспроизведения в различных режимах +//! \~\} /* PIP - Platform Independent Primitives Class for write binary data to logfile, and read or playback this data @@ -29,10 +33,8 @@ #include "pichunkstream.h" #include "pifile.h" -//! \ingroup IO -//! \~\brief -//! \~english Binary log -//! \~russian Бинарный лог +//! \~english Class for writing and reading binary data to/from log files, with support for playback in different modes +//! \~russian Класс для записи и чтения бинарных данных в/из файлов логов с поддержкой воспроизведения в различных режимах class PIP_EXPORT PIBinaryLog: public PIIODevice { PIIODEVICE(PIBinaryLog, "binlog"); @@ -40,94 +42,147 @@ public: explicit PIBinaryLog(); virtual ~PIBinaryLog(); - //! \brief Play modes for \a PIBinaryLog - enum PlayMode { - PlayRealTime /*! Play in system realtime, default mode */, - PlayVariableSpeed /*! Play in software realtime with speed, set by \a setSpeed */, - PlayStaticDelay /*! Play with custom static delay, ignoring timestamp */ - }; + //! \~english Play modes for \a PIBinaryLog + //! \~russian Режимы воспроизведения для \a PIBinaryLog + enum PlayMode { + PlayRealTime /*! \~english Play in system realtime, default mode \~russian В системном реальном времени, режим по умолчанию */, + PlayVariableSpeed /*! \~english Play in software realtime with speed, set by \a setSpeed \~russian В программном реальном времени со скоростью, задаваемой через \a setSpeed */, + PlayStaticDelay /*! \~english Play with custom static delay, ignoring timestamp \~russian С пользовательской статической задержкой, игнорируя метку времени */ + }; - //! \brief Different split modes for writing \a PIBinaryLog, which can separate files by size, by time or by records count - enum SplitMode { - SplitNone /*! Without separate, default mode */, - SplitTime /*! Separate files by record time */, - SplitSize /*! Separate files by size */, - SplitCount /*! Separate files by records count */ - }; + //! \~english Different split modes for writing \a PIBinaryLog, which can separate files by size, by time or by records count + //! \~russian Различные режимы разделения для записи \a PIBinaryLog, позволяющие разделять файлы по размеру, времени или количеству записей + enum SplitMode { + SplitNone /*! \~english Without separate, default mode \~russian Без разделения, режим по умолчанию */, + SplitTime /*! \~english Separate files by record time \~russian Разделение файлов по времени записи */, + SplitSize /*! \~english Separate files by size \~russian Разделение файлов по размеру */, + SplitCount /*! \~english Separate files by records count \~russian Разделение файлов по количеству записей */ + }; #pragma pack(push, 8) - //! \brief Struct contains information about all records with same ID - struct PIP_EXPORT BinLogRecordInfo { - BinLogRecordInfo() { - id = count = 0; - minimum_size = maximum_size = 0; - } - int id; - int count; - int minimum_size; - int maximum_size; - PISystemTime start_time; - PISystemTime end_time; - }; + //! \~english Struct contains information about all records with same ID + //! \~russian Структура содержит информацию обо всех записях с одинаковым ID + struct PIP_EXPORT BinLogRecordInfo { + //! \~english Constructor, initializes all fields to zero + //! \~russian Конструктор, инициализирует все поля нулями + BinLogRecordInfo() { + id = count = 0; + minimum_size = maximum_size = 0; + } + //! \~english Record ID + //! \~russian ID записи + int id; + //! \~english Records count + //! \~russian Количество записей + int count; + //! \~english Minimum record size + //! \~russian Минимальный размер записи + int minimum_size; + //! \~english Maximum record size + //! \~russian Максимальный размер записи + int maximum_size; + //! \~english Start time of records + //! \~russian Время начала записей + PISystemTime start_time; + //! \~english End time of records + //! \~russian Время окончания записей + PISystemTime end_time; + }; - //! \brief Struct contains position, ID and timestamp of record in file - struct PIP_EXPORT BinLogIndex { - int id; - int data_size; - llong pos; - PISystemTime timestamp; - }; + //! \~english Struct contains position, ID and timestamp of record in file + //! \~russian Структура содержит позицию, ID и метку времени записи в файле + struct PIP_EXPORT BinLogIndex { + //! \~english Record ID + //! \~russian ID записи + int id; + //! \~english Data size + //! \~russian Размер данных + int data_size; + //! \~english Position in file + //! \~russian Позиция в файле + llong pos; + //! \~english Timestamp + //! \~russian Метка времени + PISystemTime timestamp; + }; #pragma pack(pop) - //! \brief Struct contains full information about Binary Log file and about all Records using map of \a BinLogRecordInfo - struct PIP_EXPORT BinLogInfo { - PIString path; - int records_count = 0; - llong log_size = 0L; - PISystemTime start_time; - PISystemTime end_time; - PIMap records; - PIByteArray user_header; - }; + //! \~english Struct contains full information about Binary Log file and about all Records using map of \a BinLogRecordInfo + //! \~russian Структура содержит полную информацию о файле бинарного лога и обо всех записях с использованием карты \a BinLogRecordInfo + struct PIP_EXPORT BinLogInfo { + //! \~english Path to the log file + //! \~russian Путь к файлу лога + PIString path; + //! \~english Total records count + //! \~russian Общее количество записей + int records_count = 0; + //! \~english Log file size + //! \~russian Размер файла лога + llong log_size = 0L; + //! \~english Start time of logging + //! \~russian Время начала логирования + PISystemTime start_time; + //! \~english End time of logging + //! \~russian Время окончания логирования + PISystemTime end_time; + //! \~english Map of record information by ID + //! \~russian Карта информации о записях по ID + PIMap records; + //! \~english User-defined header data + //! \~russian Пользовательские данные заголовка + PIByteArray user_header; + }; - //! Current \a PlayMode - PlayMode playMode() const { return play_mode; } + //! \~english Returns current \a PlayMode + //! \~russian Возвращает текущий \a PlayMode + PlayMode playMode() const { return play_mode; } - //! Current \a SplitMode - SplitMode splitMode() const { return split_mode; } + //! \~english Returns current \a SplitMode + //! \~russian Возвращает текущий \a SplitMode + SplitMode splitMode() const { return split_mode; } - //! Current directory where billogs wiil be saved - PIString logDir() const { return property("logDir").toString(); } + //! \~english Returns current directory where binlogs will be saved + //! \~russian Возвращает текущий каталог, куда будут сохраняться бинарные логи + PIString logDir() const { return property("logDir").toString(); } - //! Returns current file prefix - PIString filePrefix() const { return property("filePrefix").toString(); } + //! \~english Returns current file prefix + //! \~russian Возвращает текущий префикс файла + PIString filePrefix() const { return property("filePrefix").toString(); } - //! Default ID, used in \a write function - int defaultID() const { return default_id; } + //! \~english Returns default ID, used in \a write function + //! \~russian Возвращает ID по умолчанию, используемый в функции \a write + int defaultID() const { return default_id; } - //! Returns current play speed - double playSpeed() const { return play_speed > 0 ? 1. / play_speed : 0.; } + //! \~english Returns current play speed + //! \~russian Возвращает текущую скорость воспроизведения + double playSpeed() const { return play_speed > 0 ? 1. / play_speed : 0.; } - //! Returns current play delay - PISystemTime playDelay() const { return play_delay; } + //! \~english Returns current play delay + //! \~russian Возвращает текущую задержку воспроизведения + PISystemTime playDelay() const { return play_delay; } - //! Returns current binlog file split time - PISystemTime splitTime() const { return split_time; } + //! \~english Returns current binlog file split time + //! \~russian Возвращает текущее время разделения файла бинарного лога + PISystemTime splitTime() const { return split_time; } - //! Returns current binlog file split size - llong splitFileSize() const { return split_size; } + //! \~english Returns current binlog file split size + //! \~russian Возвращает текущий размер разделения файла бинарного лога + llong splitFileSize() const { return split_size; } - //! Returns current binlog file split records count - int splitRecordCount() const { return split_count; } + //! \~english Returns current binlog file split records count + //! \~russian Возвращает текущее количество записей для разделения файла бинарного лога + int splitRecordCount() const { return split_count; } - //! Returns if rapid start enabled - bool rapidStart() const { return rapid_start; } + //! \~english Returns if rapid start enabled + //! \~russian Возвращает, включено ли быстрое начало + bool rapidStart() const { return rapid_start; } - //! Returns if index creates while writing - bool createIndexOnFly() const { return create_index_on_fly; } + //! \~english Returns if index creates while writing + //! \~russian Возвращает, создается ли индекс во время записи + bool createIndexOnFly() const { return create_index_on_fly; } //! Create binlog file with Filename = path void createNewFile(const PIString & path); diff --git a/libs/main/io_utils/piconnection.h b/libs/main/io_utils/piconnection.h index 113688f7..62ee6e72 100644 --- a/libs/main/io_utils/piconnection.h +++ b/libs/main/io_utils/piconnection.h @@ -1,10 +1,13 @@ -/*! \file piconnection.h - * \brief - * \ingroup IO-Utils - * \~\brief - * \~english Complex I/O point - * \~russian Составное устройство ввода/вывода - */ +//! \addtogroup IO-Utils +//! \{ +//! \file piconnection.h +//! \brief +//! \~english Complex I/O point +//! \~russian Составное устройство ввода/вывода +//! \details +//! \~english This class provides a complex I/O point that can manage multiple devices, filters, channels, and senders. +//! \~russian Этот класс предоставляет составное устройство ввода/вывода, которое может управлять множеством устройств, фильтров, каналов и отправителей. +//! \~\} /* PIP - Platform Independent Primitives Complex I/O point @@ -34,269 +37,371 @@ class PIConfig; //! \~english Complex I/O point //! \~russian Составное устройство ввода/вывода +//! \details This class provides a complex I/O point that can manage multiple devices, filters, channels, and senders. +//! \~russian Этот класс предоставляет составное устройство ввода/вывода, которое может управлять множеством устройств, фильтров, каналов и отправителей. class PIP_EXPORT PIConnection: public PIObject { PIOBJECT_SUBCLASS(PIConnection, PIObject); public: - //! Constructs connection with name "name", or with default name = "connection" + //! \~english Constructs connection with name "name", or with default name = "connection" + //! \~russian Создает подключение с именем "name" или с именем по умолчанию "connection" PIConnection(const PIString & name = PIStringAscii("connection")); - //! Constructs connection and configure it from config file "config" from section "name" + //! \~english Constructs connection and configure it from config file "config" from section "name" + //! \~russian Создает подключение и настраивает его из файла конфигурации "config" из секции "name" PIConnection(const PIString & config, const PIString & name); - //! Constructs connection and configure it from config content "string" from section "name" + //! \~english Constructs connection and configure it from config content "string" from section "name" + //! \~russian Создает подключение и настраивает его из содержимого конфигурации "string" из секции "name" PIConnection(PIString * string, const PIString & name); + //! \~english Destructor + //! \~russian Деструктор ~PIConnection(); - /*! \brief Configure connection from config file "config" from section "name". Returns if configuration was successful - * \details \b Warning: all devices, filters and channels removed before configure! */ + //! \~english Configure connection from config file "config" from section "name". Returns if configuration was successful + //! \~russian Настраивает подключение из файла конфигурации "config" из секции "name". Возвращает успешность настройки + //! \details \b Warning: all devices, filters and channels removed before configure! + //! \~russian \b Внимание: все устройства, фильтры и каналы удаляются перед настройкой! bool configureFromConfig(const PIString & config, const PIString & name = PIStringAscii("connection")); - /*! \brief Configure connection from config content "string" from section "name". Returns if configuration was successful - * \details \b Warning: all devices, filters and channels removed before configure! */ + //! \~english Configure connection from config content "string" from section "name". Returns if configuration was successful + //! \~russian Настраивает подключение из содержимого конфигурации "string" из секции "name". Возвращает успешность настройки + //! \details \b Warning: all devices, filters and channels removed before configure! + //! \~russian \b Внимание: все устройства, фильтры и каналы удаляются перед настройкой! bool configureFromString(PIString * string, const PIString & name = PIStringAscii("connection")); - //! Returns config file section of current connection configuration + //! \~english Returns config file section of current connection configuration + //! \~russian Возвращает секцию файла конфигурации текущей конфигурации подключения PIString makeConfig() const; - /*! \brief Add device with full path "full_path", open mode "mode" to Device pool and connection - * \details Returns pointer to device or null if device can not be created. If "start" is true, - * read thread is started immediately. Else, you can start read thread with functions \a startThreadedRead() - * or \a startAllThreadedReads(). By default, read thread doesn`t start */ + //! \~english Add device with full path "full_path", open mode "mode" to Device pool and connection + //! \~russian Добавляет устройство с полным путем "full_path", режимом открытия "mode" в пул устройств и подключение + //! \details Returns pointer to device or null if device can not be created. If "start" is true, + //! \~english read thread is started immediately. Else, you can start read thread with functions \a startThreadedRead() + //! \~russian поток чтения запускается немедленно. В противном случае можно запустить поток чтения с помощью функций \a startThreadedRead() + //! \~english or \a startAllThreadedReads(). By default, read thread doesn`t start + //! \~russian или \a startAllThreadedReads(). По умолчанию поток чтения не запускается PIIODevice * addDevice(const PIString & full_path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite, bool start = false); + //! \~english Sets the name for device "dev" + //! \~russian Устанавливает имя для устройства "dev" void setDeviceName(PIIODevice * dev, const PIString & name); + //! \~english Returns list of device names + //! \~russian Возвращает список имен устройств PIStringList deviceNames(const PIIODevice * dev) const; - /*! \brief Remove device with full path "full_path" from connection - * \details Returns if device was removed. If there is no connection bounded to this device, - * it will be removed from Device pool */ + //! \~english Remove device with full path "full_path" from connection + //! \~russian Удаляет устройство с полным путем "full_path" из подключения + //! \details Returns if device was removed. If there is no connection bounded to this device, + //! \~english it will be removed from Device pool + //! \~russian оно будет удалено из пула устройств bool removeDevice(const PIString & full_path); - /*! \brief Remove all device from connection - * \details If there is no connection bounded to there devices, they removed from Device pool */ + //! \~english Remove all device from connection + //! \~russian Удаляет все устройства из подключения + //! \details If there is no connection bounded to there devices, they removed from Device pool + //! \~russian Если к устройствам не привязано подключение, они удаляются из пула устройств void removeAllDevices(); - //! Returns device with full path "full_path" or null if there is no such device + //! \~english Returns device with full path "full_path" or null if there is no such device + //! \~russian Возвращает устройство с полным путем "full_path" или null, если такого устройства нет PIIODevice * deviceByFullPath(const PIString & full_path) const; - //! Returns device with name "name" or null if there is no such device + //! \~english Returns device with name "name" or null if there is no such device + //! \~russian Возвращает устройство с именем "name" или null, если такого устройства нет PIIODevice * deviceByName(const PIString & name) const; - //! Returns all devices bounded to this connection + //! \~english Returns all devices bounded to this connection + //! \~russian Возвращает все устройства, привязанные к этому подключению PIVector boundedDevices() const; - /*! \brief Add filter with name "name" to device with full path "full_path_name" or filter "full_path_name" - * \details If there is no filter with name "name", connection create new with split mode "mode" and bound - * to it device "full_path_name" or filter "full_path_name". If filter with name "name" already exists, - * device "full_path_name" or filter "full_path_name" add to this filter. - * This function returns PIPacketExtractor * assosiated with this filter - * \n \b Attention! "mode" is altual olny if new filter was created! */ + //! \~english Add filter with name "name" to device with full path "full_path_name" or filter "full_path_name" + //! \~russian Добавляет фильтр с именем "name" к устройству с полным путем "full_path_name" или фильтру "full_path_name" + //! \details If there is no filter with name "name", connection create new with split mode "mode" and bound + //! \~english to it device "full_path_name" or filter "full_path_name". If filter with name "name" already exists, + //! \~english device "full_path_name" or filter "full_path_name" add to this filter. + //! \~russian к нему устройство "full_path_name" или фильтр "full_path_name". Если фильтр с именем "name" уже существует, + //! \~english This function returns PIPacketExtractor * assosiated with this filter + //! \~russian устройство "full_path_name" или фильтр "full_path_name" добавляется к этому фильтру. + //! \~english This function returns PIPacketExtractor * assosiated with this filter + //! \~russian Эта функция возвращает PIPacketExtractor *, связанный с этим фильтром + //! \~\sa PIPacketExtractor + //! \details \b Attention! "mode" is altual olny if new filter was created! + //! \~russian \b Внимание! "mode" актуален только если был создан новый фильтр! PIPacketExtractor * addFilter(const PIString & name, const PIString & full_path_name, PIPacketExtractor::SplitMode mode = PIPacketExtractor::None); - //! Add filter with name "name" to device "dev" + //! \~english Add filter with name "name" to device "dev" + //! \~russian Добавляет фильтр с именем "name" к устройству "dev" PIPacketExtractor * addFilter(const PIString & name, const PIIODevice * dev, PIPacketExtractor::SplitMode mode = PIPacketExtractor::None) { return addFilter(name, devFPath(dev), mode); } - //! Add filter with "filter" to device "dev" + //! \~english Add filter with "filter" to device "dev" + //! \~russian Добавляет фильтр "filter" к устройству "dev" PIPacketExtractor * addFilter(PIPacketExtractor * filter, const PIString & full_path_name); - //! Add filter with "filter" to device "dev" + //! \~english Add filter with "filter" to device "dev" + //! \~russian Добавляет фильтр "filter" к устройству "dev" PIPacketExtractor * addFilter(PIPacketExtractor * filter, const PIIODevice * dev) { return addFilter(filter, devFPath(dev)); } - /*! \brief Remove from filter with name "name" device with full path "full_path_name" or filter "full_path_name" - * \details If there is no devices bounded to this filter, it will be removed. Returns if device was removed */ + //! \~english Remove from filter with name "name" device with full path "full_path_name" or filter "full_path_name" + //! \~russian Удаляет из фильтра с именем "name" устройство с полным путем "full_path_name" или фильтр "full_path_name" + //! \details If there is no devices bounded to this filter, it will be removed. Returns if device was removed + //! \~russian Если к этому фильтру не привязано устройств, он будет удален. Возвращает успешность удаления устройства bool removeFilter(const PIString & name, const PIString & full_path_name); - //! Remove from filter with name "name" device or filter "dev" + //! \~english Remove from filter with name "name" device or filter "dev" + //! \~russian Удаляет из фильтра с именем "name" устройство или фильтр "dev" bool removeFilter(const PIString & name, const PIIODevice * dev); - //! Remove filter with name "name". Returns if filter was removed + //! \~english Remove filter with name "name". Returns if filter was removed + //! \~russian Удаляет фильтр с именем "name". Возвращает успешность удаления фильтра bool removeFilter(const PIString & name); - //! Remove all filters from connection + //! \~english Remove all filters from connection + //! \~russian Удаляет все фильтры из подключения void removeAllFilters(); - //! Returns all filters of connection + //! \~english Returns all filters of connection + //! \~russian Возвращает все фильтры подключения PIVector filters() const; - //! Returns all filter names of connection + //! \~english Returns all filter names of connection + //! \~russian Возвращает все имена фильтров подключения PIStringList filterNames() const; - //! Returns PIPacketExtractor * assosiated with filter "name" or null if there is no such filter + //! \~english Returns PIPacketExtractor * assosiated with filter "name" or null if there is no such filter + //! \~russian Возвращает PIPacketExtractor *, связанный с фильтром "name" или null, если такого фильтра нет PIPacketExtractor * filter(const PIString & name) const; - //! Returns all devices bounded to filter "name" + //! \~english Returns all devices bounded to filter "name" + //! \~russian Возвращает все устройства, привязанные к фильтру "name" PIVector filterBoundedDevices(const PIString & name) const; - /*! \brief Add to connection channel from "name_from" to "name_to" - * \details "name_from" and "name_to" can be full pathes of devices or device names or filter names. - * Returns \b false if there if no such device or filter, else create channel and returns \b true */ + //! \~english Add to connection channel from "name_from" to "name_to" + //! \~russian Добавляет в подключение канал от "name_from" к "name_to" + //! \details "name_from" and "name_to" can be full pathes of devices or device names or filter names. + //! \~english Returns \b false if there if no such device or filter, else create channel and returns \b true + //! \~russian Возвращает \b false, если такого устройства или фильтра нет, иначе создает канал и возвращает \b true bool addChannel(const PIString & name_from, const PIString & name_to); - //! Add to connection channel from "name_from" to "dev_to" + //! \~english Add to connection channel from "name_from" to "dev_to" + //! \~russian Добавляет в подключение канал от "name_from" к "dev_to" bool addChannel(const PIString & name_from, const PIIODevice * dev_to) { return addChannel(name_from, devFPath(dev_to)); } - //! Add to connection channel from "dev_from" to "name_to" + //! \~english Add to connection channel from "dev_from" to "name_to" + //! \~russian Добавляет в подключение канал от "dev_from" к "name_to" bool addChannel(const PIIODevice * dev_from, const PIString & name_to) { return addChannel(devFPath(dev_from), name_to); } - //! Add to connection channel from "dev_from" to "dev_to" + //! \~english Add to connection channel from "dev_from" to "dev_to" + //! \~russian Добавляет в подключение канал от "dev_from" к "dev_to" bool addChannel(const PIIODevice * dev_from, const PIIODevice * dev_to) { return addChannel(devFPath(dev_from), devFPath(dev_to)); } - /*! \brief Remove from connection channel from "name_from" to "name_to" - * \details "name_from" and "name_to" can be full pathes of devices or filter names. - * Returns \b false if there if no such device or filter, else remove channel and returns \b true */ + //! \~english Remove from connection channel from "name_from" to "name_to" + //! \~russian Удаляет из подключения канал от "name_from" к "name_to" + //! \details "name_from" and "name_to" can be full pathes of devices or filter names. + //! \~english Returns \b false if there if no such device or filter, else remove channel and returns \b true + //! \~russian Возвращает \b false, если такого устройства или фильтра нет, иначе удаляет канал и возвращает \b true bool removeChannel(const PIString & name_from, const PIString & name_to); - //! Remove from connection channel from "name_from" to "dev_to" + //! \~english Remove from connection channel from "name_from" to "dev_to" + //! \~russian Удаляет из подключения канал от "name_from" к "dev_to" bool removeChannel(const PIString & name_from, const PIIODevice * dev_to) { return removeChannel(name_from, devFPath(dev_to)); } - //! Remove from connection channel from "dev_from" to "name_to" + //! \~english Remove from connection channel from "dev_from" to "name_to" + //! \~russian Удаляет из подключения канал от "dev_from" к "name_to" bool removeChannel(const PIIODevice * dev_from, const PIString & name_to) { return removeChannel(devFPath(dev_from), name_to); } - //! Remove from connection channel from "dev_from" to "dev_to" + //! \~english Remove from connection channel from "dev_from" to "dev_to" + //! \~russian Удаляет из подключения канал от "dev_from" к "dev_to" bool removeChannel(const PIIODevice * dev_from, const PIIODevice * dev_to) { return removeChannel(devFPath(dev_from), devFPath(dev_to)); } - /*! \brief Remove from connection all channels from "name_from" - * \details "name_from" can be full path of device or filter name. - * Returns \b false if there if no such device or filter, else remove channels and returns \b true */ + //! \~english Remove from connection all channels from "name_from" + //! \~russian Удаляет из подключения все каналы от "name_from" + //! \details "name_from" can be full path of device or filter name. + //! \~english Returns \b false if there if no such device or filter, else remove channels and returns \b true + //! \~russian Возвращает \b false, если такого устройства или фильтра нет, иначе удаляет каналы и возвращает \b true bool removeChannel(const PIString & name_from); - //! Remove from connection all channels from "dev_from" + //! \~english Remove from connection all channels from "dev_from" + //! \~russian Удаляет из подключения все каналы от "dev_from" bool removeChannel(const PIIODevice * dev_from) { return removeChannel(devFPath(dev_from)); } - //! Remove from connection all channels + //! \~english Remove from connection all channels + //! \~russian Удаляет из подключения все каналы void removeAllChannels(); - //! Returns all channels of this connection as full pathes or filter names pair array (from, to) + //! \~english Returns all channels of this connection as full pathes or filter names pair array (from, to) + //! \~russian Возвращает все каналы этого подключения в виде массива пар полных путей или имен фильтров (от, до) PIVector> channels() const; - /*! \brief Add to connection sender with name "name" device with full path "full_path" - * \details If there is no sender with name "name", connection create new, bound - * to it device "full_path_name" and start sender timer with frequency "frequency". - * If sender with name "name" already exists, device "full_path_name" add to this sender - * If "start" is true, sender is started immediately. Else, you can start sender with - * functions \a startSender() - * \n \b Attention! "frequency" is actual olny if new sender was created! */ + //! \~english Add to connection sender with name "name" device with full path "full_path" + //! \~russian Добавляет в подключение отправителя с именем "name" устройство с полным путем "full_path" + //! \details If there is no sender with name "name", connection create new, bound + //! \~english to it device "full_path_name" and start sender timer with frequency "frequency". + //! \~russian к нему устройство "full_path_name" и запускает таймер отправителя с частотой "frequency". + //! \~english If sender with name "name" already exists, device "full_path_name" add to this sender + //! \~russian Если отправитель с именем "name" уже существует, устройство "full_path_name" добавляется к этому отправителю + //! \~english If "start" is true, sender is started immediately. Else, you can start sender with + //! \~russian Если "start" равно true, отправитель запускается немедленно. В противном случае можно запустить отправителя с помощью + //! \~english functions \a startSender() + //! \~russian функций \a startSender() + //! \~\sa startSender() + //! \details \b Attention! "frequency" is actual olny if new sender was created! + //! \~russian \b Внимание! "frequency" актуален только если был создан новый отправитель! void addSender(const PIString & name, const PIString & full_path_name, float frequency, bool start = false); - //! Add to connection sender with name "name" device "dev" + //! \~english Add to connection sender with name "name" device "dev" + //! \~russian Добавляет в подключение отправителя с именем "name" устройство "dev" void addSender(const PIString & name, const PIIODevice * dev, float frequency, bool start = false) { addSender(name, devFPath(dev), frequency, start); } - /*! \brief Remove from sender with name "name" device with full path "full_path_name" - * \details If there is no devices bounded to this sender, it will be removed. Returns if sender was removed */ + //! \~english Remove from sender with name "name" device with full path "full_path_name" + //! \~russian Удаляет из отправителя с именем "name" устройство с полным путем "full_path_name" + //! \details If there is no devices bounded to this sender, it will be removed. Returns if sender was removed + //! \~russian Если к этому отправителю не привязано устройств, он будет удален. Возвращает успешность удаления отправителя bool removeSender(const PIString & name, const PIString & full_path_name); - //! Remove from sender with name "name" device "dev" + //! \~english Remove from sender with name "name" device "dev" + //! \~russian Удаляет из отправителя с именем "name" устройство "dev" bool removeSender(const PIString & name, const PIIODevice * dev) { return removeSender(name, devFPath(dev)); } - //! Remove sender with name "name", returns if sender was removed + //! \~english Remove sender with name "name", returns if sender was removed + //! \~russian Удаляет отправителя с именем "name", возвращает успешность удаления отправителя bool removeSender(const PIString & name); - //! Set sender "name" fixed send data "data", returns if sender exists + //! \~english Set sender "name" fixed send data "data", returns if sender exists + //! \~russian Устанавливает фиксированные данные отправки для отправителя "name", возвращает существование отправителя bool setSenderFixedData(const PIString & name, const PIByteArray & data); - //! Remove sender "name" fixed send data, returns if sender exists + //! \~english Remove sender "name" fixed send data, returns if sender exists + //! \~russian Удаляет фиксированные данные отправки для отправителя "name", возвращает существование отправителя bool clearSenderFixedData(const PIString & name); - //! Returns sender "name" fixed send data + //! \~english Returns sender "name" fixed send data + //! \~russian Возвращает фиксированные данные отправки для отправителя "name" PIByteArray senderFixedData(const PIString & name) const; - //! Returns sender "name" timer frequency, -1 if there is no such sender, or 0 if sender is not started yet + //! \~english Returns sender "name" timer frequency, -1 if there is no such sender, or 0 if sender is not started yet + //! \~russian Возвращает частоту таймера отправителя "name", -1 если такого отправителя нет, или 0 если отправитель еще не запущен float senderFrequency(const PIString & name) const; - //! Remove from connection all senders + //! \~english Remove from connection all senders + //! \~russian Удаляет из подключения всех отправителей void removeAllSenders(); - //! Start read thread of device with full path "full_path" + //! \~english Start read thread of device with full path "full_path" + //! \~russian Запускает поток чтения устройства с полным путем "full_path" void startThreadedRead(const PIString & full_path_name); - //! Start read thread of device "dev" + //! \~english Start read thread of device "dev" + //! \~russian Запускает поток чтения устройства "dev" void startThreadedRead(const PIIODevice * dev) { startThreadedRead(devFPath(dev)); } - //! Start read threads of all Device pool device + //! \~english Start read threads of all Device pool device + //! \~russian Запускает потоки чтения всех устройств пула устройств void startAllThreadedReads(); - //! Start sender "name" timer + //! \~english Start sender "name" timer + //! \~russian Запускает таймер отправителя "name" void startSender(const PIString & name); - //! Start all senders timers + //! \~english Start all senders timers + //! \~russian Запускает все таймеры отправителей void startAllSenders(); - //! Start all read threads and senders + //! \~english Start all read threads and senders + //! \~russian Запускает все потоки чтения и отправителей void start() { startAllThreadedReads(); startAllSenders(); } - //! Stop read thread of device with full path "full_path" + //! \~english Stop read thread of device with full path "full_path" + //! \~russian Останавливает поток чтения устройства с полным путем "full_path" void stopThreadedRead(const PIString & full_path_name); - //! Stop read thread of device "dev" + //! \~english Stop read thread of device "dev" + //! \~russian Останавливает поток чтения устройства "dev" void stopThreadedRead(const PIIODevice * dev) { stopThreadedRead(devFPath(dev)); } - //! Stop read threads of all Device pool device + //! \~english Stop read threads of all Device pool device + //! \~russian Останавливает потоки чтения всех устройств пула устройств void stopAllThreadedReads(); - //! Stop sender "name" timer + //! \~english Stop sender "name" timer + //! \~russian Останавливает таймер отправителя "name" void stopSender(const PIString & name); - //! Stop all senders timers + //! \~english Stop all senders timers + //! \~russian Останавливает все таймеры отправителей void stopAllSenders(); - //! Stop all read threads and senders + //! \~english Stop all read threads and senders + //! \~russian Останавливает все потоки чтения и отправителей void stop() { stopAllThreadedReads(); stopAllSenders(); } - //! Stop connection and remove all devices + //! \~english Stop connection and remove all devices + //! \~russian Останавливает подключение и удаляет все устройства void destroy() { stop(); removeAllDevices(); } - //! Returns if there are no devices in this connection + //! \~english Returns if there are no devices in this connection + //! \~russian Возвращает, если в этом подключении нет устройств bool isEmpty() const { return device_modes.isEmpty(); } - //! Returns PIDiagnostics * assosiated with device with full path "full_path_name", name "full_path_name" or filter "full_path_name" + //! \~english Returns PIDiagnostics * assosiated with device with full path "full_path_name", name "full_path_name" or filter "full_path_name" + //! \~russian Возвращает PIDiagnostics *, связанный с устройством с полным путем "full_path_name", именем "full_path_name" или фильтром "full_path_name" PIDiagnostics * diagnostic(const PIString & full_path_name) const; - //! Returns PIDiagnostics * assosiated with device or filter "dev" + //! \~english Returns PIDiagnostics * assosiated with device or filter "dev" + //! \~russian Возвращает PIDiagnostics *, связанный с устройством или фильтром "dev" PIDiagnostics * diagnostic(const PIIODevice * dev) const { return diags_.value(const_cast(dev), 0); } - //! Write data "data" to device with full path "full_path" and returns result of \a write() function of device + //! \~english Write data "data" to device with full path "full_path" and returns result of \a write() function of device + //! \~russian Записывает данные "data" в устройство с полным путем "full_path" и возвращает результат функции \a write() устройства int writeByFullPath(const PIString & full_path, const PIByteArray & data); - //! Write data "data" to device with name "name" and returns result of \a write() function of device + //! \~english Write data "data" to device with name "name" and returns result of \a write() function of device + //! \~russian Записывает данные "data" в устройство с именем "name" и возвращает результат функции \a write() устройства int writeByName(const PIString & name, const PIByteArray & data); - //! Write data "data" to device "dev" and returns result of \a write() function of device + //! \~english Write data "data" to device "dev" and returns result of \a write() function of device + //! \~russian Записывает данные "data" в устройство "dev" и возвращает результат функции \a write() устройства int write(PIIODevice * dev, const PIByteArray & data); - //! Returns all connections in application + //! \~english Returns all connections in application + //! \~russian Возвращает все подключения в приложении static PIVector allConnections(); - //! Returns all devices in Device pool + //! \~english Returns all devices in Device pool + //! \~russian Возвращает все устройства в пуле устройств static PIVector allDevices(); - //! Set Device pool fake mode to \"yes\" and returns previous mode + //! \~english Set Device pool fake mode to \"yes\" and returns previous mode + //! \~russian Устанавливает фальшивый режим пула устройств в \"yes\" и возвращает предыдущий режим static bool setFakeMode(bool yes); - //! Returns if Device pool works in fake mode + //! \~english Returns if Device pool works in fake mode + //! \~russian Возвращает, работает ли пул устройств в фальшивом режиме static bool isFakeMode(); + //! \~english Device pool class + //! \~russian Класс пула устройств class PIP_EXPORT DevicePool: public PIThread { PIOBJECT_SUBCLASS(DevicePool, PIThread); friend void __DevicePool_threadReadDP(void * ddp); @@ -316,54 +421,95 @@ public: void unboundConnection(PIConnection * parent); PIIODevice * device(const PIString & fp) const; DeviceData * deviceData(PIIODevice * d) const; + //! \~english Returns list of bounded connections + //! \~russian Возвращает список привязанных подключений PIVector boundedConnections() const; + //! \~english Returns list of bounded devices + //! \~russian Возвращает список привязанных устройств PIVector boundedDevices() const; + //! \~english Returns list of bounded devices for specific parent connection + //! \~russian Возвращает список привязанных устройств для конкретного родительского подключения PIVector boundedDevices(const PIConnection * parent) const; protected: + //! \~english Device data structure + //! \~russian Структура данных устройства struct PIP_EXPORT DeviceData { + //! \~english Constructor + //! \~russian Конструктор DeviceData(): dev(0), rthread(0), started(false) {} + //! \~english Destructor + //! \~russian Деструктор ~DeviceData(); + //! \~english Device pointer + //! \~russian Указатель на устройство PIIODevice * dev; + //! \~english Read thread pointer + //! \~russian Указатель на поток чтения PIThread * rthread; + //! \~english Started flag + //! \~russian Флаг запуска bool started; + //! \~english List of listeners + //! \~russian Список слушателей PIVector listeners; }; + //! \~english Thread execution function + //! \~russian Функция выполнения потока void run() override; + //! \~english Called when device is read + //! \~russian Вызывается при чтении устройства void deviceReaded(DeviceData * dd, const PIByteArray & data); + //! \~english Map of devices + //! \~russian Карта устройств PIMap devices; + //! \~english Fake mode flag + //! \~russian Флаг фальшивого режима bool fake; }; + //! \~english Data received event + //! \~russian Событие получения данных EVENT2(dataReceivedEvent, const PIString &, from, const PIByteArray &, data); + //! \~english Packet received event + //! \~russian Событие получения пакета EVENT2(packetReceivedEvent, const PIString &, from, const PIByteArray &, data); + //! \~english Quality changed event + //! \~russian Событие изменения качества EVENT3(qualityChanged, const PIIODevice *, dev, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality); - //! \events + //! \~english Events + //! \~russian События //! \{ //! \fn void dataReceivedEvent(const PIString & from, const PIByteArray & data) - //! \brief Raise on data received from device with full path "from" + //! \~english Raise on data received from device with full path "from" + //! \~russian Возникает при получении данных от устройства с полным путем "from" //! \fn void packetReceivedEvent(const PIString & from, const PIByteArray & data) - //! \brief Raise on packet received from filter with name "from" + //! \~english Raise on packet received from filter with name "from" + //! \~russian Возникает при получении пакета от фильтра с именем "from" //! \fn void qualityChanged(const PIIODevice * device, PIDiagnostics::Quality new_quality, PIDiagnostics::Quality old_quality) - //! \brief Raise on diagnostic quality of device "device" changed from "old_quality" to "new_quality" + //! \~english Raise on diagnostic quality of device "device" changed from "old_quality" to "new_quality" + //! \~russian Возникает при изменении диагностического качества устройства "device" с "old_quality" на "new_quality" //! \} protected: - //! Executes on data received from device with full path "from" + //! \~english Executes on data received from device with full path "from" + //! \~russian Выполняется при получении данных от устройства с полным путем "from" virtual void dataReceived(const PIString & from, const PIByteArray & data) {} - //! Executes on packet received from filter with name "from" + //! \~english Executes on packet received from filter with name "from" + //! \~russian Выполняется при получении пакета от фильтра с именем "from" virtual void packetReceived(const PIString & from, const PIByteArray & data) {} - //! You should returns data for sender "sender_name" + //! \~english You should returns data for sender "sender_name" + //! \~russian Вы должны возвращать данные для отправителя "sender_name" virtual PIByteArray senderData(const PIString & sender_name); private: diff --git a/libs/main/io_utils/pidiagnostics.h b/libs/main/io_utils/pidiagnostics.h index cc50bd25..c5ac9417 100644 --- a/libs/main/io_utils/pidiagnostics.h +++ b/libs/main/io_utils/pidiagnostics.h @@ -1,9 +1,13 @@ -/*! \file pidiagnostics.h - * \ingroup IO - * \~\brief - * \~english Connection quality diagnostics - * \~russian Диагностика качества связи - */ +//! \addtogroup IO +//! \{ +//! \file pidiagnostics.h +//! \brief +//! \~english Connection quality diagnostics +//! \~russian Диагностика качества связи +//! \details +//! \~english This class provides connection quality diagnostics based on packet reception statistics +//! \~russian Класс обеспечивает диагностику качества связи на основе статистики приема пакетов +//! \~\} /* PIP - Platform Independent Primitives Speed and quality in/out diagnostics @@ -30,6 +34,8 @@ #include "pitimer.h" +//! \~english Connection quality diagnostics class based on packet statistics +//! \~russian Класс диагностики качества связи на основе статистики пакетов class PIP_EXPORT PIDiagnostics: public PITimer { PIOBJECT_SUBCLASS(PIDiagnostics, PITimer); friend class PIConnection; @@ -37,118 +43,215 @@ class PIP_EXPORT PIDiagnostics: public PITimer { public: NO_COPY_CLASS(PIDiagnostics); - //! Constructs an empty diagnostics and if "start_" start it + //! \~english Constructs an empty diagnostics and if "start_" start it + //! \~russian Создает пустую диагностику и запускает её, если "start_" установлено PIDiagnostics(bool start_ = true); + //! \~english Virtual destructor + //! \~russian Виртуальный деструктор virtual ~PIDiagnostics(); - //! Connection quality + //! \~english Connection quality enumeration + //! \~russian Перечисление качества связи enum Quality { - Unknown /** Unknown, no one packet received yet */ = 1, - Failure /** No connection, no one correct packet received for last period */ = 2, - Bad /** Bad connection, correct packets received <= 20% */ = 3, - Average /** Average connection, correct packets received > 20% and <= 80% */ = 4, - Good /** Good connection, correct packets received > 80% */ = 5 + //! \~english Unknown, no one packet received yet + //! \~russian Неизвестно, еще не получен ни один пакет + Unknown = 1, + //! \~english No connection, no one correct packet received for last period + //! \~russian Нет соединения, за последний период не получено ни одного корректного пакета + Failure = 2, + //! \~english Bad connection, correct packets received <= 20% + //! \~russian Плохое соединение, корректных пакетов получено <= 20% + Bad = 3, + //! \~english Average connection, correct packets received > 20% and <= 80% + //! \~russian Среднее соединение, корректных пакетов получено > 20% и <= 80% + Average = 4, + //! \~english Good connection, correct packets received > 80% + //! \~russian Хорошее соединение, корректных пакетов получено > 80% + Good = 5 }; - //! Information about current diagnostics state + //! \~english Information about current diagnostics state + //! \~russian Информация о текущем состоянии диагностики struct PIP_EXPORT State { + //! \~english Default constructor + //! \~russian Конструктор по умолчанию State(); + //! \~english Immediate frequency in Hz + //! \~russian Мгновенная частота в Гц float immediate_freq = 0.f; + //! \~english Integral frequency in Hz + //! \~russian Интегральная частота в Гц float integral_freq = 0.f; + //! \~english Received packets per second + //! \~russian Принятых пакетов в секунду ullong received_packets_per_sec = 0ull; + //! \~english Total received packets count + //! \~russian Общее количество принятых пакетов ullong received_packets = 0ull; + //! \~english Total received wrong packets count + //! \~russian Общее количество неправильно принятых пакетов ullong received_packets_wrong = 0ull; + //! \~english Received bytes per second + //! \~russian Принятых байт в секунду ullong received_bytes_per_sec = 0ull; + //! \~english Total received bytes count + //! \~russian Общее количество принятых байт ullong received_bytes = 0ull; + //! \~english Total received wrong bytes count + //! \~russian Общее количество неправильно принятых байт ullong received_bytes_wrong = 0ull; + //! \~english Sended packets per second + //! \~russian Отправленных пакетов в секунду ullong sended_packets_per_sec = 0ull; + //! \~english Total sended packets count + //! \~russian Общее количество отправленных пакетов ullong sended_packets = 0ull; + //! \~english Sended bytes per second + //! \~russian Отправленных байт в секунду ullong sended_bytes_per_sec = 0ull; + //! \~english Total sended bytes count + //! \~russian Общее количество отправленных байт ullong sended_bytes = 0ull; + //! \~english Receive speed string in format "n {B|kB|MB|GB|TB}/s" + //! \~russian Строка скорости приема в формате "n {B|kB|MB|GB|TB}/s" PIString receive_speed; + //! \~english Send speed string in format "n {B|kB|MB|GB|TB}/s" + //! \~russian Строка скорости отправки в формате "n {B|kB|MB|GB|TB}/s" PIString send_speed; + //! \~english Current connection quality + //! \~russian Текущее качество соединения PIDiagnostics::Quality quality = PIDiagnostics::Unknown; }; - //! Returns current state + //! \~english Returns current diagnostics state + //! \~russian Возвращает текущее состояние диагностики PIDiagnostics::State state() const; - //! Returns period of full disconnect in seconds and period of averaging frequency + //! \~english Returns period of full disconnect in seconds and period of averaging frequency + //! \~russian Возвращает период полного отключения в секундах и период усреднения частоты PISystemTime disconnectTimeout() const { return disconn_; } - //! Returns period of full disconnect in seconds and period of averaging frequency + //! \~english Set disconnect timeout (deprecated, use PISystemTime version) + //! \~russian Установить таймаут отключения (устаревший, используйте версию с PISystemTime) void setDisconnectTimeout(float s) DEPRECATEDM("use setDisconnectTimeout(PISystemTime)") { setDisconnectTimeout(PISystemTime::fromSeconds(s)); } - //! Returns period of full disconnect and period of averaging frequency + //! \~english Set disconnect timeout + //! \~russian Установить таймаут отключения void setDisconnectTimeout(PISystemTime tm) { setProperty("disconnectTimeout", tm); } - //! Returns connection quality + //! \~english Returns connection quality + //! \~russian Возвращает качество соединения PIDiagnostics::Quality quality() const; - //! Returns receive speed in format "n {B|kB|MB|GB|TB}/s" + //! \~english Returns receive speed in format "n {B|kB|MB|GB|TB}/s" + //! \~russian Возвращает скорость приема в формате "n {B|kB|MB|GB|TB}/s" PIString receiveSpeed() const; - //! Returns send speed in format "n {B|kB|MB|GB|TB}/s" + //! \~english Returns send speed in format "n {B|kB|MB|GB|TB}/s" + //! \~russian Возвращает скорость отправки в формате "n {B|kB|MB|GB|TB}/s" PIString sendSpeed() const; - - EVENT_HANDLER0(void, start); - EVENT_HANDLER1(void, start, PISystemTime, interval); - EVENT_HANDLER0(void, reset); - - EVENT_HANDLER1(void, received, int, size) { received(size, true); } - EVENT_HANDLER2(void, received, int, size, bool, correct); - EVENT_HANDLER1(void, sended, int, size); - - EVENT2(qualityChanged, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality); - //! \handlers //! \{ - //! \fn void start(double msecs = 1000.) - //! \brief Start diagnostics evaluations with period "msecs" milliseconds + //! \fn void start() + //! \~english Start diagnostics with default period (1000ms) + //! \~russian Запустить диагностику с периодом по умолчанию (1000мс) + EVENT_HANDLER0(void, start); + + //! \fn void start(PISystemTime interval) + //! \~english Start diagnostics with specified period + //! \~russian Запустить диагностику с указанным периодом + EVENT_HANDLER1(void, start, PISystemTime, interval); //! \fn void reset() - //! \brief Reset diagnostics counters + //! \~english Reset diagnostics counters + //! \~russian Сбросить счетчики диагностики + EVENT_HANDLER0(void, reset); - //! \fn void received(int size, bool correct = true) - //! \brief Notify diagnostics about "correct" corected received packet + //! \fn void received(int size) + //! \~english Notify diagnostics about received packet + //! \~russian Уведомить диагностику о принятом пакете + EVENT_HANDLER1(void, received, int, size) { received(size, true); } + + //! \fn void received(int size, bool correct) + //! \~english Notify diagnostics about received packet with correctness flag + //! \~russian Уведомить диагностику о принятом пакете с флагом корректности + EVENT_HANDLER2(void, received, int, size, bool, correct); //! \fn void sended(int size) - //! \brief Notify diagnostics about sended packet + //! \~english Notify diagnostics about sended packet + //! \~russian Уведомить диагностику об отправленном пакете + EVENT_HANDLER1(void, sended, int, size); //! \} //! \events //! \{ //! \fn void qualityChanged(PIDiagnostics::Quality new_quality, PIDiagnostics::Quality old_quality) - //! \brief Raise on change receive quality from "old_quality" to "new_quality" + //! \~english Emitted when receive quality changes + //! \~russian Генерируется при изменении качества приема + EVENT2(qualityChanged, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality); //! \} private: + //! \~english Internal structure for packet statistics history + //! \~russian Внутренняя структура для истории статистики пакетов struct PIP_EXPORT Entry { + //! \~english Number of correct bytes + //! \~russian Количество корректных байт ullong bytes_ok = 0; + //! \~english Number of wrong bytes + //! \~russian Количество неправильных байт ullong bytes_fail = 0; + //! \~english Count of correct packets + //! \~russian Количество корректных пакетов uint cnt_ok = 0; + //! \~english Count of wrong packets + //! \~russian Количество неправильных пакетов uint cnt_fail = 0; + //! \~english Flag indicating if entry is empty + //! \~russian Флаг, указывающий, что запись пустая bool empty = true; }; + //! \~english Equality operator for Entry structure + //! \~russian Оператор равенства для структуры Entry friend bool operator==(const PIDiagnostics::Entry & f, const PIDiagnostics::Entry & s); + //! \~english Inequality operator for Entry structure + //! \~russian Оператор неравенства для структуры Entry friend bool operator!=(const PIDiagnostics::Entry & f, const PIDiagnostics::Entry & s); + //! \~english Less-than operator for Entry structure + //! \~russian Оператор меньше для структуры Entry friend bool operator<(const PIDiagnostics::Entry & f, const PIDiagnostics::Entry & s); + //! \~english Timer tick handler + //! \~russian Обработчик тика таймера void tick(int) override; + //! \~english Calculate history statistics + //! \~russian Вычислить статистику истории Entry calcHistory(PIQueue & hist, int & cnt); + //! \~english Property changed handler + //! \~russian Обработчик изменения свойства void propertyChanged(const char *) override; + //! \~english Change disconnect timeout + //! \~russian Изменить таймаут отключения void changeDisconnectTimeout(PISystemTime disct); + //! \~english History queue for received packets + //! \~russian Очередь истории для принятых пакетов PIQueue history_rec, history_send; + //! \~english Disconnect timeout + //! \~russian Таймаут отключения PISystemTime disconn_; + //! \~english Current state + //! \~russian Текущее состояние State cur_state; + //! \~english Mutex for state access protection + //! \~russian Мьютекс для защиты доступа к состоянию mutable PIMutex mutex_state; }; diff --git a/libs/main/io_utils/pipacketextractor.h b/libs/main/io_utils/pipacketextractor.h index 7348068c..ea6e1bdf 100644 --- a/libs/main/io_utils/pipacketextractor.h +++ b/libs/main/io_utils/pipacketextractor.h @@ -1,9 +1,13 @@ -/*! \file pipacketextractor.h - * \ingroup IO - * \~\brief - * \~english Packets extractor - * \~russian Извлекатель пакетов - */ +//! \addtogroup IO +//! \{ +//! \file pipacketextractor.h +//! \brief +//! \~english Packets extractor +//! \~russian Извлекатель пакетов +//! \details +//! \~english The PIPacketExtractor class provides packet recognition from data stream using various algorithms. +//! \~russian Класс PIPacketExtractor предоставляет распознавание пакетов из потока данных с использованием различных алгоритмов. +//! \~\} /* PIP - Platform Independent Primitives Packets extractor @@ -28,21 +32,25 @@ #include "piiodevice.h" -/// TODO: написать документацию, тут ничего не понятно -/// Pass SourceHeaderPtr, ReceivedHeaderPtr, HeaderSize. -/// Return size of payload if packet is correct, or -1 if incorrect. +//! \~english Header validation function type +//! \~russian Тип функции проверки заголовка typedef std::function PacketExtractorHeaderFunc; -/// Pass ReceivedDataPtr, DataSize. -/// Return true if packet is correct, false otherwise. +//! \~english Payload validation function type +//! \~russian Тип функции проверки полезной нагрузки typedef std::function PacketExtractorPayloadFunc; -/// Pass SourceFooterPtr, ReceivedFooterPtr, FooterSize. -/// Return true if packet is correct, false otherwise. +//! \~english Footer validation function type +//! \~russian Тип функции проверки окончания typedef std::function PacketExtractorFooterFunc; //! \~english Packets extractor //! \~russian Извлекатель пакетов +//! \details +//! \~english The PIPacketExtractor class provides packet recognition from data stream using various algorithms such as header detection, +//! footer detection, size-based extraction, and timeout-based extraction. +//! \~russian Класс PIPacketExtractor предоставляет распознавание пакетов из потока данных с использованием различных алгоритмов, таких как +//! обнаружение заголовка, обнаружение окончания, извлечение по размеру и извлечение по таймауту. class PIP_EXPORT PIPacketExtractor: public PIIODevice { PIIODEVICE(PIPacketExtractor, "pckext"); friend class PIConnection; @@ -50,6 +58,9 @@ class PIP_EXPORT PIPacketExtractor: public PIIODevice { public: //! \~english Extract algorithms //! \~russian Алгоритмы извлечения + //! \details + //! \~english Defines the packet extraction algorithms supported by PIPacketExtractor + //! \~russian Определяет алгоритмы извлечения пакетов, поддерживаемые PIPacketExtractor enum SplitMode { None /** No data processing */, Header /** Detect packets with \a header() and following \a payloadSize() */, @@ -78,64 +89,108 @@ public: //! \~english Get bytes available //! \~russian Получить доступные байты + //! \details + //! \~english Returns the number of bytes available for reading from the child device + //! \~russian Возвращает количество байт, доступных для чтения из дочернего устройства ssize_t bytesAvailable() const override; //! \~english Set header check function //! \~russian Установить функцию проверки заголовка + //! \details + //! \~english Sets the callback function used to validate packet headers + //! \~russian Устанавливает функцию обратного вызова, используемую для проверки заголовков пакетов void setHeaderCheckSlot(PacketExtractorHeaderFunc f) { func_header = f; } //! \~english Set payload check function //! \~russian Установить функцию проверки полезной нагрузки + //! \details + //! \~english Sets the callback function used to validate packet payload + //! \~russian Устанавливает функцию обратного вызова, используемую для проверки полезной нагрузки пакетов void setPayloadCheckSlot(PacketExtractorPayloadFunc f) { func_payload = f; } //! \~english Set footer check function //! \~russian Установить функцию проверки окончания + //! \details + //! \~english Sets the callback function used to validate packet footers + //! \~russian Устанавливает функцию обратного вызова, используемую для проверки окончаний пакетов void setFooterCheckSlot(PacketExtractorFooterFunc f) { func_footer = f; } //! \~english Set extract algorithm //! \~russian Установить алгоритм извлечения + //! \details + //! \~english Sets the packet extraction algorithm to be used + //! \~russian Устанавливает алгоритм извлечения пакетов, который будет использоваться void setSplitMode(SplitMode mode) { setProperty("splitMode", int(mode)); } //! \~english Set payload size, used for PIPacketExtractor::Header and PIPacketExtractor::Footer algorithms //! \~russian Установить размер полезной нагрузки + //! \details + //! \~english Sets the expected payload size for Header and Footer extraction algorithms + //! \~russian Устанавливает ожидаемый размер полезной нагрузки для алгоритмов извлечения Header и Footer void setPayloadSize(int size); //! \~english Set header data, used for PIPacketExtractor::Header and PIPacketExtractor::HeaderAndFooter algorithms //! \~russian Установить данные заголовка + //! \details + //! \~english Sets the header pattern used to identify packet start + //! \~russian Устанавливает шаблон заголовка, используемый для идентификации начала пакета void setHeader(const PIByteArray & data); //! \~english Set footer data, used for PIPacketExtractor::Footer and PIPacketExtractor::HeaderAndFooter algorithms //! \~russian Установить данные окончания + //! \details + //! \~english Sets the footer pattern used to identify packet end + //! \~russian Устанавливает шаблон окончания, используемый для идентификации конца пакета void setFooter(const PIByteArray & data); //! \~english Set timeout, used for PIPacketExtractor::Timeout algorithm //! \~russian Установить таймаут + //! \details Sets the timeout duration for the Timeout extraction algorithm + //! \~russian Устанавливает длительность таймаута для алгоритма извлечения Timeout void setTimeout(PISystemTime tm) { setProperty("timeout", tm); } //! \~english Returns current extract algorithm //! \~russian Возвращает текущий алгоритм извлечения + //! \details + //! \~english Returns the currently configured packet extraction algorithm + //! \~russian Возвращает текущий настроенный алгоритм извлечения пакетов SplitMode splitMode() const { return mode_; } //! \~english Returns current payload size //! \~russian Возвращает текущий размер полезной нагрузки + //! \details + //! \~english Returns the expected payload size used by Header and Footer algorithms + //! \~russian Возвращает ожидаемый размер полезной нагрузки, используемый алгоритмами Header и Footer int payloadSize() const { return dataSize; } //! \~english Returns current header data //! \~russian Возвращает текущие данные заголовка + //! \details + //! \~english Returns the configured header pattern + //! \~russian Возвращает настроенный шаблон заголовка PIByteArray header() const { return src_header; } //! \~english Returns current footer data //! \~russian Возвращает текущие данные окончания + //! \details + //! \~english Returns the configured footer pattern + //! \~russian Возвращает настроенный шаблон окончания PIByteArray footer() const { return src_footer; } //! \~english Returns current timeout in milliseconds //! \~russian Возвращает текущий таймаут в миллисекундах + //! \details + //! \~english Returns the configured timeout duration + //! \~russian Возвращает настроенную длительность таймаута PISystemTime timeout() const { return time_; } //! \~english Returns missed by validating functions bytes count //! \~russian Возвращает количество байт, пропущенных функциями проверки + //! \details + //! \~english Returns the number of bytes that were skipped during validation failures + //! \~russian Возвращает количество байт, которые были пропущены при неудачных проверках ullong missedBytes() const { return missed; } //! \~english Add data to extractor, raise \a packetReceived() if packet is ready @@ -146,13 +201,12 @@ public: //! \~russian Добавить данные в экстрактор, вызвать \a packetReceived() если пакет готов void appendData(const PIByteArray & data) { threadedRead(data.data(), data.size_s()); } - EVENT2(packetReceived, const uchar *, data, int, size); - //! \events //! \{ //! \fn void packetReceived(const uchar * data, int size) //! \brief Raise on successfull \a packetValidate() function + EVENT2(packetReceived, const uchar *, data, int, size); //! \} diff --git a/libs/main/io_utils/piparsehelper.h b/libs/main/io_utils/piparsehelper.h index c4c7bff0..47e4dfc2 100644 --- a/libs/main/io_utils/piparsehelper.h +++ b/libs/main/io_utils/piparsehelper.h @@ -1,9 +1,16 @@ -/*! \file piparsehelper.h - * \ingroup IO - * \~\brief - * \~english Helper class to automate structs receive - * \~russian Класс для автоматизации приема структур - */ +//! \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 @@ -30,62 +37,49 @@ #include "pip_io_utils_export.h" -/** \class PIParseHelper - * \brief Helper class to automate structs receive - * - * - * \section PIParseHelper_synopsis Synopsis - * This class helps to deserialize and invoke neccessarily methods. - * - * Data packets with header and various data types can be automated by this class. - * Every key value mapped to object member function, lambda-function or functor. - * - * This class can remove \b switch-case with deserialization code and - * replace it with several \a assign() calls, binded to ready-to-use event handlers. - * Moreover data type automatic takes from event handler or lambda argument. One should - * only make \"PIByteArray & operator <<()\" with used types, deserialization will be - * performed by %PIParseHelper. - * - * - * \section PIParseHelper_usage Usage - * - * Create instance of %PIParseHelper, or subclass. - * - * In \a assign() methods you can use object member function, lambda-function - * or functor with 0 or 1 arguments, - * - * - * \section PIParseHelper_lambda Lambda-functions - * \code assign(1, [this](const SomeStruct & s){}) \endcode - * - * - * \section PIParseHelper_examples Examples - * First example describes subclass variant. As one can see, it`s a single place to change - * type of received data - event handler argument. - * \snippet piparsehelper.cpp 0 - * - * Second example show separate variant: - * \snippet piparsehelper.cpp 1 - * - **/ +//! \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(). Извлечение типа данных автоматически выполняется из +//! сигнатуры обработчика. -//! \~english Template helper class to automate structs receive -//! \~russian Шаблонный класс для автоматизации приема структур template class PIParseHelper { public: - //! \brief Construct %PIParseHelper + //! \~english Construct PIParseHelper + //! \~russian Создать PIParseHelper PIParseHelper() {} - //! \brief Assign key \"key\" to lambda-function \"func\" without arguments + //! \~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 func) { auto lf = [func](PIByteArray) { func(); }; functions[key] << lf; } - //! \brief Assign key \"key\" to lambda-function \"func\" with 1 argument + //! \~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 void assign(Key key, std::function func) { auto lf = [func](PIByteArray data) { @@ -99,7 +93,17 @@ public: } - //! \brief Assign key \"key\" to member function of object \"obj\" without arguments + //! \~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 void assign(Key key, O * obj, void (O::*member_func)()) { auto lf = [member_func, obj](PIByteArray) { (obj->*member_func)(); }; @@ -107,7 +111,17 @@ public: } - //! \brief Assign key \"key\" to member function of object \"obj\" with 1 argument + //! \~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 void assign(Key key, O * obj, void (O::*member_func)(const T &)) { auto lf = [member_func, obj](PIByteArray data) { @@ -121,14 +135,28 @@ public: } - //! \brief Assign key \"key\" to functor \"func\" with 0 or 1 argument + //! \~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 void assign(Key key, L func) { return assign(key, toStdFunction(func)); } - //! \brief Deserialize data and invoke assigned to \"key\" methods + //! \~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) @@ -136,8 +164,11 @@ public: } private: + //! \~english Map of assigned functions + //! \~russian Карта назначенных функций PIMap>> functions; }; +//! \} #endif // PIPARSEHELPER_H diff --git a/libs/main/math/pievaluator.h b/libs/main/math/pievaluator.h index e071a6ae..d9a937c7 100644 --- a/libs/main/math/pievaluator.h +++ b/libs/main/math/pievaluator.h @@ -1,12 +1,14 @@ //! \addtogroup Math //! \{ //! \file pievaluator.h -//! \brief -//! \~english Mathematic expressions calculator -//! \~russian Вычислитель математических выражений +//! \brief Mathematical expressions evaluator +//! \~english Mathematical expressions evaluator for parsing and calculating math expressions +//! \~russian Вычислитель математических выражений для разбора и вычисления математических выражений //! \details -//! \~english Evaluator for parsing and calculating mathematical expressions -//! \~russian Вычислитель для разбора и вычисления математических выражений +//! \~english PIEvaluator provides functionality to parse and evaluate mathematical expressions. It supports variables, functions (both +//! built-in and custom), and various operators including arithmetic, comparison, and logical operations. +//! \~russian PIEvaluator предоставляет функциональность для разбора и вычисления математических выражений. Поддерживаются переменные, +//! функции (как встроенные, так и пользовательские), а также различные операторы: арифметические, сравнения и логические. //! \} /* PIP - Platform Independent Primitives @@ -36,146 +38,292 @@ namespace PIEvaluatorTypes { +//! \~english Handler function type for custom functions +//! \~russian Тип обработчика для пользовательских функций typedef std::function FuncHanlder; +//! \~english Type of evaluator element +//! \~russian Тип элемента вычислителя enum eType { - etNumber, - etOperator, - etVariable, - etFunction -}; -enum Operation { - oNone, - oAdd, - oSubtract, - oMultiply, - oDivide, - oResidue, - oPower, - oEqual, - oNotEqual, - oGreater, - oSmaller, - oGreaterEqual, - oSmallerEqual, - oAnd, - oOr, - oFunction -}; -enum BaseFunctions { - bfUnknown, - bfSin, - bfCos, - bfTg, - bfCtg, - bfArcsin, - bfArccos, - bfArctg, - bfArcctg, - bfExp, - bfRandom, - bfRandomn, - bfSh, - bfCh, - bfTh, - bfCth, - bfSqrt, - bfSqr, - bfPow, - bfAbs, - bfLn, - bfLg, - bfLog, - bfSign, - bfIm, - bfRe, - bfArg, - bfLen, - bfConj, - bfRad, - bfDeg, - bfJ0, - bfJ1, - bfJN, - bfY0, - bfY1, - bfYN, - bfMin, - bfMax, - bfClamp, - bfStep, - bfMix, - bfDefined, - bfRound, - bfCustom = 0xFFFF + etNumber, //! \~english Number value + //! \~russian Числовое значение + etOperator, //! \~english Operator symbol + //! \~russian Символ оператора + etVariable, //! \~english Variable reference + //! \~russian Ссылка на переменную + etFunction //! \~english Function call + //! \~russian Вызов функции }; +//! \~english Operation types supported by evaluator +//! \~russian Типы операций, поддерживаемые вычислителем +enum Operation { + oNone, //! \~english No operation + //! \~russian Нет операции + oAdd, //! \~english Addition operator (+) + //! \~russian Оператор сложения (+) + oSubtract, //! \~english Subtraction operator (-) + //! \~russian Оператор вычитания (-) + oMultiply, //! \~english Multiplication operator (*) + //! \~russian Оператор умножения (*) + oDivide, //! \~english Division operator (/) + //! \~russian Оператор деления (/) + oResidue, //! \~english Residue operator + //! \~russian Оператор остатка + oPower, //! \~english Power operator (^) + //! \~russian Оператор возведения в степень (^) + oEqual, //! \~english Equal comparison operator (=) + //! \~russian Оператор равенства (=) + oNotEqual, //! \~english Not equal comparison operator (<>) + //! \~russian Оператор неравенства (<>) + oGreater, //! \~english Greater than comparison operator (>) + //! \~russian Оператор больше (>) + oSmaller, //! \~english Smaller than comparison operator (<) + //! \~russian Оператор меньше (<) + oGreaterEqual, //! \~english Greater or equal comparison operator (>=) + //! \~russian Оператор больше или равно (>=) + oSmallerEqual, //! \~english Smaller or equal comparison operator (<=) + //! \~russian Оператор меньше или равно (<=) + oAnd, //! \~english Logical AND operator + //! \~russian Логический оператор И + oOr, //! \~english Logical OR operator + //! \~russian Логический оператор ИЛИ + oFunction //! \~english Function call + //! \~russian Вызов функции +}; + +//! \~english Built-in base functions supported by evaluator +//! \~russian Встроенные базовые функции, поддерживаемые вычислителем +enum BaseFunctions { + bfUnknown, //! \~english Unknown function + //! \~russian Неизвестная функция + bfSin, //! \~english Sine function + //! \~russian Синус + bfCos, //! \~english Cosine function + //! \~russian Косинус + bfTg, //! \~english Tangent function + //! \~russian Тангенс + bfCtg, //! \~english Cotangent function + //! \~russian Котангенс + bfArcsin, //! \~english Arcsine function + //! \~russian Арксинус + bfArccos, //! \~english Arccosine function + //! \~russian Арккосинус + bfArctg, //! \~english Arctangent function + //! \~russian Арктангенс + bfArcctg, //! \~english Arccotangent function + //! \~russian Арккотангенс + bfExp, //! \~english Exponential function (e^x) + //! \~russian Экспонента (e^x) + bfRandom, //! \~english Random number generator [0,1] + //! \~russian Генератор случайных чисел [0,1] + bfRandomn, //! \~english Normal distribution random number + //! \~russian Случайное число с нормальным распределением + bfSh, //! \~english Hyperbolic sine + //! \~russian Гиперболический синус + bfCh, //! \~english Hyperbolic cosine + //! \~russian Гиперболический косинус + bfTh, //! \~english Hyperbolic tangent + //! \~russian Гиперболический тангенс + bfCth, //! \~english Hyperbolic cotangent + //! \~russian Гиперболический котангенс + bfSqrt, //! \~english Square root + //! \~russian Квадратный корень + bfSqr, //! \~english Square function (x^2) + //! \~russian Возведение в квадрат (x^2) + bfPow, //! \~english Power function + //! \~russian Возведение в степень + bfAbs, //! \~english Absolute value + //! \~russian Модуль (абсолютное значение) + bfLn, //! \~english Natural logarithm + //! \~russian Натуральный логарифм + bfLg, //! \~english Base-10 logarithm + //! \~russian Десятичный логарифм + bfLog, //! \~english Base-N logarithm + //! \~russian Логарифм по основанию N + bfSign, //! \~english Sign function + //! \~russian Знак числа + bfIm, //! \~english Imaginary part of complex number + //! \~russian Мнимая часть комплексного числа + bfRe, //! \~english Real part of complex number + //! \~russian Действительная часть комплексного числа + bfArg, //! \~english Argument (phase) of complex number + //! \~russian Аргумент (фаза) комплексного числа + bfLen, //! \~english Length (magnitude) of complex number + //! \~russian Модуль (длина) комплексного числа + bfConj, //! \~english Complex conjugate + //! \~russian Комплексно-сопряженное + bfRad, //! \~english Convert degrees to radians + //! \~russian Перевод градусов в радианы + bfDeg, //! \~english Convert radians to degrees + //! \~russian Перевод радианов в градусы + bfJ0, //! \~english Bessel function J0 + //! \~russian Функция Бесселя J0 + bfJ1, //! \~english Bessel function J1 + //! \~russian Функция Бесселя J1 + bfJN, //! \~english Bessel function Jn + //! \~russian Функция Бесселя Jn + bfY0, //! \~english Bessel function Y0 + //! \~russian Функция Бесселя Y0 + bfY1, //! \~english Bessel function Y1 + //! \~russian Функция Бесселя Y1 + bfYN, //! \~english Bessel function Yn + //! \~russian Функция Бесселя Yn + bfMin, //! \~english Minimum of two values + //! \~russian Минимум из двух значений + bfMax, //! \~english Maximum of two values + //! \~russian Максимум из двух значений + bfClamp, //! \~english Clamp value to range + //! \~russian Ограничение значения диапазоном + bfStep, //! \~english Step function + //! \~russian Ступенчатая функция + bfMix, //! \~english Mix/interpolation function + //! \~russian Смешивание/интерполяция + bfDefined, //! \~english Check if variable is defined + //! \~russian Проверка определена ли переменная + bfRound, //! \~english Round to nearest integer + //! \~russian Округление до ближайшего целого + bfCustom = 0xFFFF //! \~english Custom user-defined function + //! \~russian Пользовательская функция +}; + +//! \~english Instruction for evaluator - contains operation, output index, function index and operator indices +//! \~russian Инструкция для вычислителя - содержит операцию, индекс вывода, индекс функции и индексы операторов struct PIP_EXPORT Instruction { + //! \~english Constructs empty instruction with default values + //! \~russian Создает пустую инструкцию со значениями по умолчанию Instruction() { out = -1; function = -1; operation = oNone; } + + //! \~english Constructs instruction with operation, operators, output index and optional function index + //! \~russian Создает инструкцию с указанной операцией, операторами, индексом вывода и опционально индексом функции Instruction(Operation oper, PIVector opers, short out_ind, short func = -1) { operation = oper; operators = opers; out = out_ind; function = func; } + + //! \~english Operation to perform + //! \~russian Операция для выполнения Operation operation; + //! \~english Output variable index + //! \~russian Индекс переменной вывода short out; + //! \~english Function index (if operation is function call) + //! \~russian Индекс функции (если операция - вызов функции) short function; + //! \~english Input operator indices + //! \~russian Индексы входных операторов PIVector operators; }; + +//! \~english Evaluator element representing a number, variable, operator or function +//! \~russian Элемент вычислителя, представляющий число, переменную, оператор или функцию struct PIP_EXPORT Element { + //! \~english Constructs empty element (number type with value 0) + //! \~russian Создает пустой элемент (тип число со значением 0) Element() { num = 0; var_num = -1; type = etNumber; } + + //! \~english Constructs element with specified type and numeric/variable indices + //! \~russian Создает элемент с указанным типом и числовыми/переменными индексами Element(eType new_type, short new_num, short new_var_num = -1) { set(new_type, new_num, new_var_num); } + + //! \~english Sets element type and numeric/variable indices + //! \~russian Устанавливает тип элемента и числовые/переменные индексы void set(eType new_type, short new_num, short new_var_num = -1) { type = new_type; num = new_num; var_num = new_var_num; } + + //! \~english Element type (number, operator, variable or function) + //! \~russian Тип элемента (число, оператор, переменная или функция) eType type; + //! Numeric value or operator index + //! \~english Numeric value or operator index + //! \~russian Числовое значение или индекс оператора short num; + //! Variable index (for variables) + //! \~english Variable index (for variables) + //! \~russian Индекс переменной (для переменных) short var_num; }; + +//! \~english Function definition with name, type and handler +//! \~russian Определение функции с именем, типом и обработчиком struct PIP_EXPORT Function { + //! \~english Constructs unknown function with 0 arguments + //! \~russian Создает неизвестную функцию с 0 аргументами Function() { arguments = 0; type = bfUnknown; handler = nullptr; } + + //! \~english Constructs built-in function with name, argument count and base function type + //! \~russian Создает встроенную функцию с именем, количеством аргументов и типом базовой функции Function(const PIString & name, short args, BaseFunctions ftype) { identifier = name; arguments = args; type = ftype; handler = nullptr; } + + //! \~english Constructs custom function with name, argument count and handler function + //! \~russian Создает пользовательскую функцию с именем, количеством аргументов и обработчиком Function(const PIString & name, short args, FuncHanlder h) { identifier = name; arguments = args; type = bfCustom; handler = h; } + + //! \~english Function identifier (name) + //! \~russian Идентификатор функции (имя) PIString identifier; + //! \~english Function type (built-in or custom) + //! \~russian Тип функции (встроенная или пользовательская) BaseFunctions type; + //! \~english Handler function for custom functions + //! \~russian Обработчик для пользовательских функций FuncHanlder handler; + //! \~english Number of arguments + //! \~russian Количество аргументов short arguments; }; + +//! \~english Variable definition with name and value +//! \~russian Определение переменной с именем и значением struct PIP_EXPORT Variable { + //! \~english Constructs variable with value 0 + //! \~russian Создает переменную со значением 0 Variable() { value = 0.; } + //! \~english Constructs variable with name and value + //! \~russian Создает переменную с именем и значением Variable(const PIString & var_name, complexd val) { name = var_name; value = val; } + + //! \~english Variable name + //! \~russian Имя переменной PIString name; + //! \~english Variable value + //! \~russian Значение переменной complexd value; }; } // namespace PIEvaluatorTypes + +//! \~english Evaluator types namespace containing enums, structs and types for PIEvaluator +//! \~russian Пространство имен типов вычислителя, содержащее перечисления, структуры и типы для PIEvaluator /* ≠ : ≥ } @@ -185,69 +333,103 @@ struct PIP_EXPORT Variable { */ //! Content container for variables and functions -//! \~\english Container for variables and functions of the evaluator +//! \~english Container for variables and functions of the evaluator //! \~russian Контейнер для переменных и функций вычислителя +//! \details +//! \~english PIEvaluatorContent manages variables and functions for the evaluator. It provides methods to add, find, +//! and retrieve functions and variables. +//! \~russian PIEvaluatorContent управляет переменными и функциями вычислителя. Он предоставляет методы для добавления, +//! поиска и получения функций и переменных. class PIP_EXPORT PIEvaluatorContent { friend class PIEvaluator; BINARY_STREAM_FRIEND(PIEvaluatorContent); public: - //! Constructs an empty evaluator content + //! \~english Constructs an empty evaluator content + //! \~russian Создает пустой контент вычислителя PIEvaluatorContent(); ~PIEvaluatorContent() { ; } - //! Add function with specified name and argument count //! \~english Add function with name and default 1 argument //! \~russian Добавить функцию с указанным именем и количеством аргументов (по умолчанию 1) void addFunction(const PIString & name, int args = 1); - //! Add variable with specified name and value + //! \~english Add variable with name and optional value, returns variable index //! \~russian Добавить переменную с указанным именем и значением, возвращает индекс переменной int addVariable(const PIString & name, const complexd & val = 0.); - //! Add custom function with handler + //! \~english Add custom function with name, argument count and handler function //! \~russian Добавить пользовательскую функцию с обработчиком void addCustomFunction(const PIString & name, int args_count, PIEvaluatorTypes::FuncHanlder func); - //! Get number of functions + + //! \~english Returns number of registered functions + //! \~russian Возвращает количество зарегистрированных функций int functionsCount() const { return functions.size(); } - //! Get number of variables + + //! \~english Returns number of registered variables + //! \~russian Возвращает количество зарегистрированных переменных int variablesCount() const { return variables.size(); } - //! Get number of custom variables + + //! \~english Returns number of custom variables + //! \~russian Возвращает количество пользовательских переменных int customVariablesCount() const; - //! Find function index by name + + //! \~english Finds function index by name, returns -1 if not found + //! \~russian Находит индекс функции по имени, возвращает -1 если не найдена int findFunction(const PIString & name) const; - //! Find variable index by name + + //! \~english Finds variable index by name, returns -1 if not found + //! \~russian Находит индекс переменной по имени, возвращает -1 если не найдена int findVariable(const PIString & var_name) const; - //! Get function by index + + //! \~english Returns function by index + //! \~russian Возвращает функцию по индексу PIEvaluatorTypes::Function function(int index); - //! Get variable by index + + //! \~english Returns variable by index + //! \~russian Возвращает переменную по индексу PIEvaluatorTypes::Variable variable(int index); - //! Get function by name + + //! \~english Returns function by name, convenience wrapper + //! \~russian Возвращает функцию по имени, удобная обертка PIEvaluatorTypes::Function function(const PIString & name) { return function(findFunction(name)); } - //! Get variable by name + + //! \~english Returns variable by name, convenience wrapper + //! \~russian Возвращает переменную по имени, удобная обертка PIEvaluatorTypes::Variable variable(const PIString & name) { return variable(findVariable(name)); } - //! Get custom variable by index + + //! \~english Returns custom variable by index + //! \~russian Возвращает пользовательскую переменную по индексу PIEvaluatorTypes::Variable customVariable(int index); - //! Set variable value by index + //! \~english Set variable value by index, returns true on success //! \~russian Установить значение переменной по индексу, возвращает true при успехе bool setVariableValue(int index, complexd new_value); - //! Set variable value by name + //! \~english Set variable value by name, returns true on success //! \~russian Установить значение переменной по имени, возвращает true при успехе bool setVariableValue(const PIString & var_name, const complexd & new_value) { return setVariableValue(findVariable(var_name), new_value); } - //! Set variable name by index + + //! \~english Set variable name by index + //! \~russian Установить имя переменной по индексу bool setVariableName(int index, const PIString & new_name); - //! Set variable name by name - bool setVariableName(const PIString & var_name, const PIString & new_name) { return setVariableName(findVariable(var_name), new_name); } - //! Clear all custom variables + + //! \~english Set variable name by name, convenience wrapper + //! \~russian Установить имя переменной по имени, удобная обертка + bool setVariableName(const PIString & var_name, const PIString & new_name) { + return setVariableName(findVariable(var_name), new_name); + } + + //! \~english Clears all custom variables + //! \~russian Очищает все пользовательские переменные void clearCustomVariables(); - //! Get base function type by name + + //! \~english Returns base function type by name + //! \~russian Возвращает тип базовой функции по имени PIEvaluatorTypes::BaseFunctions getBaseFunction(const PIString & name); - //! Dump content to console for debugging //! \~english Print all functions and variables to console //! \~russian Вывести все функции и переменные в консоль void dump(); @@ -260,11 +442,17 @@ private: //! Main evaluator class for parsing and calculating mathematical expressions -//! \~\english Main class for parsing and evaluating mathematical expressions +//! \~english Main class for parsing and evaluating mathematical expressions //! \~russian Главный класс для разбора и вычисления математических выражений +//! \details +//! \~english PIEvaluator provides functionality to parse and evaluate mathematical expressions. It supports variables, functions (both +//! built-in and custom), and various operators including arithmetic, comparison, and logical operations. +//! \~russian PIEvaluator предоставляет функциональность для разбора и вычисления математических выражений. Поддерживаются переменные, +//! функции (как встроенные, так и пользовательские), а также различные операторы: арифметические, сравнения и логические. class PIP_EXPORT PIEvaluator { public: - //! Constructs an empty evaluator + //! \~english Constructs an empty evaluator + //! \~russian Создает пустой вычислитель PIEvaluator() { correct = false; data_ = 0; @@ -273,53 +461,68 @@ public: ~PIEvaluator() { ; } - //! Returns custom data + //! \~english Returns custom data pointer + //! \~russian Возвращает указатель на пользовательские данные void * data() { return data_; } - //! Set custom data to "_data" + //! \~english Sets custom data pointer to "_data" + //! \~russian Устанавливает указатель на пользовательские данные в "_data" void setData(void * _data) { data_ = _data; } - - //! Check mathematical expression and parse it to list of instructions + //! \~english Checks mathematical expression and parses it to list of instructions + //! \~russian Проверяет математическое выражение и разбирает его в список инструкций bool check(const PIString & string); - //! Returns true if expression was checked succesfully + //! \~english Returns true if expression was checked successfully + //! \~russian Возвращает true если выражение было успешно проверено bool isCorrect() const { return correct; } - //! Set variable value with name "name" to value "value". Add variable if it doesn`t exists + //! \~english Set variable value by name, adds variable if it does not exist, returns variable index + //! \~russian Устанавливает значение переменной по имени, добавляет переменную если она не существует, возвращает индекс переменной int setVariable(const PIString & name, complexd value = complexd(0.)); - //! Set variable value with index "index" to value "value". Don`t add variable if it doesn`t exists + //! \~english Set variable value by index, does not add variable if it does not exist + //! \~russian Устанавливает значение переменной по индексу, не добавляет переменную если она не существует void setVariable(int index, complexd value = 0.); - //! Evaluate last successfully checked with function \a check() expression and returns result + //! \~english Evaluates the last successfully checked expression and returns result + //! \~russian Вычисляет последнее успешно проверенное выражение и возвращает результат complexd evaluate(); - //! Remove all manually added variables + //! \~english Removes all manually added variables + //! \~russian Удаляет все вручную добавленные переменные void clearCustomVariables() { content.clearCustomVariables(); } - //! Returns index of variable with name "name" + //! \~english Returns index of variable by name + //! \~russian Возвращает индекс переменной по имени int variableIndex(const PIString & name) const { return content.findVariable(name); } - //! Returns all unknown variables founded in last expression passed to \a check() function + //! \~english Returns list of unknown variables found in the last expression passed to check() + //! \~russian Возвращает список неизвестных переменных, найденных в последнем выражении, переданном в check() const PIStringList & unknownVariables() const { return unknownVars; } - //! Returns all used variables founded in last expression passed to \a check() function + //! \~english Returns list of used variables found in the last expression passed to check() + //! \~russian Возвращает список используемых переменных, найденных в последнем выражении, переданном в check() const PIStringList & usedVariables() const { return usedVars; } - //! Returns processed last expression passed to \a check() function + //! \~english Returns the last expression passed to check() + //! \~russian Возвращает последнее выражение, переданное в check() const PIString & expression() const { return currentString; } - //! Returns last error description occured in \a check() function + //! \~english Returns last error description from check() function + //! \~russian Возвращает описание последней ошибки из функции check() const PIString & error() const { return lastError; } - //! Returns last result of \a evaluate() + //! \~english Returns last result of evaluate() + //! \~russian Возвращает последний результат evaluate() const complexd & lastResult() const { return out; } - //! Save to %PIByteArray evaluator state (expression, variables, errors, compiled instructions) + //! \~english Saves evaluator state to PIByteArray (expression, variables, errors, compiled instructions) + //! \~russian Сохраняет состояние вычислителя в PIByteArray (выражение, переменные, ошибки, скомпилированные инструкции) PIByteArray save() const; - //! Restore from %PIByteArray evaluator state (expression, variables, errors, compiled instructions) + //! \~english Restores evaluator state from PIByteArray (expression, variables, errors, compiled instructions) + //! \~russian Восстанавливает состояние вычислителя из PIByteArray (выражение, переменные, ошибки, скомпилированные инструкции) void load(PIByteArray ba); private: diff --git a/libs/main/math/pimathsolver.h b/libs/main/math/pimathsolver.h index 51ad762b..6a439d3d 100644 --- a/libs/main/math/pimathsolver.h +++ b/libs/main/math/pimathsolver.h @@ -32,40 +32,51 @@ #include "pimathmatrix.h" -/// Differential evaluations +//! \~english Differential evaluations +//! \~russian Дифференциальные вычисления -//! Transfer function representation -//! \~english Structure representing transfer function with numerator and denominator coefficients -//! \~russian Структура, представляющая передаточную функцию с коэффициентами числителя и знаменателя +//! \~english Transfer function representation +//! \~russian Представление передаточной функции struct PIP_EXPORT TransferFunction { PIVector vector_Bm, vector_An; }; -//! Mathematical solver for differential equations -//! \~\english Solver for ordinary differential equations using various numerical methods -//! \~russian Решатель обыкновенных дифференциальных уравнений +//! \~english Mathematical solver for differential equations +//! \~russian Математический решатель дифференциальных уравнений class PIP_EXPORT PIMathSolver { public: - //! Solving methods for differential equations + //! \~english Solving methods for differential equations + //! \~russian Методы решения дифференциальных уравнений enum Method { - Global = -1, //!< Use global method - Eyler_1 = 01, //!< Euler method (first order) - Eyler_2 = 02, //!< Euler method (second order) - EylerKoshi = 03, //!< Euler-Cauchy method - RungeKutta_4 = 14, //!< Runge-Kutta 4th order - AdamsBashfortMoulton_2 = 22, //!< Adams-Bashforth-Moulton 2nd order - AdamsBashfortMoulton_3 = 23, //!< Adams-Bashforth-Moulton 3rd order - AdamsBashfortMoulton_4 = 24, //!< Adams-Bashforth-Moulton 4th order - PolynomialApproximation_2 = 32, //!< Polynomial approximation 2nd order - PolynomialApproximation_3 = 33, //!< Polynomial approximation 3rd order - PolynomialApproximation_4 = 34, //!< Polynomial approximation 4th order - PolynomialApproximation_5 = 35 //!< Polynomial approximation 5th order + Global = -1, //!< \~english Use global method + //! \~russian Использовать глобальный метод + Eyler_1 = 01, //!< \~english Euler method (first order) + //! \~russian Метод Эйлера (1-й порядок) + Eyler_2 = 02, //!< \~english Euler method (second order) + //! \~russian Метод Эйлера (2-й порядок) + EylerKoshi = 03, //!< \~english Euler-Cauchy method + //! \~russian Метод Эйлера-Коши + RungeKutta_4 = 14, //!< \~english Runge-Kutta 4th order + //! \~russian Метод Рунге-Кутта 4-го порядка + AdamsBashfortMoulton_2 = 22, //!< \~english Adams-Bashforth-Moulton 2nd order + //! \~russian Метод Адамса-Башфорта-Мултона 2-го порядка + AdamsBashfortMoulton_3 = 23, //!< \~english Adams-Bashforth-Moulton 3rd order + //! \~russian Метод Адамса-Башфорта-Мултона 3-го порядка + AdamsBashfortMoulton_4 = 24, //!< \~english Adams-Bashforth-Moulton 4th order + //! \~russian Метод Адамса-Башфорта-Мултона 4-го порядка + PolynomialApproximation_2 = 32, //!< \~english Polynomial approximation 2nd order + //! \~russian Метод полиномиальной аппроксимации 2-го порядка + PolynomialApproximation_3 = 33, //!< \~english Polynomial approximation 3rd order + //! \~russian Метод полиномиальной аппроксимации 3-го порядка + PolynomialApproximation_4 = 34, //!< \~english Polynomial approximation 4th order + //! \~russian Метод полиномиальной аппроксимации 4-го порядка + PolynomialApproximation_5 = 35 //!< \~english Polynomial approximation 5th order + //! \~russian Метод полиномиальной аппроксимации 5-го порядка }; //! Constructs an empty solver PIMathSolver(); - //! Solve differential equation with step h //! \~english Solve differential equation at point u with step h //! \~russian Решить дифференциальное уравнение в точке u с шагом h void solve(double u, double h); @@ -83,34 +94,48 @@ public: //! \~russian Установить время моделирования void setTime(double time); - //! Solve using Euler method (1st order) + //! \~english Solve using Euler method (1st order) + //! \~russian Решение методом Эйлера (1-й порядок) void solveEyler1(double u, double h); - //! Solve using Euler method (2nd order) + //! \~english Solve using Euler method (2nd order) + //! \~russian Решение методом Эйлера (2-й порядок) void solveEyler2(double u, double h); - //! Solve using Runge-Kutta 4th order + //! \~english Solve using Runge-Kutta 4th order + //! \~russian Решение методом Рунге-Кутта 4-го порядка void solveRK4(double u, double h); - //! Solve using Adams-Bashforth-Moulton 2nd order + //! \~english Solve using Adams-Bashforth-Moulton 2nd order + //! \~russian Решение методом Адамса-Башфорта-Мултона 2-го порядка void solveABM2(double u, double h); - //! Solve using Adams-Bashforth-Moulton 3rd order + //! \~english Solve using Adams-Bashforth-Moulton 3rd order + //! \~russian Решение методом Адамса-Башфорта-Мултона 3-го порядка void solveABM3(double u, double h); - //! Solve using Adams-Bashforth-Moulton 4th order + //! \~english Solve using Adams-Bashforth-Moulton 4th order + //! \~russian Решение методом Адамса-Башфорта-Мултона 4-го порядка void solveABM4(double u, double h); - //! Solve using polynomial approximation + //! \~english Solve using polynomial approximation + //! \~russian Решение методом полиномиальной аппроксимации void solvePA(double u, double h, uint deg); - //! Solve using polynomial approximation 2nd order + //! \~english Solve using polynomial approximation 2nd order + //! \~russian Решение методом полиномиальной аппроксимации 2-го порядка void solvePA2(double u, double h); - //! Solve using polynomial approximation 3rd order + //! \~english Solve using polynomial approximation 3rd order + //! \~russian Решение методом полиномиальной аппроксимации 3-го порядка void solvePA3(double u, double h); - //! Solve using polynomial approximation 4th order + //! \~english Solve using polynomial approximation 4th order + //! \~russian Решение методом полиномиальной аппроксимации 4-го порядка void solvePA4(double u, double h); - //! Solve using polynomial approximation 5th order + //! \~english Solve using polynomial approximation 5th order + //! \~russian Решение методом полиномиальной аппроксимации 5-го порядка void solvePA5(double u, double h); - //! Solution vector + //! \~english Solution vector + //! \~russian Вектор решения PIMathVectord X; - //! Global default method + //! \~english Global default method + //! \~russian Глобальный метод по умолчанию static Method method_global; - //! Description of available methods + //! \~english Description of available methods + //! \~russian Описание доступных методов static const char methods_desc[]; private: diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index 7698a618..73bd2cdf 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -5,8 +5,11 @@ //! \~english Math vector //! \~russian Математический вектор //! \details -//! \~english Fixed-size and dynamic mathematical vector implementations -//! \~russian Реализации математических векторов фиксированного и динамического размера +//! \~english Fixed-size and dynamic mathematical vector implementations. Provides PIMathVectorT for compile-time fixed-size vectors and +//! PIMathVector for runtime dynamic-size vectors with support for arithmetic and complex number types. +//! \~russian Реализации математических векторов фиксированного и динамического размера. Предоставляет PIMathVectorT для векторов +//! фиксированного размера во время компиляции и PIMathVector для векторов динамического размера во время выполнения с поддержкой +//! арифметических и комплексных типов чисел. //! \} /* PIP - Platform Independent Primitives @@ -44,9 +47,15 @@ class PIMathMatrixT; #define PIMV_FOR for (uint i = 0; i < Size; ++i) -//! Fixed-size mathematical vector //! \~english Template class for fixed-size mathematical vector //! \~russian Шаблонный класс для математического вектора фиксированного размера +//! \brief Fixed-size mathematical vector with compile-time size +//! \~english Fixed-size mathematical vector with compile-time size +//! \~russian Вектор математический фиксированного размера с размером во время компиляции +//! \details Provides vector operations including arithmetic, normalization, angles, cross product, and dot product +//! \~russian Предоставляет операции вектора включая арифметику, нормализацию, углы, векторное произведение и скалярное произведение +//! \tparam Size The fixed size of the vector +//! \tparam Type The element type (arithmetic or complex) template class PIP_EXPORT PIMathVectorT { typedef PIMathVectorT _CVector; @@ -54,50 +63,93 @@ class PIP_EXPORT PIMathVectorT { static_assert(Size > 0, "Size must be > 0"); public: + //! \~english Constructor with default value for all elements + //! \~russian Конструктор со значением по умолчанию для всех элементов + //! \param v The value to initialize all elements PIMathVectorT(const Type & v = Type()) { PIMV_FOR c[i] = v; } + //! \~english Constructor from PIVector + //! \~russian Конструктор из PIVector + //! \param val The PIVector to copy from PIMathVectorT(const PIVector & val) { assert(Size == val.size()); PIMV_FOR c[i] = val[i]; } + //! \~english Constructor from initializer list + //! \~russian Конструктор из списка инициализации + //! \param init_list The initializer list to copy from PIMathVectorT(std::initializer_list init_list) { assert(Size == init_list.size()); PIMV_FOR c[i] = init_list.begin()[i]; } + //! \~english Create vector from two points (st -> fn) + //! \~russian Создать вектор из двух точек (st -> fn) + //! \param st The start point + //! \param fn The finish point + //! \returns Vector from st to fn static _CVector fromTwoPoints(const _CVector & st, const _CVector & fn) { _CVector tv; PIMV_FOR tv[i] = fn[i] - st[i]; return tv; } + //! \~english Get vector size + //! \~russian Получить размер вектора + //! \returns The fixed size of the vector constexpr uint size() const { return Size; } + //! \~english Fill vector with a single value + //! \~russian Заполнить вектор одним значением + //! \param v The value to fill + //! \returns Reference to this vector _CVector & fill(const Type & v) { PIMV_FOR c[i] = v; return *this; } + //! \~english Add value to all elements + //! \~russian Прибавить значение ко всем элементам + //! \param v The value to add + //! \returns Reference to this vector _CVector & move(const Type & v) { PIMV_FOR c[i] += v; return *this; } + //! \~english Add vector to this vector + //! \~russian Прибавить вектор к этому вектору + //! \param v The vector to add + //! \returns Reference to this vector _CVector & move(const _CVector & v) { PIMV_FOR c[i] += v[i]; return *this; } + //! \~english Swap two elements + //! \~russian Поменять два элемента местами + //! \param f First element index + //! \param s Second element index + //! \returns Reference to this vector _CVector & swapElements(uint f, uint s) { piSwap(c[f], c[s]); return *this; } + //! \~english Get squared length of vector + //! \~russian Получить квадрат длины вектора + //! \returns Sum of squares of all elements Type lengthSqr() const { Type tv(0); PIMV_FOR tv += c[i] * c[i]; return tv; } + //! \~english Get length of vector + //! \~russian Получить длину вектора + //! \returns Square root of lengthSqr, unavailable for complex types Type length() const { static_assert(std::is_arithmetic::value, "Unavailable for complex"); if (std::is_arithmetic::value) return std::sqrt(lengthSqr()); // if (is_complex::value) return 1000.; // std::sqrt(lengthSqr()); } + //! \~english Get Manhattan length (sum of absolute values) + //! \~russian Получить манхэттенскую длину (сумма абсолютных значений) + //! \returns Sum of absolute values of all elements, unavailable for complex types Type manhattanLength() const { static_assert(std::is_arithmetic::value, "Unavailable for complex"); if (std::is_arithmetic::value) { @@ -106,6 +158,10 @@ public: return tv; } } + //! \~english Get cosine of angle between two vectors + //! \~russian Получить косинус угла между двумя векторами + //! \param v The other vector + //! \returns cos(angle), unavailable for complex types Type angleCos(const _CVector & v) const { static_assert(std::is_arithmetic::value, "Unavailable for complex"); if (std::is_arithmetic::value) { @@ -114,6 +170,10 @@ public: return dot(v) / tv; } } + //! \~english Get sine of angle between two vectors + //! \~russian Получить синус угла между двумя векторами + //! \param v The other vector + //! \returns sin(angle), unavailable for complex types Type angleSin(const _CVector & v) const { static_assert(std::is_arithmetic::value, "Unavailable for complex"); if (std::is_arithmetic::value) { @@ -121,24 +181,40 @@ public: return std::sqrt(Type(1) - tv * tv); } } + //! \~english Get angle in radians between two vectors + //! \~russian Получить угол в радианах между двумя векторами + //! \param v The other vector + //! \returns Angle in radians, unavailable for complex types Type angleRad(const _CVector & v) const { static_assert(std::is_arithmetic::value, "Unavailable for complex"); if (std::is_arithmetic::value) { return std::acos(angleCos(v)); } } + //! \~english Get angle in degrees between two vectors + //! \~russian Получить угол в градусах между двумя векторами + //! \param v The other vector + //! \returns Angle in degrees, unavailable for complex types Type angleDeg(const _CVector & v) const { static_assert(std::is_arithmetic::value, "Unavailable for complex"); if (std::is_arithmetic::value) { return toDeg(angleRad(v)); } } + //! \~english Get elevation angle + //! \~russian Получить угол возвышения + //! \param v The other vector + //! \returns Elevation angle in degrees, unavailable for complex types Type angleElevation(const _CVector & v) const { static_assert(std::is_arithmetic::value, "Unavailable for complex"); if (std::is_arithmetic::value) { return 90.0 - angleDeg(v - *this); } } + //! \~english Get projection of this vector onto another vector + //! \~russian Получить проекцию этого вектора на другой вектор + //! \param v The vector to project onto + //! \returns Projection vector, unavailable for complex types _CVector projection(const _CVector & v) { static_assert(std::is_arithmetic::value, "Unavailable for complex"); if (std::is_arithmetic::value) { @@ -147,6 +223,9 @@ public: return v * (dot(v) / tv); } } + //! \~english Normalize vector in place + //! \~russian Нормализовать вектор на месте + //! \returns Reference to this vector, unavailable for complex types _CVector & normalize() { static_assert(std::is_arithmetic::value, "Unavailable for complex"); if (std::is_arithmetic::value) { @@ -157,61 +236,134 @@ public: return *this; } } + //! \~english Get normalized copy of vector + //! \~russian Получить нормализованную копию вектора + //! \returns New normalized vector, unavailable for complex types _CVector normalized() { _CVector tv(*this); tv.normalize(); return tv; } + //! \~english Check if vector is null (all elements zero) + //! \~russian Проверить, является ли вектор нулевым (все элементы нули) + //! \returns true if vector is null bool isNull() const { PIMV_FOR if (c[i] != Type{}) return false; return true; } + //! \~english Check if vectors are orthogonal + //! \~russian Проверить, перпендикулярны ли векторы + //! \param v The other vector + //! \returns true if vectors are orthogonal bool isOrtho(const _CVector & v) const { return ((*this) ^ v) == Type{}; } + //! \~english Get element at index (non-const) + //! \~russian Получить элемент по индексу (non-const) + //! \param index Element index + //! \returns Reference to element Type & operator[](uint index) { return c[index]; } + //! \~english Get element at index (const) + //! \~russian Получить элемент по индексу (const) + //! \param index Element index + //! \returns Copy of element const Type & operator[](uint index) const { return c[index]; } + //! \~english Get element at index (const version) + //! \~russian Получить элемент по индексу (версия const) + //! \param index Element index + //! \returns Copy of element Type at(uint index) const { return c[index]; } + //! \~english Get element at index (non-const, alternative) + //! \~russian Получить элемент по индексу (non-const, альтернативный метод) + //! \param index Element index + //! \returns Reference to element inline Type & element(uint index) { return c[index]; } + //! \~english Get element at index (const, alternative) + //! \~russian Получить элемент по индексу (const, альтернативный метод) + //! \param index Element index + //! \returns Copy of element inline const Type & element(uint index) const { return c[index]; } + //! \~english Assign value to all elements + //! \~russian Присвоить значение всем элементам + //! \param v The value to assign + //! \returns Reference to this vector _CVector & operator=(const Type & v) { PIMV_FOR c[i] = v; return *this; } + //! \~english Check equality with another vector + //! \~russian Проверить равенство с другим вектором + //! \param v The vector to compare with + //! \returns true if all elements are equal bool operator==(const _CVector & v) const { PIMV_FOR if (c[i] != v[i]) return false; return true; } + //! \~english Check inequality with another vector + //! \~russian Проверить неравенство с другим вектором + //! \param v The vector to compare with + //! \returns true if any element differs bool operator!=(const _CVector & v) const { return !(*this == c); } + //! \~english Add vector to this vector + //! \~russian Прибавить вектор к этому вектору + //! \param v The vector to add void operator+=(const _CVector & v) { PIMV_FOR c[i] += v[i]; } + //! \~english Subtract vector from this vector + //! \~russian Вычесть вектор из этого вектора + //! \param v The vector to subtract void operator-=(const _CVector & v) { PIMV_FOR c[i] -= v[i]; } + //! \~english Multiply all elements by scalar + //! \~russian Умножить все элементы на скаляр + //! \param v The scalar to multiply by void operator*=(const Type & v) { PIMV_FOR c[i] *= v; } + //! \~english Divide all elements by scalar + //! \~russian Разделить все элементы на скаляр + //! \param v The scalar to divide by void operator/=(const Type & v) { assert(std::abs(v) > PIMATHVECTOR_ZERO_CMP); PIMV_FOR c[i] /= v; } + //! \~english Unary minus operator + //! \~russian Унарный оператор минус + //! \returns New vector with negated elements _CVector operator-() const { _CVector tv; PIMV_FOR tv[i] = -c[i]; return tv; } + //! \~english Add two vectors + //! \~russian Сложить два вектора + //! \param v The vector to add + //! \returns New vector with sum of elements _CVector operator+(const _CVector & v) const { _CVector tv(*this); PIMV_FOR tv[i] += v[i]; return tv; } + //! \~english Subtract two vectors + //! \~russian Вычесть два вектора + //! \param v The vector to subtract + //! \returns New vector with difference of elements _CVector operator-(const _CVector & v) const { _CVector tv(*this); PIMV_FOR tv[i] -= v[i]; return tv; } + //! \~english Multiply vector by scalar + //! \~russian Умножить вектор на скаляр + //! \param v The scalar to multiply by + //! \returns New vector with scaled elements _CVector operator*(const Type & v) const { _CVector tv(*this); PIMV_FOR tv[i] *= v; return tv; } + //! \~english Divide vector by scalar + //! \~russian Разделить вектор на скаляр + //! \param v The scalar to divide by + //! \returns New vector with scaled elements _CVector operator/(const Type & v) const { assert(std::abs(v) > PIMATHVECTOR_ZERO_CMP); _CVector tv = _CVector(*this); @@ -219,6 +371,10 @@ public: return tv; } + //! \~english Compute cross product with another vector (3D only) + //! \~russian Вычислить векторное произведение с другим вектором (только 3D) + //! \param v The other vector + //! \returns Cross product vector _CVector cross(const _CVector & v) const { static_assert(Size == 3, "cross product avalible only for 3D vectors"); _CVector tv; @@ -227,17 +383,33 @@ public: tv[2] = c[0] * v[1] - v[0] * c[1]; return tv; } + //! \~english Compute dot product with another vector + //! \~russian Вычислить скалярное произведение с другим вектором + //! \param v The other vector + //! \returns Dot product (sum of element-wise products) Type dot(const _CVector & v) const { Type tv{}; PIMV_FOR tv += c[i] * v[i]; return tv; } + //! \~english Element-wise multiplication with another vector + //! \~russian Покомпонентное умножение с другим вектором + //! \param v The other vector + //! \returns New vector with element-wise products _CVector mul(const _CVector & v) const { _CVector tv(*this); PIMV_FOR tv[i] *= v[i]; return tv; } + //! \~english Element-wise multiplication with scalar + //! \~russian Покомпонентное умножение на скаляр + //! \param v The scalar to multiply by + //! \returns New vector with scaled elements _CVector mul(const Type & v) const { return (*this) * v; } + //! \~english Element-wise division by another vector + //! \~russian Покомпонентное деление на другой вектор + //! \param v The vector to divide by + //! \returns New vector with element-wise quotients _CVector div(const _CVector & v) const { _CVector tv(*this); PIMV_FOR { @@ -246,14 +418,26 @@ public: } return tv; } + //! \~english Element-wise division by scalar + //! \~russian Покомпонентное деление на скаляр + //! \param v The scalar to divide by + //! \returns New vector with scaled elements _CVector div(const Type & v) const { return (*this) / v; } + //! \~english Transpose vector to 1xN matrix + //! \~russian Транспонировать вектор в матрицу 1xN + //! \returns 1xN matrix representation of this vector PIMathMatrixT<1, Size, Type> transposed() const { PIMathMatrixT<1, Size, Type> ret; PIMV_FOR ret[0][i] = c[i]; return ret; } + //! \~english Get distance from this point to line defined by two points + //! \~russian Получить расстояние от этой точки до линии, заданной двумя точками + //! \param lp0 First point on the line + //! \param lp1 Second point on the line + //! \returns Distance from point to line, unavailable for complex types Type distToLine(const _CVector & lp0, const _CVector & lp1) { static_assert(std::is_arithmetic::value, "Unavailable for complex"); if (std::is_arithmetic::value) { @@ -265,6 +449,11 @@ public: } } + //! \~english Convert vector to another size and type + //! \~russian Преобразовать вектор в другой размер и тип + //! \tparam Size1 New vector size + //! \tparam Type1 New element type + //! \returns Vector with new size and type template /// vector {Size, Type} to vector {Size1, Type1} PIMathVectorT turnTo() const { PIMathVectorT tv; @@ -274,10 +463,10 @@ public: return tv; } - //! \~english - //! \brief Returns this vector with another element type. - //! \~russian - //! \brief Возвращает этот вектор с другим типом элементов. + //! \~english Returns this vector with another element type + //! \~russian Возвращает этот вектор с другим типом элементов + //! \tparam T New element type + //! \returns Vector with new element type template PIMathVectorT toType() const { PIMathVectorT ret; @@ -285,13 +474,22 @@ public: return ret; } - //! \~english - //! \brief Returns the subvector with size SubSize. Elements takes from coordinates "offset". - //! \details - //! \~russian - //! \brief Возвращает подвектор с размерами SubSize. Элементы берутся с координат "offset". - //! \details Координаты могут быть отрицательными. Возвращаемый подвектор может быть любого размера. Если исходные элементы выходят - //! за границы исходного подвектора, то в подвекторе будут нули. + //! \~english Returns the subvector with size SubSize. Elements are taken from coordinates "offset" + //! \~russian Возвращает подвектор с размерами SubSize. Элементы берутся с координат "offset" + //! \tparam SubSize Size of the subvector + //! \param offset Starting coordinate (can be negative) + //! \details Coordinates can be negative. The returned subvector can be of any size. If original elements are out of bounds, zeros will + //! be used + //! \~russian Координаты могут быть отрицательными. Возвращаемый подвектор может быть любого размера. Если исходные элементы выходят за + //! границы исходного подвектора, то в подвекторе будут нули \returns Subvector of specified size + //! \~english Returns the subvector with size SubSize. Elements are taken from coordinates "offset" + //! \~russian Возвращает подвектор с размерами SubSize. Элементы берутся с координат "offset" + //! \tparam SubSize Size of the subvector + //! \param offset Starting coordinate (can be negative) + //! \details Coordinates can be negative. The returned subvector can be of any size. If original elements are out of bounds, zeros will + //! be used + //! \~russian Координаты могут быть отрицательными. Возвращаемый подвектор может быть любого размера. Если исходные элементы выходят за + //! границы исходного подвектора, то в подвекторе будут нули \returns Subvector of specified size template PIMathVectorT subvector(int offset = 0) const { PIMathVectorT ret; @@ -303,14 +501,16 @@ public: return ret; } - //! \~english - //! \brief Set the subvector "v" in coordinates "index". - //! \details - //! \~russian - //! \brief Устанавливает подвектор "v" в координаты "index". - //! \details Присваивает значения из вектора "v" в область текущиего вектора, ограниченную - //! размерами "v", самого вектор и границами, исходя из координат установки. Координаты могут быть отрицательными. - //! Вектор "v" может быть любого размера. Возвращает ссылку на этот вектор. + //! \~english Set the subvector "v" at coordinates "index" + //! \~russian Устанавливает подвектор "v" в координаты "index" + //! \tparam SubSize Size of the subvector + //! \param index Starting coordinate (can be negative) + //! \param v The subvector to set + //! \details Assigns values from vector "v" to the area of current vector bounded by "v"'s size and vector boundaries, based on the + //! installation coordinates. Coordinates can be negative. Vector "v" can be of any size. Returns reference to this vector. + //! \~russian Присваивает значения из вектора "v" в область текущего вектора, ограниченную размерами "v", самого вектор и границами, + //! исходя из координат установки. Координаты могут быть отрицательными. Вектор "v" может быть любого размера. Возвращает ссылку на этот + //! вектор. \returns Reference to this vector template PIMathVectorT & setSubvector(int index, const PIMathVectorT & v) { for (int i = 0; i < (int)SubSize; ++i) { @@ -321,23 +521,68 @@ public: return *this; } + //! \~english Static cross product of two vectors + //! \~russian Статическое векторное произведение двух векторов + //! \param v1 First vector + //! \param v2 Second vector + //! \returns Cross product vector static _CVector cross(const _CVector & v1, const _CVector & v2) { return v1.cross(v2); } + //! \~english Static dot product of two vectors + //! \~russian Статическое скалярное произведение двух векторов + //! \param v1 First vector + //! \param v2 Second vector + //! \returns Dot product static Type dot(const _CVector & v1, const _CVector & v2) { return v1.dot(v2); } + //! \~english Static element-wise multiplication of two vectors + //! \~russian Статическое покомпонентное умножение двух векторов + //! \param v1 First vector + //! \param v2 Second vector + //! \returns New vector with element-wise products static _CVector mul(const _CVector & v1, const _CVector & v2) { return v1.mul(v2); } + //! \~english Static scalar multiplication (scalar * vector) + //! \~russian Статическое скалярное умножение (скаляр * вектор) + //! \param v1 Scalar + //! \param v2 Vector + //! \returns Scaled vector static _CVector mul(const Type & v1, const _CVector & v2) { return v2 * v1; } + //! \~english Static scalar multiplication (vector * scalar) + //! \~russian Статическое скалярное умножение (вектор * скаляр) + //! \param v1 Vector + //! \param v2 Scalar + //! \returns Scaled vector static _CVector mul(const _CVector & v1, const Type & v2) { return v1 * v2; } + //! \~english Static element-wise division of two vectors + //! \~russian Статическое покомпонентное деление двух векторов + //! \param v1 First vector + //! \param v2 Second vector + //! \returns New vector with element-wise quotients static _CVector div(const _CVector & v1, const _CVector & v2) { return v1.div(v2); } + //! \~english Static scalar division (vector / scalar) + //! \~russian Статическое скалярное деление (вектор / скаляр) + //! \param v1 Vector + //! \param v2 Scalar + //! \returns Scaled vector static _CVector div(const _CVector & v1, const Type & v2) { return v1 / v2; } private: Type c[Size]; }; +//! \~english Scalar multiplication (scalar * vector) +//! \~russian Скалярное умножение (скаляр * вектор) +//! \param x Scalar +//! \param v Vector +//! \returns Scaled vector template inline PIMathVectorT operator*(const Type & x, const PIMathVectorT & v) { return v * x; } +//! \~english Output vector to PIP stream +//! \~russian Вывести вектор в поток PIP +//! \param s The PIP output stream +//! \param v The vector to output +//! \returns Reference to the stream template inline PICout operator<<(PICout s, const PIMathVectorT & v) { s.space(); @@ -352,12 +597,23 @@ inline PICout operator<<(PICout s, const PIMathVectorT & v) { return s; } - +//! \~english 2D integer vector +//! \~russian 2D целочисленный вектор typedef PIMathVectorT<2u, int> PIMathVectorT2i; +//! \~english 3D integer vector +//! \~russian 3D целочисленный вектор typedef PIMathVectorT<3u, int> PIMathVectorT3i; +//! \~english 4D integer vector +//! \~russian 4D целочисленный вектор typedef PIMathVectorT<4u, int> PIMathVectorT4i; +//! \~english 2D double vector +//! \~russian 2D вектор с числами двойной точности typedef PIMathVectorT<2u, double> PIMathVectorT2d; +//! \~english 3D double vector +//! \~russian 3D вектор с числами двойной точности typedef PIMathVectorT<3u, double> PIMathVectorT3d; +//! \~english 4D double vector +//! \~russian 4D вектор с числами двойной точности typedef PIMathVectorT<4u, double> PIMathVectorT4d; @@ -367,9 +623,14 @@ typedef PIMathVectorT<4u, double> PIMathVectorT4d; #define PIMV_FOR for (uint i = 0; i < c.size(); ++i) -//! Dynamic-size mathematical vector //! \~english Template class for dynamic-size mathematical vector //! \~russian Шаблонный класс для математического вектора динамического размера +//! \brief Dynamic-size mathematical vector with runtime size +//! \~english Dynamic-size mathematical vector with runtime size +//! \~russian Вектор математический динамического размера с размером во время выполнения +//! \details Provides vector operations including arithmetic, normalization, angles, cross product, and dot product for dynamic-size vectors +//! \~russian Предоставляет операции вектора включая арифметику, нормализацию, углы, векторное произведение и скалярное произведение для +//! векторов динамического размера \tparam Type The element type (arithmetic or complex) template class PIP_EXPORT PIMathVector { typedef PIMathVector _CVector; @@ -379,17 +640,38 @@ class PIP_EXPORT PIMathVector { friend PIBinaryStream

& operator>>(PIBinaryStream

& s, PIMathVector & v); public: + //! \~english Constructor with size and initial value + //! \~russian Конструктор с размером и начальным значением + //! \param size The initial size of the vector + //! \param new_value The initial value for all elements PIMathVector(const uint size = 0, const Type & new_value = Type()) { c.resize(size, new_value); } + //! \~english Constructor from PIVector + //! \~russian Конструктор из PIVector + //! \param val The PIVector to copy from PIMathVector(const PIVector & val) { c = val; } + //! \~english Constructor from move PIVector + //! \~russian Конструктор из move PIVector + //! \param val The PIVector to move from PIMathVector(PIVector && val): c(std::move(val)) {} + //! \~english Constructor from initializer list + //! \~russian Конструктор из списка инициализации + //! \param init_list The initializer list to copy from PIMathVector(std::initializer_list init_list) { c = PIVector(init_list); } + //! \~english Constructor from fixed-size vector + //! \~russian Конструктор из фиксированного вектора + //! \param val The fixed-size vector to copy from template PIMathVector(const PIMathVectorT & val) { c.resize(Size); PIMV_FOR c[i] = val[i]; } + //! \~english Create vector from two points (st -> fn) + //! \~russian Создать вектор из двух точек (st -> fn) + //! \param st The start point + //! \param fn The finish point + //! \returns Vector from st to fn static PIMathVector fromTwoPoints(const _CVector & st, const _CVector & fn) { assert(st.size() == fn.size()); _CVector v(st.size()); @@ -397,8 +679,22 @@ public: v.c[i] = fn[i] - st[i]; } + //! \~english Create zero vector of specified size + //! \~russian Создать нулевой вектор указанного размера + //! \param size The size of the vector + //! \returns Zero vector static PIMathVector zeros(const uint size) { return PIMathVector(size, Type()); } + //! \~english Create vector with all elements set to 1 + //! \~russian Создать вектор со всеми элементами, равными 1 + //! \param size The size of the vector + //! \returns Vector filled with ones static PIMathVector ones(const uint size) { return PIMathVector(size, Type(1)); } + //! \~english Create vector with values in arithmetic progression + //! \~russian Создать вектор со значениями в арифметической прогрессии + //! \param start The start value + //! \param stop The stop value (exclusive) + //! \param step The step between values + //! \returns Vector with arithmetic progression static PIMathVector arange(const Type start, const Type stop, const Type step = Type(1)) { PIVector v; for (Type i = start; i < stop; i += step) @@ -406,63 +702,125 @@ public: return PIMathVector(std::move(v)); } + //! \~english Get vector size + //! \~russian Получить размер вектора + //! \returns The dynamic size of the vector uint size() const { return c.size(); } + //! \~english Resize the vector + //! \~russian Изменить размер вектора + //! \param size The new size + //! \param new_value The value for new elements + //! \returns Reference to this vector _CVector & resize(uint size, const Type & new_value = Type()) { c.resize(size, new_value); return *this; } + //! \~english Get resized copy of the vector + //! \~russian Получить копию вектора с измененным размером + //! \param size The new size + //! \param new_value The value for new elements + //! \returns New vector with new size _CVector resized(uint size, const Type & new_value = Type()) { _CVector tv = _CVector(*this); tv.resize(size, new_value); return tv; } + //! \~english Fill vector with a single value + //! \~russian Заполнить вектор одним значением + //! \param v The value to fill + //! \returns Reference to this vector _CVector & fill(const Type & v) { c.fill(v); return *this; } + //! \~english Add value to all elements + //! \~russian Прибавить значение ко всем элементам + //! \param v The value to add + //! \returns Reference to this vector _CVector & move(const Type & v) { PIMV_FOR c[i] += v; return *this; } + //! \~english Add vector to this vector + //! \~russian Прибавить вектор к этому вектору + //! \param v The vector to add + //! \returns Reference to this vector _CVector & move(const _CVector & v) { assert(c.size() == v.size()); PIMV_FOR c[i] += v[i]; return *this; } + //! \~english Swap two elements + //! \~russian Поменять два элемента местами + //! \param f First element index + //! \param s Second element index + //! \returns Reference to this vector _CVector & swapElements(uint f, uint s) { piSwap(c[f], c[s]); return *this; } + //! \~english Get squared length of vector + //! \~russian Получить квадрат длины вектора + //! \returns Sum of squares of all elements Type lengthSqr() const { Type tv(0); PIMV_FOR tv += c[i] * c[i]; return tv; } + //! \~english Get length of vector + //! \~russian Получить длину вектора + //! \returns Square root of lengthSqr Type length() const { return std::sqrt(lengthSqr()); } + //! \~english Get Manhattan length (sum of absolute values) + //! \~russian Получить манхэттенскую длину (сумма абсолютных значений) + //! \returns Sum of absolute values of all elements Type manhattanLength() const { Type tv(0); PIMV_FOR tv += piAbs(c[i]); return tv; } + //! \~english Get cosine of angle between two vectors + //! \~russian Получить косинус угла между двумя векторами + //! \param v The other vector + //! \returns cos(angle) Type angleCos(const _CVector & v) const { assert(c.size() == v.size()); Type tv = v.length() * length(); assert(std::abs(tv) > PIMATHVECTOR_ZERO_CMP); return dot(v) / tv; } + //! \~english Get sine of angle between two vectors + //! \~russian Получить синус угла между двумя векторами + //! \param v The other vector + //! \returns sin(angle) Type angleSin(const _CVector & v) const { assert(c.size() == v.size()); Type tv = angleCos(v); return std::sqrt(Type(1) - tv * tv); } + //! \~english Get angle in radians between two vectors + //! \~russian Получить угол в радианах между двумя векторами + //! \param v The other vector + //! \returns Angle in radians Type angleRad(const _CVector & v) const { return std::acos(angleCos(v)); } + //! \~english Get angle in degrees between two vectors + //! \~russian Получить угол в градусах между двумя векторами + //! \param v The other vector + //! \returns Angle in degrees Type angleDeg(const _CVector & v) const { return toDeg(angleRad(v)); } + //! \~english Get projection of this vector onto another vector + //! \~russian Получить проекцию этого вектора на другой вектор + //! \param v The vector to project onto + //! \returns Projection vector _CVector projection(const _CVector & v) { assert(c.size() == v.size()); Type tv = v.length(); assert(std::abs(tv) > PIMATHVECTOR_ZERO_CMP); return v * (dot(v) / tv); } + //! \~english Normalize vector in place + //! \~russian Нормализовать вектор на месте + //! \returns Reference to this vector _CVector & normalize() { Type tv = length(); assert(std::abs(tv) > PIMATHVECTOR_ZERO_CMP); @@ -470,71 +828,143 @@ public: PIMV_FOR c[i] /= tv; return *this; } + //! \~english Get normalized copy of vector + //! \~russian Получить нормализованную копию вектора + //! \returns New normalized vector _CVector normalized() { _CVector tv(*this); tv.normalize(); return tv; } + //! \~english Check if vector is null (all elements zero) + //! \~russian Проверить, является ли вектор нулевым (все элементы нули) + //! \returns true if vector is null bool isNull() const { PIMV_FOR if (c[i] != Type(0)) return false; return true; } + //! \~english Check if vector is valid (non-empty) + //! \~russian Проверить, валиден ли вектор (не пустой) + //! \returns true if vector is valid bool isValid() const { return !c.isEmpty(); } + //! \~english Check if vectors are orthogonal + //! \~russian Проверить, перпендикулярны ли векторы + //! \param v The other vector + //! \returns true if vectors are orthogonal bool isOrtho(const _CVector & v) const { return dot(v) == Type(0); } + //! \~english Get element at index (non-const) + //! \~russian Получить элемент по индексу (non-const) + //! \param index Element index + //! \returns Reference to element Type & operator[](uint index) { return c[index]; } + //! \~english Get element at index (const) + //! \~russian Получить элемент по индексу (const) + //! \param index Element index + //! \returns Copy of element const Type & operator[](uint index) const { return c[index]; } + //! \~english Get element at index (const version) + //! \~russian Получить элемент по индексу (версия const) + //! \param index Element index + //! \returns Copy of element Type at(uint index) const { return c[index]; } + //! \~english Assign value to all elements + //! \~russian Присвоить значение всем элементам + //! \param v The value to assign + //! \returns Reference to this vector _CVector & operator=(const Type & v) { PIMV_FOR c[i] = v; return *this; } + //! \~english Check equality with another vector + //! \~russian Проверить равенство с другим вектором + //! \param v The vector to compare with + //! \returns true if all elements are equal bool operator==(const _CVector & v) const { return c == v.c; } + //! \~english Check inequality with another vector + //! \~russian Проверить неравенство с другим вектором + //! \param v The vector to compare with + //! \returns true if any element differs bool operator!=(const _CVector & v) const { return c != v.c; } + //! \~english Add vector to this vector + //! \~russian Прибавить вектор к этому вектору + //! \param v The vector to add void operator+=(const _CVector & v) { assert(c.size() == v.size()); PIMV_FOR c[i] += v[i]; } + //! \~english Subtract vector from this vector + //! \~russian Вычесть вектор из этого вектора + //! \param v The vector to subtract void operator-=(const _CVector & v) { assert(c.size() == v.size()); PIMV_FOR c[i] -= v[i]; } + //! \~english Multiply all elements by scalar + //! \~russian Умножить все элементы на скаляр + //! \param v The scalar to multiply by void operator*=(const Type & v) { PIMV_FOR c[i] *= v; } + //! \~english Divide all elements by scalar + //! \~russian Разделить все элементы на скаляр + //! \param v The scalar to divide by void operator/=(const Type & v) { assert(std::abs(v) > PIMATHVECTOR_ZERO_CMP); PIMV_FOR c[i] /= v; } + //! \~english Unary minus operator + //! \~russian Унарный оператор минус + //! \returns New vector with negated elements _CVector operator-() const { _CVector tv(c.size()); PIMV_FOR tv[i] = -c[i]; return tv; } + //! \~english Add two vectors + //! \~russian Сложить два вектора + //! \param v The vector to add + //! \returns New vector with sum of elements _CVector operator+(const _CVector & v) const { assert(c.size() == v.size()); _CVector tv(*this); PIMV_FOR tv[i] += v[i]; return tv; } + //! \~english Subtract two vectors + //! \~russian Вычесть два вектора + //! \param v The vector to subtract + //! \returns New vector with difference of elements _CVector operator-(const _CVector & v) const { assert(c.size() == v.size()); _CVector tv(*this); PIMV_FOR tv[i] -= v[i]; return tv; } + //! \~english Multiply vector by scalar + //! \~russian Умножить вектор на скаляр + //! \param v The scalar to multiply by + //! \returns New vector with scaled elements _CVector operator*(const Type & v) const { _CVector tv(*this); PIMV_FOR tv[i] *= v; return tv; } + //! \~english Divide vector by scalar + //! \~russian Разделить вектор на скаляр + //! \param v The scalar to divide by + //! \returns New vector with scaled elements _CVector operator/(const Type & v) const { assert(std::abs(v) > PIMATHVECTOR_ZERO_CMP); _CVector tv(*this); PIMV_FOR tv[i] /= v; return tv; } + //! \~english Compute cross product with another vector (3D only) + //! \~russian Вычислить векторное произведение с другим вектором (только 3D) + //! \param v The other vector + //! \returns Cross product vector _CVector cross(const _CVector & v) const { assert(c.size() == 3); assert(v.size() == 3); @@ -544,19 +974,35 @@ public: tv[2] = c[0] * v[1] - v[0] * c[1]; return tv; } + //! \~english Compute dot product with another vector + //! \~russian Вычислить скалярное произведение с другим вектором + //! \param v The other vector + //! \returns Dot product (sum of element-wise products) Type dot(const _CVector & v) const { assert(c.size() == v.size()); Type tv(0); PIMV_FOR tv += c[i] * v[i]; return tv; } + //! \~english Element-wise multiplication with another vector + //! \~russian Покомпонентное умножение с другим вектором + //! \param v The other vector + //! \returns New vector with element-wise products _CVector mul(const _CVector & v) const { assert(c.size() == v.size()); _CVector tv(*this); PIMV_FOR tv[i] *= v[i]; return tv; } + //! \~english Element-wise multiplication with scalar + //! \~russian Покомпонентное умножение на скаляр + //! \param v The scalar to multiply by + //! \returns New vector with scaled elements _CVector mul(const Type & v) const { return (*this) * v; } + //! \~english Element-wise division by another vector + //! \~russian Покомпонентное деление на другой вектор + //! \param v The vector to divide by + //! \returns New vector with element-wise quotients _CVector div(const _CVector & v) const { assert(c.size() == v.size()); _CVector tv(*this); @@ -566,8 +1012,17 @@ public: } return tv; } + //! \~english Element-wise division by scalar + //! \~russian Покомпонентное деление на скаляр + //! \param v The scalar to divide by + //! \returns New vector with scaled elements _CVector div(const Type & v) const { return (*this) / v; } + //! \~english Get distance from this point to line defined by two points + //! \~russian Получить расстояние от этой точки до линии, заданной двумя точками + //! \param lp0 First point on the line + //! \param lp1 Second point on the line + //! \returns Distance from point to line Type distToLine(const _CVector & lp0, const _CVector & lp1) { assert(c.size() == lp0.size()); assert(c.size() == lp1.size()); @@ -578,24 +1033,75 @@ public: return piAbs(a[0] * b[1] - a[1] * b[0]) / tv; } + //! \~english Convert to PIVector + //! \~russian Преобразовать в PIVector + //! \returns PIVector with same elements PIVector toVector() const { return c; } + //! \~english Apply function to each element (const) + //! \~russian Применить функцию к каждому элементу (const) + //! \param f The function to apply void forEach(std::function f) const { c.forEach(f); } + //! \~english Apply function to each element + //! \~russian Применить функцию к каждому элементу + //! \param f The function to apply + //! \returns Reference to this vector _CVector & forEach(std::function f) { c.forEach(f); return *this; } + //! \~english Get pointer to underlying data + //! \~russian Получить указатель на внутренние данные + //! \returns Pointer to first element inline Type * data() { return c.data(); } + //! \~english Get pointer to underlying data (const) + //! \~russian Получить указатель на внутренние данные (const) + //! \returns Pointer to first element inline const Type * data() const { return c.data(); } + //! \~english Static cross product of two vectors + //! \~russian Статическое векторное произведение двух векторов + //! \param v1 First vector + //! \param v2 Second vector + //! \returns Cross product vector static _CVector cross(const _CVector & v1, const _CVector & v2) { return v1.cross(v2); } + //! \~english Static dot product of two vectors + //! \~russian Статическое скалярное произведение двух векторов + //! \param v1 First vector + //! \param v2 Second vector + //! \returns Dot product static Type dot(const _CVector & v1, const _CVector & v2) { return v1.dot(v2); } + //! \~english Static element-wise multiplication of two vectors + //! \~russian Статическое покомпонентное умножение двух векторов + //! \param v1 First vector + //! \param v2 Second vector + //! \returns New vector with element-wise products static _CVector mul(const _CVector & v1, const _CVector & v2) { return v1.mul(v2); } + //! \~english Static scalar multiplication (scalar * vector) + //! \~russian Статическое скалярное умножение (скаляр * вектор) + //! \param v1 Scalar + //! \param v2 Vector + //! \returns Scaled vector static _CVector mul(const Type & v1, const _CVector & v2) { return v2 * v1; } + //! \~english Static scalar multiplication (vector * scalar) + //! \~russian Статическое скалярное умножение (вектор * скаляр) + //! \param v1 Vector + //! \param v2 Scalar + //! \returns Scaled vector static _CVector mul(const _CVector & v1, const Type & v2) { return v1 * v2; } + //! \~english Static element-wise division of two vectors + //! \~russian Статическое покомпонентное деление двух векторов + //! \param v1 First vector + //! \param v2 Second vector + //! \returns New vector with element-wise quotients static _CVector div(const _CVector & v1, const _CVector & v2) { return v1.div(v2); } + //! \~english Static scalar division (vector / scalar) + //! \~russian Статическое скалярное деление (вектор / скаляр) + //! \param v1 Vector + //! \param v2 Scalar + //! \returns Scaled vector static _CVector div(const _CVector & v1, const Type & v2) { return v1 / v2; } private: @@ -610,6 +1116,11 @@ inline PIMathVector operator*(const Type & x, const PIMathVector & v #undef PIMV_FOR #ifdef PIP_STD_IOSTREAM +//! \~english Output vector to stream +//! \~russian Вывести вектор в поток +//! \param s The output stream +//! \param v The vector to output +//! \returns Reference to the stream template inline std::ostream & operator<<(std::ostream & s, const PIMathVector & v) { s << "{"; @@ -622,6 +1133,11 @@ inline std::ostream & operator<<(std::ostream & s, const PIMathVector & v) } #endif +//! \~english Output vector to PIP stream +//! \~russian Вывести вектор в поток PIP +//! \param s The PIP output stream +//! \param v The vector to output +//! \returns Reference to the stream template inline PICout operator<<(PICout s, const PIMathVector & v) { s.space(); @@ -636,11 +1152,21 @@ inline PICout operator<<(PICout s, const PIMathVector & v) { return s; } +//! \~english Serialize vector to binary stream +//! \~russian Сериализовать вектор в бинарный поток +//! \param s The binary stream +//! \param v The vector to serialize +//! \returns Reference to the stream template inline PIBinaryStream

& operator<<(PIBinaryStream

& s, const PIMathVector & v) { s << v.c; return s; } +//! \~english Deserialize vector from binary stream +//! \~russian Десериализовать вектор из бинарного потока +//! \param s The binary stream +//! \param v The vector to deserialize +//! \returns Reference to the stream template inline PIBinaryStream

& operator>>(PIBinaryStream

& s, PIMathVector & v) { s >> v.c; @@ -648,7 +1174,11 @@ inline PIBinaryStream

& operator>>(PIBinaryStream

& s, PIMathVector & v } +//! \~english 32-bit integer dynamic vector +//! \~russian Динамический вектор с 32-битными целыми числами typedef PIMathVector PIMathVectori; +//! \~english Double precision dynamic vector +//! \~russian Динамический вектор с числами двойной точности typedef PIMathVector PIMathVectord; #endif // PIMATHVECTOR_H diff --git a/libs/main/math/pirect.h b/libs/main/math/pirect.h index e1be892b..2fdb97b6 100644 --- a/libs/main/math/pirect.h +++ b/libs/main/math/pirect.h @@ -1,8 +1,11 @@ //! \file pirect.h //! \ingroup Math //! \brief -//! \~english Rect class -//! \~russian Класс прямоугольника +//! \~english Rect class for 2D geometry +//! \~russian Класс прямоугольника для 2D геометрии +//! \details +//! \~english The PIRect class provides a two-dimensional rectangle class for 2D geometry. +//! \~russian Класс PIRect предоставляет двумерный класс прямоугольника для 2D геометрии. /* PIP - Platform Independent Primitives Rect class @@ -30,9 +33,9 @@ //! \brief //! \~english Rect class //! \~russian Класс прямоугольника -//! \~\details -//! \~russian -//! Этот класс описывает прямоугольник на плоскости в прямоугольной системе координат +//! \details +//! \~english The PIRect class provides a two-dimensional rectangle class for 2D geometry. +//! \~russian Класс PIRect предоставляет двумерный класс прямоугольника для 2D геометрии. template class PIP_EXPORT PIRect { static_assert(std::is_arithmetic::value, "Type must be arithmetic"); @@ -360,6 +363,9 @@ private: //! \~english Stream output operator for PIRect. //! \~russian Перегруженный оператор для вывода прямоугольника в \a PICout. +//! \details +//! \~english The operator outputs rectangle information in format: Rect{bottomLeft:widthxheight} +//! \~russian Оператор выводит информацию о прямоугольнике в формате: Rect{bottomLeft:widthxheight} template PICout operator<<(PICout & s, const PIRect & v) { s.space();