[commit] r1085 - in trunk/GME: Interfaces Mga

GMESRC Repository Notifications gme-commit at list.isis.vanderbilt.edu
Mon Nov 15 13:31:47 CST 2010


Author: lph
Date: Mon Nov 15 13:31:47 2010
New Revision: 1085

Log:
OBJEVENT_COPIED (The object is being copied) and OBJEVENT_PRE_STATUS (The status of an attribute or registry node is going to change) added, the latter replacing previously committed PRE_CLEARED. 

Notification OBJEVENT_ATTR given on attribute Clear.  (GME-301 and GME-308)

Event notifications ATTR, REGISTRY, PROPERTIES, and PRE_STATUS receive change details in previously unused event sink parameter.

Modified:
   trunk/GME/Interfaces/Mga.idl
   trunk/GME/Mga/MgaAttribute.cpp
   trunk/GME/Mga/MgaComplexOps.cpp
   trunk/GME/Mga/MgaFCO.cpp
   trunk/GME/Mga/MgaFCO.h
   trunk/GME/Mga/MgaFolder.cpp

Modified: trunk/GME/Interfaces/Mga.idl
==============================================================================
--- trunk/GME/Interfaces/Mga.idl	Mon Nov 15 13:14:50 2010	(r1084)
+++ trunk/GME/Interfaces/Mga.idl	Mon Nov 15 13:31:47 2010	(r1085)
@@ -110,11 +110,11 @@
 [ helpstring("The object has been destroyed (limited access is available)")]
 		OBJEVENT_DESTROYED  =   0x40000000,             
 [ helpstring("The object is going to be deleted.")]
-		OBJEVENT_PRE_DESTROYED  =   0x20000000,
-[ helpstring("Attribute or registry node is going to be cleared or removed.")]
-		OBJEVENT_PRE_CLEARED =   0x10000000,
-[ helpstring("The object is going to be copied.")]
-		OBJEVENT_COPIED     =   0x08000000, 
+		OBJEVENT_PRE_DESTROYED  = 0x20000000,
+[ helpstring("Status of attribute/registry node is going to change.")]
+		OBJEVENT_PRE_STATUS =   0x10000000,
+[ helpstring("The object is being copied.")]
+		OBJEVENT_COPIED     =   0x08000000,
 [ helpstring("Attribute changed")]
 		OBJEVENT_ATTR       =   0x00000001,             
 [ helpstring("Registry changed")]

Modified: trunk/GME/Mga/MgaAttribute.cpp
==============================================================================
--- trunk/GME/Mga/MgaAttribute.cpp	Mon Nov 15 13:14:50 2010	(r1084)
+++ trunk/GME/Mga/MgaAttribute.cpp	Mon Nov 15 13:31:47 2010	(r1085)
@@ -147,27 +147,40 @@
 }
 
 
+class attrnotifytask : public DeriveTreeTask {
+	bool Do(CoreObj self, std::vector<CoreObj> *peers = NULL) {
+		ObjForCore(self)->SelfMark(OBJEVENT_ATTR);
+		return true;
+	}
+};
+
+
 STDMETHODIMP CMgaAttribute::Clear() {
 	COMTRY_IN_TRANSACTION {
 		fco->CheckWrite();
 		CoreObjs attrs = fco->self[ATTRID_ATTRPARENT+ATTRID_COLLECTION];
 		ITERATE_THROUGH(attrs) {
 			if(mref == ITER[ATTRID_META]) {
+				// lph: Pre-Notification PRE_STATUS (the attribute is being changed to its default value)
+				CComQIPtr<IMgaMetaAttribute> ma(mgaproject->FindMetaRef(mref));
+				CComBSTR name;
+				COMTHROW(ma->get_Name(&name));
+				CComBSTR desc = "ATTR,";
+				desc.Append(name);
+				desc.Append(",Cleared");
+				fco->PreNotify(OBJEVENT_PRE_STATUS, CComVariant(desc));
+				//---------------------------------------------------------------------------------------
 				COMTHROW(ITER->Delete());
 				load_status = ATTSTATUS_INVALID;
+				// lph: added notification of attribute mod
+				attrnotifytask().DoWithDeriveds(fco->self);
+				//-----------------------------------------
 				break;
 			}
 		}
 	} COMCATCH_IN_TRANSACTION(;);
 }
 
