This commit is contained in:
2022-03-17 18:13:02 +03:00
parent cc4e1f48aa
commit 7a26ae7292
11 changed files with 746 additions and 357 deletions

View File

@@ -1,4 +1,5 @@
/*! \file pibase.h
* \ingroup Core
* \~\brief
* \~english Base types and functions
* \~russian Базовые типы и методы
@@ -38,6 +39,7 @@
#include "pip_export.h"
#include "pip_defs.h"
#include "string.h"
//! \~english
//! Meta-information section for any entity.
//! Parsing by \a pip_cmg and can be accessed by \a PICodeInfo.

View File

@@ -20,15 +20,28 @@
#include "picollection.h"
/** \class PICollection
* \brief Interface to discover element groups
* \details
* \section PICollection_sec0 Synopsis
* This class has only static functions so no need to create instance of the
* %PICollection. This class provide macros to add some classes or existing
* objects to global collection and access to them from any place of the code.
* \snippet picollection.cpp main
* */
//! \addtogroup Core
//! \{
//! \~\class PICollection picollection.h
//! \~\brief
//! \~english Helper to collect and retrieve classes to groups
//! \~russian Помощник для создания и получения классов в группы
//!
//! \~\details
//! \~english \section PICollection_sec0 Synopsis
//! \~russian \section PICollection_sec0 Краткий обзор
//! \~english
//! This class has only static functions so no need to create instance of the
//! %PICollection. This class provide macros to add some classes or existing
//! objects to global collection and access to them from any place of the code.
//!
//! \~russian
//! Этот класс предоставляет статические методы, поэтому не нужно создавать
//! его экземпляр. Имеется несколько макросов для добавления классов или существующих
//! объектов в глобальные группы. Затем можно получить их список в любом месте программы.
//! \~\snippet picollection.cpp main
//!
//! \}
PIStringList PICollection::groups() {
@@ -77,6 +90,7 @@ PIVector<PICollection::Group> & PICollection::_groups() {
PICollection::CollectionAdder::CollectionAdder(const PIString & group, const PIObject * element, const PIString & name, bool own) {
if (!element) return;
if (name.isNotEmpty())
const_cast<PIObject * >(element)->setName(name);
bool added = PICollection::addToGroup(group, element);
if (!added && own)

View File

@@ -1,5 +1,7 @@
/*! \file picollection.h
* \brief Custom elements collection
* \~\brief
* \~english Custom elements collection
* \~russian
*/
/*
PIP - Platform Independent Primitives
@@ -27,32 +29,70 @@
#ifdef DOXYGEN
/** \brief Add existing element "object" in group with name "group"
* \relatesalso PICollection
* \details If there is no group with name "group" it will be created.
* Only one element of the class "object" can be in group "group". If
* this is already exists nothing be happens. \n "object" should to
* be pointer to object based on PIObject. */
//! \~\relatesalso PICollection
//! \~\brief
//! \~english Add existing element "object" in group with name "group"
//! \~russian Добавляет существующий элемент "object" в группу с именем "group"
//! \~\details
//! \~english
//! If this is no group with name "group" it will be created.
//! Only one element of the class "object" can be in group. If
//! this is already exists nothing be happens. \n "object" should to
//! be pointer to object based on \a PIObject.
//! \~russian
//! Если такой группы нет, она создается. В каждой группе может присутствовать
//! только один элемент класса объекта "object". Если такой элемент уже есть,
//! то ничего не изменится. \n "object" должен быть наследником \a PIObject.
# define ADD_TO_COLLECTION(group, object)
/** \brief Add new element of class "class" in group with name "group"
* \relatesalso PICollection
* \details If there is no group with name "group" it will be created.
* Only one element of the class "class" can be in group "group". If
* this is already exists nothing be happens. \n "class" should to
* be name of the any class based on PIObject. */
//! \~\relatesalso PICollection
//! \~\brief
//! \~english Add existing element "object" in group with name "group" and set its name to "name"
//! \~russian Добавляет существующий элемент "object" в группу с именем "group" и присваивает объекту имя "name"
//! \~\details
//! \~english
//! Similar to \a ADD_TO_COLLECTION(group, object) but set object name to "name"
//! \~russian
//! Аналогично \a ADD_TO_COLLECTION(group, object), но присваивает имя объекту "name"
# define ADD_TO_COLLECTION_WITH_NAME(group, object, name)
//! \~\relatesalso PICollection
//! \~\brief
//! \~english Add new element of class "class" in group with name "group"
//! \~russian Добавляет новый элемент класса "class" в группу с именем "group"
//! \~\details
//! \~english
//! If this is no group with name "group" it will be created.
//! Only one element of the class "class" can be in group. If
//! this is already exists nothing be happens. \n "class" should to
//! be name of the any class based on PIObject.
//! \~russian
//! Если такой группы нет, она создается. В каждой группе может присутствовать
//! только один элемент класса "class". Если такой элемент уже есть,
//! то ничего не изменится. \n "class" должен быть любым классом, наследным от \a PIObject.
# define ADD_NEW_TO_COLLECTION(group, class)
//! \~\relatesalso PICollection
//! \~\brief
//! \~english Add new element of class "class" in group with name "group" and set its name to "name"
//! \~russian Добавляет новый элемент класса "class" в группу с именем "group" и присваивает объекту имя "name"
//! \~\details
//! \~english
//! Similar to \a ADD_NEW_TO_COLLECTION(group, class) but set object name to "name"
//! \~russian
//! Аналогично \a ADD_NEW_TO_COLLECTION(group, class), но присваивает имя объекту "name"
# define ADD_NEW_TO_COLLECTION_WITH_NAME(group, class, name)
#else
# define ADD_TO_COLLECTION(group, object) \
static PICollection::CollectionAdder _PIP_ADD_COUNTER(_collection_adder_)(#group, object, false);
static PICollection::CollectionAdder _PIP_ADD_COUNTER(_collection_adder_)(#group, object, "", false);
# define ADD_TO_COLLECTION_WITH_NAME(group, object, name) \
static PICollection::CollectionAdder _PIP_ADD_COUNTER(_collection_adder_)(#group, object, #name, false);
# define ADD_NEW_TO_COLLECTION(group, class) \
static PICollection::CollectionAdder _PIP_ADD_COUNTER(_collection_adder_)(#group, new class(), true);
static PICollection::CollectionAdder _PIP_ADD_COUNTER(_collection_adder_)(#group, new class(), "", true);
# define ADD_NEW_TO_COLLECTION_WITH_NAME(group, class, name) \
static PICollection::CollectionAdder _PIP_ADD_COUNTER(_collection_adder_)(#group, new class(), #name, true);
@@ -65,10 +105,12 @@ class PIP_EXPORT PICollection
public:
PICollection() {;}
//! \brief Returns all existing groups by their names
//! \~english Returns all existing groups by their names
//! \~russian Возвращает имена всех групп
static PIStringList groups();
//! \brief Returns all elements of group "group"
//! \~english Returns all elements of group "group"
//! \~russian Возвращает все элементы группы "group"
static PIVector<const PIObject * > groupElements(const PIString & group);
static bool addToGroup(const PIString & group, const PIObject * element);

View File

@@ -27,26 +27,11 @@
* C++ | #include <picoremodule.h>
* CMake | PIP
*
* \~english These files provides platform abstraction, useful macros, methods and classes:
* \~russian Эти файлы обеспечивают абстракцию операционной системы, полезные макросы, методы и классы:
* \~
* * \a PIFlags
* * \a PICout
* * \a PICLI
* * \a PIChar
* * \a PIString
* * \a PIStringList
* * \a PIBitArray
* * \a PIByteArray
* * \a PIChunkStream
* * \a PIPropertyStorage
* * \a PITime
* * \a PIDate
* * \a PIDateTime
* * \a PISystemTime
* * \a PITimeMeasurer
* * \a PIVariant
* * \a PIObject
* \~english
* These files provides platform abstraction, useful macros, methods and classes
*
* \~russian
* Эти файлы обеспечивают абстракцию операционной системы, полезные макросы, методы и классы
*
* \~\authors
* \~english

View File

@@ -30,6 +30,82 @@
#endif
//! \addtogroup Core
//! \{
//! \~\class PICout picout.h
//! \~\brief
//! \~english Universal output to console class
//! \~russian Универсальный вывод в консоль
//!
//! \~english \section PICout_sec0 Synopsis
//! \~russian \section PICout_sec0 Краткий обзор
//! \~english
//! This class provide many stream operators for output with some features.
//! Output to %PICout is thread-sequential, i.e. doesn`t mixed from parallel
//! threads.
//!
//! \~russian
//! Данный класс предоставляет множество операторов для вывода в консоль.
//! Вывод в %PICout потоково-последовательный, т.е. не смешивается из параллельных
//! потоков.
//!
//! \~english \section PICout_sec1 Features
//! \~russian \section PICout_sec1 Особенности
//! \~english
//! * support text formatting (color, style)
//! * insertion spaces between entries
//! * insertion new line at the end of output
//! * strings are quoted
//! * custom output operator can be easily written
//! * can outpur to console, internal buffer or both
//!
//! \~russian
//! * поддержка форматирования (цвет, стиль)
//! * вставка пробелов между выводами
//! * вставка новой строки после последнего вывода
//! * строки обрамляются кавычками
//! * легко создавать сови операторы вывода
//! * может выводить в консоль, внутренний буфер или в оба места
//!
//! \~english \section PICout_ex0 Usage
//! \~russian \section PICout_ex0 Использование
//! \~\snippet picout.cpp 0
//!
//! \~english \section PICout_ex1 Writing your own output operator
//! \~russian \section PICout_ex1 Создание своего оператора вывода
//! \~\snippet picout.cpp own
//!
//! \}
//! \addtogroup Core
//! \{
//! \~\class PICout::Notifier picout.h
//! \~\brief
//! \~english Class for emit notifications of PICout
//! \~russian Класс для посылки событий от PICout
//!
//! \~english \section PICout_sec0 Synopsis
//! \~russian \section PICout_sec0 Краткий обзор
//! \~english
//! This class used as PICout events emitter. When
//! PICout constructs with external PIString* buffer
//! and some ID, last copy of this PICout on delete
//! emit event "finished()" on object Notifier::object().
//! Sample:
//!
//! \~russian
//! Этот класс используется как источник событий PICout.
//! Когда PICout сконструирован с внешним буфером PIString*
//! и каким-то ID, последняя копия этого PICout при уничтожении
//! посылает событие "finished()" у объекта Notifier::object().
//! Пример:
//!
//! \~\snippet picout.cpp notifier
//!
//! \}
class NotifierObject: public PIObject {
PIOBJECT(NotifierObject)
public:
@@ -204,6 +280,49 @@ PICout PICout::operator <<(const PICoutAction v) {
}
PICout PICout::operator <<(const PICoutManipulators::PICoutFormat v) {
switch (v) {
case PICoutManipulators::Bin: cnb_ = 2; break;
case PICoutManipulators::Oct: cnb_ = 8; break;
case PICoutManipulators::Dec: cnb_ = 10; break;
case PICoutManipulators::Hex: cnb_ = 16; break;
default: applyFormat(v);
};
return *this;
}
PICout PICout::operator <<(const PIFlags<PICoutManipulators::PICoutFormat> & v) {
if (v[PICoutManipulators::Bin]) cnb_ = 2;
if (v[PICoutManipulators::Oct]) cnb_ = 8;
if (v[PICoutManipulators::Dec]) cnb_ = 10;
if (v[PICoutManipulators::Hex]) cnb_ = 16;
if (v[PICoutManipulators::Bold]) applyFormat(PICoutManipulators::Bold);
if (v[PICoutManipulators::Faint]) applyFormat(PICoutManipulators::Faint);
if (v[PICoutManipulators::Italic]) applyFormat(PICoutManipulators::Italic);
if (v[PICoutManipulators::Underline]) applyFormat(PICoutManipulators::Underline);
if (v[PICoutManipulators::Blink]) applyFormat(PICoutManipulators::Blink);
if (v[PICoutManipulators::Black]) applyFormat(PICoutManipulators::Black);
if (v[PICoutManipulators::Red]) applyFormat(PICoutManipulators::Red);
if (v[PICoutManipulators::Green]) applyFormat(PICoutManipulators::Green);
if (v[PICoutManipulators::Blue]) applyFormat(PICoutManipulators::Blue);
if (v[PICoutManipulators::Yellow]) applyFormat(PICoutManipulators::Yellow);
if (v[PICoutManipulators::Magenta]) applyFormat(PICoutManipulators::Magenta);
if (v[PICoutManipulators::Cyan]) applyFormat(PICoutManipulators::Cyan);
if (v[PICoutManipulators::White]) applyFormat(PICoutManipulators::White);
if (v[PICoutManipulators::BackBlack]) applyFormat(PICoutManipulators::BackBlack);
if (v[PICoutManipulators::BackRed]) applyFormat(PICoutManipulators::BackRed);
if (v[PICoutManipulators::BackGreen]) applyFormat(PICoutManipulators::BackGreen);
if (v[PICoutManipulators::BackBlue]) applyFormat(PICoutManipulators::BackBlue);
if (v[PICoutManipulators::BackYellow]) applyFormat(PICoutManipulators::BackYellow);
if (v[PICoutManipulators::BackMagenta]) applyFormat(PICoutManipulators::BackMagenta);
if (v[PICoutManipulators::BackCyan]) applyFormat(PICoutManipulators::BackCyan);
if (v[PICoutManipulators::BackWhite]) applyFormat(PICoutManipulators::BackWhite);
if (v[PICoutManipulators::Default]) applyFormat(PICoutManipulators::Default);
return *this;
}
#define PICOUTTOTARGET(v) { \
if (buffer_) {\
(*buffer_) << (v);\
@@ -346,6 +465,12 @@ PICout & PICout::restoreControl() {
#undef PICOUTTOTARGET
#undef PINUMERICCOUT
//! \details
//! \~english
//! If it is not a first output and control \a AddSpaces is set space character is put
//! \~russian
//! Добавляет пробел если это не первый вывод и установлен флаг \a AddSpaces
//! \~\sa \a quote(), \a newLine()
PICout & PICout::space() {
if (!act_) return *this;
if (!fo_ && co_[AddSpaces]) {
@@ -360,6 +485,12 @@ PICout & PICout::space() {
return *this;
}
//! \details
//! \~english
//! If control \a AddQuotes is set quote character is put
//! \~russian
//! Добавляет кавычки если установлен флаг \a AddQuotes
//! \~\sa \a space(), \a newLine()
PICout & PICout::quote() {
if (!act_) return *this;
if (co_[AddQuotes]) {
@@ -374,6 +505,12 @@ PICout & PICout::quote() {
return *this;
}
//! \details
//! \~english
//! If control \a AddNewLine is set new line character is put
//! \~russian
//! Добавляет новую строку если установлен флаг \a AddNewLine
//! \~\sa \a space(), \a quote()
PICout & PICout::newLine() {
if (!act_) return *this;
if (co_[AddNewLine]) {

View File

@@ -1,5 +1,7 @@
/*! \file picout.h
* \brief Universal output to console class
* \~\brief
* \~english Universal output to console class
* \~russian Универсальный вывод в консоль
*/
/*
PIP - Platform Independent Primitives
@@ -27,10 +29,13 @@
#ifdef DOXYGEN
//! \brief Macro used for conditional (piDebug) output to PICout
//! \~english Macro used for conditional (piDebug) output to PICout
//! \~russian Макрос для условного (piDebug) вывода в PICout
# define piCout
//! \relatesalso PIObject \brief Macro used for conditional (piDebug and PIObject::debug()) output to PICout for subclasses of PIObject
//! \relatesalso PIObject
//! \~english Macro used for conditional (piDebug && PIObject::debug()) output to PICout for subclasses of PIObject
//! \~russian Макрос для условного (piDebug && PIObject::debug()) вывода в PICout для наследников PIObject
# define piCoutObj
#else
@@ -42,106 +47,97 @@
class PIObject;
//! \brief Namespace contains enums controlled PICout
//! \relatesalso PICout
//! \~english Namespace contains enums that controls PICout
//! \~russian Пространство имен содержит перечисления для контроля PICout
namespace PICoutManipulators {
//! \brief Enum contains special characters
//! \~english Enum contains special characters
//! \~russian Перечисление со спецсимволами
enum PICoutSpecialChar {
Null /*! Null-character, '\\0' */,
NewLine /*! New line character, '\\n' */,
Tab /*! Tab character, '\\t' */,
Esc /*! Escape character, '\\e' */,
Quote /*! Quote character, '"' */
Null /*! \~english Null-character, '\\0' \~russian Нулевой символ, '\\0' */,
NewLine /*! \~english New line character, '\\n' \~russian Новая строка, '\\n' */,
Tab /*! \~english Tab character, '\\t' \~russian Табуляция, '\\t' */,
Esc /*! \~english Escape character, '\\e' \~russian Esc-символ, '\\e' */,
Quote /*! \~english Quote character, '"' \~russian Кавычки, '"' */
};
//! \brief Enum contains immediate action
//! \~english Enum contains immediate action
//! \~russian Перечисление с немедленными действиями
enum PICoutAction {
Flush /*! Flush the output */,
Backspace /*! Remove last symbol */,
ShowCursor /*! Show cursor */,
HideCursor /*! Hide cursor */,
ClearLine /*! Clear current line */,
ClearScreen /*! Clear the screen */,
SaveContol /*! Save control flags, equivalent to \a saveControl() */,
RestoreControl /*! Restore control flags, equivalent to \a restoreControl() */
Flush /*! \~english Flush the output \~russian Обновить вывод */,
Backspace /*! \~english Remove last symbol \~russian Удалить последний символ */,
ShowCursor /*! \~english Show cursor \~russian Показать курсор */,
HideCursor /*! \~english Hide cursor \~russian Скрыть курсор */,
ClearLine /*! \~english Clear current line \~russian Очистить текущую строку */,
ClearScreen /*! \~english Clear the screen \~russian Очистить экран */,
SaveContol /*! \~english Save control flags, equivalent to \a saveControl() \~russian Сохранить флаги, аналогично \a saveControl() */,
RestoreControl /*! \~english Restore control flags, equivalent to \a restoreControl() \~russian Восстановить флаги, аналогично \a restoreControl() */
};
//! \brief Enum contains control of PICout
//! \~english Enum contains control of PICout
//! \~russian Перечисление с управлением PICout
enum PICoutControl {
AddNone /*! No controls */ = 0x0,
AddSpaces /*! Spaces will be appear after each output */ = 0x1,
AddNewLine /*! New line will be appear after all output */ = 0x2,
AddQuotes /*! Each string will be quoted */ = 0x4,
DefaultControls /*! Default controls */ = AddSpaces | AddNewLine,
AddAll /*! All controls */ = 0xFF,
NoLock /*! Don`t use mutex for output */ = 0x100,
AddNone /*! \~english No controls \~russian Без управления */ = 0x0,
AddSpaces /*! \~english Spaces will be appear after each output \~russian Пробел после каждого вывода */ = 0x1,
AddNewLine /*! \~english New line will be appear after all output \~russian Новая строка после завершения вывода */ = 0x2,
AddQuotes /*! \~english Each string will be quoted \~russian Каждая строка в кавычках */ = 0x4,
DefaultControls /*! \~english Default controls \~russian Управление по умолчанию */ = AddSpaces | AddNewLine,
AddAll /*! \~english All controls \~russian Всё управление */ = 0xFF,
NoLock /*! \~english Don`t use mutex for output \~russian Не использовать мьютекс при выводе */ = 0x100,
};
//! \brief Enum contains output format
//! \~english Enum contains output format
//! \~russian Перечисление с форматом вывода
enum PICoutFormat {
Bin /*! Binary representation of integers */ = 0x01,
Oct /*! Octal representation of integers */ = 0x02,
Dec /*! Decimal representation of integers */ = 0x04,
Hex /*! Hexadecimal representation of integers */ = 0x08,
Bold /*! Bold */ = 0x10,
Faint /*! */ = 0x20,
Italic /*! */ = 0x40,
Underline /*! Underline */ = 0x80,
Blink /*! Blink */ = 0x100,
Black /*! Black font */ = 0x400,
Red /*! Red font */ = 0x800,
Green /*! Green font */ = 0x1000,
Blue /*! Blue font */ = 0x2000,
Yellow /*! Yellow font */ = 0x4000,
Magenta /*! Magenta font */ = 0x8000,
Cyan /*! Cyan font */ = 0x10000,
White /*! White font */ = 0x20000,
BackBlack /*! Black background */ = 0x40000,
BackRed /*! Red background */ = 0x80000,
BackGreen /*! Green background */ = 0x100000,
BackBlue /*! Blue background */ = 0x200000,
BackYellow /*! Yellow background */ = 0x400000,
BackMagenta /*! Magenta background */ = 0x800000,
BackCyan /*! Cyan background */ = 0x1000000,
BackWhite /*! White background */ = 0x2000000,
Default /*! Default format */ = 0x4000000
Bin /*! \~english Binary representation of integers \~russian Двоичное представление для целых чисел */ = 0x01,
Oct /*! \~english Octal representation of integers \~russian Восьмеричное представление для целых чисел */ = 0x02,
Dec /*! \~english Decimal representation of integers \~russian Десятичное представление для целых чисел */ = 0x04,
Hex /*! \~english Hexadecimal representation of integers \~russian Шестнадцатеричное представление для целых чисел */ = 0x08,
Bold /*! \~english Bold \~russian Жирный */ = 0x10,
Faint /*! \~english \~russian */ = 0x20,
Italic /*! \~english \~russian */ = 0x40,
Underline /*! \~english Underline \~russian Подчеркнутый */ = 0x80,
Blink /*! \~english Blink \~russian Мигающий */ = 0x100,
Black /*! \~english Black font \~russian Чёрный */ = 0x400,
Red /*! \~english Red font \~russian Красный */ = 0x800,
Green /*! \~english Green font \~russian Зелёный */ = 0x1000,
Blue /*! \~english Blue font \~russian Синий */ = 0x2000,
Yellow /*! \~english Yellow font \~russian Жёлтый */ = 0x4000,
Magenta /*! \~english Magenta font \~russian Пурпурный */ = 0x8000,
Cyan /*! \~english Cyan font \~russian Голубой */ = 0x10000,
White /*! \~english White font \~russian Белый */ = 0x20000,
BackBlack /*! \~english Black background \~russian Чёрный фон */ = 0x40000,
BackRed /*! \~english Red background \~russian Красный фон */ = 0x80000,
BackGreen /*! \~english Green background \~russian Зелёный фон */ = 0x100000,
BackBlue /*! \~english Blue background \~russian Синий фон */ = 0x200000,
BackYellow /*! \~english Yellow background \~russian Жёлтый фон */ = 0x400000,
BackMagenta /*! \~english Magenta background \~russian Пурпурный фон */ = 0x800000,
BackCyan /*! \~english Cyan background \~russian Голубой фон */ = 0x1000000,
BackWhite /*! \~english White background \~russian Белый фон */ = 0x2000000,
Default /*! \~english Default format \~russian Формат по умолчанию */ = 0x4000000
};
typedef PIFlags<PICoutControl> PICoutControls;
}
/*! \class PICout
* \brief Class for formatted output similar std::cout
*
* \section PICout_sec0 Synopsis
* This class provide many stream operators for output with some features.
* Output to PICout is thread-sequential, i.e. doesn`t mixed from parallel
* threads.
*
* \section PICout_sec1 Features
* - insertion spaces between entries
* - insertion new line at the end of output
* - strings are quoted
* - custom output operator can be easily written
*
* \section PICout_ex0 Usage
* \snippet picout.cpp 0
*
* \section PICout_ex1 Writing your own output operator
* \snippet picout.cpp own
*/
class PIP_EXPORT PICout {
public:
//! Default constructor with default features (AddSpaces and AddNewLine)
//! \~english Default constructor with default features (AddSpaces and AddNewLine)
//! \~russian Конструктор по умолчанию (AddSpaces и AddNewLine)
PICout(PIFlags<PICoutManipulators::PICoutControl> controls = PICoutManipulators::DefaultControls);
PICout(PICoutManipulators::PICoutControl control = PICoutManipulators::DefaultControls);
//! Construct with default features (AddSpaces and AddNewLine), but if \"active\" is false does nothing
//! \~english Construct with default features (AddSpaces and AddNewLine), but if \"active\" is false does nothing
//! \~russian Конструктор по умолчанию (AddSpaces и AddNewLine), но если не \"active\" то будет неактивным
PICout(bool active);
//! Construct with external buffer and id "id". See \a Notifier for details
//! \~english Construct with external buffer and ID "id". See \a Notifier for details
//! \~russian Конструктор с внешним буфером и ID "id". Подробнее \a Notifier
PICout(PIString * buffer, int id = 0, PIFlags<PICoutManipulators::PICoutControl> controls = PICoutManipulators::AddSpaces | PICoutManipulators::AddNewLine);
PICout(const PICout & other);
@@ -149,171 +145,171 @@ public:
~PICout();
/*! \class PICout::Notifier
* \brief Class for emit notifications of PICout
*
* \section PICout_sec0 Synopsis
* This class used as PICout events emitter. When
* PICout constructs with external PIString* buffer
* and some id, last copy of this PICout on delete
* emit event "finished()" on object Notifier::object().
* Sample:
* \snippet picout.cpp notifier
*/
class PIP_EXPORT Notifier {
public:
//! \~english Singleton access to %PICout::Notifier
//! \~russian Синглтон класса %PICout::Notifier
static Notifier * instance();
//! \~english Object that emit events from %PICout
//! \~russian Объект, который посылает события от %PICout
static PIObject * object();
private:
Notifier();
PIObject * o;
};
//! \brief Enum contains output devices of PICout
//! \~english Enum contains output devices of %PICout
//! \~russian Перечисление с устройствами вывода для %PICout
enum OutputDevice {
NoDevices /** PICout is disabled */ = 0x0,
StdOut /** Standard console output */ = 0x1,
Buffer /** Internal buffer */ = 0x2,
AllDevices /** All */ = 0xFFFF,
NoDevices /** \~english %PICout is disabled \~russian %PICout неактивен */ = 0x0,
StdOut /** \~english Standard console output \~russian Стандартный вывод в консоль */ = 0x1,
Buffer /** \~english Internal buffer \~russian Внутренний буфер */ = 0x2,
AllDevices /** \~english All \~russian Все */ = 0xFFFF,
};
typedef PIFlags<OutputDevice> OutputDevices;
//! Output operator for strings with <tt>"const char * "</tt> type
//! \~english Output operator for strings with <tt>"const char * "</tt> type
//! \~russian Оператор вывода для строк <tt>"const char * "</tt>
PICout operator <<(const char * v);
// ! Output operator for strings with <tt>"std::string"</tt> type
//PICout operator <<(const std::string & v);
//! Output operator for boolean values
//! \~english Output operator for boolean values
//! \~russian Оператор вывода для логических значений
PICout operator <<(const bool v);
//! Output operator for <tt>"char"</tt> values
//! \~english Output operator for <tt>"char"</tt> values
//! \~russian Оператор вывода для <tt>"char"</tt> значений
PICout operator <<(const char v);
//! Output operator for <tt>"unsigned char"</tt> values
//! \~english Output operator for <tt>"unsigned char"</tt> values
//! \~russian Оператор вывода для <tt>"unsigned char"</tt> значений
PICout operator <<(const uchar v);
//! Output operator for <tt>"short"</tt> values
//! \~english Output operator for <tt>"short"</tt> values
//! \~russian Оператор вывода для <tt>"short"</tt> значений
PICout operator <<(const short v);
//! Output operator for <tt>"unsigned short"</tt> values
//! \~english Output operator for <tt>"unsigned short"</tt> values
//! \~russian Оператор вывода для <tt>"unsigned short"</tt> значений
PICout operator <<(const ushort v);
//! Output operator for <tt>"int"</tt> values
//! \~english Output operator for <tt>"int"</tt> values
//! \~russian Оператор вывода для <tt>"int"</tt> значений
PICout operator <<(const int v);
//! Output operator for <tt>"unsigned int"</tt> values
//! \~english Output operator for <tt>"unsigned int"</tt> values
//! \~russian Оператор вывода для <tt>"unsigned int"</tt> значений
PICout operator <<(const uint v);
//! Output operator for <tt>"long"</tt> values
//! \~english Output operator for <tt>"long"</tt> values
//! \~russian Оператор вывода для <tt>"long"</tt> значений
PICout operator <<(const long v);
//! Output operator for <tt>"unsigned long"</tt> values
//! \~english Output operator for <tt>"unsigned long"</tt> values
//! \~russian Оператор вывода для <tt>"unsigned long"</tt> значений
PICout operator <<(const ulong v);
//! Output operator for <tt>"long long"</tt> values
//! \~english Output operator for <tt>"long long"</tt> values
//! \~russian Оператор вывода для <tt>"long long"</tt> значений
PICout operator <<(const llong v);
//! Output operator for <tt>"unsigned long long"</tt> values
//! \~english Output operator for <tt>"unsigned long long"</tt> values
//! \~russian Оператор вывода для <tt>"unsigned long long"</tt> значений
PICout operator <<(const ullong v);
//! Output operator for <tt>"float"</tt> values
//! \~english Output operator for <tt>"float"</tt> values
//! \~russian Оператор вывода для <tt>"float"</tt> значений
PICout operator <<(const float v);
//! Output operator for <tt>"double"</tt> values
//! \~english Output operator for <tt>"double"</tt> values
//! \~russian Оператор вывода для <tt>"double"</tt> значений
PICout operator <<(const double v);
//! Output operator for pointers
//! \~english Output operator for pointers
//! \~russian Оператор вывода для указателей
PICout operator <<(const void * v);
//! Output operator for PIObject and ancestors
//! \~english Output operator for PIObject and ancestors
//! \~russian Оператор вывода для PIObject и наследников
PICout operator <<(const PIObject * v);
//! Output operator for \a PICoutSpecialChar values
//! \~english Output operator for \a PICoutSpecialChar values
//! \~russian Оператор вывода для \a PICoutSpecialChar
PICout operator <<(const PICoutManipulators::PICoutSpecialChar v);
//! Output operator for \a PIFlags<PICoutFormat> values
PICout operator <<(const PIFlags<PICoutManipulators::PICoutFormat> & v) {
if (v[PICoutManipulators::Bin]) cnb_ = 2;
if (v[PICoutManipulators::Oct]) cnb_ = 8;
if (v[PICoutManipulators::Dec]) cnb_ = 10;
if (v[PICoutManipulators::Hex]) cnb_ = 16;
if (v[PICoutManipulators::Bold]) applyFormat(PICoutManipulators::Bold);
if (v[PICoutManipulators::Faint]) applyFormat(PICoutManipulators::Faint);
if (v[PICoutManipulators::Italic]) applyFormat(PICoutManipulators::Italic);
if (v[PICoutManipulators::Underline]) applyFormat(PICoutManipulators::Underline);
if (v[PICoutManipulators::Blink]) applyFormat(PICoutManipulators::Blink);
if (v[PICoutManipulators::Black]) applyFormat(PICoutManipulators::Black);
if (v[PICoutManipulators::Red]) applyFormat(PICoutManipulators::Red);
if (v[PICoutManipulators::Green]) applyFormat(PICoutManipulators::Green);
if (v[PICoutManipulators::Blue]) applyFormat(PICoutManipulators::Blue);
if (v[PICoutManipulators::Yellow]) applyFormat(PICoutManipulators::Yellow);
if (v[PICoutManipulators::Magenta]) applyFormat(PICoutManipulators::Magenta);
if (v[PICoutManipulators::Cyan]) applyFormat(PICoutManipulators::Cyan);
if (v[PICoutManipulators::White]) applyFormat(PICoutManipulators::White);
if (v[PICoutManipulators::BackBlack]) applyFormat(PICoutManipulators::BackBlack);
if (v[PICoutManipulators::BackRed]) applyFormat(PICoutManipulators::BackRed);
if (v[PICoutManipulators::BackGreen]) applyFormat(PICoutManipulators::BackGreen);
if (v[PICoutManipulators::BackBlue]) applyFormat(PICoutManipulators::BackBlue);
if (v[PICoutManipulators::BackYellow]) applyFormat(PICoutManipulators::BackYellow);
if (v[PICoutManipulators::BackMagenta]) applyFormat(PICoutManipulators::BackMagenta);
if (v[PICoutManipulators::BackCyan]) applyFormat(PICoutManipulators::BackCyan);
if (v[PICoutManipulators::BackWhite]) applyFormat(PICoutManipulators::BackWhite);
if (v[PICoutManipulators::Default]) applyFormat(PICoutManipulators::Default);
return *this;
}
//! \~english Output operator for \a PIFlags<PICoutFormat> values
//! \~russian Оператор вывода для \a PIFlags<PICoutFormat>
PICout operator <<(const PIFlags<PICoutManipulators::PICoutFormat> & v);
//! Output operator for \a PICoutFormat values
PICout operator <<(const PICoutManipulators::PICoutFormat v) {
switch (v) {
case PICoutManipulators::Bin: cnb_ = 2; break;
case PICoutManipulators::Oct: cnb_ = 8; break;
case PICoutManipulators::Dec: cnb_ = 10; break;
case PICoutManipulators::Hex: cnb_ = 16; break;
default: applyFormat(v);
};
return *this;
}
//! \~english Output operator for \a PICoutFormat values
//! \~russian Оператор вывода для \a PICoutFormat
PICout operator <<(const PICoutManipulators::PICoutFormat v);
//! Do some action
//! \~english Do some action
//! \~russian Делает действие
PICout operator <<(const PICoutManipulators::PICoutAction v);
//! Set control flag "c" is "on" state
//! \~english Set control flag "c" is "on" state
//! \~russian Установить флаг "c" в "on" состояние
PICout & setControl(PICoutManipulators::PICoutControl c, bool on = true) {co_.setFlag(c, on); return *this;}
//! Set control flags "c" and if "save" exec \a saveControl()
//! \~english Set control flags "c" and if "save" exec \a saveControl()
//! \~russian Установить флаг "c" и если "save" то выполнить \a saveControl()
PICout & setControl(PICoutManipulators::PICoutControls c, bool save = false) {if (save) saveControl(); co_ = c; return *this;}
//! Save control flags to internal stack \sa \a restoreControl()
//! \~english Save control flags to internal stack
//! \~russian Сохраняет состояние флагов во внутренний стек
//! \~\sa \a restoreControl()
PICout & saveControl();
//! Restore control flags from internal stack \sa \a saveControl()
//! \~english Restore control flags from internal stack
//! \~russian Восстанавливает состояние флагов из внутреннего стека
//! \~\sa \a saveControl()
PICout & restoreControl();
/*! \brief Conditional put space character to output
* \details If it is not a first output and control \a AddSpaces is set
* space character is put \sa \a quote(), \a newLine() */
//! \~english Conditional put space character to output
//! \~russian Условно добавляет пробел
PICout & space();
/*! \brief Conditional put quote character to output
* \details If control \a AddQuotes is set
* quote character is put \sa \a space(), \a newLine() */
//! \~english Conditional put quote character to output
//! \~russian Условно добавляет кавычки
PICout & quote();
/*! \brief Conditional put new line character to output
* \details If control \a AddNewLine is set
* new line character is put \sa \a space(), \a quote() */
//! \~english Conditional put new line character to output
//! \~russian Условно добавляет новую строку
PICout & newLine();
//! \~english Set output device to \a PICout::Buffer and if "clear" clear it
//! \~russian Устанавливает устройство вывода на \a PICout::Buffer и если "clear" то очищает его
static bool setBufferActive(bool on, bool clear = false);
//! \~english Equivalent to \a isOutputDeviceActive(OutputDevice)
//! \~russian Аналог \a isOutputDeviceActive(OutputDevice)
static bool isBufferActive();
//! \~english Returns internal PIString buffer and if "clear" clear it
//! \~russian Возвращает внутренний PIString буфер и если "clear" то очищает его
static PIString buffer(bool clear = false);
//! \~english Clear internal PIString buffer
//! \~russian Очищает внутренний PIString буфер
static void clearBuffer();
//! \~english Set output to device "d" enabled "on". Returns if it was enabled
//! \~russian Устройство вывода "d" устанавливается в "on". Возвращает было ли устройство активно
static bool setOutputDevice(OutputDevice d, bool on = true);
//! \~english Set output to devices to "d"
//! \~russian Устанавливает устройства вывода "d"
static void setOutputDevices(OutputDevices d);
//! \~english Returns if output device "d" is active
//! \~russian Возвращает активно ли устройство вывода "d"
static bool isOutputDeviceActive(OutputDevice d);
static PIMutex & __mutex__();

View File

@@ -1,5 +1,7 @@
/*! \file piflags.h
* \brief General flags class
* \~\brief
* \~english General flags class
* \~russian Универсальные флаги
*/
/*
PIP - Platform Independent Primitives
@@ -25,109 +27,220 @@
#include "pip_export.h"
/*! \brief This class used as container for bit flags
* \details PIFlags is wrapper around \c "int". There are many
* bit-wise operators, native conversion to int and function
* to test flag. \n Example:
* \snippet piincludes.cpp flags
*/
//! \addtogroup Core
//! \{
//! \~\class PIFlags piflags.h
//! \~\brief
//! \~english Container for bit flags
//! \~russian Контейнер для битовых полей (флагов)
//!
//! \~\details
//! \~english
//! %PIFlags is wrapper around \c "int". One can use it as native \c "int".
//! There are manybit-wise operators,
//! native conversion to "int" and function
//! to test flag. \n Example:
//!
//! \~russian
//! %PIFlags по сути обертка вокруг \c "int". Можно использовать его как обычный \c "int".
//! Имеет много битовых операторов,
//! неявное преобразование в "int" и методы для проверки
//! флагов. \n Пример:
//!
//! \~\snippet piincludes.cpp flags
//!
//! \}
template<typename Enum>
class PIFlags {
public:
//! Constructor with flags = 0
//! \~english Constructor with flags = 0
//! \~russian Создает нулевые флаги
PIFlags(): flags(0) {;}
//! Constructor with flags = Enum "e"
//! \~english Constructor with flags = Enum "e"
//! \~russian Создает флаги со значением = Enum "e"
PIFlags(Enum e): flags(e) {;}
//! Constructor with flags = int "i"
//! \~english Constructor with flags = int "i"
//! \~russian Создает флаги со значением = int "i"
PIFlags(const int i): flags(i) {;}
//! Set flags "f" to value "on"
//! \~english Set flags on positions "f" to value "on"
//! \~russian Устанавливает флаги по позициям "f" в "on"
PIFlags & setFlag(const PIFlags & f, bool on = true) {if (on) flags |= f.flags; else flags &= ~f.flags; return *this;}
//! Set flag "e" to value "on"
//! \~english Set flag "e" to value "on"
//! \~russian Устанавливает флаг "e" в "on"
PIFlags & setFlag(const Enum & e, bool on = true) {if (on) flags |= e; else flags &= ~e; return *this;}
//! Set flag "i" to value "on"
//! \~english Set flag "i" to value "on"
//! \~russian Устанавливает флаг "i" в "on"
PIFlags & setFlag(const int & i, bool on = true) {if (on) flags |= i; else flags &= ~i; return *this;}
//! copy operator
//! \~english Copy operator
//! \~russian Оператор присваивания
void operator =(const Enum & e) {flags = e;}
//! copy operator
//! \~english Copy operator
//! \~russian Оператор присваивания
void operator =(const int & i) {flags = i;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator ==(const PIFlags & f) {return flags == f.flags;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator ==(const Enum & e) {return flags == e;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator ==(const int i) {return flags == i;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator !=(const PIFlags & f) {return flags != f.flags;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator !=(const Enum & e) {return flags != e;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator !=(const int i) {return flags != i;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator >(const PIFlags & f) {return flags > f.flags;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator >(const Enum & e) {return flags > e;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator >(const int i) {return flags > i;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator <(const PIFlags & f) {return flags < f.flags;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator <(const Enum & e) {return flags < e;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator <(const int i) {return flags < i;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator >=(const PIFlags & f) {return flags >= f.flags;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator >=(const Enum & e) {return flags >= e;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator >=(const int i) {return flags >= i;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator <=(const PIFlags & f) {return flags <= f.flags;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator <=(const Enum & e) {return flags <= e;}
//! compare operator
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator <=(const int i) {return flags <= i;}
//! Bit-wise AND operator
//! \~english Bit-wise AND operator
//! \~russian Оператор побитового И
void operator &=(const PIFlags & f) {flags &= f.flags;}
//! Bit-wise AND operator
//! \~english Bit-wise AND operator
//! \~russian Оператор побитового И
void operator &=(const Enum & e) {flags &= e;}
//! Bit-wise AND operator
//! \~english Bit-wise AND operator
//! \~russian Оператор побитового И
void operator &=(const int i) {flags &= i;}
//! Bit-wise OR operator
//! \~english Bit-wise OR operator
//! \~russian Оператор побитового ИЛИ
void operator |=(const PIFlags & f) {flags |= f.flags;}
//! Bit-wise OR operator
//! \~english Bit-wise OR operator
//! \~russian Оператор побитового ИЛИ
void operator |=(const Enum & e) {flags |= e;}
//! Bit-wise OR operator
//! \~english Bit-wise OR operator
//! \~russian Оператор побитового ИЛИ
void operator |=(const int i) {flags |= i;}
//! Bit-wise XOR operator
//! \~english Bit-wise XOR operator
//! \~russian Оператор побитового исключающего ИЛИ
void operator ^=(const PIFlags & f) {flags ^= f.flags;}
//! Bit-wise XOR operator
//! \~english Bit-wise XOR operator
//! \~russian Оператор побитового исключающего ИЛИ
void operator ^=(const Enum & e) {flags ^= e;}
//! Bit-wise XOR operator
//! \~english Bit-wise XOR operator
//! \~russian Оператор побитового исключающего ИЛИ
void operator ^=(const int i) {flags ^= i;}
//! Bit-wise AND operator
//! \~english Bit-wise AND operator
//! \~russian Оператор побитового И
PIFlags operator &(PIFlags f) const {PIFlags tf(flags & f.flags); return tf;}
//! Bit-wise AND operator
//! \~english Bit-wise AND operator
//! \~russian Оператор побитового И
PIFlags operator &(Enum e) const {PIFlags tf(flags & e); return tf;}
//! Bit-wise AND operator
//! \~english Bit-wise AND operator
//! \~russian Оператор побитового И
PIFlags operator &(int i) const {PIFlags tf(flags & i); return tf;}
//! Bit-wise OR operator
//! \~english Bit-wise OR operator
//! \~russian Оператор побитового ИЛИ
PIFlags operator |(PIFlags f) const {PIFlags tf(flags | f.flags); return tf;}
//! Bit-wise OR operator
//! \~english Bit-wise OR operator
//! \~russian Оператор побитового ИЛИ
PIFlags operator |(Enum e) const {PIFlags tf(flags | e); return tf;}
//! Bit-wise OR operator
//! \~english Bit-wise OR operator
//! \~russian Оператор побитового ИЛИ
PIFlags operator |(int i) const {PIFlags tf(flags | i); return tf;}
//! Bit-wise XOR operator
//! \~english Bit-wise XOR operator
//! \~russian Оператор побитового исключающего ИЛИ
PIFlags operator ^(PIFlags f) const {PIFlags tf(flags ^ f.flags); return tf;}
//! Bit-wise XOR operator
//! \~english Bit-wise XOR operator
//! \~russian Оператор побитового исключающего ИЛИ
PIFlags operator ^(Enum e) const {PIFlags tf(flags ^ e); return tf;}
//! Bit-wise XOR operator
//! \~english Bit-wise XOR operator
//! \~russian Оператор побитового исключающего ИЛИ
PIFlags operator ^(int i) const {PIFlags tf(flags ^ i); return tf;}
//! Test flag operator
//! \~english Test flag operator
//! \~russian Оператор проверки флага
bool operator [](Enum e) const {return (flags & e) == e;}
//! Implicity conversion to \c int
//! \~english Implicity conversion to \c int
//! \~russian Оператор неявного преобразования в \c int
operator int() const {return flags;}
private:
int flags;
};
#endif // PIFLAGS_H

View File

@@ -42,6 +42,7 @@ struct lconv;
extern PIP_EXPORT lconv * currentLocale;
//! \ingroup Core
//! \brief
//! \~english
//! Return readable error description in format "code <number> - <description>"
@@ -49,6 +50,7 @@ extern PIP_EXPORT lconv * currentLocale;
//! Возвращает читаемое описание ошибки в формате "code <номер> - <описание>"
PIP_EXPORT PIString errorString();
//! \ingroup Core
//! \brief
//! \~english
//! Reset last error
@@ -61,6 +63,7 @@ PIP_EXPORT void piqsort(void* base, size_t num, size_t size, int (*compar)(const
PIP_EXPORT void randomize();
PIP_EXPORT int randomi();
//! \ingroup Core
//! \brief
//! \~english Return readable version of PIP
//! \~russian Возвращает читаемую версию PIP

View File

@@ -1,5 +1,7 @@
/*! \file piinit.h
* \brief Initialization
* \~\brief
* \~english Library initialization
* \~russian Инициализация библиотеки
*/
/*
PIP - Platform Independent Primitives
@@ -51,19 +53,29 @@ class PIP_EXPORT PIInit {
public:
~PIInit();
//! \brief Build options which PIP library was built
//! \ingroup Core
//! \~english Build options which PIP library was built
//! \~russian Опции, с которыми был собран PIP
enum BuildOption {
boICU /*! Unicode support */ = 0x01,
boUSB /*! USB support */ = 0x02,
boCrypt /*! Crypt support */ = 0x08,
boIntrospection /*! Introspection */ = 0x010,
boFFTW /*! FFTW3 support */ = 0x40,
boCompress /*! Zlib compression support */ = 0x80,
boOpenCL /*! OpenCL support */ = 0x100,
boCloud /*! Cloud transport support */ = 0x200,
boICU /*! \~english Unicode support by ICU \~russian Поддержка юникода через ICU */ = 0x01,
boUSB /*! \~english USB support \~russian Поддержка USB */ = 0x02,
boCrypt /*! \~english Crypt support \~russian Поддержка шифрования */ = 0x08,
boIntrospection /*! \~english Introspection \~russian Интроспекция */ = 0x010,
boFFTW /*! \~english FFTW3 support \~russian Поддержка FFTW3 */ = 0x40,
boCompress /*! \~english Zlib compression support \~russian Поддержка сжатия Zlib */ = 0x80,
boOpenCL /*! \~english OpenCL support \~russian Поддержка OpenCL */ = 0x100,
boCloud /*! \~english PICloud transport support \~russian Поддержка облачного транспорта PICloud */ = 0x200,
};
static PIInit * instance() {return __PIInit_Initializer__::__instance__;}
//! \ingroup Core
//! \~english Returns if build option was enabled
//! \~russian Возвращает была ли включена опция при сборке
static bool isBuildOptionEnabled(BuildOption o);
//! \ingroup Core
//! \~english Returns build options as stringlist
//! \~russian Возвращает опции сборки как список строк
static PIStringList buildOptions();
private:
explicit PIInit();

View File

@@ -25,37 +25,61 @@
# include "pifile.h"
#endif
/** \class PIObject
* \brief This is base class for any classes which use events -> handlers mechanism.
* \details
* \section PIObject_sec0 Events and Event handlers
* %PIObject provide notification mechanism similar Qt but implemented
* on language capabilities without any special preprocessors or compilers.
* Any class inherits PIObject should use macro \a PIOBJECT() immediate
* after declaration to proper compile.
*
* Event is a some abstract event that can be raised at any time.
* Event is a function but declared with special macro \a EVENT().
* To raise event simply execute event function.
*
* Event handler is a function but declared with special macro
* \a EVENT_HANDLER(). You can use event handlers as ordinary functions.
*
* Main goal of this mechanism is perform abstract connections between
* various objects. This functionality provide macro \a CONNECT() which
* connect some event of first object to some event handler or event of
* second object. Each event can be connected any times to any event handlers.
*
* \image html events_handlers.png
*
* Example: \snippet piobject.cpp main
* Result:
\code{.cpp}
handler B: 2 , 0.5
handler A: event to handler
handler A: event to event
\endcode
*/
//! \addtogroup Core
//! \{
//! \~\class PIObject piobject.h
//! \~\brief
//! \~english This is base class for any classes which use events -> handlers mechanism
//! \~russian Этот класс является базовым для использования механизма события -> обработчики
//!
//! \~\details
//! \~english \section PIObject_sec0 Events and Event handlers
//! \~russian \section PIObject_sec0 События и Обработчики событий
//!
//! \~english
//! %PIObject provide notification mechanism similar Qt but implemented
//! on language capabilities without any special preprocessors or compilers.
//! Any class inherits PIObject should use macro \a PIOBJECT() immediate
//! after declaration to proper compile.
//!
//! Event is a some abstract event that can be raised at any time.
//! Event is a function but declared with special macro \a EVENT().
//! To raise event simply execute event function.
//!
//! Event handler is a function but declared with special macro
//! \a EVENT_HANDLER(). You can use event handlers as ordinary functions.
//!
//! Main goal of this mechanism is perform abstract connections between
//! various objects. This functionality provide macro \a CONNECT() which
//! connect some event of first object to some event handler or event of
//! second object. Each event can be connected any times to any event handlers.
//!
//! \~russian
//!
//! \~\image html events_handlers.png
//!
//! \~english Example:
//! \~russian Пример:
//!
//! \~\snippet piobject.cpp main
//! \~english Result:
//! \~russian Результат:
//! \~\code{.cpp}
//! handler B: 2 , 0.5
//! handler A: event to handler
//! handler A: event to event
//! \~\endcode
//! \}
//! \addtogroup Core
//! \{
//! \~\class PIObject::Connection piobject.h
//! \~\brief
//! \~english Helper class for obtain info about if connection successful and disconnect single connection
//! \~russian Вспомогательный класс для получения информации об успешности соединения и возможности его разрыва
//! \}
PIString PIObject::__MetaFunc::arguments() const {
@@ -454,6 +478,14 @@ void PIObject::callQueuedEvents() {
}
//! \details
//! \~english
//! On first call background thread started to delete objects.
//! Each object deletes when it`s outside from any events and hadlers.
//! \~russian
//! При первом вызове стартует фоновый поток для удаления объектов.
//! Каждый объект из очереди удаляется только когда выйдет из всех
//! событий и обработок.
void PIObject::deleteLater() {
Deleter::instance()->post(this);
}

View File

@@ -1,7 +1,7 @@
/*! \file piobject.h
* \brief Base object
*
* This file declare PIObject class
* \~\brief
* \~english Base object
* \~russian Базовый класс
*/
/*
PIP - Platform Independent Primitives
@@ -47,12 +47,12 @@ class PIP_EXPORT PIObject {
public:
NO_COPY_CLASS(PIObject)
//! Contructs PIObject with name "name"
//! \~english Contructs %PIObject with name "name"
//! \~russian Создает %PIObject с именем "name"
explicit PIObject(const PIString & name = PIString());
virtual ~PIObject();
//! Helper class for obtain info about if connection successful and disconnect single connection
class PIP_EXPORT Connection {
friend class PIObject;
Connection(void * sl, void * si, const PIString & e = PIString(),
@@ -81,22 +81,28 @@ public:
int args_count;
public:
//! Contructs invalid %Connection
//! \~english Contructs invalid %Connection
//! \~russian Создает недействительный %Connection
Connection();
//! Returns if %Connection is valid
//! \~english Returns if %Connection is valid
//! \~russian Возвращает успешен ли %Connection
bool isValid() const {return signal;}
//! Returns source object
//! \~english Returns source object
//! \~russian Возвращает объект-источник
PIObject * sourceObject() const {return src_o;}
//! Returns destination object or nullptr if this is lambda connection
//! \~english Returns destination object or "nullptr" if this is lambda connection
//! \~russian Возвращает объект-приемник или "nullptr" если это соединение на лямбда-функцию
PIObject * destinationObject() const {return dest_o;}
//! Returns performer object or nullptr if this is non-queued connection
//! \~english Returns performer object or "nullptr" if this is non-queued connection
//! \~russian Возвращает объект-приемник или "nullptr" если это соединение не отложенное
PIObject * performerObject() const {return performer;}
//! Disconnect this %Connection, returns if operation successful
//! \~english Disconnect this %Connection, returns if operation successful
//! \~russian Разрывает этот %Connection, возвращает успешен ли разрыв
bool disconnect();
};
@@ -105,10 +111,12 @@ private:
public:
//! Returns object name
//! \~english Returns object name
//! \~russian Возвращает имя объекта
PIString name() const {return property(PIStringAscii("name")).toString();}
//! Returns object class name
//! \~english Returns object class name
//! \~russian Возвращает имя класса объекта
virtual const char * className() const {return "PIObject";}
virtual uint classNameID() const {static uint ret = PIStringAscii("PIObject").hash(); return ret;}
@@ -116,36 +124,45 @@ public:
static const PIString __classNameS() {return PIStringAscii("PIObject");}
static uint __classNameIDS() {static uint ret = PIStringAscii("PIObject").hash(); return ret;}
//! Returns parent object class name
//! \~english Returns parent class name
//! \~russian Возвращает имя родительского класса
virtual const char * parentClassName() const {return "";}
//! Return if debug of this object is active
//! \~english Return if debug of this object is active
//! \~russian Возвращает включен ли вывод на консоль для этого объекта
bool debug() const {return property(PIStringAscii("debug")).toBool();}
//! Set object name
//! \~english Set object name
//! \~russian Устанавливает имя объекта
void setName(const PIString & name) {setProperty(PIStringAscii("name"), name);}
void setName(const char * name) {setName(PIStringAscii(name));}
//! Set object debug active
//! \~english Set object debug active
//! \~russian Включает или отключает вывод на консоль для этого объекта
void setDebug(bool debug) {setProperty(PIStringAscii("debug"), debug);}
//! Returns properties of the object
//! \~english Returns properties of the object
//! \~russian Возвращает словарь свойств объекта
PIMap<PIString, PIVariant> properties() const;
//! Returns properties count of the object
//! \~english Returns properties count of the object
//! \~russian Возвращает количество свойств объекта
int propertiesCount() const {return properties_.size_s();}
//! Returns property with name "name"
//! \~english Returns property with name "name"
//! \~russian Возвращает свойство объекта по имени "name"
PIVariant property(const PIString & name) const {return properties_.value(name.hash(), Property(PIString(), PIVariant())).second;}
PIVariant property(const char * name) const {return property(PIStringAscii(name));}
//! Set property with name "name" to "value". If there is no such property in object it will be added
//! \~english Set property with name "name" to "value". If there is no such property in object it will be added
//! \~russian Устанавливает у объекта свойство по имени "name" в "value". Если такого свойства нет, оно добавляется
void setProperty(const PIString & name, const PIVariant & value) {properties_[name.hash()] = Property(name, value); propertyChanged(name);}
void setProperty(const char * name, const PIVariant & value) {setProperty(PIStringAscii(name), value);}
//! Returns if property with name "name" exists
//! \~english Returns if property with name "name" exists
//! \~russian Возвращает присутствует ли свойство по имени "name"
bool isPropertyExists(const PIString & name) const {return properties_.contains(name.hash());}
bool isPropertyExists(const char * name) const {return isPropertyExists(PIStringAscii(name));}
@@ -183,7 +200,10 @@ public:
void dump(const PIString & line_prefix = PIString()) const;
//! \~english Returns subclass scope of this object (including this class name)
//! \~russian Возвращает цепочку наследования объекта (вместе с классом самого объекта)
PIStringList scopeList() const;
PIStringList methodsEH() const;
bool isMethodEHContains(const PIString & name) const;
PIString methodEHArguments(const PIString & name) const;
@@ -200,23 +220,29 @@ public:
}
//! Disconnect object from all connections with event name "sig", connected to destination object "dest" and handler "ev_h"
//! \~english Disconnect object from all connections with event name "sig", connected to destination object "dest" and handler "ev_h"
//! \~russian Разрывает все соединения от события "sig" к объекту "dest" и обработчику "ev_h"
void piDisconnect(const PIString & sig, PIObject * dest, void * ev_h) {piDisconnect(this, sig, dest, ev_h);}
//! Disconnect object from all connections with event name "sig", connected to destination object "dest"
//! \~english Disconnect object from all connections with event name "sig", connected to destination object "dest"
//! \~russian Разрывает все соединения от события "sig" к объекту "dest"
void piDisconnect(const PIString & sig, PIObject * dest) {piDisconnect(this, sig, dest);}
//! Disconnect object from all connections with event name "sig"
//! \~english Disconnect object from all connections with event name "sig"
//! \~russian Разрывает все соединения от события "sig"
void piDisconnect(const PIString & sig) {piDisconnect(this, sig);}
//! Disconnect object "src" from all connections with event name "sig", connected to destination object "dest" and handler "ev_h"
//! \~english Disconnect object "src" from all connections with event name "sig", connected to destination object "dest" and handler "ev_h"
//! \~russian Разрывает все соединения от события "sig" объекта "src" к объекту "dest" и обработчику "ev_h"
static void piDisconnect(PIObject * src, const PIString & sig, PIObject * dest, void * ev_h);
//! Disconnect object "src" from all connections with event name "sig", connected to destination object "dest"
//! \~english Disconnect object "src" from all connections with event name "sig", connected to destination object "dest"
//! \~russian Разрывает все соединения от события "sig" объекта "src" к объекту "dest"
static void piDisconnect(PIObject * src, const PIString & sig, PIObject * dest);
//! Disconnect object "src" from all connections with event name "sig"
//! \~english Disconnect object "src" from all connections with event name "sig"
//! \~russian Разрывает все соединения от события "sig" объекта "src"
static void piDisconnect(PIObject * src, const PIString & sig);
// / Raise events
@@ -398,23 +424,36 @@ public:
if (i->name() != name) continue;
return i;
}
return 0;
return nullptr;
}
//! \~english Returns if this is valid %PIObject (check signature)
//! \~russian Возвращает действительный ли это %PIObject (проверяет подпись)
bool isPIObject() const {return isPIObject(this);}
//! \~english Returns if this is valid %PIObject subclass "T" (check signature and classname)
//! \~russian Возвращает действительный ли это наследник %PIObject типа "T" (проверяет подпись и имя класса)
template<typename T>
bool isTypeOf() const {
if (!isPIObject()) return false;
return scopeList().contains(T::__classNameS());
}
//! \~english Returns cast to T if this is valid subclass "T" (check by \a isTypeOf()) or "nullptr"
//! \~russian Возвращает преобразование к типу T если это действительный наследник типа "T" (проверяет через \a isTypeOf()), или "nullptr"
template<typename T>
T * cast() const {
if (!isTypeOf<T>()) return (T*)0;
if (!isTypeOf<T>()) return (T*)nullptr;
return (T*)this;
}
//! \~english Returns if "o" is valid %PIObject (check signature)
//! \~russian Возвращает действительный ли "o" %PIObject (проверяет подпись)
static bool isPIObject(const PIObject * o);
static bool isPIObject(const void * o) {return isPIObject((PIObject*)o);}
//! \~english Returns if "o" is valid %PIObject subclass "T" (check signature and classname)
//! \~russian Возвращает действительный ли "o" наследник %PIObject типа "T" (проверяет подпись и имя класса)
template<typename T>
static bool isTypeOf(const PIObject * o) {return o->isTypeOf<T>();}
template<typename T>
@@ -445,17 +484,22 @@ public:
};
typedef PIPair<const void * , __MetaFunc> __EHPair;
//! \brief Execute all posted events from CONNECTU_QUEUED connections
//! \~english Execute all posted events from CONNECTU_QUEUED connections
//! \~russian Выполнить все отложенные события от CONNECTU_QUEUED соединений
void callQueuedEvents();
//! \~english
//! \brief Check if any CONNECTU_QUEUED connections to this object and execute them
//! \details This function is more optimized than \a callQueuedEvents() for objects that doesn`t
//! appears as \"performer\" target at CONNECTU_QUEUED
//! \~russian
//! \brief Если было хотя бы одно CONNECTU_QUEUED соединение с исполнителем this, то выполнить события
//! \details Этот метод более оптимален, чем \a callQueuedEvents(), для объектов, которые не были в роли
//! \"performer\" в макросе CONNECTU_QUEUED
bool maybeCallQueuedEvents() {if (proc_event_queue) callQueuedEvents(); return proc_event_queue;}
//! \brief Mark object to delete
//! \details On first call background thread started to delete objects.
//! Each object deletes when it`s outside from any events and hadlers.
//! \~english Mark object to delete
//! \~russian Пометить объект на удаление
void deleteLater();
static PIMutex & __meta_mutex();
@@ -463,10 +507,12 @@ public:
protected:
//! Returns PIObject* which has raised an event. This value is correct only in definition of some event handler
//! \~english Returns %PIObject* which has raised an event. This value is correct only in definition of some event handler
//! \~russian Возвращает %PIObject* который вызвал это событие. Значение допустимо только из методов обработчиков событий
PIObject * emitter() const {return emitter_;}
//! Virtual function executes after property with name "name" has been changed
//! \~english Virtual function executes after property with name "name" has been changed
//! \~russian Виртуальная функция, вызывается после изменения любого свойства.
virtual void propertyChanged(const PIString & name) {}
EVENT1(deleted, PIObject *, o)
@@ -474,10 +520,17 @@ protected:
//! \events
//! \{
/** \fn void deleted(PIObject * o)
* \brief Raise before object delete
* \note This event raised from destructor, so use only "o" value,
* don`t try to cast deleted object to some subclass! */
//! \fn void deleted(PIObject * o)
//! \brief
//! \~english Raise before object delete
//! \~russian Вызывается перед удалением объекта
//! \~\warning
//! \~english
//! This event raised from destructor, so use only "o" numeric value,
//! don`t try to cast deleted object to some subclass!
//! \~russian
//! Это событие вызывается из деструктора, поэтому используйте
//! только численное значение "o", не надо кастовать его в другие типы!
//! \}