[commit] r2305 - in trunk: GME/Core GME/Gme GME/Meta GME/Mga Tests/GPyUnit

GMESRC Repository Notifications gme-commit at list.isis.vanderbilt.edu
Tue Aug 27 09:21:48 CDT 2013


Author: ksmyth
Date: Tue Aug 27 09:21:48 2013
New Revision: 2305

Log:
Meta needs to clean up CoreObjects itself now, since CoreTerritory isnt doing it. Some _ATL_DEBUG_INTERFACES improvements (still a WIP for Core and Meta)

Modified:
   trunk/GME/Core/CoreAttribute.cpp
   trunk/GME/Core/CoreAttribute.h
   trunk/GME/Core/CoreObject.cpp
   trunk/GME/Core/CoreObject.h
   trunk/GME/Core/CoreProject.cpp
   trunk/GME/Gme/GMEPartBrowser.cpp
   trunk/GME/Meta/Meta.cpp
   trunk/GME/Meta/MgaMetaBase.cpp
   trunk/GME/Meta/MgaMetaProject.cpp
   trunk/GME/Meta/MgaMetaProject.h
   trunk/GME/Mga/MgaProject.h
   trunk/Tests/GPyUnit/test_registry.py

Modified: trunk/GME/Core/CoreAttribute.cpp
==============================================================================
--- trunk/GME/Core/CoreAttribute.cpp	Tue Aug 27 09:21:00 2013	(r2304)
+++ trunk/GME/Core/CoreAttribute.cpp	Tue Aug 27 09:21:48 2013	(r2305)
@@ -61,7 +61,7 @@
 			typedef CComPartObject< CCorePointerAttribute > COMTYPE;
 
 			COMTYPE *p = NULL;
-			COMTHROW( COMTYPE::CreateInstance(CastToUnknown(object), &p) );
+			COMTHROW( COMTYPE::CreateInstance(CastToUnknown_Object(object), &p) );
 			attribute = p;
 
 			break;
@@ -72,7 +72,7 @@
 			typedef CComPartObject< CCoreCollectionAttribute > COMTYPE;
 
 			COMTYPE *p = NULL;
-			COMTHROW( COMTYPE::CreateInstance(CastToUnknown(object), &p) );
+			COMTHROW( COMTYPE::CreateInstance(CastToUnknown_Object(object), &p) );
 			attribute = p;
 
 			break;
@@ -83,7 +83,7 @@
 			typedef CComPartObject< CCoreLongAttribute > COMTYPE;
 
 			COMTYPE *p = NULL;
-			COMTHROW( COMTYPE::CreateInstance(CastToUnknown(object), &p) );
+			COMTHROW( COMTYPE::CreateInstance(CastToUnknown_Object(object), &p) );
 			attribute = p;
 
 			break;
@@ -94,7 +94,7 @@
 			typedef CComPartObject< CCoreDictAttribute > COMTYPE;
 
 			COMTYPE *p = NULL;
-			COMTHROW( COMTYPE::CreateInstance(CastToUnknown(object), &p) );
+			COMTHROW( COMTYPE::CreateInstance(CastToUnknown_Object(object), &p) );
 			attribute = p;
 
 			break;
@@ -105,7 +105,7 @@
 			typedef CComPartObject< CCoreStringAttribute > COMTYPE;
 
 			COMTYPE *p = NULL;
-			COMTHROW( COMTYPE::CreateInstance(CastToUnknown(object), &p) );
+			COMTHROW( COMTYPE::CreateInstance(CastToUnknown_Object(object), &p) );
 			attribute = p;
 
 			break;
@@ -116,7 +116,7 @@
 			typedef CComPartObject< CCoreBinaryAttribute > COMTYPE;
 
 			COMTYPE *p = NULL;
-			COMTHROW( COMTYPE::CreateInstance(CastToUnknown(object), &p) );
+			COMTHROW( COMTYPE::CreateInstance(CastToUnknown_Object(object), &p) );
 			attribute = p;
 
 			break;
@@ -127,7 +127,7 @@
 			typedef CComPartObject< CCoreRealAttribute > COMTYPE;
 
 			COMTYPE *p = NULL;
