[GME-commit] GMESRC/GME/Mga MgaDeriveOps.cpp,1.2,1.3 MgaComplexOps.cpp,1.10,1.11

gme-commit at list.isis.vanderbilt.edu gme-commit at list.isis.vanderbilt.edu
Tue Aug 30 23:25:33 CDT 2005


Update of /project/gme-repository/GMESRC/GME/Mga
In directory escher:/tmp/cvs-serv10997

Modified Files:
	MgaDeriveOps.cpp MgaComplexOps.cpp 
Log Message:
DetachFromArcheType implemented.



CVS User: Zoltan Molnar, ISIS (zolmol)

Index: MgaComplexOps.cpp
===================================================================
RCS file: /project/gme-repository/GMESRC/GME/Mga/MgaComplexOps.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -d -r1.10 -r1.11
*** MgaComplexOps.cpp	26 Jan 2005 17:30:46 -0000	1.10
--- MgaComplexOps.cpp	30 Aug 2005 22:25:30 -0000	1.11
***************
*** 1446,1447 ****
--- 1446,1635 ----
  
  
+ 
+ // this recursive method is different from ObjTreeCopy in that it doesn't
+ // create a new object into 'nobj' as its first step
+ // some inner collections are copied with the help of ObjTreeCopy
+ // it doesn't create anything except RegNodes and Attributes which are still tied to the base
+ void ObjDetachAndMerge( CMgaProject *mgaproject, CoreObj orig, CoreObj &nobj, coreobjpairhash& crealist, unsigned long nextrelid, bool prim = true)
+ {
+ 	bool has_last_relid_attr = false;
+ 	unsigned long nb_of_children = 0;
+ 	unsigned long last_relid_set = 0;
+ 
+ 	CComPtr<ICoreAttributes> atts;
+ 	COMTHROW(orig->get_Attributes(&atts));
+ 	MGACOLL_ITERATE(ICoreAttribute, atts) {
+ 			attrid_type ai;
+ 			CComPtr<ICoreMetaAttribute> mattr;
+ 			COMTHROW(MGACOLL_ITER->get_MetaAttribute(&mattr));
+ 			COMTHROW(mattr->get_AttrID(&ai));
+ 			if(ai < ATTRID_COLLECTION) {
+ 				switch(ai) {
+ 					case ATTRID_DERIVED: 
+ 					case ATTRID_MASTEROBJ:
+ 					{
+ 						nobj[ai] = CComVariant( (IDispatch*) 0);//an empty value;
+ 						break;
+ 					}
+ 					case ATTRID_PERMISSIONS:
+ 					{
+ 						if( nobj[ai] & INSTANCE_FLAG) //if INSTANCE_FLAG present
+ 							nobj[ai] = (orig[ai]) & 0;//then INSTANCE_FLAG removed;
+ 						break;
+ 					}
+ 					case ATTRID_RELID:
+ 					{
+ 						if( !prim) // it was a child of a primary derived, being detached
+ 						{
+ 							long relid = nobj[ai]-RELIDSPACE; // revert a secondary derived objects relid to a normal relid
+ 							if(relid >= 0 && relid < RELIDSPACE) 
+ 							{
+ 								// this command would cause ambiguity if the parent has plain children
+ 								//nobj[ai] = relid; // object will be no more secondary derived!
+ 								// that is why we use new relids
+ 								ASSERT( nextrelid >= 0 && nextrelid < RELIDSPACE);
+ 								nobj[ai] = nextrelid;
+ 							}
+ 							else
+ 							{
+ 								ASSERT(0); // problem
+ 								COMTHROW(E_MGA_LONG_DERIVCHAIN);
+ 							}
+ 						}
+ 						break;
+ 					}
+ 					case ATTRID_LASTRELID:
+ 					{
+ 						unsigned long old_val = nobj[ai];
+ 						// the old value 'nobj[ai]' contains only the number of the plain objects
+ 						// this is a temp value (the correct value is inserted upon exit)
+ 						//nobj[ai] = 0L;
+ 						has_last_relid_attr = true;
+ 						break;
+ 					}
+ 					default:
+ 						break; // no copy/change needed in other plain cases
+ 				}; // endswitch
+ 			}
+ 			else if( LINKREF_ATTR(ai-ATTRID_COLLECTION)){
+ 				ai -= ATTRID_COLLECTION;
+ 
+ 				switch( ai) {
+ 					case ATTRID_REGNOWNER: // merge registry
+ 					{ 
+ 						CoreObjs collmembers = orig[ai + ATTRID_COLLECTION]; // copy the base's entries
+ 						ITERATE_THROUGH(collmembers) {
+ 							CoreObj nchild;
+ 							ObjTreeCopy(mgaproject, ITER, nchild, crealist);
+ 							nchild[ai] = nobj;
+ 						}
+ 						break;
+ 					}
+ 					case ATTRID_ATTRPARENT: // copy the unfilled attributes
+ 					{
+ 						unsigned int owned_attrs(0), inherited_attrs(0), l3(0);
+ 						CComBSTR nm;
+ 						ObjForCore(nobj)->get_Name( &nm);
+ 
+ 						std::list<metaref_type> ownedAttrVec;
+ 						{
+ 							CoreObjs my_attrs = nobj[ai + ATTRID_COLLECTION]; // count first the # of owned attributes
+ 							ITERATE_THROUGH(my_attrs) { 
+ 								++owned_attrs;
+ 								metaref_type attr_i = ITER[ATTRID_META];
+ 								if( std::find( ownedAttrVec.begin(), ownedAttrVec.end(), attr_i) == ownedAttrVec.end())
+ 									ownedAttrVec.push_back( attr_i);
+ 								else
+ 									ASSERT(0); // can an attribute belong to self twice?
+ 							}
+ 						}
+ 						// owned_attrs is the number of owned attributes
+ 						// in case the user overwrites the inherited attribute values 
+ 						// the instance or subtype gets an additional attribute (initially had none)
+ 						// thus in case of detaching, we need to distinguish between owned values
+ 						// and inherited values (owned preferred)
+ 
+ 						{
+ 							CoreObjs base_attrs = orig[ai + ATTRID_COLLECTION]; // copy the base's values selectively
+ 							ITERATE_THROUGH(base_attrs) { 
+ 								bool fnd = std::find( ownedAttrVec.begin(), ownedAttrVec.end(), ITER[ATTRID_META]) != ownedAttrVec.end();
+ 								if( !fnd)
+ 								{
+ 									++inherited_attrs;
+ 									CoreObj nchild;
+ 									ObjTreeCopy(mgaproject, ITER, nchild, crealist);
+ 									nchild[ai] = nobj;
+ 								}
+ 							}
+ 						}
+ 						{
+ 							CoreObjs mine = nobj[ai + ATTRID_COLLECTION]; // overwrite with mine 
+ 							ITERATE_THROUGH( mine) { 
+ 								++l3;
+ 							//	CoreObj nchild;
+ 							//	ObjTreeCopy(mgaproject, ITER, nchild, crealist);
+ 							//	nchild[ai] = nobj;
+ 							}
+ 						}
+ 
+ 						ASSERT( owned_attrs + inherited_attrs == l3);
+ 						break;
+ 					}
+ 					case ATTRID_FCOPARENT: // for all secondary derived fco children-> detach
+ 					{
+ 						// we will calc the max_relid of those child objects which are not secondary, tertiary, ... objects
+ 						// because in case of subtypes not all children originate from the current base:
+ 						// some children might be plain objects, and some others may be primary subtypes of other bases
+ 						long cur_max_relid = nobj[ATTRID_LASTRELID];
+ 						CoreObjs children = nobj[ai + ATTRID_COLLECTION];
+ 						ITERATE_THROUGH(children) {
+ 							// this will help set the last relid correctly
+ 							++nb_of_children;
+ 							CoreObj base = (ITER)[ATTRID_DERIVED];
+ 							if( base) // child is also derived
+ 							{
+ 								VARIANT_BOOL primDer = VARIANT_FALSE;
+ 								if( nobj.IsFCO()) ObjForCore( ITER)->get_IsPrimaryDerived( &primDer);
+ 								if( primDer != VARIANT_TRUE) // it is a child derived along with 'orig'
+ 								{
+ 									// detach it as well from its base
+ 									ObjDetachAndMerge(mgaproject, base, ITER, crealist, ++cur_max_relid, false);
+ 									// increase the cur_max_relid for the next child
+ 									nobj[ATTRID_LASTRELID] = last_relid_set = cur_max_relid;
+ 								}
+ 								else 
+ 								{	// it might be a primary subtype/instance placed into this subtype
+ 									// leave this object untouched
+ 								}
+ 							}
+ 							else
+ 							{	// additional child->no action needed
+ 							}
+ 						}
+ 						break;
+ 					}
+ 					default: // for all others -> detach
+ 					{ 
+ 						CoreObjs collmembers = nobj[ai + ATTRID_COLLECTION];
+ 						ITERATE_THROUGH(collmembers) {
+ 							// remove the ATTRID_DERIVED attrs if any?
+ 							ObjDetachAndMerge(mgaproject, ITER, ITER, crealist, 0, false);
+ 						}
+ 					}
+ 				}; // endswitch
+ 			}
+ 
+ 	} MGACOLL_ITERATE_END;
+ 
+ 	if( has_last_relid_attr) // if this CoreObj has RELID_LAST attribute
+ 	{
+ 		unsigned long r = nobj[ATTRID_LASTRELID];
+ 		ASSERT( last_relid_set >= nb_of_children);
+ 		if( r < last_relid_set)
+ 			nobj[ATTRID_LASTRELID] = last_relid_set; // fill it with the correct value
+ 	}
+ }
+ 
+ 
+ 
+ 

