/** * Sets the current state of the stream listener. * * @param pStateName The name of the state * @return An error if the state name is not recognized. */ UT_Error ODi_StreamListener::setState(const char* pStateName) { UT_ASSERT(m_stateStack.getItemCount() == 0); UT_ASSERT(m_pCurrentState == NULL); _clear(); m_pCurrentState = _createState(pStateName); m_deleteCurrentWhenPop = true; if (m_pCurrentState) { return UT_OK; } else { return UT_ERROR; } }
/** * Push or pop the stack according to the action stated by the current state. */ void ODi_StreamListener::_handleStateAction () { ODi_StreamListener::StackCell stackCell; switch (m_stateAction.getAction()) { case ODi_ListenerStateAction::ACTION_PUSH: m_stateStack.push_back( ODi_StreamListener::StackCell(m_pCurrentState, m_deleteCurrentWhenPop)); if (m_stateAction.getState() != NULL) { m_pCurrentState = m_stateAction.getState(); m_deleteCurrentWhenPop = m_stateAction.getDeleteWhenPop(); } else { if (!strcmp(m_stateAction.getStateName().c_str(), "FontFaceDecls")) { m_pCurrentState = &m_fontFaceDecls; m_deleteCurrentWhenPop = false; } else { m_pCurrentState = _createState( m_stateAction.getStateName().c_str()); m_deleteCurrentWhenPop = true; } } UT_ASSERT(m_pCurrentState); break; case ODi_ListenerStateAction::ACTION_POP: if (m_deleteCurrentWhenPop) { DELETEP(m_pCurrentState); } else { m_pCurrentState = NULL; } if (m_stateStack.getItemCount() > 0) { stackCell = m_stateStack.getLastItem(); m_pCurrentState = stackCell.m_pState; m_deleteCurrentWhenPop = stackCell.m_deleteWhenPop; m_stateStack.pop_back(); } break; case ODi_ListenerStateAction::ACTION_POSTPONE: // If the state wants to come back later he shouldn't be deleted. //UT_ASSERT(!m_deleteCurrentWhenPop); ODi_Postpone_ListenerState* pPostponeState; if (m_stateAction.getState() != NULL) { pPostponeState = new ODi_Postpone_ListenerState( m_stateAction.getState(), m_stateAction.getDeleteWhenPop(), *m_pElementStack); } else { ODi_ListenerState* pNewState; UT_ASSERT(!m_stateAction.getStateName().empty()); pNewState = _createState(m_stateAction.getStateName().c_str()); pPostponeState = new ODi_Postpone_ListenerState( pNewState, m_stateAction.getDeleteWhenPop(), *m_pElementStack); } m_postponedParsing.addItem(pPostponeState); m_stateStack.push_back( ODi_StreamListener::StackCell(m_pCurrentState, m_deleteCurrentWhenPop)); m_pCurrentState = pPostponeState; m_deleteCurrentWhenPop = false; UT_ASSERT(m_pCurrentState); break; case ODi_ListenerStateAction::ACTION_BRINGUPALL: { UT_sint32 i; bool comeBackAfter = m_stateAction.getComeBackAfter(); for (i=0; i<m_postponedParsing.getItemCount(); i++) { _resumeParsing(m_postponedParsing[i]); } UT_VECTOR_PURGEALL(ODi_Postpone_ListenerState*, m_postponedParsing); m_postponedParsing.clear(); if (!comeBackAfter) { m_stateAction.popState(); this->_handleStateAction(); } } break; case ODi_ListenerStateAction::ACTION_BRINGUP: if (m_postponedParsing.getItemCount() > 0) { ODi_Postpone_ListenerState* pPostponedState; pPostponedState = m_postponedParsing.getLastItem(); const UT_String& rStateName = pPostponedState->getParserState()->getStateName(); if (rStateName == m_stateAction.getStateName()) { bool comeBackAfter = m_stateAction.getComeBackAfter(); _resumeParsing(pPostponedState); DELETEP(pPostponedState); m_postponedParsing.pop_back(); if (!comeBackAfter) { m_stateAction.popState(); this->_handleStateAction(); } } } break; case ODi_ListenerStateAction::ACTION_REPEAT: UT_ASSERT(m_currentAction == ODI_NONE); m_currentAction = ODI_RECORDING; m_xmlRecorder.clear(); m_elemenStackSize = m_pElementStack->getStackSize(); break; case ODi_ListenerStateAction::ACTION_IGNORE: UT_ASSERT(m_currentAction == ODI_NONE); m_currentAction = ODI_IGNORING; UT_ASSERT(m_stateAction.getElementLevel() >= -1); UT_ASSERT((int)m_pElementStack->getStackSize() - (m_stateAction.getElementLevel()+1) >= 0); m_elemenStackSize = m_pElementStack->getStackSize() - (m_stateAction.getElementLevel()+1); break; }; }
void _testTree() { // create 3 lvls for the initial tree //first lvl, max's turn, initial state of board _createNode(0,board); //create initial node for test_tree_head, current state = head at this point //second lvl, min's turn, 4 states //(top left corner, (4,4), (5,5), bottom right corner) char new_state[BOARD_SIZE][BOARD_SIZE]; /*NOTE: x - 1, and y - 1 as array range from 0 -7, not 1 - 8 */ /* top left corner */ _createState(0,0,new_state,current_state->state); _createNode(0,new_state); /* (4,4) */ _createState(3,3,new_state,current_state->state); _createNode(0,new_state); /* (5,5) */ _createState(4,4,new_state,current_state->state); _createNode(0,new_state); /* bottom right corner */ _createState(7,7,new_state,current_state->state); _createNode(0,new_state); /*third lvl, middle states have 4 children each, corners have 2 */ /*NOTE: current state should point to child_head of top left corner node */ current_state = current_state->child_head; //reset current state to firsts lvl's child_head /*NOTE: x - 1, and y - 1 as array range from 0 -7, not 1 - 8 */ /* top left corner children = (1,2), (2,1) */ _createState(0,1,new_state,current_state->state); _playerMove(0,0,0,1,new_state); //zero all slots between moves _createNode(0,new_state); _createState(1,0,new_state,current_state->state); _playerMove(0,0,1,0,new_state); //zero all slots between moves _createNode(0,new_state); /* (4,4) = (3,4), (4,3), (5,4), (4,5)*/ _createState(2,3,new_state,current_state->next->state); //skip to next as current_state not reset _playerMove(3,3,2,3,new_state); //zero all slots between moves _createNode(1, new_state); //reset current_state to next parent _createState(3,2,new_state,current_state->state); _playerMove(3,3,3,2,new_state); //zero all slots between moves _createNode(0,new_state); _createState(4,3,new_state,current_state->state); _playerMove(3,3,4,3,new_state); //zero all slots between moves _createNode(0,new_state); _createState(3,4,new_state,current_state->state); _playerMove(3,3,3,4,new_state); //zero all slots between moves _createNode(0,new_state); /* (5,5) = (4,5), (5,4), (5,6), (6,5) */ _createState(3,4,new_state,current_state->next->state); //skip to next as current_state not reset _playerMove(4,4,3,4,new_state); //zero all slots between moves _createNode(1, new_state); //reset current-state to next parent _createState(4,3,new_state,current_state->state); _playerMove(4,4,4,3,new_state); //zero all slots between moves _createNode(0,new_state); _createState(4,5,new_state,current_state->state); _playerMove(4,4,4,5,new_state); //zero all slots between moves _createNode(0,new_state); _createState(5,4,new_state,current_state->state); _playerMove(4,4,5,4,new_state); //zero all slots between moves _createNode(0,new_state); /* bottom right corner = (8,7), (7,8) */ _createState(7,6,new_state,current_state->next->state); //skip to next as current_state not reset _playerMove(7,7,7,6,new_state); //zero all slots between moves _createNode(1, new_state); //reset current-state to next parent _createState(6,7,new_state,current_state->state); _playerMove(7,7,6,7,new_state); //zero all slots between moves _createNode(0,new_state); // print tree and clean up memory _printTesttree(test_tree_head); _cleanTesttree(test_tree_head); }