reman3/Rayman_X/cpa/tempgrp/ITF/cohemngr.cpp

1070 lines
34 KiB
C++

/*
*=======================================================================================
* 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