123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- //
- //////////////////////////////////////////////////////////////////////////////
- //
- // Copyright 2015 Autodesk, Inc. All rights reserved.
- //
- // Use of this software is subject to the terms of the Autodesk license
- // agreement provided at the time of installation or download, or which
- // otherwise accompanies this software in either electronic or hard copy form.
- //
- //////////////////////////////////////////////////////////////////////////////
- //
- // AXOBJREF.H
- //
- // Object reference proxy and smart pointer template classes
- //
- #ifndef __AXOBJREF_H_
- #define __AXOBJREF_H_
- #include "dbobjptr.h"
- #pragma pack (push, 8)
- #pragma warning (disable : 4786)
- //
- // ---- AcAxObjectRef Class ----
- //
- // This class provides an abstract packaging of a reference to an AcDbObject,
- // that is represented either as an AcDbObjectId or as an AcDbObject pointer.
- // This packaging allows other classes to encapsulate an AcAxObjectRef instance
- // instead of separate AcDbObjectId and pointer references, and to pass the
- // reference around as a parameter without advance knowledge of the actual
- // reference type.
- //
- // The following special behaviors apply to this implementation:
- //
- // 1. The AcAxObjectRef owns any pointers that it may encapsulate. Callers
- // should not cache any object pointers managed by an AcAxObjectRef. The
- // AcAxObjectRef destructor deletes objects it has pointers for if they
- // are not database resident.
- //
- // 2. The AcAxObjectRef does not manage the lifetime (i.e. does not own)
- // any AcDbObjectIds that it may encapsulate. The lifetime of the objects
- // referenced by AcDbObjectIds is not bound by the lifetime of the
- // AcAxObjectRef.
- //
- // 3. The AcAxObjectRef only encapsulates an AcDbObject pointer or an
- // AcDbObjectId at any given time. Placing an AcDbObjectId into an
- // AcAxObjectRef which already encapsulates an AcDbObject pointer causes
- // the object to be deleted if it is not database resident.
- //
- // 3. Copy and assignment operations are prohibited, they would violate
- // the "ownership" aspect of the class. Derived classes should override
- // copy and constructor members and declare them private.
- //
- // 4. Callers use the acquire() and release() methods to manage the
- // objects encapsulated by an AcAxObjectRef. There are no accessor methods
- // the encapsulated references. Callers must use the release() method to
- // obtain references to the encapsulated pointer or objectId, which
- // "detaches" the AcAxObjectRef from the references.
- class AcAxObjectRef
- {
- public:
- AcAxObjectRef();
- AcAxObjectRef(AcDbObjectId objId);
- AcAxObjectRef(AcDbObject *& pObj);
- ~AcAxObjectRef();
-
- Acad::ErrorStatus acquire(AcDbObjectId objId);
- Acad::ErrorStatus acquire(AcDbObject *& pObj);
- Acad::ErrorStatus release(AcDbObjectId& objId, AcDbObject *& pObj);
-
- bool isNull();
- AcDbObjectId objectId();
- private:
- // Disallow copy constructor and assignment
- AcAxObjectRef(AcAxObjectRef & ref);
- AcAxObjectRef& operator=(AcAxObjectRef & ref);
- void internalRelease();
- // Object references
- AcDbObjectId m_objId;
- AcDbObject * m_pObj;
- };
- inline
- AcAxObjectRef::AcAxObjectRef()
- : m_objId(NULL),
- m_pObj(NULL)
- {
- }
- inline
- AcAxObjectRef::AcAxObjectRef(AcDbObjectId objId)
- : m_objId(NULL),
- m_pObj(NULL)
- {
- acquire(objId);
- }
- inline
- AcAxObjectRef::AcAxObjectRef(AcDbObject *& pObj)
- : m_objId(NULL),
- m_pObj(NULL)
- {
- acquire(pObj);
- }
- inline
- AcAxObjectRef::~AcAxObjectRef()
- {
- internalRelease();
- }
-
- inline Acad::ErrorStatus
- AcAxObjectRef::acquire(AcDbObjectId objId)
- {
- if (objId.isNull())
- return Acad::eNullObjectId;// VC8:Removed extra qualifier
-
- internalRelease();
-
- m_objId = objId;
- return Acad::eOk;// VC8:Removed extra qualifier
- }
- inline Acad::ErrorStatus
- AcAxObjectRef::acquire(AcDbObject *& pObj)
- {
- if (NULL == pObj)
- return Acad::eNullObjectPointer;
- if (!pObj->objectId().isNull())
- return acquire(pObj->objectId());
-
- internalRelease();
- m_pObj = pObj;
- pObj = NULL;
-
- return Acad::eOk;
- }
-
- inline Acad::ErrorStatus
- AcAxObjectRef::release(AcDbObjectId& objId, AcDbObject *& pObj)
- {
- if (isNull())
- return Acad::eNullObjectPointer;
- pObj = m_pObj;
- objId = m_objId;
- m_pObj = NULL;
- m_objId.setNull();
-
- return Acad::eOk;
- }
- inline void
- AcAxObjectRef::internalRelease()
- {
- if (NULL != m_pObj)
- {
- if (m_pObj->objectId().isNull())
- delete m_pObj;
-
- else
- {
- // Somebody forgot to get back the pointer to close
- // the object
- //_ASSERTE(NULL == m_pObj && m_pObj->objectId().isNull());
- }
- m_pObj = NULL;
- }
- m_objId.setNull();
- }
- inline bool
- AcAxObjectRef::isNull()
- {
- return (NULL == m_pObj && m_objId.isNull());
- }
- inline AcDbObjectId
- AcAxObjectRef::objectId()
- {
- return m_objId;
- }
-
- // ---- Class AcAxObjectRefPtr ----
- //
- // This class provides "smart pointer" behavior for AcAxObjectRef instances,
- // similar to the behavior provided by the AcDbObjectPointer template class for
- // AcDbObjectIds. Unlike the AcDbObjectPointer class handling of non-database
- // resident objects, the lifetime of the referenced object is not bound to the
- // lifetime of the AcAxObjectRefPtr, only the open/closed state is managed by
- // the AcAxObjectRefPtr class.
- //
- // The following special behaviors apply to this implementation:
- //
- // 1. The object references used by the AcAxObjectRefPtr class are "owned"
- // by the AcAxObjectRefPtr instance for the duration of its lifetime. When
- // constructed the AcAxObjectRefPtr releases the AcAxObjectRef of it's
- // object references. As it is destroyed the AcAxObjectRefPtr returns the
- // ownership of these references to the AcAxObjectRef.
- //
- // 2. The objects managed by an AcAxObjectRefPtr are maintained in an
- // "open" state for as long as the objects are managed by the pointer
- // class. Open object references are "closed" when the AcAxObjectRefPtr
- // object is destroyed.
- //
- // 3. All of the caveats and usage notes mentioned for
- // AcDbObjectPointerBase in dbobjptr.h apply to this class as well.
- //
- template<class T_OBJECT>
- class AcAxObjectRefPtr : public AcDbObjectPointer<T_OBJECT>
- {
- public:
- AcAxObjectRefPtr();
- AcAxObjectRefPtr(AcAxObjectRef* const pRef,
- AcDb::OpenMode mode,
- bool openErased = false);
- ~AcAxObjectRefPtr();
- private:
- // Disallow copy constructor, assignment operator
- AcAxObjectRefPtr(AcAxObjectRefPtr & pObj);
- AcAxObjectRefPtr& operator=(AcAxObjectRefPtr & pObj);
- AcAxObjectRef* const m_pRef;
- };
- template<class T_OBJECT> inline
- AcAxObjectRefPtr<T_OBJECT>::AcAxObjectRefPtr()
- : AcDbObjectPointer<T_OBJECT>(),
- m_pRef(NULL)
- {}
- template<class T_OBJECT> inline
- AcAxObjectRefPtr<T_OBJECT>::AcAxObjectRefPtr(AcAxObjectRef* const pRef, AcDb::OpenMode mode, bool openErased)
- : m_pRef(pRef)
- {
- //_ASSERTE(NULL != pRef);
- if (NULL == pRef)
- {
- this->m_status = Acad::eNullObjectPointer;// VC8:Removed extra qualifier
- return;
- }
- // Acquire the reference as either an objectId or pointer
- AcDbObjectId objId = pRef->objectId();
-
- // If it is a non-null objectId just open it
- if (!objId.isNull())
- this->m_status = acdbOpenObject(this->m_ptr, objId, mode, openErased);
- // If it is a null objectId we will need to acquire the
- // pointer from the AcAxObjectRef
- else
- {
- AcDbObject* pTmp = NULL;
- m_pRef->release(objId, pTmp);
- // Check for downcast of AcDbObject pointer to T_OBJECT
- // Restore object reference if this cast fails
- T_OBJECT* pTyped= T_OBJECT::cast(pTmp);
- if (NULL == pTyped) {
- this->m_ptr = NULL;
- m_pRef->acquire(pTmp);
- this->m_status = Acad::eNotThatKindOfClass;
- }
- else
- acquire(pTyped);
- }
- }
-
- template<class T_OBJECT> inline
- AcAxObjectRefPtr<T_OBJECT>::~AcAxObjectRefPtr()
- {
- // If the objectid is null we need to release
- // our reference and store it on the AcAxObjectRef.
- if (NULL != this->m_ptr && this->m_ptr->objectId().isNull()) {
- T_OBJECT* pTmp;
- release(pTmp);
- m_pRef->acquire(reinterpret_cast<AcDbObject*&>(pTmp));
- }
- }
- typedef AcAxObjectRefPtr<AcDbObject> AcDbObjectRefPtr;
- typedef AcAxObjectRefPtr<AcDbEntity> AcDbEntityRefPtr;
- #pragma pack (pop)
- #endif
|