-			COMTHROW( COMTYPE::CreateInstance(CastToUnknown(object), &p) );
+			COMTHROW( COMTYPE::CreateInstance(CastToUnknown_Object(object), &p) );
 			attribute = p;
 
 			break;
@@ -138,7 +138,7 @@
 			typedef CComPartObject< CCoreLockAttribute > COMTYPE;
 
 			COMTYPE *p = NULL;
-			COMTHROW( COMTYPE::CreateInstance(CastToUnknown(object), &p) );
+			COMTHROW( COMTYPE::CreateInstance(CastToUnknown_Object(object), &p) );
 			attribute = p;
 
 			break;
@@ -162,7 +162,9 @@
 	ASSERT( metaattribute != NULL );
 	ASSERT( !IsDirty() );
 
+#ifndef _ATL_DEBUG_INTERFACES
 	GetObject()->UnregisterAttribute(this);
+#endif
 }
 
 #ifdef DEBUG
@@ -308,6 +310,16 @@
 		locking_type locking = LOCKING_NONE;
 		CopyTo(p, locking);
 
+		// this kludge value is used by meta to indicate that the project is about to be closed, so just call Release on our object and be done with it
+		if (locking == (unsigned char)-1)
+		{
+			SetStatusFlag(COREATTRIBUTE_LOCK_CLOSED);
+			read_count = write_count = 0;
+			SetDirty();
+			Unload();
+			return S_OK;
+		}
+
 		if( !(LOCKING_NONE <= locking && locking <= LOCKING_EXCLUSIVE) )
 			HR_THROW(E_INVALIDARG);
 
@@ -350,6 +362,8 @@
 
 void CCoreLockAttribute::RegisterLockTry(locking_type unreg, locking_type reg)
 {
+	if (GetStatusFlag(COREATTRIBUTE_LOCK_CLOSED))
+		return;
 	ASSERT( InTransaction() );
 
 	locking_type old_locking = CombineLock(read_count, write_count);

Modified: trunk/GME/Core/CoreAttribute.h
==============================================================================
--- trunk/GME/Core/CoreAttribute.h	Tue Aug 27 09:21:00 2013	(r2304)
+++ trunk/GME/Core/CoreAttribute.h	Tue Aug 27 09:21:48 2013	(r2305)
@@ -90,6 +90,14 @@
 	// if type mismatch then returns false
 	virtual bool DoesMatch(bool do_load, const VARIANT &v) { return false; }
 
+#ifdef _ATL_DEBUG_INTERFACES
+	HRESULT FinalConstruct()
+	{
+		m_pOuterUnknown->AddRef();
+		return S_OK;
+	}
+#endif
+
 // ------- Inline
 
 public:
@@ -101,6 +109,7 @@
 #define COREATTRIBUTE_DIRTY				0x0001
 #define COREATTRIBUTE_LOCKGROUP_LOADED	0x0002
 #define COREATTRIBUTE_COLL_UPTODATE		0x0004
+#define COREATTRIBUTE_LOCK_CLOSED		0x0008
 
 public:
 	void SetStatusFlag(status_type flags) NOTHROW { status |= flags; }

Modified: trunk/GME/Core/CoreObject.cpp
==============================================================================
--- trunk/GME/Core/CoreObject.cpp	Tue Aug 27 09:21:00 2013	(r2304)
+++ trunk/GME/Core/CoreObject.cpp	Tue Aug 27 09:21:48 2013	(r2305)
@@ -69,8 +69,14 @@
 	aggregates.clear();
 
 	// the attribute will remove itself from the list
+#ifndef _ATL_DEBUG_INTERFACES
 	while( !attributes.empty() )
 		delete attributes.front();
+#else
+	for (auto it = attributes.begin(); it != attributes.end(); it++)
+		delete *it;
+	attributes.clear();
+#endif
 
 	if( project != NULL )
 		project->UnregisterObject(GetMetaID(), objid);
@@ -510,6 +516,20 @@
 
 	// we do not unregister, the object_lookup is cleared
 
+#ifdef _ATL_DEBUG_INTERFACES
+	attributes_type::const_iterator i = attributes.begin();
+	attributes_type::const_iterator e = attributes.end();
+	while( i != e )
+	{
+		if ((*i)->GetAttrID() == ATTRID_LOCK)
+			ASSERT(!((CCoreLockAttribute*)*i)->GetStatusFlag(COREATTRIBUTE_LOCKGROUP_LOADED));
+
+		(*i)->Release();
+		i++;
+	}
+	cleanup.clear();
+#endif
+
 	project = NULL;
 	metaobject = NULL;
 }

