//////////////////////////////////////////////////////////////////////////////// /** \file \brief \ru Пользовательские атрибуты. \en User attributes. \~ */ //////////////////////////////////////////////////////////////////////////////// #ifndef __ATTR_USER_ATTRIBUT_H #define __ATTR_USER_ATTRIBUT_H #include #include #include #include #include #include #include class MATH_CLASS MbExternalAttribute; class MATH_CLASS MbUserAttribute; class MATH_CLASS MbFixAttrSet; //------------------------------------------------------------------------------ /** \brief \ru Интерфейс определения атрибута. \en Attribute definition interface. \~ \details \ru Интерфейс определения атрибута. Определение атрибута - объект используемый для преобразования пользовательских внесистемных атрибутов в пользовательские системные, а так же для разборки пользовательских системных атрибутов на составные части - другие атрибуты системные атрибуты, и обратной сборки. \en Attribute definition interface. Attribute definition - the object used for converting user external attributes to user system attributes and for a disassembly of user system attributes to their components - other system attributes, and for reassembly. \~ \ingroup Model_Attributes */ class IAttrDefinition { public: /// \ru Преобразовать из пользовательского в "системный". \en Convert user attribute to "system" one. virtual MbUserAttribute * ReduceUserAttrib ( const MbExternalAttribute & source ) = 0; /// \ru Преобразовать из "системного" в пользовательский. \en Convert "system" attribute to user one. virtual MbExternalAttribute * AdvanceUserAttrib( const MbUserAttribute & source ) = 0; /// \ru "Разобрать" на составляющие атрибуты. \en Disassemble on attributes. virtual MbFixAttrSet * DisassembleUserAttrib( const MbExternalAttribute & source ) = 0; /// \ru "Собрать" из составляющих атрибутов. \en Reassemble from attributes. virtual bool ReassembleUserAttrib ( const MbFixAttrSet & source, MbExternalAttribute & target ) = 0; }; //------------------------------------------------------------------------------ /** \brief \ru Шаблон "определения" пользовательского атрибута. \en A template of user attribute definition. \~ \details \ru Шаблонный класс "Определения" пользовательского атрибута - используется для создания стандартных определений, с предопределенным функционалом. \en Template class "Definition" of user attribute - used for creation of standard definitions with predefined functionality. \~ \ingroup Model_Attributes */ template class UserAttrDefinition : public IAttrDefinition { public: /// \ru Преобразовать из пользовательского в "системный". \en Convert user attribute to "system" one. virtual MbUserAttribute * ReduceUserAttrib ( const MbExternalAttribute & source ); /// \ru Преобразовать из "системного" в пользовательский. \en Convert "system" attribute to user one. virtual MbExternalAttribute * AdvanceUserAttrib( const MbUserAttribute & source ); /// \ru "Разобрать" на составляющие атрибуты. \en Disassemble on attributes. virtual MbFixAttrSet * DisassembleUserAttrib( const MbExternalAttribute & source ); /// \ru "Собрать" из составляющих атрибутов. \en Reassemble from attributes. virtual bool ReassembleUserAttrib( const MbFixAttrSet & source, MbExternalAttribute & target ); }; //------------------------------------------------------------------------------ /** \brief \ru Пользовательский системный атрибут. \en User system attribute. \~ \details \ru Пользовательский системный атрибут. \n \en User system attribute. \n \~ \ingroup Model_Attributes */ class MATH_CLASS MbUserAttribute : public MbAttribute, public MbSyncItem { typedef std::unique_ptr UniqueMembufPtr; protected : MbUserAttribType userType_; ///< \ru Тип пользовательского атрибута. \en Type of user attribute. c3d::string_t prompt_; ///< \ru Строка описания. \en String of description. private: SPtr extAttr; mutable UniqueMembufPtr userBuf; private: // public: // You must inherit from MbExternalAttribute only!!! /// \ru Конструктор. \en Constructor. MbUserAttribute( const TCHAR *, const MbUserAttribType & ); public: MbeAttributeType AttributeFamily() const override; // \ru Дать тип атрибута. \en Get type of an attribute. MbeAttributeType AttributeType() const override; // \ru Выдать подтип атрибута. \en Get subtype of an attribute. /// \ru Выдать подтип пользовательского атрибута по пользовательскому типу. \en Get subtype of an user attribute by user-defined type. static MbeAttributeType AttributeType( const MbUserAttribType & userType ); MbAttribute & Duplicate( MbRegDuplicate * = nullptr ) const override; // \ru Сделать копию элемента. \en Create a copy of the element. bool IsSame( const MbAttribute &, double accuracy ) const override; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. bool Init( const MbAttribute & ) override; // \ru Инициализировать данные по присланным. \en Initialize data by given attribute. // \ru Выполнить действия при изменении владельца не связанное с другими действиями \en Perform actions which are not associated with other actions when changing the owner void OnChangeOwner( const MbAttributeContainer & owner ) override; // \ru Выполнить действия при конвертации владельца \en Perform actions when converting the owner void OnConvertOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ) override; // \ru Выполнить действия при трансформировании владельца \en Perform actions when transforming the owner void OnTransformOwner( const MbAttributeContainer & owner, const MbMatrix3D &, MbRegTransform * = nullptr ) override; // \ru Выполнить действия при перемещении владельца. \en Perform actions when moving the owner. void OnMoveOwner( const MbAttributeContainer & owner, const MbVector3D &, MbRegTransform * = nullptr ) override; // \ru Выполнить действия при вращении владельца. \en Perform actions when rotating the owner. void OnRotateOwner( const MbAttributeContainer & owner, const MbAxis3D &, double angle, MbRegTransform * = nullptr ) override; // \ru Выполнить действия при копировании владельца \en Perform actions when copying the owner. void OnCopyOwner( const MbAttributeContainer & owner, MbAttributeContainer & other, MbRegDuplicate * = nullptr ) override; // \ru Выполнить действия при объединении владельца \en Perform actions when merging the owner. void OnMergeOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ) override; // \ru Выполнить действия при замене владельца. \en Perform actions when replacing the owner. void OnReplaceOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ) override; // \ru Выполнить действия при разделении владельца. \en Perform actions when splitting the owner. void OnSplitOwner( const MbAttributeContainer & owner, const std::vector & others ) override; // \ru Выполнить действия при удалении владельца. \en Perform actions when deleting the owner. void OnDeleteOwner( const MbAttributeContainer & owner ) override; /// \ru Выдать подсказку. \en Get a hint. const TCHAR * GetPrompt() const; /// \ru Выдать идентификатор хранимого атрибута. \en Get identifier of stored attribute. void GetUserAttribId( MbUserAttribType & attrId ) const; /// \ru Установить пользовательские данные. \en Set user data. void SetUserData( const char * extAttrMemory ); /// \ru Установить пользовательские данные. \en Set user data. void SetUserData( const std::vector & extAttrData ); /// \ru Получить пользовательские данные. \en Get user data. bool GetUserData( membuf & ) const; /// \ru Создать пользовательский внесистемный атрибут по пользовательским данным. \en Make a user external attribute using user data. bool MakeExternalAttribute( bool keepExisting ); /// \ru Обновить пользовательские данные по внесистемному атрибуту пользователя. \en Update user data using the user external attribute. bool UpdateByExternalAttribute() const; /// \ru Выдать пользовательский внесистемный атрибут. \en Get a user external attribute. const MbExternalAttribute * GetExternalAttribute() const { return extAttr; } /// \ru Установить пользовательский внесистемный атрибут. \en Set a user external attribute. bool SetExternalAttribute( MbExternalAttribute * ); /// \ru Установить пользовательский внесистемный атрибут (его копию). \en Set a user external attribute (copy). void SetExternalAttribute( const MbExternalAttribute & ); void GetProperties( MbProperties & ) override; // \ru Выдать свойства объекта. \en Get properties of the object. size_t SetProperties( const MbProperties & ) override; // \ru Установить свойства объекта. \en Set properties of the object. MbePrompt GetPropertyName() override; // \ru Выдать заголовок свойства объекта. \en Get a name of object property. //warning: dependent nested name specifier 'UserAttrDefinition::' for friend class declaration is not supported; turning off access control for 'MbUserAttribute' //template //friend MbUserAttribute * UserAttrDefinition::ReduceUserAttrib( const MbExternalAttribute & ); template friend class UserAttrDefinition; protected: virtual ~MbUserAttribute(); // Use AddRef/Release or smart pointer SPtr to destruct it correctly. DECLARE_PERSISTENT_CLASS_NEW_DEL_BASE( MbUserAttribute, MATH_FUNC_EX ) OBVIOUS_PRIVATE_COPY( MbUserAttribute ) }; IMPL_PERSISTENT_OPS( MbUserAttribute ) //------------------------------------------------------------------------------ /** \brief \ru Пользовательский внесистемный атрибут - базовый класс. \en User external attribute - the base class. \~ \details \ru Пользовательский внесистемный атрибут - базовый класс. \n \en User external attribute - the base class. \n \~ \ingroup Model_Attributes */ class MATH_CLASS MbExternalAttribute : public MbAttribute { public : /// \ru Конструктор. \en Constructor. MbExternalAttribute(); /// \ru Деструктор. \en Destructor. virtual ~MbExternalAttribute(); MbeAttributeType AttributeFamily() const override; // \ru Дать тип атрибута. \en Get type of an attribute. MbeAttributeType AttributeType() const override; // \ru Выдать подтип атрибута. \en Get subtype of an attribute. /// \ru Выдать подтип атрибута. \en Get subtype of an attribute. virtual MbUserAttribType AttrTypeEx() const = 0; virtual MbAttribute & Duplicate( MbRegDuplicate * = nullptr ) const override = 0; // \ru Сделать копию элемента. \en Create a copy of the element. virtual bool IsSame( const MbAttribute &, double accuracy ) const override = 0; // \ru Определить, являются ли объекты равными. \en Determine whether objects are equal. virtual bool Init( const MbAttribute & ) override = 0; // \ru Инициализировать данные по присланным. \en Initialize data. // \ru Выполнить действия при изменении владельца, не связанное с другими действиями. \en Perform actions which are not associated with other actions when changing the owner. virtual void OnChangeOwner( const MbAttributeContainer & owner ) override; // \ru Выполнить действия при конвертации владельца. \en Perform actions when converting the owner. virtual void OnConvertOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ) override; // \ru Выполнить действия при трансформировании владельца. \en Perform actions when transforming the owner. virtual void OnTransformOwner( const MbAttributeContainer & owner, const MbMatrix3D &, MbRegTransform * = nullptr ) override; // \ru Выполнить действия при перемещении владельца. \en Perform actions when moving the owner. virtual void OnMoveOwner( const MbAttributeContainer & owner, const MbVector3D &, MbRegTransform * = nullptr ) override; // \ru Выполнить действия при вращении владельца. \en Perform actions when rotating the owner. virtual void OnRotateOwner( const MbAttributeContainer & owner, const MbAxis3D &, double angle, MbRegTransform * = nullptr ) override; // \ru Выполнить действия при копировании владельца. \en Perform actions when copying the owner. virtual void OnCopyOwner( const MbAttributeContainer & owner, MbAttributeContainer & other, MbRegDuplicate * = nullptr ) override; // \ru Выполнить действия при объединении владельца. \en Perform actions when merging the owner. virtual void OnMergeOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ) override; // \ru Выполнить действия при замене владельца. \en Perform actions when replacing the owner. virtual void OnReplaceOwner( const MbAttributeContainer & owner, MbAttributeContainer & other ) override; // \ru Выполнить действия при разделении владельца. \en Perform actions when splitting the owner. virtual void OnSplitOwner( const MbAttributeContainer & owner, const std::vector & others ) override; // \ru Выполнить действия при удалении владельца. \en Perform actions when deleting the owner. virtual void OnDeleteOwner( const MbAttributeContainer & owner ) override; virtual void GetProperties( MbProperties & ) override; // \ru Выдать свойства объекта. \en Get properties of the object. virtual size_t SetProperties( const MbProperties & ) override; // \ru Установить свойства объекта. \en Set properties of the object. MbePrompt GetPropertyName() override; // \ru Выдать заголовок свойства объекта. \en Get a name of object property. OBVIOUS_PRIVATE_COPY( MbExternalAttribute ) }; //------------------------------------------------------------------------------ /** \brief \ru Фиксированный набор атрибутов \en Fixed set of attributes. \~ \details \ru Набор атрибутов, состав которого нельзя изменить, но никто не запрещает менять значение самих атрибутов. \en A set of attributes the structure of which cannot be changed, but it is possible to change values of the attributes. \~ \ingroup Model_Attributes */ class MATH_CLASS MbFixAttrSet { private: MbUserAttribType userAttrId; ///< \ru Идентификатор соответствующего пользовательского атрибута. \en Identifier of the corresponding external attribute. c3d::AttrVector attributes; ///< \ru Атрибуты. \en Attributes. private: /// \ru Конструктор. \en Constructor. MbFixAttrSet( c3d::AttrVector & ); public: /// \ru Деструктор. \en Destructor. ~MbFixAttrSet() { std::for_each( attributes.begin(), attributes.end(), ReleaseItem ); } public: /// \ru Выдать идентификатор атрибута. \en Get attribute identifier. const MbUserAttribType & GetUserAttrId() const { return userAttrId; } /// \ru Выдать атрибуты. \en Get attributes. const MbAttribute * GetAttribute( size_t k ) const { return ((k < attributes.size()) ? attributes[k] : nullptr); } // \ru Выдать количество атрибутов. \en Get the number of attributes. size_t AttributesCount() const { return attributes.size(); } friend class MbExternalAttribute; OBVIOUS_PRIVATE_COPY( MbFixAttrSet ) }; //------------------------------------------------------------------------------ /** \brief \ru Шаблон явления "Определения" пользовательского атрибута. \en A template of "Definition" phenomenon of user attribute. \~ \ingroup Model_Attributes */ template class UserAttrDefinitionInstance : public AttrDefInstance, public MbSyncItem { private: AttrDefClass * attrDef; ///< \ru "Определение" пользовательского атрибута. \en "Definition" of user attribute. public: /// \ru Конструктор. \en Constructor. UserAttrDefinitionInstance( const MbUserAttribType & ); /// \ru Деструктор. \en Destructor. virtual ~UserAttrDefinitionInstance(); public: // \ru Дать "определение" пользовательского атрибута. \en Get a "definition" of user attribute. virtual IAttrDefinition * GetAttrDefinition(); }; //------------------------------------------------------------------------------ /// \ru Преобразовать из пользовательского в "системный". \en Convert user attribute to "system" one. // --- template MbUserAttribute * UserAttrDefinition::ReduceUserAttrib( const MbExternalAttribute & source ) { MbUserAttribType attrId( source.AttrTypeEx() ); MbUserAttribute * resAttr = new MbUserAttribute( _T("AttrClass"), attrId ); resAttr->InitActions( source ); { const char * charBuf = nullptr; size_t memLen = 0; { membuf memBuf; { const AttrClass * attrPtr = static_cast(&source); writer::writer_ptr out = writer::CreateMemWriter( memBuf, io::out ); if ( out->good() ) *out << attrPtr; } memBuf.closeBuff(); // before memBuf.getMemLen!!! memLen = memBuf.getMemLen(); charBuf = new char[memLen]; memBuf.toMemory( charBuf, memLen ); } resAttr->SetUserData( charBuf ); delete [] charBuf; } return resAttr; } //------------------------------------------------------------------------------ /// \ru Преобразовать из "системного" в пользовательский. \en Convert "system" attribute to user one. // --- template MbExternalAttribute * UserAttrDefinition::AdvanceUserAttrib( const MbUserAttribute & source ) { AttrClass * resAttr = nullptr; MbUserAttribType attrId; source.GetUserAttribId( attrId ); { membuf memBuf; { bool canRead = true; if ( !source.GetUserData( memBuf ) ) { canRead = false; if ( source.UpdateByExternalAttribute() ) { canRead = source.GetUserData( memBuf ); } } if ( canRead ) { reader::reader_ptr in = reader::CreateMemReader( memBuf, io::in ); if ( in->good() ) *in >> resAttr; } } memBuf.closeBuff(); } return resAttr; } //------------------------------------------------------------------------------ /// \ru "Разобрать" на составляющие атрибуты. \en Disassemble on attributes. // --- template MbFixAttrSet * UserAttrDefinition::DisassembleUserAttrib( const MbExternalAttribute & /*source*/ ) { return nullptr; } //------------------------------------------------------------------------------ /// \ru "Собрать" из составляющих атрибутов. \en Reassemble from attributes. // --- template bool UserAttrDefinition::ReassembleUserAttrib( const MbFixAttrSet & /*source*/, MbExternalAttribute & /*target*/ ) { return false; } //------------------------------------------------------------------------------ // \ru Конструктор. \en Constructor. // --- template UserAttrDefinitionInstance::UserAttrDefinitionInstance( const MbUserAttribType & type ) : AttrDefInstance( type ) , attrDef( nullptr ) { } //------------------------------------------------------------------------------ // \ru Деструктор. \en Destructor. // --- template UserAttrDefinitionInstance::~UserAttrDefinitionInstance() { if ( attrDef != nullptr ) delete attrDef; } //------------------------------------------------------------------------------ // \ru Дать "определение" пользовательского атрибута. \en Get a "definition" of user attribute. // --- template IAttrDefinition * UserAttrDefinitionInstance::GetAttrDefinition() { if ( attrDef == nullptr ) { ScopedLock ll( GetLock() ); attrDef = new AttrDefClass(); } return attrDef; } #endif // __ATTR_USER_ATTRIBUT_H