/*============================================================================= * * 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* p_oListOfStates, CPA_List* p_oListOfStatesTransitional) { CPA_List p_oListOfStatesTrans1; //list with states pointing to the default state CPA_List p_oListOfStatesTrans2; //list with states pointing to another transitional state CPA_List 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* p_oListOfStates = &m_oListOfStates; CPA_List p_oListOfStatesNormal; CPA_List 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 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