Modified: trunk/GME/Core/CoreObject.h
==============================================================================
--- trunk/GME/Core/CoreObject.h	Tue Aug 27 09:21:00 2013	(r2304)
+++ trunk/GME/Core/CoreObject.h	Tue Aug 27 09:21:48 2013	(r2305)
@@ -146,18 +146,34 @@
 	virtual void AbortFinalTransaction() NOTHROW;
 	virtual void CommitFinalTransaction();
 	virtual void CommitFinalTransactionFinish(bool undo) NOTHROW;
+#ifdef _ATL_DEBUG_INTERFACES
+	std::vector<CComPtr<IUnknown> > cleanup;
+#endif
 };
 
 #ifndef _ATL_DEBUG_INTERFACES
 inline IUnknown *CastToUnknown(CCoreObject *p) { return (IUnknown*)(ICoreObject*)p; }
 inline CCoreObject *CastToObject(IUnknown *p) { return (CCoreObject*)(ICoreObject*)p; }
+inline IUnknown *CastToUnknown_Object(CCoreObject *p) { return CastToUnknown(p); }
 #else
-inline IUnknown *CastToUnknown(CCoreObject *p)
+inline CComPtr<IUnknown> CastToUnknown(CCoreObject *p)
+{
+	CComPtr<IUnknown> pUnk;
+	p->QueryInterface(IID_IUnknown, (void**)&pUnk.p);
+	p->cleanup.push_back(pUnk);
+	return pUnk;
+}
+
+inline CComPtr<IUnknown> CastToUnknown_Object(CCoreObject *p)
 {
-	IUnknown* pUnk;
-	p->QueryInterface(IID_IUnknown, (void**)&pUnk);
+	CComPtr<IUnknown> pUnk;
+	p->QueryInterface(IID_IUnknown, (void**)&pUnk.p);
+	p->cleanup.push_back(pUnk);
+
+	pUnk = 0;
+	p->QueryInterface(__uuidof(ICoreObject), (void**)&pUnk.p);
+	p->cleanup.push_back(pUnk);
 	return pUnk;
-	return (IUnknown*)(ICoreObject*)p;
 }
 
 inline CCoreObject *CastToObject(IUnknown *p) {

Modified: trunk/GME/Core/CoreProject.cpp
==============================================================================
--- trunk/GME/Core/CoreProject.cpp	Tue Aug 27 09:21:00 2013	(r2304)
+++ trunk/GME/Core/CoreProject.cpp	Tue Aug 27 09:21:48 2013	(r2305)
@@ -98,6 +98,10 @@
 			object_lookup_iterator e = object_lookup.end();
 			while( i != e )
 			{
+#ifdef _ATL_DEBUG_INTERFACES
+				CComPtr<IUnknown> obj1 = (IDispatchImpl<ICoreObject, &__uuidof(ICoreObject), &__uuidof(__MGACoreLib)>*)i->second;
+				CComPtr<IUnknown> obj2 = (IDispatchImpl<ICoreObject, &__uuidof(ICoreObject), &__uuidof(__MGACoreLib)>*)i->second;
+#endif
 				(*i).second->SetZombie();
 
 				++i;

Modified: trunk/GME/Gme/GMEPartBrowser.cpp
==============================================================================
--- trunk/GME/Gme/GMEPartBrowser.cpp	Tue Aug 27 09:21:00 2013	(r2304)
+++ trunk/GME/Gme/GMEPartBrowser.cpp	Tue Aug 27 09:21:48 2013	(r2305)
@@ -139,7 +139,7 @@
 
 void CGMEPartBrowser::SetMetaModel(CGuiMetaModel* meta)
 {
-	LPUNKNOWN pMeta = NULL;
+	CComPtr<IUnknown> pMeta = NULL;
 	guiMetaModel = meta;
 	if (meta != NULL) {
 		CComQIPtr<IMgaMetaModel> iMeta;

Modified: trunk/GME/Meta/Meta.cpp
==============================================================================
--- trunk/GME/Meta/Meta.cpp	Tue Aug 27 09:21:00 2013	(r2304)
+++ trunk/GME/Meta/Meta.cpp	Tue Aug 27 09:21:48 2013	(r2305)
@@ -182,6 +182,8 @@
 			CMgaMetaPointerSpec::Traverse(metaproject, me);
 		else if( SUCCEEDED(QueryInterface(me, regnode)) )
 			CMgaMetaRegNode::Traverse(metaproject, me);
+
+		metaproject->core_object_cleanup.push_back(CComPtr<ICoreObject>(me.p));
 	}
 }
 

Modified: trunk/GME/Meta/MgaMetaBase.cpp
==============================================================================
--- trunk/GME/Meta/MgaMetaBase.cpp	Tue Aug 27 09:21:00 2013	(r2304)
+++ trunk/GME/Meta/MgaMetaBase.cpp	Tue Aug 27 09:21:48 2013	(r2305)
@@ -41,12 +41,24 @@
 	COMTHROW( ::QueryInterface(me, ibase) );
 	ASSERT( ibase != NULL );
 
+#ifdef _ATL_DEBUG_INTERFACES
+	IUnknown* pUnk = ((ATL::_QIThunk *)(ibase.p))->m_pUnk;
+	pUnk = ((ATL::_QIThunk *)(pUnk))->m_pUnk; // this is needed if Core has _ATL_DEBUG_INTERFACES
+	CMgaMetaBase *base = (CMgaMetaBase *)(IMgaMetaBase*)(pUnk);
+#else
 	CMgaMetaBase *base = static_cast<CMgaMetaBase*>((IMgaMetaBase*)ibase);
+#endif
 	ASSERT( base != NULL );
 
 	ASSERT( base->metaproject == NULL );
 
+#ifdef _ATL_DEBUG_INTERFACES
+	CComQIPtr<IMgaMetaBase> base2;
+	base->QueryInterface(&base2.p);
+	metaproject->RegisterMetaBase(metaref, base2);
+#else
 	metaproject->RegisterMetaBase(metaref, base);
+#endif
 
 	base->metaprojectref = metaproject;
 	base->metaref = metaref;

Modified: trunk/GME/Meta/MgaMetaProject.cpp
==============================================================================
--- trunk/GME/Meta/MgaMetaProject.cpp	Tue Aug 27 09:21:00 2013	(r2304)
+++ trunk/GME/Meta/MgaMetaProject.cpp	Tue Aug 27 09:21:48 2013	(r2305)
@@ -171,25 +171,51 @@
 	{
 		if( coreproject != NULL )
 		{
-			rootobject = NULL;
-
 			short count = 0;
 			COMTHROW( coreproject->get_NestedTransactionCount(&count) );
 
 			if( count == 1 )
 				COMTHROW( coreproject->AbortTransaction(TRANSTYPE_ANY) );
 
+			short undos;
+			COMTHROW(coreproject->get_UndoQueueSize(&undos));
+			if (undos)
+			{
+				COMTHROW(coreproject->SaveProject(L"", VARIANT_TRUE));
+			}
+			COMTHROW(coreproject->FlushRedoQueue());
+			COMTHROW(coreproject->FlushUndoQueue());
+
+			COMTHROW( coreproject->BeginTransaction(TRANSTYPE_FIRST) );
+			COMTHROW( coreproject->PushTerritory(coreterritory) );
+
+
+			for (auto it = metaobj_lookup.begin(); it != metaobj_lookup.end(); it++)
+			{
+				CCoreObjectPtr self(it->second);
+				COMTHROW(self->put_AttributeValue(ATTRID_LOCK, CComVariant((locking_type)-1)));
+			}
+			for (auto it = core_object_cleanup.begin(); it != core_object_cleanup.end(); it++)
+			{
+				COMTHROW((*it)->put_AttributeValue(ATTRID_LOCK, CComVariant((locking_type)-1)));
+			}
+			core_object_cleanup.clear();
+
+			COMTHROW( coreproject->CommitTransaction(TRANSTYPE_FIRST) );
+
+			metaobj_lookup.clear();
+			max_metaref = 1000;
+
+			rootobject = NULL;
+
 			if( coreterritory != NULL )
 			{
 				COMTHROW( coreterritory->Clear() );
 				coreterritory = NULL;
 			}
 
-			COMTHROW( coreproject->CloseProject() );
+			COMTHROW( coreproject->CloseProject(VARIANT_TRUE) );
 			coreproject = NULL;
-
-			metaobj_lookup.clear();
-			max_metaref = 1000;
 		}
 
 		ASSERT( coreproject == NULL );
@@ -352,7 +378,7 @@
 	if( i == metaobj_lookup.end() )
 		COMRETURN(E_NOTFOUND);
 
-	CopyTo((*i).second, p);
+	CopyTo((*i).second.p, p);
 	return S_OK;
 }
 

Modified: trunk/GME/Meta/MgaMetaProject.h
==============================================================================
--- trunk/GME/Meta/MgaMetaProject.h	Tue Aug 27 09:21:00 2013	(r2304)
+++ trunk/GME/Meta/MgaMetaProject.h	Tue Aug 27 09:21:48 2013	(r2305)
@@ -68,14 +68,9 @@
 
 // ------- metaobj_lookup
 
-	// Through the metaobj_lookup we do not keep references (AddRef)
-	// to objects, this would result in a dead-lock. So we use our
-	// CoreTerritory to keep these objects alive. They will register
-	// and unregister themselves.
-
 public:
 	typedef stdext::hash_map< metaref_type
-	                        , IMgaMetaBase*
+	                        , CComPtr<IMgaMetaBase>
 	                        , metaid_hashfunc
 	                        > metaobj_lookup_type;
 	typedef metaobj_lookup_type::iterator metaobj_lookup_iterator;
@@ -83,6 +78,8 @@
 	metaobj_lookup_type metaobj_lookup;
 	metaref_type max_metaref;
 
+	std::vector<CComPtr<ICoreObject> > core_object_cleanup;
+
 public:
 	void RegisterMetaBase(metaref_type metaref, IMgaMetaBase *obj);
 	void UnregisterMetaBase(metaref_type metaref, IMgaMetaBase *obj) NOTHROW;

Modified: trunk/GME/Mga/MgaProject.h
==============================================================================
--- trunk/GME/Mga/MgaProject.h	Tue Aug 27 09:21:00 2013	(r2304)
+++ trunk/GME/Mga/MgaProject.h	Tue Aug 27 09:21:48 2013	(r2305)
@@ -152,15 +152,15 @@
 	{
 		dataprojectNull = !!dataproject;
 	}
-	ICoreProject* get_dataproject()
+	CComPtr<ICoreProject> get_dataproject()
 	{
 		if (dataprojectNull)
 			return NULL;
-		ICoreProject* ret;
-		COMTHROW(inner->QueryInterface(__uuidof(ICoreProject), (void**)&ret));
+		CComPtr<ICoreProject> ret;
+		COMTHROW(inner->QueryInterface(__uuidof(ICoreProject), (void**)&ret.p));
 		return ret;
 	}
-	__declspec(property(get=get_dataproject, put=put_dataproject)) ICoreProject* dataproject;
+	__declspec(property(get=get_dataproject, put=put_dataproject)) CComPtr<ICoreProject> dataproject;
 #endif
 	void ObjMark(IMgaObject *s, long mask);
 	void FixupGUID(bool write = true);

Modified: trunk/Tests/GPyUnit/test_registry.py
==============================================================================
--- trunk/Tests/GPyUnit/test_registry.py	Tue Aug 27 09:21:00 2013	(r2304)
+++ trunk/Tests/GPyUnit/test_registry.py	Tue Aug 27 09:21:48 2013	(r2305)
@@ -43,7 +43,7 @@
                     sheet_meta = self.project.RootMeta.RootFolder.DefinedFCOs.Item(i)
             sheet = self.project.RootFolder.CreateRootObject(sheet_meta)
             sheetregs = sheet.GetRegistryDisp(True)
-            self.assertEqual(set([reg.Name for reg in sheetregs]), set(['namePosition', 'isTypeInfoShown']))
+            self.assertEqual(set([reg.Name for reg in sheetregs]), set(['namePosition', 'isTypeInfoShown'])) # this assert will fail with an old MetaGME registered
             
             namePosition = sheet.GetRegistryNodeDisp('namePosition')
             self.assertEqual(namePosition.Name, 'namePosition')


More information about the gme-commit mailing list