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,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
PIMap<PIString, PIVariant> properties() const;
//! \~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", не надо кастовать его в другие типы!
//! \}