Index: MgaDeriveOps.cpp
===================================================================
RCS file: /project/gme-repository/GMESRC/GME/Mga/MgaDeriveOps.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** MgaDeriveOps.cpp	13 Oct 2004 15:17:55 -0000	1.2
--- MgaDeriveOps.cpp	30 Aug 2005 22:25:30 -0000	1.3
***************
*** 279,285 ****
  
  // ----------------------------------------
! // Attach/detach (unimplemented)
  // ----------------------------------------
! HRESULT FCO::DetachFromArcheType ()  { return E_MGA_NOT_IMPLEMENTED; };
  
  HRESULT FCO::AttachToArcheType( IMgaFCO *newtype,  VARIANT_BOOL instance) {
--- 279,305 ----
  
  // ----------------------------------------
! // Attach/detach (freshly implemented)
  // ----------------------------------------
! HRESULT FCO::DetachFromArcheType ()
! {
! 	COMTRY_IN_TRANSACTION {
! 		CheckWrite();
! 		CoreObj d = self[ATTRID_DERIVED], d2;
! 		if(d) { // if self is really derived from something (d)
! 			while((d2 = d[ATTRID_DERIVED]) != NULL) 
! 				d <<= d2;
! 
! 			// copy/merge/detach from parent to self (overwrite the derivation)
! 			// almost like ObjTreeCopy, copies from 'd' (the archetype) to 'self' (the derived)
! 			coreobjpairhash crealist2;
! 			ObjDetachAndMerge(mgaproject, d, self, crealist2, 0, true);
! 
! 		}
! 		SelfMark(OBJEVENT_SUBT_INST);
! 		CoreObjMark( self[ATTRID_PARENT], OBJEVENT_LOSTCHILD);
! 	} COMCATCH_IN_TRANSACTION(;);
! 
! 	return S_OK;
! }
  
  HRESULT FCO::AttachToArcheType( IMgaFCO *newtype,  VARIANT_BOOL instance) {



More information about the GME-commit mailing list