-class attrnotifytask : public DeriveTreeTask {
-	bool Do(CoreObj self, std::vector<CoreObj> *peers = NULL) {
-		ObjForCore(self)->SelfMark(OBJEVENT_ATTR);
-		return true;
-	}
-};
-
 
 STDMETHODIMP CMgaAttribute::put_Value(VARIANT newVal) {
 		COMTRY_IN_TRANSACTION {
@@ -188,6 +201,15 @@
 					load_status = ATTSTATUS_INVALID;
 					valueobj = NULL;
 					COMTHROW(mgaproject->dataproject->CreateObject(DTID_ATTRTYPESBASE+attrtyp, &valueobj.ComPtr()));
+					// lph: Pre-Notification PRE_STATUS (the attribute is being changed from its default value)
+					CComQIPtr<IMgaMetaAttribute> ma(mgaproject->FindMetaRef(mref));
+					CComBSTR name;
+					COMTHROW(ma->get_Name(&name));
+					CComBSTR desc = "ATTR,";
+					desc.Append(name);
+					desc.Append(",Defined");
+					fco->PreNotify(OBJEVENT_PRE_STATUS, CComVariant(desc));
+					//-----------------------------------------------------------------------------------------
 					valueobj[ATTRID_META]=mref;
 					valueobj[ATTRID_ATTRPARENT]=fco->self;
 					load_status = ATTSTATUS_HERE;
@@ -856,6 +878,12 @@
 			long dummy;
 			valueobj <<= findregvalueobj(fco->self, mypath, dummy, false);
 			if(valueobj) {
+				// lph: Pre-Notification PRE_STATUS (the registry node is being destroyed)
+				CComBSTR desc = "REGISTRY,";
+				desc.Append(mypath);
+				desc.Append(",Removed");
+				fco->PreNotify(OBJEVENT_PRE_STATUS, CComVariant(desc));
+				//--------------------------------------------------------------------------
 				RegistryChildrenRemove(valueobj);
 				COMTHROW(valueobj->Delete());			
 				load_status = ATTSTATUS_INVALID;

Modified: trunk/GME/Mga/MgaComplexOps.cpp
==============================================================================
--- trunk/GME/Mga/MgaComplexOps.cpp	Mon Nov 15 13:14:50 2010	(r1084)
+++ trunk/GME/Mga/MgaComplexOps.cpp	Mon Nov 15 13:31:47 2010	(r1085)
@@ -174,25 +174,25 @@
 	}
 
 	// Notification
-	
-	try 
-	{
-		long chmask = OBJEVENT_PRE_DESTROYED;
-		
+	PreNotify(OBJEVENT_PRE_DESTROYED, CComVariant());
+}
+
+// Added by lph (Taken from PreDeleteNotify) Notification service for precursory object events
+HRESULT FCO::PreNotify(unsigned long changemask, CComVariant param) {
+	COMTRY {
 		CMgaProject::addoncoll::iterator ai, abeg = mgaproject->alladdons.begin(), aend = mgaproject->alladdons.end();
 		if(abeg != aend) 
 		{
-			CComVariant nil;
 			COMTHROW(mgaproject->pushterr(*mgaproject->reserveterr));
 			for(ai = abeg; ai != aend; ) 
 			{
 				CComPtr<CMgaAddOn> t = *ai++;	
 				unsigned long mmask;
-				if((mmask = (t->eventmask & chmask)) != 0) {
+				if((mmask = (t->eventmask & changemask)) != 0) {
 					CComPtr<IMgaObject> tt;
 					getinterface(&tt);
 
-					if(t->handler->ObjectEvent(tt, mmask, nil) != S_OK) {
+					if(t->handler->ObjectEvent(tt, mmask, param) != S_OK) {
 						ASSERT(("Notification failed", false));
 					}
 				    t->notified = true;
@@ -200,11 +200,7 @@
 			}
 			COMTHROW(mgaproject->popterr());
 		}
-	} 
-	catch(hresult_exception&)
-	{
-		ASSERT(0);
-	}
+	} COMCATCH(;)
 }
 
 HRESULT FCO::DeleteObject() { 
@@ -1084,6 +1080,7 @@
 		std::vector<CoreObj> nobjs(cnt);
 		MGACOLL_ITERATE(IMgaFCO, copylist) {
 			CoreObj oldobj = CoreObj(MGACOLL_ITER);
+			ObjForCore(oldobj)->SelfMark(OBJEVENT_COPIED);
 			int derdist = GetRealSubtypeDist(oldobj);
 			ObjTreeCopy(mgaproject, oldobj, nobjs[i], crealist);  // copy
 			if(derdist) ObjTreeDist(nobjs[i], derdist);

Modified: trunk/GME/Mga/MgaFCO.cpp
==============================================================================
--- trunk/GME/Mga/MgaFCO.cpp	Mon Nov 15 13:14:50 2010	(r1084)
+++ trunk/GME/Mga/MgaFCO.cpp	Mon Nov 15 13:31:47 2010	(r1085)
@@ -829,7 +829,107 @@
 	} COMCATCH(;)
 }
 
+//-------------------------------------------------------------------------------------
+// lph: Change description for ATTR, REGISTRY and PROPERTIES notifications
 
+typedef std::vector<CComVariant> ModificationsVector;
+
+void getRegistryModifications(CoreObj &cobj, CComBSTR &path, ModificationsVector &mv) {
+	CComVariant current  = cobj[ATTRID_REGNODEVALUE];
+	CComVariant previous;
+	COMTHROW(cobj->get_PreviousAttrValue(ATTRID_REGNODEVALUE, &previous));
+	if (previous != current) {
+		CComBSTR label = "REGISTRY:";
+		label.Append(path);
+		CComVariant ident = label;
+		mv.push_back(ident);
+		mv.push_back(previous);
+	}
+	ITERATE_THROUGH(cobj[ATTRID_REGNOWNER+ATTRID_COLLECTION]) {
+		CComBSTR cname = ITER[ATTRID_NAME];
+		CComBSTR cpath = path;
+		cpath.Append("/");
+		cpath.Append(cname);
+		getRegistryModifications(ITER, cpath, mv);
+	}
+}
+
+HRESULT get_Modifications(FCO *fco, unsigned long changemask, CComVariant *mods) {
+	ModificationsVector modifications;
+	if (changemask & OBJEVENT_REGISTRY) {
+		ITERATE_THROUGH(fco->self[ATTRID_REGNOWNER+ATTRID_COLLECTION]) {
+			CComBSTR path = ITER[ATTRID_NAME];
+			getRegistryModifications(ITER, path, modifications);
+		}
+	}
+	if (changemask & OBJEVENT_ATTR) {
+		CComPtr<IMgaMetaFCO> mfco;
+		COMTHROW(fco->get_Meta(&mfco));
+		ITERATE_THROUGH(fco->self[ATTRID_ATTRPARENT+ATTRID_COLLECTION]) {
+			CComPtr<IMgaMetaAttribute> ma;
+			COMTHROW(mfco->get_AttributeByRef(ITER[ATTRID_META], &ma));
+			attval_enum vt;
+			COMTHROW(ma->get_ValueType(&vt));
+			if (vt == ATTVAL_ENUM) vt = ATTVAL_STRING;
+			attrid_type aid = ATTRID_ATTRTYPESBASE + vt;
+			CComVariant current = ITER[aid];
+			static const VARTYPE vartypes[] = { VT_NULL, VT_BSTR, VT_I4, VT_R8, VT_BOOL, VT_DISPATCH, VT_BSTR };
+			if(vartypes[vt] != current.vt) {
+				COMTHROW(current.ChangeType(vartypes[vt]));
+			}
+			CComVariant previous;
+			COMTHROW(ITER->get_PreviousAttrValue(aid, &previous));
+			if(vartypes[vt] != previous.vt) {
+				COMTHROW(previous.ChangeType(vartypes[vt]));
+			}
+			if (previous != current) {
+				CComBSTR name;
+				COMTHROW(ma->get_Name(&name));
+				CComBSTR label = "ATTR:";
+				label.Append(name);
+				CComVariant ident = label;
+				modifications.push_back(ident);
+				modifications.push_back(previous);
+			}
+		}
+	}
+	if (changemask & OBJEVENT_PROPERTIES) {
+		CComVariant name = fco->self[ATTRID_NAME];
+		CComVariant pname;
+		fco->self->get_PreviousAttrValue(ATTRID_NAME, &pname);
+		if (pname != name) {
+			CComVariant ident = "PROPERTIES:Name";
+			modifications.push_back(ident);
+			modifications.push_back(pname);
+		}
+/* lph: possibly necessary, but not yet
+		CComVariant perm = fco->self[ATTRID_PERMISSIONS];
+		CComVariant pperm;
+		COMTHROW(fco->self->get_PreviousAttrValue(ATTRID_PERMISSIONS, &pperm));
+		if (pperm != perm) {
+			CComVariant ident = "PROPERTIES:Permissions";
+			modifications.push_back(ident);
+			modifications.push_back(pperm);
+		}
+*/
+	}
+	if (modifications.size() > 0) {
+		SAFEARRAY *pVariantsArray = NULL;
+		SAFEARRAYBOUND rgsabound[1];
+		rgsabound[0].lLbound = 0;
+		rgsabound[0].cElements = modifications.size();
+		pVariantsArray = SafeArrayCreate(VT_VARIANT, 1, rgsabound);
+		for (LONG i=0; i<LONG(modifications.size()); i++) {
+			SafeArrayPutElement(pVariantsArray, &i, &modifications[i]);
+		}
+		CComVariant varOut;
+		varOut.vt = VT_ARRAY | VT_VARIANT;
+		varOut.parray = pVariantsArray;
+		varOut.Detach(mods);
+	}
+	return S_OK;
+}
+//-------------------------------------------------------------------------------------
 
 #define REQUIRE_NOTIFICATION_SUCCESS 1   // return with error if addons/rwhandlers fail
 
@@ -841,7 +941,9 @@
 			if(chmask & OBJEVENT_DESTROYED) chmask = OBJEVENT_DESTROYED;
 			CMgaProject::addoncoll::iterator ai, abeg = mgaproject->alladdons.begin(), aend = mgaproject->alladdons.end();
 			if(abeg != aend) {
-				CComVariant nil;
+				CComVariant mods;
+				if(!(chmask & OBJEVENT_CREATED) && (chmask & (OBJEVENT_REGISTRY+OBJEVENT_ATTR+OBJEVENT_PROPERTIES)))
+					COMTHROW(get_Modifications(this, chmask, &mods));
 				COMTHROW(mgaproject->pushterr(*mgaproject->reserveterr));
 				for(ai = abeg; ai != aend; ) {
 					CComPtr<CMgaAddOn> t = *ai++;	// it is important to incr ii here, while obj 
@@ -852,9 +954,9 @@
 						getinterface(&tt);
 
 #if(REQUIRE_NOTIFICATION_SUCCESS)
-						COMTHROW(t->handler->ObjectEvent(tt, mmask, nil));
+						COMTHROW(t->handler->ObjectEvent(tt, mmask, mods));
 #else
-						if((s = t->handler->ObjectEvent(tt, mmask, nil)) != S_OK) {
+						if((s = t->handler->ObjectEvent(tt, mmask, mods)) != S_OK) {
 							ASSERT(("Notification failed", false));
 						}
 #endif

Modified: trunk/GME/Mga/MgaFCO.h
==============================================================================
--- trunk/GME/Mga/MgaFCO.h	Mon Nov 15 13:14:50 2010	(r1084)
+++ trunk/GME/Mga/MgaFCO.h	Mon Nov 15 13:31:47 2010	(r1085)
@@ -340,6 +340,7 @@
 
 // PreDelete Notification by Tihamer for the PAMS SynchTool
 	void PreDeleteNotify();
+
 public:
 	class NoAddRefCoreObj : public CoreObj {	// CoreObj, but non-addref/release-ing
 	public:
@@ -597,6 +598,9 @@
 	void objforgetchange();
 	void removeterrfromlist(CMgaTerritory *t);
 
+	// lph: notification service for precursory object events (used by PRE_DESTROYED and PRE_STATUS)
+	HRESULT PreNotify(unsigned long changemask, CComVariant param);
+
 	template <class Q>
 	void getinterface(Q **p, CMgaTerritory *terr = NULL) {
 		CComPtr<IMgaObject> zz;

Modified: trunk/GME/Mga/MgaFolder.cpp
==============================================================================
--- trunk/GME/Mga/MgaFolder.cpp	Mon Nov 15 13:14:50 2010	(r1084)
+++ trunk/GME/Mga/MgaFolder.cpp	Mon Nov 15 13:31:47 2010	(r1085)
@@ -76,6 +76,7 @@
 		std::vector<CoreObj> nobjs(cnt);
 		MGACOLL_ITERATE(IMgaFolder, copylist) {
 			CoreObj oldobj = CoreObj(MGACOLL_ITER);
+			ObjForCore(oldobj)->SelfMark(OBJEVENT_COPIED);
 			ObjTreeCopyFoldersToo(mgaproject, oldobj, nobjs[i], crealist);  // copy
 			assignnewchild(nobjs[i]);
 			


More information about the gme-commit mailing list