reman3/Rayman_X/cpa/tempgrp/TAc/src/CPAAction.cpp

727 lines
28 KiB
C++

/*=============================================================================
*
* Filename: CPAAction.cpp
* Version: 1.0
* Date: 30/12/96
* Author: Marc Trabucato & V.L.
*
* Description: implementation of CPA_Action class
* (this is a derivation of CPA_SaveObject)
*
*===========================================================================*/
#ifdef ACTIVE_EDITOR
//MFC
#include "stdafx.h"
//ACP
#include "ACP_Base.h"
#include "ITF.h"
#include "x:\cpa\main\inc\_editid.h"
#include "DPT.h"
#include "TAC.h"
#include "TFa.h"
#include "OAC.h"
#include "ACInterf.hpp"
/******************************************************************************
* Macros
******************************************************************************/
#define M_GetFamily() ((CPA_Family*)GetOwner())
/*-----------------------------------------------------------------------------
* Constructor
*---------------------------------------------------------------------------*/
CPA_Action::CPA_Action( CPA_EditorBase *p_oEditor, CPA_BaseObject *_p_oOwnerFamily, CString _csActionName )
:CPA_SaveObject( p_oEditor, C_szActionTypeName, E_ss_Responsible, _p_oOwnerFamily, TRUE, fn_szGetFamiliesDataPath(),
CPA_Action::mfn_vCallBackSave )
{
ASSERT( _p_oOwnerFamily );
// Section Name & Section File Name
char szFileName[SCR_CV_ui_Cfg_MaxLenName];
char szReferencedSectionName[SCR_CV_ui_Cfg_MaxLenName];
strcpy( szFileName, _p_oOwnerFamily -> fn_p_szGetName() );
strcat( szFileName, "\\" );
strcat( szFileName, _p_oOwnerFamily -> fn_p_szGetName() );
strcat( szFileName, ".ace" );
SCR_fn_v_RdL0_ComputeSectionName( szReferencedSectionName, szFileName, C_szActionSectionName, "" );
SetReferencedSectionName( szReferencedSectionName );
SetSectionData( this );
SetExistingSection( FALSE );
m_p_oDefaultState = NULL;
// Name
if( fn_eRename( _csActionName ) != E_mc_None )
SetDefaultValidName( _csActionName );
fn_vUpdateSectionName();
m_oListOfStates.RemoveAll();
// about saving
m_oListOfStatesInterrupted . RemoveAll();
}
/******************************************************************************
* Static function : call back for SCRIPT analysis
******************************************************************************/
/*-----------------------------------------------------------------------------
* Description : callback for Edit-CreateNewAction section in .EAC file
*---------------------------------------------------------------------------*/
SCR_tde_Anl_ReturnValue CPA_Action::fn_AddNewAction( SCR_tdst_File_Description *_p_stFile, char *_p_szName,
char *_ap_szParams[], SCR_tde_Anl_Action _eAction )
{
CPA_DLLBase *p_oDLL;
CPA_Family *p_oFamily;
CPA_Action *p_oAction;
CPA_State *p_oState;
CPA_Interface *p_oInterface;
BOOL bPreviousLoadingWorld;
SCR_M_RdL0_GetContextLong(0, 0, CPA_Family*, p_oFamily);
p_oDLL = p_oFamily -> GetMainWorld() -> GetToolDLLWithName( C_szDLLActionName );
p_oInterface = p_oFamily -> GetMainWorld() -> GetInterface();
bPreviousLoadingWorld = p_oInterface -> fn_bIsLoadingWorld();
switch (_eAction)
{
case SCR_EA_Anl_BeginSection:
// create editor action
p_oInterface -> SetLoadingWorld( TRUE );
p_oAction = new CPA_Action ( p_oDLL, p_oFamily, _p_szName );
p_oInterface -> SetLoadingWorld( bPreviousLoadingWorld );
p_oAction -> SetExistingSection( TRUE );
p_oFamily -> mfn_vAddAction( p_oAction );
SCR_M_RdL0_SetSectionLong( 0, 0, p_oAction );
break;
case SCR_EA_Anl_Entry:
// load Action Content
SCR_M_RdL0_GetSectionLong(0, 0, CPA_Action*, p_oAction);
p_oInterface -> SetLoadingWorld( TRUE );
if( !strcmpi(_p_szName,"Initial") )
{
// set as initial action of family
p_oFamily -> mfn_vSetInitialAction( p_oAction );
}
else if( !strcmpi(_p_szName,"AddState") )
{
// add editor state
p_oState = p_oAction -> mfn_p_oCreateNewState( _ap_szParams[0] );
}
else if ( !strcmpi(_p_szName,"AddDefaultState") )
{
// add default editor state
p_oState = p_oAction -> mfn_p_oCreateNewState( _ap_szParams[0] );
p_oAction -> mfn_vSetDefaultState( p_oState, TRUE );
}
else if ( !strcmpi(_p_szName,"AddTransitionalState") )
{
// add editor transitional state
p_oState = p_oAction -> mfn_p_oCreateNewState( _ap_szParams[0] );
p_oState -> mfn_vSetTransitional( TRUE , FALSE );
}
p_oInterface -> SetLoadingWorld( bPreviousLoadingWorld );
break;
case SCR_EA_Anl_EndSection:
SCR_M_RdL0_GetSectionLong(0, 0, CPA_Action*, p_oAction);
// init default state
if( ! p_oAction -> mfn_p_oGetDefaultState () )
p_oAction -> mfn_vSetDefaultState ( NULL , TRUE ) ;
// CPA_Ed_1 Mihaela Tancu begin
//p_oAction->mfn_vSetListOfStates(); //sort the list with states at the loading
// CPA_Ed_1 Mihaela Tancu end
break;
}
return SCR_ERV_Anl_NormalReturn;
}
/*-----------------------------------------------------------------------------
* Description : save action on SCRIPT File .EAC (actuellement .ace)
*---------------------------------------------------------------------------*/
void CPA_Action::mfn_vCallBackSave( SCR_tdst_File_Description *_p_stActionFile, char *_p_szSectionName,
void *_p_vData, SCR_tde_Ntfy_Action _eAction)
{
CPA_Action *p_oAction = (CPA_Action*)_p_vData;
char szActionName[SCR_CV_ui_Cfg_MaxLenName];
char szIdName[SCR_CV_ui_Cfg_MaxLenName];
char szSectionName[SCR_CV_ui_Cfg_MaxLenName];
POSITION stPos;
switch ( _eAction )
{
case SCR_EA_Ntfy_AddSection:
SCR_fn_v_SvL1_ToEndSection( _p_stActionFile );
case SCR_EA_Ntfy_RebuildSection:
// construct section name
SCR_fn_v_RdL0_SplitSectionName( _p_szSectionName, NULL, szActionName, szIdName );
SCR_fn_v_RdL0_ComputeSectionName( szSectionName, NULL, szActionName, szIdName );
// save begin section
SCR_M_SvL0_SaveBeginSection( _p_stActionFile, szSectionName, SCR_CC_C_Cfg_EOL );
// initial action ????
if( p_oAction == ((CPA_Family*)p_oAction->GetOwner())->mfn_p_oGetInitialAction() )
SCR_M_SvL0_SaveEntry( _p_stActionFile, "Initial", SCR_CC_C_Cfg_EOL );
// save states
stPos = p_oAction -> m_oListOfStates . GetHeadPosition () ;
while ( stPos )
{
CPA_State *p_oState = p_oAction -> m_oListOfStates . GetNext ( stPos ) ;
if( p_oState == p_oAction -> m_p_oDefaultState )
{
SCR_M_SvL0_SaveEntry( _p_stActionFile, "AddDefaultState", SCR_CC_C_Cfg_NoChar );
SCR_fn_v_SvL0_SaveParameters_MP( _p_stActionFile, SCR_EF_SvL0_Normal, 1, p_oState -> fn_p_szGetName() );
}
else if( p_oState -> mfn_bGetTransitional() )
{
SCR_M_SvL0_SaveEntry( _p_stActionFile, "AddTransitionalState", SCR_CC_C_Cfg_NoChar );
SCR_fn_v_SvL0_SaveParameters_MP( _p_stActionFile, SCR_EF_SvL0_Normal, 1, p_oState -> fn_p_szGetName() );
}
else
{
SCR_M_SvL0_SaveEntry( _p_stActionFile, "AddState", SCR_CC_C_Cfg_NoChar );
SCR_fn_v_SvL0_SaveParameters_MP( _p_stActionFile, SCR_EF_SvL0_Normal, 1, p_oState -> fn_p_szGetName() );
}
}
// End Section
SCR_M_SvL0_SaveEndSection( _p_stActionFile, SCR_CC_C_Cfg_EOL ) ;
SCR_M_SvL0_SaveBlankLine( _p_stActionFile ) ;
// update Section name
p_oAction -> fn_vSectionSaved();
break;
case SCR_EA_Ntfy_DeleteSection:
p_oAction -> fn_vSectionDeleted();
break;
}
}
// CPA_Ed_1 Mihaela Tancu begin
/*-----------------------------------------------------------------------------
* Description : Order the list of transitional states
* Author: Mihaela Tancu
*---------------------------------------------------------------------------*/
void CPA_Action::mfn_vSetListOfTransitionalStates(CPA_List<CPA_State>* p_oListOfStates, CPA_List<CPA_State>* p_oListOfStatesTransitional)
{
CPA_List<CPA_State> p_oListOfStatesTrans1; //list with states pointing to the default state
CPA_List<CPA_State> p_oListOfStatesTrans2; //list with states pointing to another transitional state
CPA_List<CPA_State> p_oListOfStatesTrans; //list ordered with transitional states
CPA_State* p_oState, *p_oStateNext;
// obtain from the initial list with transitional states
// one list for the states which are pointing to the default state
// and one list with the states which are pointing to each other.
while (!(p_oListOfStatesTransitional->IsEmpty()))
{
p_oState = p_oListOfStatesTransitional->RemoveHead ( ) ;
p_oStateNext = p_oState -> mfn_p_oGetNextState();
// Shaitan => state list in the level
if (!p_oStateNext)
{
tdxHandleToState hStateNext = fn_hGetNextStateInState(p_oState->GetStruct());
p_oStateNext = (CPA_State*) p_oState->GetBaseObjectList()->fn_p_oFindObjectWithdData((void*)hStateNext, C_szStateTypeName, p_oState->mfn_p_oGetFamily());
if (!p_oStateNext)
{
hStateNext = mfn_hGetStateFromLinkTable((char *)hStateNext, (char *) (LPCSTR) p_oState->mfn_p_oGetFamily()->GetName());
fn_vSetNextStateInState(p_oState->GetStruct(), hStateNext);
p_oStateNext = (CPA_State*) p_oState->GetBaseObjectList()->fn_p_oFindObjectWithdData((void*)hStateNext, C_szStateTypeName, p_oState->mfn_p_oGetFamily());
}
}
// End Shaitan => state list in the level
if (p_oStateNext-> mfn_bGetTransitional()) // points to another transitional state
p_oListOfStatesTrans2.AddTail(p_oState);
else // points to the default state
p_oListOfStatesTrans1.AddTail(p_oState);
}
BOOL bExist=FALSE;
//if there exist the list with states which are pointing to another transitional states
if (!(p_oListOfStatesTrans2.IsEmpty()))
{
p_oState = p_oListOfStatesTrans2.RemoveHead ( ) ;
p_oStateNext = p_oState -> mfn_p_oGetNextState();
bExist = TRUE; // say that this list exist
}
POSITION stPos;
while (!(p_oListOfStatesTrans2.IsEmpty()))
{ // while the list with states pointing to other transitional state exist
stPos = p_oListOfStatesTrans2.Find(p_oStateNext);
if (stPos)
{ // if the next state is in the same list as the transitional state
// add the state in the list Trans
p_oListOfStatesTrans.AddTail(p_oState);
if (!(p_oListOfStatesTrans2.IsEmpty()))
{ p_oState = p_oStateNext;
p_oListOfStatesTrans2.RemoveAt (stPos ) ;
p_oStateNext = p_oState -> mfn_p_oGetNextState();
}
}
else
{ //if (!(p_oListOfStatesTrans.IsEmpty()))
// if the next state is in the list sorted, reorder that list
stPos = p_oListOfStatesTrans.Find(p_oStateNext);
if (stPos)
{
p_oListOfStatesTrans.InsertBefore(stPos, p_oState);
if (!(p_oListOfStatesTrans2.IsEmpty()))
{
p_oState = p_oListOfStatesTrans2.RemoveHead();
p_oStateNext = p_oState->mfn_p_oGetNextState();
}
}
else
// if (!(p_oListOfStatesTrans1.IsEmpty()))
{ // if the next transitional state is in the list
// with states pointing to the default state
stPos = p_oListOfStatesTrans1.Find(p_oStateNext);
if (stPos)
{ //add the state and its next state to the Trans list
p_oListOfStatesTrans.AddTail(p_oState);
p_oListOfStatesTrans.AddTail(p_oStateNext);
p_oListOfStatesTrans1.RemoveAt(stPos);
if (!(p_oListOfStatesTrans2.IsEmpty()))
{
p_oState = p_oListOfStatesTrans2.RemoveHead();
p_oStateNext = p_oState->mfn_p_oGetNextState();
}
}
}
}
}
// for the last state, update the lists with states (Trans)
if (p_oListOfStatesTrans2.IsEmpty() && bExist)
{
stPos = p_oListOfStatesTrans1.Find(p_oStateNext);
if (stPos)
{ //if the Next state is in the list with state Trans1 (list with states pointing to the default state)
p_oListOfStatesTrans.AddTail(p_oState);
p_oListOfStatesTrans.AddTail(p_oStateNext);
p_oListOfStatesTrans1.RemoveAt(stPos);
}
else
{
stPos = p_oListOfStatesTrans.Find(p_oStateNext);
if (stPos) //if the Next state is in the Trans list
p_oListOfStatesTrans.InsertBefore(stPos, p_oState);
}
}
// if there exist transitional states pointing to another stransitional states, add them
if (bExist)
{
while (!(p_oListOfStatesTrans.IsEmpty()))
{ //put at the beggining of the list with states, the states ordered after the next state field
p_oState = p_oListOfStatesTrans.RemoveHead ( ) ;
p_oListOfStates -> AddTail(p_oState);
}
}
//add the last transitional states pointing to the default state
while (!(p_oListOfStatesTrans1.IsEmpty()))
{
p_oState = p_oListOfStatesTrans1.RemoveHead ( ) ;
p_oListOfStates -> AddTail(p_oState);
}
}
/*-----------------------------------------------------------------------------
* Description : Order the list of states asociated with one action
* Author: Mihaela Tancu
*---------------------------------------------------------------------------*/
void CPA_Action::mfn_vSetListOfStates()
{
CPA_List<CPA_State>* p_oListOfStates = &m_oListOfStates;
CPA_List<CPA_State> p_oListOfStatesNormal;
CPA_List<CPA_State> p_oListOfStatesTransitional;
CPA_State* p_oState, *p_oStateNext;
// update the list with all states (normal and transitional) with
// the new list which contain the states in the execution order
// start with the first element from the initial list
if (!(p_oListOfStates->IsEmpty()))
p_oState = p_oListOfStates->RemoveHead ( ) ;
else return;
// while it is a transitional state in the list, add transitional state at the end
// of the new list
while ((p_oState -> mfn_bGetTransitional())&& (!p_oListOfStates->IsEmpty()))
{ p_oListOfStatesTransitional.AddTail(p_oState);
p_oState = p_oListOfStates->RemoveHead ( ) ;
}
ASSERT(mfn_p_oGetDefaultState());
//search for the default state
while (!(p_oListOfStates->IsEmpty()) && (p_oState) && (p_oState != mfn_p_oGetDefaultState()))
// it is supposed to have ONE default state
{
p_oListOfStates->AddTail ( p_oState) ;
p_oState = p_oListOfStates->RemoveHead ( ) ;
}
p_oListOfStatesNormal.AddTail(p_oState);
p_oStateNext = p_oState -> mfn_p_oGetNextState();
// add at the new list, the normal states in the execution order
// looking at the NextState field of state
while ((p_oStateNext != NULL) && (!(p_oListOfStates->IsEmpty())) )
{ POSITION xPos = p_oListOfStates->Find(p_oStateNext);
if (xPos != NULL)
{ p_oListOfStates->RemoveAt(xPos);
p_oListOfStatesNormal.AddTail(p_oStateNext);
}
else break;
if (p_oStateNext == p_oStateNext -> mfn_p_oGetNextState()) break;
p_oStateNext = p_oStateNext -> mfn_p_oGetNextState();
}
// for the states which are still in the first list add them
// at the normal list or at the transitional list
while (!(p_oListOfStates->IsEmpty()))
{ p_oState = p_oListOfStates->RemoveHead ( ) ;
p_oStateNext = p_oState -> mfn_p_oGetNextState();
if (!p_oState -> mfn_bGetTransitional())
p_oListOfStatesNormal.AddTail(p_oState);
else
p_oListOfStatesTransitional.AddTail(p_oState);
}
// for every state in the new list copy the transitional states in the
// first list and set as default the first normal state in the new list
mfn_vSetListOfTransitionalStates(p_oListOfStates, &p_oListOfStatesTransitional);
// the first state in the list is the default state
if (!(p_oListOfStatesNormal.IsEmpty()))
{ p_oState = p_oListOfStatesNormal.RemoveHead ( ) ;
p_oListOfStates -> AddTail(p_oState);
}
// add the remains normal states in the list
while (!(p_oListOfStatesNormal.IsEmpty()))
{
p_oState = p_oListOfStatesNormal.RemoveHead ( ) ;
if (!p_oState -> mfn_bGetTransitional()) // the normal states at the end
p_oListOfStates -> AddTail(p_oState);
}
}
// CPA_Ed_1 Mihaela Tancu end
/******************************************************************************
* Overloaded function : call back for SCRIPT analysis
******************************************************************************/
/*-----------------------------------------------------------------------------
* Description : Return handle of default state of action
*---------------------------------------------------------------------------*/
void* CPA_Action::GetData( void )
{
if( m_p_oDefaultState )
return ( (void*) m_p_oDefaultState -> GetData() );
else
return NULL;
}
/*-----------------------------------------------------------------------------
* Description :
*---------------------------------------------------------------------------*/
void CPA_Action::fn_vNotifyRename(void)
{
CPA_SaveObject::fn_vNotifyRename();
// save al IA using this Action
CPA_DLLBase *pclIADLL = GetMainWorld()->GetToolDLLWithName(C_szDLLAIEditorName);
CList< CPA_BaseObject *, CPA_BaseObject *> oList;
if( ( pclIADLL != NULL ) && ( g_oCoherenceManager . m_fn_iGetFatherList( this, &oList ) > 0 ) )
{
POSITION xPos = oList . GetHeadPosition();
while( xPos )
{
CPA_BaseObject *p_oBsObj = oList . GetNext( xPos );
if( p_oBsObj -> fn_bIsOfType( C_szActorModelTypeName ) )
{
pclIADLL -> OnQueryAction( GetEditor(), C_uiAI_SaveIA, (LPARAM)p_oBsObj );
}
}
}
}
/******************************************************************************
* Owner functions :
******************************************************************************/
/*-----------------------------------------------------------------------------
* Description : add state to action
*---------------------------------------------------------------------------*/
void CPA_Action::mfn_vAddState(CPA_State *_p_oState, BOOL _bModifyEngine /*=TRUE*/)
{
ASSERT( _p_oState );
ASSERT( ! (m_oListOfStates . Find(_p_oState)) );
m_oListOfStates . AddTail( _p_oState );
CPA_Family *p_oFamily = M_GetFamily();
if( m_oListOfStates . GetCount() == 1 )
{
// set first state as default state
mfn_vSetDefaultState(_p_oState);
}
p_oFamily -> mfn_vAddState( _p_oState, _bModifyEngine );
// add to all ZAList
if( _bModifyEngine )
{
CPA_BaseObjectList *p_oList = GetEditor() -> GetBaseObjectList( C_szZAListTypeName );
Position lPos = p_oList -> GetHeadPosition();
while( lPos )
{
CPA_ZonesActivatingList *p_oZAList = (CPA_ZonesActivatingList*)p_oList -> GetNext( lPos );
if( p_oZAList -> GetOwner() -> GetOwner() == p_oFamily )
{
CPA_ZonesActivating *p_oZA = (CPA_ZonesActivating*)_p_oState -> mfn_p_oGetZAFromZAList( p_oZAList );
if( p_oZA == NULL )
p_oZA = (CPA_ZonesActivating*) ((CPA_tdoNameList*)p_oZAList -> GetOwner()) -> m_fnp_oGetDefaultZA();
p_oZAList -> mfn_vSetZAFromState( p_oZA, _p_oState );
}
}
}
}
/*-----------------------------------------------------------------------------
* Description : remove state from action
*---------------------------------------------------------------------------*/
void CPA_Action::mfn_vRemoveState(CPA_State *_p_oState, BOOL _bModifyEngine /*=TRUE*/)
{
ASSERT( _p_oState );
POSITION stPos = m_oListOfStates . Find(_p_oState);
ASSERT( stPos );
if( stPos )
{
CPA_Family *p_oFamily = M_GetFamily();
// remove from action
m_oListOfStates . RemoveAt( stPos );
if( _p_oState == m_p_oDefaultState )
mfn_vSetDefaultState( NULL );
// remove from family
p_oFamily -> mfn_vRemoveState( _p_oState, _bModifyEngine );
// remove from all ZAList
if( _bModifyEngine )
{
CPA_BaseObjectList *p_oList = GetEditor() -> GetBaseObjectList( C_szZAListTypeName );
Position lPos = p_oList -> GetHeadPosition();
while( lPos )
{
CPA_ZonesActivatingList *p_oZAList = (CPA_ZonesActivatingList*)p_oList -> GetNext( lPos );
if( p_oZAList -> GetOwner() -> GetOwner() == p_oFamily )
{
p_oZAList -> mfn_vRemoveState( _p_oState );
}
}
}
}
}
/*-----------------------------------------------------------------------------
* Description : Set the default initial state of action
*---------------------------------------------------------------------------*/
void CPA_Action::mfn_vSetDefaultState(CPA_State *_p_oState, BOOL _bInit /*=FALSE*/)
{
if( _p_oState == NULL )
{
// find a state to be default
POSITION xPos = m_oListOfStates . GetHeadPosition();
while ( xPos )
{
_p_oState = m_oListOfStates . GetNext( xPos );
if( ! _p_oState -> mfn_bGetTransitional() )
break;
}
}
if( (m_oListOfStates . Find(_p_oState) != NULL) && !_p_oState -> mfn_bGetTransitional() )
{
BOOL bStateChange = (m_p_oDefaultState != _p_oState );
// CPA_Ed_1 Mihaela Tancu begin
CPA_State* _p_oDefault=m_p_oDefaultState; //save the default state
// CPA_Ed_1 Mihaela Tancu end
fn_vUpdateData( _p_oState ? _p_oState -> GetData() : NULL );
m_p_oDefaultState = _p_oState;
// update all next state of transitional states
if( !_bInit )
{
POSITION xPos = m_oListOfStates . GetHeadPosition();
while ( xPos )
{
CPA_State *p_oState = m_oListOfStates . GetNext ( xPos ) ;
if( p_oState -> mfn_bGetTransitional() )
{
// CPA_Ed_1 Mihaela Tancu begin
if (p_oState ->mfn_p_oGetNextState() == _p_oDefault)
{ //only for the states pointing to the default state
//modify its next states
// CPA_Ed_1 Mihaela Tancu end
p_oState -> mfn_vSetNextState( m_p_oDefaultState );
//if( ! _bInit )
p_oState -> fn_vNotifySave();
}
}
}
}
if( ! _bInit && bStateChange )
{
// save al IA using this Action
CPA_DLLBase *p_oActorDLL = GetMainWorld() -> GetObjectDLLWithName( C_szDLLActorName );
CPA_DLLBase *pclIADLL = GetMainWorld()->GetToolDLLWithName(C_szDLLAIEditorName);
CList< CPA_BaseObject *, CPA_BaseObject *> oList;
if( ( pclIADLL != NULL ) && ( g_oCoherenceManager . m_fn_iGetFatherList( this, &oList ) > 0 ) )
{
POSITION xPos = oList . GetHeadPosition();
while( xPos )
{
CPA_BaseObject *p_oBsObj = oList . GetNext( xPos );
if( p_oBsObj -> fn_bIsOfType( C_szActorModelTypeName ) )
{
pclIADLL -> OnQueryAction( GetEditor(), C_uiAI_ProcessIA, (LPARAM)p_oBsObj );
}
}
}
// save models
p_oActorDLL -> OnQueryAction( GetEditor(), C_uiActor_ActionModif, (LPARAM)this );
}
}
}
/*-----------------------------------------------------------------------------
* Description : Create and return a copy of the action
*---------------------------------------------------------------------------*/
CPA_Action *CPA_Action::mfn_p_oDuplicateAction( void )
{
CMap<CPA_State*, CPA_State*, CPA_State*, CPA_State*> m_oMapOfStates;
CPA_Action *p_oNewAction = new CPA_Action( GetEditor(), GetOwner(), "CopyOf" + GetName() );
// saving
p_oNewAction -> SetExistingSection( FALSE );
p_oNewAction -> fn_vNotifySave();
m_oMapOfStates . RemoveAll();
// copy list of states and default state
p_oNewAction -> m_oListOfStates . RemoveAll () ;
p_oNewAction -> mfn_vSetDefaultState ( NULL ) ;
POSITION stPos = m_oListOfStates . GetHeadPosition () ;
while ( stPos )
{
CPA_State *p_oState = m_oListOfStates . GetNext ( stPos ) ;
CPA_State *p_oNewState = p_oState -> mfn_p_oDuplicateState () ;
m_oMapOfStates . SetAt( p_oState, p_oNewState );
// add state to action
p_oNewAction -> mfn_vAddState( p_oNewState );
p_oNewState -> mfn_vSetAction( p_oNewAction );
// update default state
if ( p_oState == m_p_oDefaultState )
p_oNewAction -> mfn_vSetDefaultState ( p_oNewState ) ;
}
// update next states
stPos = p_oNewAction -> m_oListOfStates . GetHeadPosition();
while ( stPos )
{
CPA_State *p_oState = p_oNewAction -> m_oListOfStates . GetNext( stPos );
CPA_State *p_oLastNextState = p_oState -> mfn_p_oGetNextState();
CPA_State *p_oNewNextState = NULL;
if ( p_oLastNextState && // Next State exist
( p_oLastNextState -> mfn_p_oGetAction() == this ) && // next state has been copied
( m_oMapOfStates . Lookup( p_oLastNextState, p_oNewNextState ) ) ) // copy of next state found
{
p_oState -> mfn_vSetNextState( p_oNewNextState );
}
}
m_oMapOfStates . RemoveAll();
// init default state
if( ( p_oNewAction -> mfn_p_oGetDefaultState() == NULL ) && (! p_oNewAction -> m_oListOfStates . IsEmpty() ) )
p_oNewAction -> mfn_vSetDefaultState ( p_oNewAction -> m_oListOfStates . GetHead () ) ;
return p_oNewAction;
}
/*-----------------------------------------------------------------------------
* Description : find the engine state with given name on linktable
*---------------------------------------------------------------------------*/
tdxHandleToState CPA_Action::mfn_hGetStateFromLinkTable(char *_szStateName,char *_szFamilyName)
{
char szFile[SCR_CV_ui_Cfg_MaxLenName],szSection[SCR_CV_ui_Cfg_MaxLenName];
SCR_tdst_Link_Value *p_tdst_LinkEntry;
sprintf( szFile, "%s\\%s\\%s.sta", fn_szGetFamiliesDataPath(), _szFamilyName, _szFamilyName );
SCR_fn_v_RdL0_ComputeSectionName( szSection, szFile, C_szStateSectionName, _szStateName);
p_tdst_LinkEntry = SCR_fnp_st_Link_SearchKey( &g_st3DOSLinkTable.stState, szSection );
if( p_tdst_LinkEntry && ( SCR_M_e_Link_GetState( p_tdst_LinkEntry ) == SCR_ELS_Link_Initialized) )
return (tdxHandleToState) SCR_M_ul_Link_GetValue( p_tdst_LinkEntry );
else
return NULL;
}
/*-----------------------------------------------------------------------------
* Description : create a new state (with engine state) and add it to action and family
*---------------------------------------------------------------------------*/
CPA_State *CPA_Action::mfn_p_oCreateNewState(char *_szStateName)
{
CPA_Family *p_oFamily = M_GetFamily();
CPA_State *p_oState = NULL;
tdxHandleToState hState = mfn_hGetStateFromLinkTable( _szStateName, p_oFamily -> fn_p_szGetName() );
if( hState )
{
p_oState = new CPA_State( GetEditor(), p_oFamily, hState, NULL, _szStateName );
p_oFamily -> m_oListOfStates . AddTail( p_oState , FALSE );
p_oState -> mfn_vSetAction( this );
m_oListOfStates . AddTail( p_oState );
}
return p_oState;
}
/*-----------------------------------------------------------------------------
* Description :
*---------------------------------------------------------------------------*/
void CPA_Action::mfn_vInterruptState(CPA_State *_p_oState)
{
if( fn_bIsValid() )
{
POSITION xPos = m_oListOfStatesInterrupted . Find( _p_oState, NULL );
if( !xPos )
m_oListOfStatesInterrupted . AddTail( _p_oState );
}
}
/*-----------------------------------------------------------------------------
* Description :
*---------------------------------------------------------------------------*/
void CPA_Action::mfn_vDontInterruptState(CPA_State *_p_oState)
{
if( fn_bIsValid() )
{
POSITION xPos = m_oListOfStatesInterrupted . Find( _p_oState, NULL );
if( xPos )
m_oListOfStatesInterrupted . RemoveAt( xPos );
}
}
#endif //EDITOR_ACTIVE