/* *======================================================================================= * Name :cohemngr.cpp * Author :VL Date :16/01/97 * Description : *======================================================================================= * Modification -> Author : VL Date : 26/05/97 * Description : * -> Links have now a weigth to allow multiple link * -> object linked are now CPA_BaseObject *======================================================================================= */ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #include "stdafx.h" /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #ifdef ACTIVE_EDITOR /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #include "itf/CMDlg.h" #include "itf/CoheMngr.hpp" /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* ======================================================================================= Globals ======================================================================================= */ CCoherenceManager g_oCoherenceManager; /* ======================================================================================= coherence manager class function ======================================================================================= */ /* ---------------------------------------------------------------------------------------- Description : constructor ---------------------------------------------------------------------------------------- */ CCoherenceManager::CCoherenceManager() { m_oChildMap.InitHashTable( 521 ); m_oFatherMap.InitHashTable( 521 ); m_oDeletedChildMap.InitHashTable( 521 ); m_oIncoherenceMap.InitHashTable( 521 ); // dialog box initialization m_p_oCMDlg = new (CCoherenceManagerDlg); m_p_oCMDlg->m_fn_vSetIncoherenceMap( &m_oIncoherenceMap ); m_p_oCMDlg->m_fn_vSetFatherMap( &m_oFatherMap ); m_p_oCMDlg->m_fn_vSetChildMap( &m_oChildMap ); m_p_oCMDlg->m_fn_vSetDeletedChildMap( &m_oDeletedChildMap ); m_bShowAlwaysDlg = FALSE; } /* ---------------------------------------------------------------------------------------- Description : destructor ---------------------------------------------------------------------------------------- */ CCoherenceManager::~CCoherenceManager() { m_fn_vRemoveAllChild( &m_oChildMap ); m_fn_vRemoveAllChild( &m_oDeletedChildMap ); m_fn_vRemoveAllFather( &m_oFatherMap ); m_fn_vRemoveAllFather( &m_oIncoherenceMap ); delete (m_p_oCMDlg); } /* ======================================================================================= private function : Find functions Delete functions ======================================================================================= */ /* ---------------------------------------------------------------------------------------- Description : find if an object is in father map (should be father map or incoherence map) ---------------------------------------------------------------------------------------- */ tdstFather *CCoherenceManager::m_fnp_stFindFather( CFatherMap *_p_oMap, CPA_BaseObject *_p_oFather ) { tdstFather *p_stFather; if (_p_oMap->Lookup( _p_oFather, p_stFather )) return p_stFather; return NULL; } /* ---------------------------------------------------------------------------------------- Description : find if an object is in child map ---------------------------------------------------------------------------------------- */ tdstChild *CCoherenceManager::m_fnp_stFindChild( CChildMap *_p_oMap, CPA_BaseObject *_p_oChild ) { tdstChild *p_stChild; if (_p_oMap->Lookup( _p_oChild, p_stChild )) return p_stChild; return NULL; } /* ---------------------------------------------------------------------------------------- Description : find if an object is in a CFatherList ---------------------------------------------------------------------------------------- */ tdstFather *CCoherenceManager::m_fnp_stFindFather( CFatherList *_p_oList, CPA_BaseObject *_p_oFather ) { POSITION xPos; tdstFather *p_stFather; xPos = _p_oList->GetHeadPosition(); while (xPos) { p_stFather = _p_oList->GetNext( xPos ); if (p_stFather->m_p_oFather == _p_oFather) return p_stFather; } return NULL; } /* ---------------------------------------------------------------------------------------- Description : find if an object is in a CChildList ---------------------------------------------------------------------------------------- */ tdstChild *CCoherenceManager::m_fnp_stFindChild( CChildList *_p_oList, CPA_BaseObject *_p_oChild ) { POSITION xPos; tdstChild *p_stChild; xPos = _p_oList->GetHeadPosition(); while (xPos) { p_stChild = _p_oList->GetNext( xPos ); if (p_stChild->m_p_oChild == _p_oChild ) return p_stChild; } return NULL; } /* ---------------------------------------------------------------------------------------- Description : find a child in a Linked child list _p_oList -> list to search for _p_stChild -> child to search Returns (tdstLinkedChild ) linked child found or NULL ---------------------------------------------------------------------------------------- */ tdstLinkedChild *CCoherenceManager::m_fnp_stFindLinkedChild( CLinkedChildList *_p_oList, tdstChild *_p_stChild) { POSITION xPos; tdstLinkedChild *p_stLinkedChild; xPos = _p_oList->GetHeadPosition(); while (xPos) { p_stLinkedChild = _p_oList->GetNext( xPos ); if (p_stLinkedChild->m_p_stChild == _p_stChild ) return p_stLinkedChild; } return NULL; } /* ---------------------------------------------------------------------------------------- Description : find a ReachableObject child in a Linked child list _p_oList -> list to search for _p_oChild -> child to search Returns (tdstLinkedChild ) linked child found or NULL ---------------------------------------------------------------------------------------- */ tdstLinkedChild *CCoherenceManager::m_fnp_stFindLinkedChild( CLinkedChildList *_p_oList, CPA_BaseObject *_p_oChild) { POSITION xPos; tdstLinkedChild *p_stLinkedChild; xPos = _p_oList->GetHeadPosition(); while (xPos) { p_stLinkedChild = _p_oList->GetNext( xPos ); if (p_stLinkedChild->m_p_stChild->m_p_oChild == _p_oChild ) return p_stLinkedChild; } return NULL; } /* ---------------------------------------------------------------------------------------- Description : say if a tdstFather struct is in a child's father list ---------------------------------------------------------------------------------------- */ BOOL CCoherenceManager::m_fn_bIsFather( CFatherList *_p_oList, tdstFather *_p_stFather ) { return ( _p_oList->Find( _p_stFather ) != NULL ); } /* ---------------------------------------------------------------------------------------- Description : say if a tdstChild struct is in a father's child list ---------------------------------------------------------------------------------------- */ BOOL CCoherenceManager::m_fn_bIsChild ( CChildList *_p_oList, tdstChild *_p_stChild ) { return ( _p_oList->Find( _p_stChild ) != NULL ); } /* ---------------------------------------------------------------------------------------- Description : say if a tdstChild struct is in a father's linked child list ---------------------------------------------------------------------------------------- */ BOOL CCoherenceManager::m_fn_bIsChild ( CLinkedChildList *_p_oList, tdstChild *_p_stChild ) { return ( m_fnp_stFindLinkedChild( _p_oList, _p_stChild) != NULL ); } /* ---------------------------------------------------------------------------------------- Description : delete all Father in a father map ---------------------------------------------------------------------------------------- */ void CCoherenceManager::m_fn_vRemoveAllFather( CFatherMap *_p_oMap ) { POSITION xPos; tdstFather *p_stFather; CPA_BaseObject *p_oObject; POSITION xPosChild; tdstLinkedChild *p_stLinkedChild; xPos = _p_oMap->GetStartPosition(); while ( xPos ) { _p_oMap->GetNextAssoc( xPos, p_oObject, p_stFather ); // delete all tdstLinkedChild structure xPosChild = p_stFather->m_oChildList.GetHeadPosition(); while (xPosChild) { p_stLinkedChild = p_stFather->m_oChildList.GetNext(xPosChild); delete p_stLinkedChild; } // emptied child list p_stFather->m_oChildList.RemoveAll(); delete( p_stFather ); } _p_oMap->RemoveAll(); } /* ---------------------------------------------------------------------------------------- Description : delete all child in a child map ---------------------------------------------------------------------------------------- */ void CCoherenceManager::m_fn_vRemoveAllChild( CChildMap *_p_oMap ) { POSITION xPos; tdstChild *p_stChild; CPA_BaseObject *p_oObject; xPos = _p_oMap->GetStartPosition(); while ( xPos ) { _p_oMap->GetNextAssoc( xPos, p_oObject, p_stChild ); p_stChild->m_oFatherList.RemoveAll(); delete( p_stChild ); } _p_oMap->RemoveAll(); } /* ---------------------------------------------------------------------------------------- Description : detach all child from his father ---------------------------------------------------------------------------------------- */ void CCoherenceManager::m_fn_vDetachAllChild( tdstFather *_p_stFather, CChildMap *_p_oChildMap ) { POSITION xPos; POSITION xFatherPos; tdstChild *p_stChild; tdstLinkedChild *p_stLinkedChild; // for each child xPos = _p_stFather->m_oChildList.GetHeadPosition(); while (xPos) { //p_stChild = _p_stFather->m_oChildList.GetNext( xPos ); p_stLinkedChild = _p_stFather->m_oChildList.GetNext( xPos ); p_stChild = p_stLinkedChild->m_p_stChild; // find father position in list and delete it xFatherPos = p_stChild->m_oFatherList.Find( _p_stFather ); p_stChild->m_oFatherList.RemoveAt( xFatherPos ); // if no more links, delete object from child list if (p_stChild->m_oFatherList.IsEmpty()) { _p_oChildMap->RemoveKey( p_stChild->m_p_oChild ); delete( p_stChild ); } } // no more child for this father _p_stFather->m_oChildList.RemoveAll(); } /* ---------------------------------------------------------------------------------------- Description : detach all father of this object (in reality transfert links in DeletedChildMap and Incoherence Map ) return TRUE if father was really Detached ---------------------------------------------------------------------------------------- */ BOOL CCoherenceManager::m_fn_bDetachAllFather( tdstChild *_p_stChild, char _cChildState ) { POSITION xPos; POSITION xChildPos; tdstFather *p_stSourceFather; tdstFather *p_stTargetFather; CFatherList m_oTempList; CFatherMap *p_oSourceMap = (_cChildState == C_cChildIsRestored)?&m_oIncoherenceMap:&m_oFatherMap; CFatherMap *p_oTargetMap = (_cChildState == C_cChildIsRestored)?&m_oFatherMap:&m_oIncoherenceMap; tdstLinkedChild *p_stLinkedChild; BOOL bResult; BOOL bCreated; BOOL bAdd; xPos = _p_stChild->m_oFatherList.GetHeadPosition(); while ( xPos ) { // for each father in child list p_stSourceFather = _p_stChild->m_oFatherList.GetNext( xPos ); // look if this father is not in target map if ( !p_oTargetMap->Lookup( p_stSourceFather->m_p_oFather, p_stTargetFather ) ) { // create a new father to put in target list p_stTargetFather = new(tdstFather); p_stTargetFather->m_p_oFather = p_stSourceFather->m_p_oFather; (*p_oTargetMap)[ p_stSourceFather->m_p_oFather ] = p_stTargetFather; bCreated = TRUE; } else { bCreated = FALSE; } bAdd = TRUE; // find child in source father p_stLinkedChild = m_fnp_stFindLinkedChild( &p_stSourceFather->m_oChildList, _p_stChild ); // delete child in source father child list xChildPos = p_stSourceFather->m_oChildList.Find( p_stLinkedChild ); p_stSourceFather->m_oChildList.RemoveAt( xChildPos ); // remove source father if it's empty if (p_stSourceFather->m_oChildList.IsEmpty() && p_stSourceFather->m_oDestroyedChildList.IsEmpty() ) { p_oSourceMap->RemoveKey( p_stSourceFather->m_p_oFather ); delete(p_stSourceFather); } // transfert child to target father if (_cChildState == C_cChildIsRestored) { //p_stTargetFather->m_oChildList.AddTail( _p_stChild ); p_stTargetFather->m_oChildList.AddTail( p_stLinkedChild ); p_stTargetFather->m_p_oFather->GetEditor()->fn_vOnRestoreLink( p_stTargetFather->m_p_oFather, _p_stChild->m_p_oChild); } else { if (_cChildState == C_cChildIsDeleted) { //p_stTargetFather->m_oChildList.AddTail( _p_stChild ); p_stTargetFather->m_oChildList.AddTail( p_stLinkedChild ); } else { char *szName = (char *) malloc ( strlen( _p_stChild->m_p_oChild->GetName() ) + 1 ); strcpy ( szName, _p_stChild->m_p_oChild->GetName() ); p_stTargetFather->m_oDestroyedChildList.AddHead( szName ); } if (p_stTargetFather->m_p_oFather->GetEditor()->fn_bOnInvalidateLink(p_stTargetFather->m_p_oFather, _p_stChild->m_p_oChild, (_cChildState == C_cChildIsDestroyed))) { if (_cChildState == C_cChildIsDeleted) p_stTargetFather->m_oChildList.RemoveTail(); else p_stTargetFather->m_oDestroyedChildList.RemoveTail(); if (bCreated) { delete p_stTargetFather; p_oTargetMap->RemoveKey( p_stTargetFather->m_p_oFather ); bAdd = FALSE; } } } if (bAdd) m_oTempList.AddTail( p_stTargetFather ); } _p_stChild->m_oFatherList.RemoveAll(); _p_stChild->m_oFatherList.AddHead( &m_oTempList ); bResult = !m_oTempList.IsEmpty(); m_oTempList.RemoveAll(); return bResult; } /* ======================================================================================= public function ======================================================================================= */ /* ---------------------------------------------------------------------------------------- Description : return true if given object is in list of Incoherent object ---------------------------------------------------------------------------------------- */ BOOL CCoherenceManager::m_fn_bIsIncoherent( CPA_BaseObject *_p_oFather ) { tdstFather *p_stFather; return m_oIncoherenceMap.Lookup( _p_oFather, p_stFather ); } /* ---------------------------------------------------------------------------------------- Description : return true if given object is in list of Father object ---------------------------------------------------------------------------------------- */ BOOL CCoherenceManager::m_fn_bIsFather( CPA_BaseObject *_p_oFather ) { tdstFather *p_stFather; return m_oFatherMap.Lookup( _p_oFather, p_stFather ); } /* ---------------------------------------------------------------------------------------- Description : return true if given object is in list of Child object ---------------------------------------------------------------------------------------- */ BOOL CCoherenceManager::m_fn_bIsChild( CPA_BaseObject *_p_oChild ) { tdstChild *p_stChild; return m_oChildMap.Lookup( _p_oChild, p_stChild ); } /* ---------------------------------------------------------------------------------------- Description : returns number of childs for this father ---------------------------------------------------------------------------------------- */ int CCoherenceManager::m_fn_iGetChildCount( CPA_BaseObject *_p_oFather ) { tdstFather *p_stFather; if ( !m_oFatherMap.Lookup( _p_oFather, p_stFather ) ) return 0; return p_stFather->m_oChildList.GetCount(); } /* ---------------------------------------------------------------------------------------- Description : add in given list all child of given father, returns number of object added in list ---------------------------------------------------------------------------------------- */ int CCoherenceManager::m_fn_iGetChildList( CPA_BaseObject *_p_oFather, CList< CPA_BaseObject *, CPA_BaseObject *> *_p_oChildList ) { POSITION xPos; tdstFather *p_stFather; tdstLinkedChild *p_stLinkedChild; if (!m_oFatherMap.Lookup( _p_oFather, p_stFather )) return 0; xPos = p_stFather->m_oChildList.GetHeadPosition(); while (xPos) { p_stLinkedChild = p_stFather->m_oChildList.GetNext( xPos ); _p_oChildList->AddTail( p_stLinkedChild->m_p_stChild->m_p_oChild ); } return p_stFather->m_oChildList.GetCount(); } /* ---------------------------------------------------------------------------------------- Description : add in given list the deleted child of given father. returns number of object added in list ---------------------------------------------------------------------------------------- */ int CCoherenceManager::m_fn_iGetDeletedChildList( CPA_BaseObject *_p_oFather, CList< CPA_BaseObject *, CPA_BaseObject *> *_p_oDeletedChildList ) { POSITION xPos; tdstFather *p_stFather; tdstLinkedChild *p_stLinkedChild; if (!m_oIncoherenceMap.Lookup( _p_oFather, p_stFather )) return 0; xPos = p_stFather->m_oChildList.GetHeadPosition(); while (xPos) { p_stLinkedChild = p_stFather->m_oChildList.GetNext( xPos ); _p_oDeletedChildList->AddTail( p_stLinkedChild->m_p_stChild->m_p_oChild ); } return (p_stFather->m_oChildList.GetCount()); } /* ---------------------------------------------------------------------------------------- Description : add in given list the name of destroyed child of given father. returns number of object added in list ---------------------------------------------------------------------------------------- */ int CCoherenceManager::m_fn_iGetDestroyedChildNameList( CPA_BaseObject *_p_oFather, CList< char *, char *> *_p_oDestroyedChildNameList ) { tdstFather *p_stFather; if (!m_oIncoherenceMap.Lookup( _p_oFather, p_stFather )) return 0; _p_oDestroyedChildNameList->AddTail( &p_stFather->m_oDestroyedChildList ); return (p_stFather->m_oChildList.GetCount()); } /* ---------------------------------------------------------------------------------------- Description : returns number of fathers for the child ---------------------------------------------------------------------------------------- */ int CCoherenceManager::m_fn_iGetFatherCount( CPA_BaseObject *_p_oChild ) { tdstChild *p_stChild; if (!m_oChildMap.Lookup( _p_oChild, p_stChild )) return 0; return p_stChild->m_oFatherList.GetCount(); } /* ---------------------------------------------------------------------------------------- Description : add in given list the father of given child object returns number of object added in list ---------------------------------------------------------------------------------------- */ int CCoherenceManager::m_fn_iGetFatherList( CPA_BaseObject *_p_oChild, CList< CPA_BaseObject *, CPA_BaseObject *> *_p_oFatherList ) { POSITION xPos; tdstChild *p_stChild; tdstFather *p_stFather; if (!m_oChildMap.Lookup( _p_oChild, p_stChild )) return 0; xPos = p_stChild->m_oFatherList.GetHeadPosition(); while (xPos) { p_stFather = p_stChild->m_oFatherList.GetNext( xPos ); _p_oFatherList->AddTail( p_stFather->m_p_oFather ); } return (p_stChild->m_oFatherList.GetCount()); } /* ---------------------------------------------------------------------------------------- Description : add in given list the invalid father of given child object returns number of object added in list ---------------------------------------------------------------------------------------- */ int CCoherenceManager::m_fn_iGetInvalidFatherList( CPA_BaseObject *_p_oChild, CList< CPA_BaseObject *, CPA_BaseObject *> *_p_oInvalidFatherList ) { POSITION xPos; tdstChild *p_stChild; tdstFather *p_stFather; if (!m_oDeletedChildMap.Lookup( _p_oChild, p_stChild )) return 0; xPos = p_stChild->m_oFatherList.GetHeadPosition(); while (xPos) { p_stFather = p_stChild->m_oFatherList.GetNext( xPos ); _p_oInvalidFatherList->AddTail( p_stFather->m_p_oFather ); } return (p_stChild->m_oFatherList.GetCount()); } /* ---------------------------------------------------------------------------------------- Description : dump list in a file ---------------------------------------------------------------------------------------- */ void CCoherenceManager::m_fn_vDumpListsInFile( char *_szFile ) { FILE *hpFile; POSITION xPos; POSITION xPosList; CPA_BaseObject *p_oObject; tdstFather *p_stFather; tdstChild *p_stChild; tdstLinkedChild *p_stLinkedChild; char *szName; if ( (hpFile = fopen( _szFile, "at")) == NULL) return; fprintf( hpFile, "*******************************\n"); fprintf( hpFile, "******* Dumping Lists *********\n"); fprintf( hpFile, "*******************************\n"); // display Child map fprintf( hpFile, "**** Dumping Child list *******\n"); xPos = m_oChildMap.GetStartPosition(); while ( xPos ) { m_oChildMap.GetNextAssoc( xPos, p_oObject, p_stChild ); fprintf(hpFile, "Child : %s\n", p_oObject->GetName() ); xPosList = p_stChild->m_oFatherList.GetHeadPosition(); while (xPosList) { p_stFather = p_stChild->m_oFatherList.GetNext( xPosList ); fprintf(hpFile, " %s\n", p_stFather->m_p_oFather->GetName() ); } } // display Father map fprintf( hpFile, "**** Dumping Father list *******\n"); xPos = m_oFatherMap.GetStartPosition(); while ( xPos ) { m_oFatherMap.GetNextAssoc( xPos, p_oObject, p_stFather ); fprintf(hpFile, "Father : %s (%X)\n", p_oObject->GetName() , p_oObject->GetEditor()->GetCurrentEditorName() ); xPosList = p_stFather->m_oChildList.GetHeadPosition(); while (xPosList) { p_stLinkedChild = p_stFather->m_oChildList.GetNext( xPosList ); fprintf(hpFile, " %s\n", p_stLinkedChild->m_p_stChild->m_p_oChild->GetName() ); } } // display deleted Child map fprintf( hpFile, "**** Dumping Deleted Child list *******\n"); xPos = m_oDeletedChildMap.GetStartPosition(); while ( xPos ) { m_oDeletedChildMap.GetNextAssoc( xPos, p_oObject, p_stChild ); fprintf(hpFile, "Child : %s\n", p_oObject->GetName() ); xPosList = p_stChild->m_oFatherList.GetHeadPosition(); while (xPosList) { p_stFather = p_stChild->m_oFatherList.GetNext( xPosList ); fprintf(hpFile, " %s\n", p_stFather->m_p_oFather->GetName() ); } } // display Incoherent map fprintf( hpFile, "**** Dumping Incoherence list *******\n"); xPos = m_oIncoherenceMap.GetStartPosition(); while ( xPos ) { m_oIncoherenceMap.GetNextAssoc( xPos, p_oObject, p_stFather ); fprintf(hpFile, "Father : %s (%X)\n", p_oObject->GetName() , p_oObject->GetEditor()->GetCurrentEditorName() ); xPosList = p_stFather->m_oChildList.GetHeadPosition(); while (xPosList) { p_stLinkedChild = p_stFather->m_oChildList.GetNext( xPosList ); fprintf(hpFile, " %s\n", p_stLinkedChild->m_p_stChild->m_p_oChild->GetName()); } // write destroyed child xPosList = p_stFather->m_oDestroyedChildList.GetHeadPosition(); while (xPosList) { szName = p_stFather->m_oDestroyedChildList.GetNext( xPosList ); fprintf(hpFile, " %s (d)", szName ); } } fclose(hpFile); } /* ---------------------------------------------------------------------------------------- Description : Add a link in list ---------------------------------------------------------------------------------------- */ void CCoherenceManager::m_fn_vAddALink( CPA_BaseObject *_p_oFather, CPA_BaseObject *_p_oChild ) { tdstFather *p_stFather = m_fnp_stFindFather( &m_oFatherMap, _p_oFather ); tdstChild *p_stChild = m_fnp_stFindChild ( &m_oChildMap, _p_oChild ); tdstLinkedChild *p_stLinkedChild; BOOL bFatherExist = (p_stFather != NULL); BOOL bChildExist = (p_stChild != NULL ); // verify or create father structure if (!bFatherExist) { p_stFather = new(tdstFather); p_stFather->m_p_oFather = _p_oFather; m_oFatherMap[ _p_oFather ] = p_stFather; } // create child struct if child doesn't exist if(!bChildExist) { p_stChild = new(tdstChild); p_stChild->m_p_oChild = _p_oChild; m_oChildMap[ _p_oChild ] = p_stChild; } // add link in Father map p_stLinkedChild = m_fnp_stFindLinkedChild( &p_stFather->m_oChildList, p_stChild ); if (p_stLinkedChild != NULL) { p_stLinkedChild->m_ulLinkWeight++; } else { p_stLinkedChild = new tdstLinkedChild; p_stLinkedChild->m_p_stChild = p_stChild; p_stLinkedChild->m_ulLinkWeight = 1; p_stFather->m_oChildList.AddTail( p_stLinkedChild ); p_stChild->m_oFatherList.AddTail( p_stFather ); } } /* ---------------------------------------------------------------------------------------- Description : remove a given number of link ---------------------------------------------------------------------------------------- */ void CCoherenceManager::m_fn_vRemoveLinks( CPA_BaseObject *_p_oFather, CPA_BaseObject *_p_oChild, unsigned long _ulNbLinkRemoved ) { tdstChild *p_stChild; tdstLinkedChild *p_stLinkedChild; tdstFather *p_stFather; BOOL bDeleted = FALSE; POSITION xPos; // search child in valid child list if ( (p_stChild = m_fnp_stFindChild( &m_oChildMap, _p_oChild )) == NULL) { // search child in deleted child list if ( (p_stChild = m_fnp_stFindChild( &m_oDeletedChildMap, _p_oChild )) == NULL) return; else { // child is a deleted child, find father in incoherence map p_stFather = m_fnp_stFindFather( &m_oIncoherenceMap, _p_oFather ); bDeleted = TRUE; } } else { // child is valid, find father in valid father map p_stFather = m_fnp_stFindFather( &m_oFatherMap, _p_oFather ); } if (p_stFather == NULL) return; // no link found // search in father the linked child if ( (p_stLinkedChild = m_fnp_stFindLinkedChild( &p_stFather->m_oChildList, p_stChild)) == NULL) return; // remove a link if (_ulNbLinkRemoved == 0) p_stLinkedChild->m_ulLinkWeight = 0; else p_stLinkedChild->m_ulLinkWeight -= _ulNbLinkRemoved; if (p_stLinkedChild->m_ulLinkWeight <= 0) { // no more link between the two object, delete child from father list and father from child list // delete father in child list xPos = p_stChild->m_oFatherList.Find( p_stFather ); if (xPos) { p_stChild->m_oFatherList.RemoveAt( xPos ); if (p_stChild->m_oFatherList.IsEmpty()) { if (bDeleted) m_oDeletedChildMap.RemoveKey( _p_oChild ); else m_oChildMap.RemoveKey( _p_oChild ); } } // delete child in father list xPos = p_stFather->m_oChildList.Find( p_stLinkedChild ); if (xPos) { p_stFather->m_oChildList.RemoveAt( xPos ); if (p_stFather->m_oChildList.IsEmpty() && p_stFather->m_oDestroyedChildList.IsEmpty() ) { if (bDeleted) m_oIncoherenceMap.RemoveKey( _p_oFather ); else m_oFatherMap.RemoveKey( _p_oFather ); } delete p_stLinkedChild; } } } /* ---------------------------------------------------------------------------------------- Description : remove a given number of link ---------------------------------------------------------------------------------------- */ void CCoherenceManager::m_fn_vRemoveALink( CPA_BaseObject *_p_oFather, CPA_BaseObject *_p_oChild ) { m_fn_vRemoveLinks( _p_oFather, _p_oChild, 1 ); } /* ---------------------------------------------------------------------------------------- Description : remove all links between two objects _p_oFather -> father object of link to remove _p_oChild -> child object of link to remove ---------------------------------------------------------------------------------------- */ void CCoherenceManager::m_fn_vRemoveAllLinks( CPA_BaseObject *_p_oFather, CPA_BaseObject *_p_oChild ) { m_fn_vRemoveLinks( _p_oFather, _p_oChild, 0 ); } /* ---------------------------------------------------------------------------------------- Description : remove all that attach an object with another one _p_oObject -> object to detach _cLinkType -> possible value are C_cLinkedAsValidChild -> remove all links were object is child C_cLinkedAsDeletedChild -> remove all links were object is deleted child C_cLinkedAsChild -> remove all links were object is child (valid or deleted) C_cLinkedAsValidFather -> remove all links were object is a valid father C_cLinkedAsIncoherentFather -> remove all links were object is a incoherent father C_cLinkedAsFather -> remove all links were object is father (valid or incoherent) C_cLinkedAsChildAndFather -> remove all links ---------------------------------------------------------------------------------------- */ void CCoherenceManager::m_fn_vRemoveAllLinks( CPA_BaseObject *_p_oObject, char _cLinkType ) { POSITION xPos; tdstChild *p_stChild; tdstFather *p_stFather; tdstLinkedChild *p_stLinkedChild; /* * delete links were object is a child */ if (_cLinkType & C_cLinkedAsValidChild) { if ( (p_stChild = m_fnp_stFindChild( &m_oChildMap, _p_oObject )) != NULL) { xPos = p_stChild->m_oFatherList.GetHeadPosition(); while (xPos) { p_stFather = p_stChild->m_oFatherList.GetNext( xPos ); m_fn_vRemoveAllLinks( p_stFather->m_p_oFather, _p_oObject ); } } } /* * delete links were object is a deleted child */ if (_cLinkType & C_cLinkedAsDeletedChild) { if ( (p_stChild = m_fnp_stFindChild( &m_oDeletedChildMap, _p_oObject )) != NULL) { xPos = p_stChild->m_oFatherList.GetHeadPosition(); while (xPos) { p_stFather = p_stChild->m_oFatherList.GetNext( xPos ); m_fn_vRemoveAllLinks( p_stFather->m_p_oFather, _p_oObject ); } } } /* * delete links were object is a father */ if (_cLinkType & C_cLinkedAsValidFather) { if ( (p_stFather = m_fnp_stFindFather( &m_oFatherMap, _p_oObject )) != NULL) { xPos = p_stFather->m_oChildList.GetHeadPosition(); while (xPos) { p_stLinkedChild = p_stFather->m_oChildList.GetNext( xPos ); m_fn_vRemoveAllLinks( _p_oObject, p_stLinkedChild->m_p_stChild->m_p_oChild); } } } /* * delete links were object is an incoherent father */ if (_cLinkType & C_cLinkedAsIncoherentFather) { if ( (p_stFather = m_fnp_stFindFather( &m_oIncoherenceMap, _p_oObject )) != NULL) { xPos = p_stFather->m_oChildList.GetHeadPosition(); while (xPos) { p_stLinkedChild = p_stFather->m_oChildList.GetNext( xPos ); m_fn_vRemoveAllLinks( _p_oObject, p_stLinkedChild->m_p_stChild->m_p_oChild); } } } } /* ---------------------------------------------------------------------------------------- Description : return number of links between two object ---------------------------------------------------------------------------------------- */ unsigned long CCoherenceManager::m_fn_ulGetLinkWeight( CPA_BaseObject *_p_oFather, CPA_BaseObject *_p_oChild) { tdstFather *p_stFather = m_fnp_stFindFather( &m_oFatherMap, _p_oFather ); tdstLinkedChild *p_stLinkedChild; if (p_stFather == NULL) return 0; if ( (p_stLinkedChild = m_fnp_stFindLinkedChild( &p_stFather->m_oChildList, _p_oChild)) == NULL) return 0; return p_stLinkedChild->m_ulLinkWeight; } /* ---------------------------------------------------------------------------------------- Description : Delete an object ---------------------------------------------------------------------------------------- */ void CCoherenceManager::m_fn_vDeleteObject( CPA_BaseObject *_p_oObject ) { tdstFather *p_stFather; tdstChild *p_stChild; // first: erase all link between this object as father and his child if ( (p_stFather = m_fnp_stFindFather( &m_oFatherMap, _p_oObject )) != NULL) { m_fn_vDetachAllChild( p_stFather, &m_oChildMap ); m_oFatherMap.RemoveKey( _p_oObject ); delete( p_stFather ); } // second : Erase all incoherence with this object if ( (p_stFather = m_fnp_stFindFather( &m_oIncoherenceMap, _p_oObject )) != NULL) { m_fn_vDetachAllChild( p_stFather, &m_oDeletedChildMap ); m_oIncoherenceMap.RemoveKey( _p_oObject ); delete(p_stFather); } // third : put all parent of this object in incoherent list if ( (p_stChild = m_fnp_stFindChild (&m_oChildMap, _p_oObject)) != NULL) { BOOL bIncoherence; bIncoherence = m_fn_bDetachAllFather( p_stChild, C_cChildIsDeleted ); m_oChildMap.RemoveKey( _p_oObject ); m_oDeletedChildMap[_p_oObject] = p_stChild; if (bIncoherence && m_bShowAlwaysDlg) m_fn_vShowIncoherence(); } } /* ---------------------------------------------------------------------------------------- Description : Restore an object ---------------------------------------------------------------------------------------- */ void CCoherenceManager::m_fn_vRestoreObject( CPA_BaseObject *_p_oObject ) { tdstChild *p_stChild; if ( (p_stChild = m_fnp_stFindChild (&m_oDeletedChildMap, _p_oObject)) != NULL) { m_fn_bDetachAllFather( p_stChild, C_cChildIsRestored); m_oDeletedChildMap.RemoveKey( _p_oObject ); m_oChildMap[_p_oObject] = p_stChild; } } /* ---------------------------------------------------------------------------------------- Description : Destroy an object ---------------------------------------------------------------------------------------- */ void CCoherenceManager::m_fn_vDestroyObject( CPA_BaseObject *_p_oObject ) { tdstFather *p_stFather; tdstChild *p_stChild; // first: erase all link between this object as father and his child if ( (p_stFather = m_fnp_stFindFather( &m_oFatherMap, _p_oObject )) != NULL) { m_fn_vDetachAllChild( p_stFather, &m_oChildMap ); m_oFatherMap.RemoveKey( _p_oObject ); delete( p_stFather ); } // second : Erase all incoherence with this object if ( (p_stFather = m_fnp_stFindFather( &m_oIncoherenceMap, _p_oObject )) != NULL) { m_fn_vDetachAllChild( p_stFather, &m_oDeletedChildMap ); m_oIncoherenceMap.RemoveKey( _p_oObject ); delete(p_stFather); } // third : put all parent of this object in incoherent list if ( (p_stChild = m_fnp_stFindChild (&m_oChildMap, _p_oObject)) != NULL) { BOOL bIncoherence; bIncoherence = m_fn_bDetachAllFather( p_stChild, C_cChildIsDestroyed ); m_oChildMap.RemoveKey( _p_oObject ); if (bIncoherence && m_bShowAlwaysDlg) m_fn_vShowIncoherence(); } } /* ---------------------------------------------------------------------------------------- Description : Modify an object ( notify all father ) ---------------------------------------------------------------------------------------- */ void CCoherenceManager::m_fn_vNotifyObjectModification( CPA_BaseObject *_p_oObject, unsigned long _ulData ) { tdstChild *p_stChild; tdstFather *p_stFather; POSITION xPos; if ( (p_stChild = m_fnp_stFindChild( &m_oChildMap, _p_oObject )) != NULL) { xPos = p_stChild->m_oFatherList.GetHeadPosition(); while (xPos) { p_stFather = p_stChild->m_oFatherList.GetNext( xPos ); if ( (p_stFather != NULL) && (p_stFather->m_p_oFather != NULL) ) { p_stFather->m_p_oFather->GetEditor()->fn_vOnModifyChild( p_stFather->m_p_oFather, _p_oObject, _ulData ); } } } } /* ---------------------------------------------------------------------------------------- Description : Show all incoherence in a dialog box ---------------------------------------------------------------------------------------- */ void CCoherenceManager::m_fn_vShowIncoherence( void ) { m_p_oCMDlg->DoModal(); } #endif // ACTIVE_EDITOR