Commit 9362bf08 by amir

Add loading fsm from stream/string

parent a2b7c5a9
......@@ -76,7 +76,8 @@ struct StateIndex
bool isValid()
{
return (uiStateIndex != nsConstants::C_NO_ENTRY &&
uiStateFlowIndex != nsConstants::C_NO_ENTRY);
uiStateFlowIndex != nsConstants::C_NO_ENTRY &&
!fsmId.empty() && !stateName.empty());
}
bool operator==(const StateIndex &rhs) const {
......
......@@ -77,6 +77,43 @@ RetStat SehEngine::BuildSingleFlowTable(string flowPrefix, string flowFile) {
return retStat;
}
RetStat SehEngine::BuildSingleFlow(string flowPrefix, string& flowFSM) {
RetStat retStat;
CallFlow* p_cf = nullptr;
CallFlow** pp_cf = (CallFlow**)GetFromMap(callFlowMap_,flowPrefix);
if(pp_cf && *pp_cf)
{
/**
* updating
*/
(*pp_cf)->Reset();
(*pp_cf)->fsmId = flowPrefix;
p_cf = *pp_cf;
}
else
{
/**
* new call flow
*/
p_cf = new CallFlow(flowPrefix);
p_cf->flowIndex = maxNumberOfCallFlows_++;
callFlowMap_[flowPrefix] = p_cf;
callFlowArray_.push_back(p_cf);
}
/**
* now resolve the builder
*/
if(p_callFlowBuilder_ == nullptr) {
string xmlPrefix = "</xml>";
if (flowFSM.rfind(xmlPrefix) != string::npos)
p_callFlowBuilder_ = new XMLCallFlowBuilder();
else
p_callFlowBuilder_ = new JsonCallFlowBuilder();
}
retStat = p_callFlowBuilder_->BuildFlowTableFromString(flowFSM.c_str(),p_cf,p_baseSEHObject_);
return retStat;
}
ICallFlowBuilder *SehEngine::createCallFlowBuilder(string flowFile) {
int lastIndexOf = flowFile.find_last_of('.');
if (lastIndexOf != string::npos)
......@@ -458,6 +495,23 @@ RetStat SehEngine::InitMultiFlows(string &flowsFileName, map<string, IBaseSEH *>
return retStat;
}
RetStat SehEngine::InitSingleFlow(string &flowPrefix, string& flowFSM, IBaseSEH *p_baseSEH) {
this->baseSEHObjectMap_[flowPrefix] = p_baseSEH;
//InitMembers();// InitMultiFlowsMembers();
activateActionData_.Reset();
eventAction_.Reset();
p_baseSEHObject_ = p_baseSEH;
maxNumberOfCallFlows_ = callFlowMap_.size();
RetStat retStat = BuildSingleFlow(flowPrefix,flowFSM);
if (retStat.Success())
{
retStat = ResolveNextStateIndexes();
if (retStat.Fail())
SEH_METHOD_ERROR("Failed in ResolveNextStateIndexes");
}
return retStat;
}
RetStat SehEngine::InitMultiFlows(map<string, string> &flowFilesMap, map<string, IBaseSEH *> &baseSehMap) {
maxNumberOfCallFlows_ = 1; // will be resolved from the flow file
this->baseSEHObjectMap_ = baseSehMap;
......@@ -497,9 +551,12 @@ RetStat SehEngine::HandleEvent(StateIndex& stateIndex, string& eventStr) {
********************/
if(!stateIndex.isValid())
{
SEH_METHOD_ERROR("-\tInvalid State index");
retStatus.SetFail();
return retStatus;
if(GetStateIndex(stateIndex.fsmId,stateIndex.stateName,stateIndex).Fail())
{
SEH_METHOD_ERROR("-\tInvalid State index");
retStatus.SetFail();
return retStatus;
}
}
/******************************
......@@ -520,49 +577,20 @@ RetStat SehEngine::HandleEvent(StateIndex& stateIndex, string& eventStr) {
* and setting the BaseSEH object
***********************************************/
this->p_state_ = p_callFlow->stateArray[this->p_stateIndex_->uiStateIndex].get();
/**
* validate names, maybe the flow has changed since last session event
*/
if(p_stateIndex_->fsmId == p_callFlow->fsmId && p_stateIndex_->stateName == p_state_->stateName) {
p_eventData_ = (EventData *) GetFromMap(this->p_state_->eventsMap, eventStr);
this->p_baseSEHObject_ = p_callFlow->p_baseSEHObject;
//this->activateActionData_.object = p_callFlow->baseSEHObject;;
string &eventName = eventStr; //this.baseSEHObject.resolveEventName(iEvent);
if (!eventName.empty())
SEH_METHOD_LOG("-\tState/Event: ", this->p_state_->stateName, '/', eventName);
/**********************************************
* if no implementation for this State/Event then looking if
* there is a BaseState
*********************************************/
if ((this->p_eventData_ == nullptr || this->p_eventData_->getNumOfActions() == 0)
&& (this->p_state_->baseState.IsValid())) {
this->p_stateIndex_ = &this->p_state_->baseState.stateIndex;
this->p_state_ = p_callFlow->stateArray[this->p_stateIndex_->uiStateIndex].get();
this->p_eventData_ = (EventData *) GetFromMap(this->p_state_->eventsMap,
eventStr); // eventCellsArray[iEvent];
}
if (this->p_eventData_ != nullptr) {
// Logger.severe("SEHEngine::HandleEvent-\tEvent: "
// + eventName + " Not Implemented for State: "
// + this.statePtr.stateName);
// retStatus.setFail();
// return retStatus;
// }
/*************************
* Get & Activate Actions
************************/
retStatus = ActivateActions(*this->p_stateIndex_);
} else {
SEH_METHOD_ERROR("-\tEvent: ", eventName, " Not Implemented for State: ",
this->p_state_->stateName);
retStatus.SetFail();
retStatus = GetEventAndActivateActions(eventStr, retStatus, p_callFlow);
}
} else
{
SEH_METHOD_ERROR("-\tState index mismatch with flow fsm and state name");
retStatus.SetFail();
if(GetStateIndex(p_stateIndex_->fsmId,p_stateIndex_->stateName,*p_stateIndex_).Success())
retStatus = GetEventAndActivateActions(eventStr, retStatus, p_callFlow);
else {
SEH_METHOD_ERROR("-\tState index mismatch with flow fsm and state name");
retStatus.SetFail();
}
}
} else
{
......@@ -579,6 +607,41 @@ RetStat SehEngine::HandleEvent(StateIndex& stateIndex, string& eventStr) {
return retStatus;
}
RetStat &SehEngine::GetEventAndActivateActions(string &eventStr, RetStat &retStatus, const CallFlow *p_callFlow) {
p_eventData_ = (EventData *) GetFromMap(p_state_->eventsMap, eventStr);
p_baseSEHObject_ = p_callFlow->p_baseSEHObject;
//this->activateActionData_.object = p_callFlow->baseSEHObject;;
string &eventName = eventStr; //this.baseSEHObject.resolveEventName(iEvent);
if (!eventName.empty())
SEH_METHOD_LOG("-\tState/Event: ", p_state_->stateName, '/', eventName);
/**********************************************
* if no implementation for this State/Event then looking if
* there is a BaseState
*********************************************/
if ((p_eventData_ == nullptr || p_eventData_->getNumOfActions() == 0)
&& (p_state_->baseState.IsValid())) {
p_stateIndex_ = &p_state_->baseState.stateIndex;
p_state_ = p_callFlow->stateArray[p_stateIndex_->uiStateIndex].get();
p_eventData_ = (EventData *) GetFromMap(p_state_->eventsMap,
eventStr); // eventCellsArray[iEvent];
}
if (p_eventData_ != nullptr) {
/*************************
* Get & Activate Actions
************************/
retStatus = ActivateActions(*p_stateIndex_);
} else {
SEH_METHOD_ERROR("-\tEvent: ", eventName, " Not Implemented for State: ",
p_state_->stateName);
retStatus.SetFail();
}
return retStatus;
}
const string &SehEngine::GetStateName(StateIndex &stateIndex) {
if (stateIndex.uiStateFlowIndex < maxNumberOfCallFlows_)
{
......@@ -700,3 +763,4 @@ RetStat SehEngine::GetStateIndex(const char *p_fsmId, const char *p_stateName, S
string stateName = p_stateName;
return GetStateIndex(fsmId,stateName,stateIndex);
}
......@@ -57,7 +57,16 @@ private:
*/
RetStat BuildSingleFlowTable(string flowPrefix, string flowFile);
ICallFlowBuilder* createCallFlowBuilder(string flowFile);
RetStat ReadAndCreateFlowsFromFile();
/**
* building call flow from string
* @param flowPrefix
* @param flowFSM
* @return
*/
RetStat BuildSingleFlow(string flowPrefix, string& flowFSM);
/**
* Resolving the next state index from the state name here there is only one
......@@ -115,6 +124,7 @@ public:
* @return
*/
RetStat HandleEvent(StateIndex& stateIndex, string& eventStr);
/**
* Handling the State/Event : This method is what this is all about, getting
* the State/Event and activating the resolved actions and setting the next
......@@ -162,6 +172,17 @@ public:
RetStat ResolveRecursiveNextState(EventData &eventData);
RetStat ResolveNextState(NextState &nextState);
/**
* init flow from fsm string
* @param flowPrefix
* @param flowFSM
* @param p_baseSEH
* @return
*/
RetStat InitSingleFlow(string &flowPrefix, string& flowFSM, IBaseSEH *p_baseSEH);
RetStat &GetEventAndActivateActions(string &eventStr, RetStat &retStatus, const CallFlow *p_callFlow);
};
......
......@@ -5,10 +5,12 @@
#include <iostream>
#include <functional>
#include <vector>
#include <cstring>
//#include <cstring>
#include <limits.h>
#include <mhash.h>
#include <ctime>
#include <fstream>
#include <sstream>
#include "../src/defs/seh_types.h"
#include "../src/seh/seh_engine.h"
......@@ -130,6 +132,8 @@ public:
INTINT_FUNC resolveFunc() { return std::bind(&TestSub::subbing,this,_1,_2); }
};
void TestFSMBuffer(basic_ifstream<char> flowFileName);
void simple_test()
{
......@@ -150,6 +154,22 @@ std::string getexepath()
return std::string( result, (count > 0) ? count : 0 );
}
RetStat TestFSMBuffer(string& fsmId,
string& flowFileName,
SehEngine* fsmEngine,
IBaseSEH* p_BaseSEH) {
RetStat stat;
std::ifstream jsonFile(flowFileName);
if(jsonFile.is_open())
{
std::stringstream buffer;
buffer << jsonFile.rdbuf();
string flowFsm = buffer.str();
stat = fsmEngine->InitSingleFlow(fsmId,flowFsm,p_BaseSEH);
}
return stat;
}
int main() {
RetStat stat;
int TEST_REP = 1000000;
......@@ -165,10 +185,20 @@ int main() {
map<string,string> flowFilesMap;
map<string,IBaseSEH*> flowsSEHMap;
//flowFilesMap.put("Test", "src/test/resources/seh/TestSEH.xml");
flowFilesMap["Test"] = "/home/amir/git/ipgallery/common/cpp/seh/test/resources/TestSEH.json";
flowsSEHMap["Test"] = &testSEH;
stat = fsmEngine->InitMultiFlows(flowFilesMap, flowsSEHMap);
string flowFile = "/home/amir/git/ipgallery/common/cpp/seh/test/resources/TestSEH.json";
std::string flowPrefix = "Test";
bool useBufferFsm = true;
if(useBufferFsm) {
stat = TestFSMBuffer(flowPrefix,flowFile, fsmEngine,(IBaseSEH*)&testSEH);
} else {
flowFilesMap[flowPrefix] = flowFile;
flowsSEHMap[flowPrefix] = &testSEH;
stat = fsmEngine->InitMultiFlows(flowFilesMap, flowsSEHMap);
}
if(stat.Success()) {
stat = fsmEngine->GetStateIndex("Test","Idle",state);
if(stat.Success()) {
......@@ -192,3 +222,4 @@ int main() {
}
return 0;
}
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