[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