Commit 7d05b37c by amir

first working version with recursive fsm

parent d62aefc2
......@@ -2,17 +2,16 @@
<module type="CPP_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/defs/enums.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/defs/retstat.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/defs/constants.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/defs/seh_types.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/defs/enums.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/defs/seh_types.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/defs/retstat.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/seh.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/seh/JsonCallFlowBuilder.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/seh/seh_engine.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/seh/seh_engine.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/seh/JsonCallFlowBuilder.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/seh/XMLCallFlowBuilder.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/seh/seh_engine.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/seh/XMLCallFlowBuilder.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/CMakeLists.txt" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/test_seh.cpp" isTestSource="false" />
......
cmake_minimum_required(VERSION 3.6)
cmake_minimum_required(VERSION 2.8.12)
project(seh)
# version stuff
set (seh_VERSION_MAJOR 0)
set (seh_VERSION_MINOR 1)
set (seh_VERSION_PATCH 0)
set(seh_VERSION_STRING ${seh_VERSION_MAJOR}.${seh_VERSION_MINOR}.${seh_VERSION_PATCH})
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
link_directories( ../3party/lib )
include_directories(SYSTEM ../3party/rapidjson-0.11/include/rapidjson)
set(SOURCE_FILES src/seh.h src/defs/constants.h src/defs/enums.h src/defs/retstat.h src/defs/seh_types.h src/defs/seh_types.cpp src/seh/seh_engine.cpp src/seh/seh_engine.h src/seh/JsonCallFlowBuilder.cpp src/seh/JsonCallFlowBuilder.h src/seh/XMLCallFlowBuilder.cpp src/seh/XMLCallFlowBuilder.h)
add_executable(seh ${SOURCE_FILES} test/test_seh.cpp)
\ No newline at end of file
set(SOURCE_FILES src/defs/constants.h src/defs/enums.h src/defs/retstat.h src/defs/seh_types.h src/defs/seh_types.cpp src/seh/seh_engine.cpp src/seh/seh_engine.h src/seh/JsonCallFlowBuilder.cpp src/seh/JsonCallFlowBuilder.h src/seh/XMLCallFlowBuilder.cpp src/seh/XMLCallFlowBuilder.h)
add_library(seh SHARED ${SOURCE_FILES})
#target_link_libraries(seh ${PROJECT_LINK_LIBS} )
set_target_properties(seh PROPERTIES VERSION ${seh_VERSION_STRING}
SOVERSION ${seh_VERSION_MAJOR})
##add_executable(seh ${SOURCE_FILES} test/test_seh.cpp)
add_executable(test_seh test/test_seh.cpp)
target_link_libraries (test_seh seh)
# install part
set (CMAKE_INSTALL_PREFIX ../internals)
file (GLOB INSTALL_FILES "src/defs/*.h src/seh/seh_engine.h")
install(TARGETS seh DESTINATION lib)
install(FILES ${INSTALL_FILES} DESTINATION include/seh)
......@@ -29,7 +29,7 @@ RetStat ComplexEventAction::ActivateActions(EventData& eventData,
/******************************************
* check whether to move to the next state
******************************************/
if (bMoveToNextState)
if (bMoveToNextState && !activateActionData.boolWasStateChanged)
{
if (iNumOfActions > 0) {
if (eventData.NextStateValid()) {
......
//
// Created by amir on 04/09/16.
//
#ifndef SEH_SEH_H
#define SEH_SEH_H
#include <seh_types.h>
#include <cstddef>
using namespace std;
struct tGeneral_StateIndexes
{
UINT ui_StateIndex;
UINT ui_StateFlowIndex;
void Reset()
{
ui_StateIndex = NO_ENTRY;
ui_StateFlowIndex = NO_ENTRY;
}
};
const int MAX_SEH_STATE_NAME_LEN = 256;
const int MAX_SEH_CALL_FLOW_FILE_NAME_LEN = 128;
const int MAX_SEH_EVENT_NAME_LEN = 128;
const int MAX_SEH_FULL_EVENT_NAME_LEN = 128;
const int MAX_SEH_FULL_ACTION_NAME = 128;
const int MAX_SEH_ERROR_MSG = 256;
#define ACTION_TYPE_REGULAR "Action"
#define ACTION_TYPE_COND_IF "If"
#define ACTION_TYPE_COND_WHILE "While"
#define ACTION_TYPE_COND_SWITCH "Switch"
#define ACTION_PARAMS "Params"
#define ACTION_PARAMS_LEN 6
#define ACTION_PRIORITY "Priority"
#define ACTION_PRIORITY_LEN 8
#define ACTION_PRIORITY_MANDATORY "Mandatory"
#define ACTION_PRIORITY_MANDATORY_LEN 9
#define ACTION_PRIORITY_CRITICAL "Critical"
#define ACTION_PRIORITY_CRITICAL_LEN 8
#define BASE_STATE "BaseState"
#define WRONG_SEH_STATE "Wrong State"
const int BASE_STATE_LEN = 9;
#define NULL_STATE "NULL"
const int NULL_STATE_LEN = 4;
// test
const int MAX_SEH_ACTIONS = 32;
template <typename T,typename P,UINT MAX_EVENTS,UINT MAX_PARTIES>
class General_StateEventHandler
{
public:
/******************************
* Definitions & Structs
******************************/
typedef eRetStat (T::*AFP)(P* pt_Param); // action pointer - return SUCCESS / FAIL
typedef tRetStat (T::*VAFP)(P* pt_Param); // value action pointer - return code and SUCCESS/FAIL
typedef AFP (T::*RAP)(char* ba_ActionName); // ResolveAction pointer
typedef VAFP (T::*RVAP)(char* ba_ActionName); // Resolve value Action pointer
typedef UINT (T::*REP)(char* ba_EventName); // ResolveEvent pointer
typedef UINT (T::*RPP)(char* ba_PartyName); // ResolveParty pointer
typedef const char* (T::*RENP)(UINT ui_Event); // ResolveEventName pointer
typedef t_XmlItemTree* (T::*PFFP)(char* ba_FlowFileName); // Parse flow file pointer
typedef P* (T::*GNPFP)(); // get new SEH p_param_ pointer
struct tActivateActionData
{
T* pt_Object;
tGeneral_StateIndexes* pt_NextStateIndex;
bool* pb_WasStateChanged; // if true means that the called object change the state - moved to the next state
};
enum eEventActionType
{
eActionType_Regular,
eActionType_If,
eActionType_While,
eActionType_Switch
};
struct tEventAction
{
AFP t_Action;
int i_Party; // 0 - no party, 1 - A, 2 - B ....
P* pt_Param;
eEventActionType e_Type;
bool b_IsMandatory; // mandatory means that it have to be execute , even if the former action failed
bool b_IsCritical; // Critical means that if this action failes then none of the following actions should be
// executed, unless they have 'mandatory' attribute
tEventAction() { e_Type = eActionType_Regular; }
virtual void Reset()
{
t_Action = NULL;
pt_Param = NULL;
b_IsMandatory = false;
b_IsCritical = false;
}
tEventAction& operator = (const tEventAction& t_EventAction)
{
t_Action = t_EventAction.t_Action;
if (t_EventAction.pt_Param)
{
pt_Param = new P;
*pt_Param = *t_EventAction.pt_Param;
}
return *this;
}
eEventActionType GetActionType() { return e_Type; }
virtual eRetStat ActivateAction(tActivateActionData* pt_ActivateActionData)
{
*(pt_ActivateActionData->pb_WasStateChanged) = false;
return (pt_ActivateActionData->pt_Object->*(t_Action))(pt_Param);
}
bool IsActionMandatory() { return b_IsMandatory; }
bool IsActionCritical() { return b_IsCritical; }
};
struct tValueEventAction: public tEventAction
{
VAFP t_VAction;
void Reset()
{
t_VAction = NULL;
tEventAction::Reset();
}
tValueEventAction& operator = (const tValueEventAction& t_EventAction)
{
t_VAction = t_EventAction.t_VAction;
tEventAction::operator = (t_EventAction);
return *this;
}
};
struct tNextState
{
tGeneral_StateIndexes t_StateIndex;
char ba_StateName[MAX_SEH_STATE_NAME_LEN];
void Reset()
{
t_StateIndex.Reset();
ba_StateName[0] = NULL;
}
tNextState& operator = (const tNextState& t_NextState)
{
t_StateIndex = t_NextState.t_StateIndex;
strcpy(ba_StateName,t_NextState.ba_StateName);
return *this;
}
bool IsValid() { return (ba_StateName[0] != '\0'); }
};
typedef tEventAction* tEventActionPtr;
struct tEventData
{
// vector < tEventAction*> ta_Actions;
// test - amir
tEventAction* ta_Actions[MAX_SEH_ACTIONS];
short s_NumOfActions; // max
tNextState t_NextState;
char ba_EventName[MAX_SEH_FULL_EVENT_NAME_LEN];
void Reset()
{
s_NumOfActions = 0;
t_NextState.Reset();
ba_EventName[0] = NULL;
}
tEventData& operator = (const tEventData& t_EventData)
{
if (t_EventData.s_NumOfActions > 0)
memcpy(ta_Actions,t_EventData.ta_Actions,(t_EventData.s_NumOfActions * sizeof(tEventAction*)));
s_NumOfActions = t_EventData.s_NumOfActions;
t_NextState = t_EventData.t_NextState;
strcpy(ba_EventName,t_EventData.ba_EventName);
return *this;
}
eRetStat AddAction(tEventAction* pt_Action) {
if (s_NumOfActions < MAX_SEH_ACTIONS)
{
ta_Actions[s_NumOfActions++] = pt_Action;
return SUCCESS;
}
else
return FAIL;
}
bool IsEmpty() { return (s_NumOfActions == 0); /*ta_Actions.empty(); */}
bool IsNextStateValid() { return t_NextState.ba_StateName[0] != '\0'; }
};
struct tComplexEventAction: public tEventAction
{
tEventAction* pt_EventAction;
eRetStat ActivateActions(tEventData* pt_EventData,
tActivateActionData* pt_ActivateActionData,
bool b_MoveToNextState);
};
struct tComplexValueEventAction: public tValueEventAction
{
tValueEventAction* pt_EventAction;
eRetStat ActivateActions(tEventData* pt_EventData,
tActivateActionData* pt_ActivateActionData,
bool b_MoveToNextState);
};
struct tEventIfAction: public tComplexEventAction
{
tEventData t_TrueActions;
tEventData t_FalseActions;
tEventIfAction() { this->e_Type = eActionType_If; }
void Reset();
eRetStat ActivateAction(tActivateActionData* pt_ActivateActionData);
tEventIfAction& operator = (const tEventIfAction& t_EventAction)
{
tEventAction::oprator = (t_EventAction);
t_TrueActions = t_EventAction.t_TrueActions;
t_FalseActions = t_EventAction.t_FalseActions;
return *this;
}
};
struct tEventWhileAction: public tComplexEventAction
{
tEventData t_WhileActions;
tEventWhileAction() { this->e_Type = eActionType_While; }
void Reset();
eRetStat ActivateAction(tActivateActionData* pt_ActivateActionData);
tEventWhileAction& operator = (const tEventWhileAction& t_EventAction)
{
tEventAction::oprator = (t_EventAction);
t_WhileActions = t_EventAction.t_WhileActions;
return *this;
}
};
struct tEventSwitchAction: public tComplexValueEventAction
{
tEventData* pt_SwitchActions;
short s_NumOfCases;
tEventSwitchAction() { this->e_Type = eActionType_Switch; }
void Reset();
eRetStat ActivateAction(tActivateActionData* pt_ActivateActionData);
tEventSwitchAction& operator = (const tEventSwitchAction& t_EventAction)
{
tValueEventAction::operator = (t_EventAction);
s_NumOfCases = t_EventAction.s_NumOfCases;
pt_SwitchActions = new tEventData[s_NumOfCases];
for (short s_i = 0; s_i < s_NumOfCases; s_i++)
pt_SwitchActions[s_i] = t_EventAction.pt_SwitchActions[s_i];
return *this;
}
};
typedef struct
{
tEventData taa_EventCellsArray[MAX_EVENTS][MAX_PARTIES];
char ba_StateName[MAX_SEH_STATE_NAME_LEN];
tNextState t_BaseState; // the base state for this state (optional)
void Reset()
{
for (int i_x = 0; i_x < MAX_EVENTS; i_x++)
for (int i_y = 0; i_y < MAX_PARTIES; i_y++)
taa_EventCellsArray[i_x][i_y].Reset();
ba_StateName[0] = NULL;
t_BaseState.Reset();
}
}tState;
typedef struct
{
tState* pta_StateArray;
int i_NumOfStates;
char ba_FlowFileName[MAX_SEH_CALL_FLOW_FILE_NAME_LEN];
void Reset()
{
pta_StateArray = NULL;
ba_FlowFileName[0] = NULL;
i_NumOfStates = 0;
}
char* GetFlowFileName() { return ba_FlowFileName; }
}tCallFlow;
private:
/**********************
* Members
**********************/
char mba_FlowsFileName[MAX_SEH_CALL_FLOW_FILE_NAME_LEN];
tCallFlow* mpta_CallFlowArray;
UINT mui_CurrentNumOfCallFlows;
UINT mui_MaxNumberOfCallFlows;
UINT mui_StartChildCallFlows;
tState* mpt_CurrentFirstState;
tEventAction mt_EventAction;
tEventData mt_EventData;
tGeneral_StateIndexes* mpt_StateIndex;
tState* mpt_State;
tEventData* mpt_EventData;
tActivateActionData* mpt_ActivateActionData;
t_XmlItemTree* mpt_XmlTree;
char mba_ErrorMsg[MAX_SEH_ERROR_MSG];
UINT mui_CurrentFlowNumOfStates;
char mba_ActionName[MAX_SEH_FULL_ACTION_NAME];
char mba_EventName[MAX_SEH_FULL_EVENT_NAME_LEN];
T* mpt_Object;
AFP mt_ActionFunc;
RAP mt_ResolveActionFunc;
RVAP mt_ResolveValueActionFunc;
REP mt_ResolveEventFunc;
RPP mt_ResolvePartyFunc;
RENP mt_ResolveEventNameFunc;
PFFP mt_ParseFlowFileFunc;
GNPFP mt_GetNewSEHParamFunc;
UINT mui_DefaultParty; // default Party index when no party stated
map<string,tGeneral_StateIndexes> mc_StateIndexMap;
map<string,tGeneral_StateIndexes>::iterator mt_StateIterator;
protected:
tEventAction* mpt_EventAction;
/************************
* Methods
***********************/
void Reset();
eRetStat InitMembers();
eRetStat BuildCallFlowTables(); // Reading the file that contains the list of the call-flows file names
eRetStat BuildFlowTable(int i_FlowIndex,
char* ba_FlowFileName); // building the tables for a single call-flow
eRetStat GetState(t_ItemNode* pt_Node,tState* pt_State);
eRetStat GetEvent(t_ItemNode* pt_Node);
eRetStat GetEventActions(t_ItemNode* pt_Node);
eRetStat GetAction(t_ItemNode* pt_Node);
eRetStat GetActionParams(tEventAction* pt_Action,t_ItemNode* pt_Node);
// Child/Parent handling
eRetStat GetParentState(char* ba_StateName,tState** ppt_ParentState);
eRetStat GetParentEvent(tState* pt_ParentState,char* ba_EventName,tEventData** ppt_ParentEvent);
// Special handling
eRetStat HandleEventIfAction(tEventIfAction* pt_Action,t_ItemNode* pt_Node);
eRetStat HandleEventWhileAction(tEventWhileAction* pt_Action,t_ItemNode* pt_Node);
eRetStat HandleEventSwitchAction(tEventSwitchAction* pt_Action,t_ItemNode* pt_Node);
eRetStat GetEventData(tEventData* pt_EventData,t_ItemNode* pt_Node);
// Resolving
UINT ResolveFlowName(char* ba_FlowName);
UINT ResolveFlowPrefix(char* ba_FlowPrefix);
UINT ResolveParty(char* ba_PartyName);
UINT ResolveEventEnum(char* ba_EventName);
eRetStat ResolveNextStateIndex(tNextState* pt_NextState);
eRetStat ResolveNextStateIndexes(UINT ui_StartFlow = 0);
eRetStat ResolveAction(tEventAction* pt_Action,char* ba_Action,bool b_ValueAction = false);
eRetStat ResolveSimpleAction(tEventAction* pt_Action,t_ItemNode* pt_Node,bool b_ValueAction = false);
eRetStat ResolveActionWithParams(tEventAction* pt_Action,t_ItemNode* pt_Node,bool b_ValueAction = false);
eRetStat ResolveComplexActionNextState(tEventAction* pt_Action);
eRetStat ReplaceParentStates(UINT ui_FlowIndex);
eRetStat ActivateActions(tGeneral_StateIndexes* pt_NextStateIndex);
eRetStat ActivateAction();
void AddStateToMap(char* pba_StateName,tGeneral_StateIndexes* pt_StateIndex);
public:
General_StateEventHandler();
eRetStat Init(const char* ba_FlowsFileName,
UINT ui_MaxNumOfCallFlows,
T* pt_Object,
RAP t_ResolveActionFunc,
REP t_ResolveEventFunc,
RPP t_ResolvePartyFunc,
PFFP t_ParseFlowFileFunc,
UINT ui_DefaultParty,
RENP t_ResolveEventNameFunc = NULL,
RVAP t_ResolveValueActionFunc = NULL);
eRetStat InitChild(const char* ba_ChildFlowsFileName,
GNPFP t_GetNewSEHParamFunc);
eRetStat AddChildFlow(const char* ba_CallFlowFileName,
GNPFP t_GetNewSEHParamFunc);
eRetStat AddCallFlow(char* ba_CallFlowFileName);
eRetStat HandleEvent(tGeneral_StateIndexes* pt_StateIndex,UINT ui_Event,UINT ui_Party);
const char* GetStateName(tGeneral_StateIndexes* pt_StateIndex);
tCallFlow* GetCallFlowsIface() { return mpta_CallFlowArray; }
UINT GetCurrentNumOfCallFlows() { return mui_CurrentNumOfCallFlows; }
eRetStat GetStateIndex(tGeneral_StateIndexes* pt_StateIndex,
const char* ba_FlowFileName,
const char* ba_StateName);
eRetStat GetStateIndex(tGeneral_StateIndexes* pt_StateIndex,
const char* ba_StateName);
};
#endif //SEH_SEH_H
......@@ -712,9 +712,11 @@ RetStat JsonCallFlowBuilder::GetEventData(EventData &eventData, Document &eventN
/*******************************
* Resolving the action
*******************************/
shared_ptr<EventAction> p_eventAction = make_shared<EventAction>();//new EventAction();
p_eventAction->Reset();
retStat = ResolveSimpleAction(p_eventAction.get(), (Document&)*actionNodeIterator);
// shared_ptr<EventAction> p_eventAction = make_shared<EventAction>();//new EventAction();
// p_eventAction->Reset();
// retStat = ResolveSimpleAction(p_eventAction.get(), (Document&)*actionNodeIterator);
shared_ptr<EventAction> p_eventAction;
retStat = GetAction((Document&)*actionNodeIterator,&p_eventAction);
if (retStat.Fail())
{
//p_eventAction = nullptr;
......
......@@ -260,42 +260,62 @@ RetStat SehEngine::ResolveComplexActionNextState(EventAction* p_eventAction) {
/*
* checking the true actions
*/
p_nextState = &p_eventIfAction->trueActions.nextState;
if (p_nextState->IsValid())
{
retStat = ResolveNextStateIndex(*p_nextState);
if (retStat.Fail())
retStat = ResolveRecursiveNextState(p_eventIfAction->trueActions);
if(retStat.Fail())
{
retStat.SetFail(string(__PRETTY_FUNCTION__).append("-\tFailed to Resolve true actions NextState : ").append(p_nextState->stateName));
retStat.SetFail(string(__PRETTY_FUNCTION__).append("-\tFailed to Resolve true actions NextState : ").append(p_eventIfAction->trueActions.nextState.stateName));
return retStat;
}
}
/*
* checking the false actions
*/
p_nextState = &p_eventIfAction->falseActions.nextState;
if (p_nextState->IsValid())
{
retStat = ResolveNextStateIndex(*p_nextState);
if (retStat.Fail())
retStat = ResolveRecursiveNextState(p_eventIfAction->falseActions);
if(retStat.Fail())
{
retStat.SetFail(string(__PRETTY_FUNCTION__).append("-\tFailed to Resolve true actions NextState : ").append(p_nextState->stateName));
retStat.SetFail(string(__PRETTY_FUNCTION__).append("-\tFailed to Resolve true actions NextState : ").append(p_eventIfAction->falseActions.nextState.stateName));
return retStat;
}
}
// p_nextState = &p_eventIfAction->trueActions.nextState;
// if (p_nextState->IsValid())
// {
// retStat = ResolveNextStateIndex(*p_nextState);
// if (retStat.Fail())
// {
// retStat.SetFail(string(__PRETTY_FUNCTION__).append("-\tFailed to Resolve true actions NextState : ").append(p_nextState->stateName));
// return retStat;
// }
// }
// /*
// * checking the false actions
// */
// p_nextState = &p_eventIfAction->falseActions.nextState;
// if (p_nextState->IsValid())
// {
// retStat = ResolveNextStateIndex(*p_nextState);
// if (retStat.Fail())
// {
// retStat.SetFail(string(__PRETTY_FUNCTION__).append("-\tFailed to Resolve true actions NextState : ").append(p_nextState->stateName));
// return retStat;
// }
// }
break;
case nsEnums::eActionType_While:
p_eventWhileAction = (EventWhileAction*)p_eventAction;
p_nextState = &p_eventWhileAction->whileActions.nextState;
if (p_nextState->IsValid())
{
retStat = ResolveNextStateIndex(*p_nextState);
if (retStat.Fail())
retStat = ResolveRecursiveNextState(p_eventWhileAction->whileActions);
if(retStat.Fail())
{
retStat.SetFail(string(__PRETTY_FUNCTION__).append("-\tFailed to Resolve NextState in the While: ").append(p_nextState->stateName));
retStat.SetFail(string(__PRETTY_FUNCTION__).append("-\tFailed to Resolve NextState in the While: ").append(p_eventWhileAction->whileActions.nextState.stateName));
return retStat;
}
}
// p_nextState = &p_eventWhileAction->whileActions.nextState;
// if (p_nextState->IsValid())
// {
// retStat = ResolveNextStateIndex(*p_nextState);
// if (retStat.Fail())
// {
// retStat.SetFail(string(__PRETTY_FUNCTION__).append("-\tFailed to Resolve NextState in the While: ").append(p_nextState->stateName));
// return retStat;
// }
// }
break;
case nsEnums::eActionType_Switch:
p_eventSwitchAction = (EventSwitchAction*)p_eventAction;
......@@ -306,16 +326,22 @@ RetStat SehEngine::ResolveComplexActionNextState(EventAction* p_eventAction) {
iter != p_eventSwitchAction->switchActions.end(); ++iter)
{
EventData& eventData = iter->second;
p_nextState = &eventData.nextState;
if (p_nextState->IsValid())
retStat = ResolveRecursiveNextState(eventData);
if(retStat.Fail())
{
retStat = ResolveNextStateIndex(*p_nextState);
if (retStat.Fail())
{
retStat.SetFail(string(__PRETTY_FUNCTION__).append("-\tFailed to Resolve NextState in the Switch: ").append(p_nextState->stateName));
retStat.SetFail(string(__PRETTY_FUNCTION__).append("-\tFailed to Resolve NextState in the Switch: ").append(eventData.nextState.stateName));
return retStat;
}
}
// p_nextState = &eventData.nextState;
// if (p_nextState->IsValid())
// {
// retStat = ResolveNextStateIndex(*p_nextState);
// if (retStat.Fail())
// {
// retStat.SetFail(string(__PRETTY_FUNCTION__).append("-\tFailed to Resolve NextState in the Switch: ").append(p_nextState->stateName));
// return retStat;
// }
// }
}
break;
}
......@@ -605,3 +631,50 @@ RetStat SehEngine::GetStateIndex(StateIndex &stateIndex, string &stateName) {
return retStatus;
}
/**
* checking recursively
* @param eventData
* @return
*/
RetStat SehEngine::ResolveRecursiveNextState(EventData &eventData) {
RetStat retStat;
NextState& nextState = eventData.nextState;
retStat = ResolveNextState(nextState);
if(retStat.Success())
{
/**
* going over the actions
*/
for (auto&& action: eventData.actions)
{
switch (action->actionType)
{
case eActionType_If:
case eActionType_While:
case eActionType_Switch:
retStat = ResolveComplexActionNextState(action.get());
break;
default:
break;
}
if(retStat.Fail())
break;
}
}
return RetStat();
}
RetStat SehEngine::ResolveNextState(NextState &nextState) {
RetStat retStat;
if (nextState.IsValid())
{
retStat = ResolveNextStateIndex(nextState);
if (retStat.Fail())
{
retStat.SetFail(string(__PRETTY_FUNCTION__).append("-\tFailed to Resolve true actions NextState : ").append(nextState.stateName));
return retStat;
}
}
return RetStat();
}
......@@ -148,6 +148,10 @@ public:
* @return
*/
RetStat GetStateIndex(StateIndex& stateIndex, string& stateName);
RetStat ResolveRecursiveNextState(EventData &eventData);
RetStat ResolveNextState(NextState &nextState);
};
......
......@@ -36,9 +36,42 @@
"TO": "30000"
}
}, {
"Type": "If",
"Name": "IfElseAction",
"Then": {
"Actions": [{
"Type": "Action",
"Name": "SimpleAction"
}, {
"Type": "Action",
"Name": "ActionWithParamInt",
"Params": {
"TO": "300"
}
}, {
"Type": "Action",
"Name": "SimpleAction"
}],
"NextState": "Idle"
},
"Else": {
"Actions": [{
"Type": "Action",
"Name": "ActionWithParamInt",
"Params": {
"TO": "5000"
}
}, {
"Type": "Action",
"Name": "SimpleAction"
}, {
"Type": "Action",
"Name": "SimpleAction"
}],
"NextState": "Idle_IfElseState"
}
}],
"NextState": "Idle_IfThenState"
},
......
......@@ -95,7 +95,7 @@ public:
RetStat IfElseAction(ISEHParam* p_param)
{
retStat.SetFail();
retStat.Reset();//SetFail();
SEH_LOG("Action: \tIfElseAction");
return retStat;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment