Commit 0066b077 by amir

initial

parent 16850be6
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
Makefile
.make.state
nbproject
build
bin
lib
tmp
CMakeFiles
CMakeCache.txt
cmake_install.cmake
install_manifest.txt
\ No newline at end of file
cmake_minimum_required(VERSION 3.6)
project(seh)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
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
//
// Created by amir on 06/09/16.
//
#ifndef SEH_CONSTANTS_H
#define SEH_CONSTANTS_H
/**
* the projects constants
*/
namespace nsConstants
{
static const int C_NO_ENTRY = -1;
static const int C_MAX_SEH_STATE_NAME_LEN = 256;
static const int C_MAX_SEH_CALL_FLOW_FILE_NAME_LEN = 128;
static const int C_MAX_SEH_EVENT_NAME_LEN = 128;
static const int C_MAX_SEH_FULL_EVENT_NAME_LEN = 128;
static const int C_MAX_SEH_FULL_ACTION_NAME = 128;
static const int C_MAX_SEH_ERROR_MSG = 256;
static const int C_ACTION_PARAMS_LEN = 6;
static const int C_ACTION_PRIORITY_LEN = 8;
static const int C_ACTION_PRIORITY_MANDATORY_LEN = 9;
static const int C_ACTION_PRIORITY_CRITICAL_LEN = 8;
static const std::string C_ACTION_PARAMS ="Params";
static const std::string C_ACTION_PRIORITY = "Priority";
static const std::string C_ACTION_PRIORITY_MANDATORY = "Mandatory";
static const std::string C_ACTION_PRIORITY_CRITICAL = "Critical";
static const std::string C_BASE_STATE = "BaseState";
static const std::string C_NAME = "Name";
static const std::string C_NEXT_STATE = "NextState";
static const std::string C_WRONG_SEH_STATE = "Wrong State";
static const std::string C_PARAM_COND_ATTRIBUTE = "Cond";
static const std::string C_NULL_STATE = "NULL";
static const std::string C_STATES = "States";
static const std::string C_EVENTS = "Events";
static const std::string C_ACTIONS = "Actions";
static const std::string C_TYPE = "Type";
static const std::string C_IF_THEN = "Then";
static const std::string C_IF_ELSE = "Else";
static const std::string C_CASES = "Cases";
}
#endif //SEH_CONSTANTS_H
//
// Created by amir on 06/09/16.
//
#ifndef SEH_ENUMS_H
#define SEH_ENUMS_H
namespace nsEnums
{
enum eRetStat
{
eFail,
eSuccess
};
enum eEventActionType
{
eActionType_Regular,
eActionType_If,
eActionType_While,
eActionType_Switch
};
}
#endif //SEH_ENUMS_H
//
// Created by amir on 06/09/16.
//
#ifndef SEH_RETSTAT_H
#define SEH_RETSTAT_H
#include <string>
#include "enums.h"
using namespace nsEnums;
class RetStat
{
private:
eRetStat retstat_;
int ret_code_;
std::string error_text_;
public:
RetStat(): retstat_(eSuccess), ret_code_(0) {}
RetStat(bool success_, int ret_code_, const std::string &error_text_) : retstat_(eSuccess),
ret_code_(ret_code_),
error_text_(error_text_) {}
void Reset()
{
retstat_ = eSuccess;
ret_code_ = 0;
error_text_.clear();
}
void SetSuccess() { retstat_ = eSuccess; }
void SetFail() { retstat_ = eFail; }
void SetFail(std::string &error)
{
retstat_ = eFail;
error_text_.assign(error);
}
void SetFail(const char* error)
{
retstat_ = eFail;
error_text_.assign(error);
}
bool Success() { return (retstat_ == eSuccess); }
bool Fail() { return (retstat_ == eFail); }
std::string& GetError() { return error_text_; }
int GetRetCode() const {
return ret_code_;
}
};
#endif //SEH_RETSTAT_H
//
// Created by amir on 06/09/16.
//
#include "retstat.h"
#include "seh_types.h"
RetStat ComplexEventAction::ActivateActions(EventData& eventData,
ActivateActionData& activateActionData,
bool bMoveToNextState)
{
int iNumOfActions = eventData.getNumOfActions();
for (EventAction eventAction : eventData.actions)
{
/*
* activating the action
*/
retStat = (RetStat) eventAction.ActivateAction(activateActionData); //action.invoke(activateActionData.object, eventAction.param);
if (retStat.Fail())
{
//logger.severe("ComplexEventAction::ActivateActions-\tFailed in Action");
SEH_LOG_ERROR("ComplexEventAction::ActivateActions-\tFailed in Action: ",retStat.GetError());
break;
}
}
/******************************************
* check whether to move to the next state
******************************************/
if (bMoveToNextState)
{
if (iNumOfActions > 0) {
if (eventData.NextStateValid()) {
activateActionData.boolWasStateChanged = true;
activateActionData.nextStateIndex.uiStateFlowIndex = eventData.nextState.stateIndex.uiStateFlowIndex;
activateActionData.nextStateIndex.uiStateIndex = eventData.nextState.stateIndex.uiStateIndex;
//logger.info("SEHEngine-\tChanging to State: " + eventData.nextState.stateName);
SEH_LOG("ComplexEventAction::ActivateActions\tChanging to State: ",eventData.nextState.stateName);
} else {
activateActionData.boolWasStateChanged = false;
}
} else {
retStat.SetFail();
return retStat;
}
}
retStat.SetSuccess();
return retStat;
}
void EventIfAction::Reset()
{
EventAction::Reset();
trueActions.Reset();
falseActions.Reset();
}
RetStat EventIfAction::ActivateAction(ActivateActionData& activateActionData)
{
retStat.Reset();
/***********************************
* Activating the Condition action
**********************************/
retStat = EventAction::ActivateAction(activateActionData);
if (retStat.Success())
return ActivateActions(trueActions, activateActionData, true);
else
return ActivateActions(falseActions, activateActionData, true);
}
void EventWhileAction::Reset()
{
EventAction::Reset();
whileActions.Reset();
}
RetStat EventWhileAction::ActivateAction(ActivateActionData &activateActionData)
{
retStat.Reset();
while (EventAction::ActivateAction(activateActionData).Success()) {
retStat = ActivateActions(whileActions, activateActionData, true);
if (retStat.Fail())
return retStat;
}
/******************************************
* check whether to move to the next state
******************************************/
if (whileActions.NextStateValid() )
{
activateActionData.boolWasStateChanged = true;
activateActionData.nextStateIndex = whileActions.nextState.stateIndex;
SEH_LOG("EventWhileAction-\tChanging to State: ",whileActions.nextState.stateName);
}
else
{
activateActionData.boolWasStateChanged = false;
}
return retStat;
}
void EventSwitchAction::Reset() {
switchActions.clear();
}
RetStat EventSwitchAction::ActivateAction(ActivateActionData &activateActionData) {
retStat.Reset();
retStat = EventAction::ActivateAction(activateActionData);
if (retStat.Fail())
return retStat;
/************************************************************
* Activating the appropriate case according to the ret_code
***********************************************************/
if (retStat.GetRetCode() < switchActions.size())
{
EventData eventData = switchActions[retStat.GetRetCode()];
retStat = ActivateActions(eventData,activateActionData,true);
if(retStat.Success())
{
/******************************************
* check whether to move to the next state
******************************************/
if (eventData.NextStateValid() )
{
activateActionData.boolWasStateChanged = true;
activateActionData.nextStateIndex = eventData.nextState.stateIndex;
SEH_LOG("EventSwitchAction-\tChanging to State: ",eventData.nextState.stateName);
}
else
{
activateActionData.boolWasStateChanged = false;
}
}
}
else
{
retStat.SetFail("EventSwitchAction::ActivateAction-\tReturn value is bigger the num of switch cases");
SEH_LOG_ERROR(retStat.GetError());
return retStat;
}
return retStat;
}
void ActivateActionData::Reset() {
this->boolWasStateChanged = false;
this->nextStateIndex.Reset();
}
//
// Created by amir on 06/09/16.
//
#ifndef SEH_SEH_TYPES_H
#define SEH_SEH_TYPES_H
#include <functional>
#include <vector>
#include <iostream>
#include <map>
#include "constants.h"
#include "retstat.h"
template <typename Arg, typename... Args>
void seh_log(std::ostream& out, Arg&& arg, Args&&... args)
{
out << std::forward<Arg>(arg);
using expander = int[];
(void)expander{0, (void(out << ',' << std::forward<Args>(args)),0)...};
}
#define SEH_LOG(...) seh_log(std::cout,__VA_ARGS__)
#define SEH_LOG_ERROR(...) seh_log(std::cerr,__VA_ARGS__) // << ... << ... << std::endl
#define SEH_METHOD_ERROR(...) SEH_LOG_ERROR(__PRETTY_FUNCTION__,__VA_ARGS__)
#define SEH_METHOD_LOG(...) SEH_LOG(__PRETTY_FUNCTION__,__VA_ARGS__)
using namespace std;
struct StateIndex
{
int uiStateIndex;
int uiStateFlowIndex;
StateIndex()
{
}
StateIndex(int uiStateIndex,int uiFlowIndex)
{
this->uiStateIndex = uiStateIndex;
this->uiStateFlowIndex = uiFlowIndex;
}
void Reset()
{
uiStateIndex = nsConstants::C_NO_ENTRY;
uiStateFlowIndex = nsConstants::C_NO_ENTRY;
}
bool isValid()
{
return (uiStateIndex != nsConstants::C_NO_ENTRY &&
uiStateFlowIndex != nsConstants::C_NO_ENTRY);
}
};
struct ISEHParam
{
virtual void SetParam(const char* name, const char* value) = 0;
};
/**
* this is the interface of all the classes
* that use the GenericSEH engine
* @author amir
*
*/
typedef std::function<RetStat (ISEHParam* )> AFP;
struct IBaseSEH
{
virtual AFP resolveAction(const char* actionName) = 0;
virtual int resolveEvent(const char* eventName);
virtual const char* resolveEventName(int event);
virtual ISEHParam* getNewSEHParam();
virtual void setAppData(void* p_appData);
//public RetStatSupplier invokeFunc(CallSite callSite, SEHParam sehParam) throws Throwable;
};
/**
* Data needed to activate the actions and move to the next state
*/
struct ActivateActionData
{
//IBaseSEH* p_object;
StateIndex nextStateIndex;
bool boolWasStateChanged; // if true means that the called object
// change the state - moved to the next
// state
void Reset();
};
/**
* contains the data for the action such as the Method (function pointer),
* the param to pass to the method is this a mandatory action or critical.
* This is also a base class for other complex actions
*
* @author amir
*
*/
struct EventAction
{
string name;
//RetStatSupplier actionFunc;
AFP action;
ISEHParam* p_param_;
eEventActionType actionType;
bool bIsMandatory = false; // mandatory means that it have to be
// execute , even if the former action
// failed
bool bIsCritical = false; // Critical means that if this action
// failes then none of the following
// actions should be
// executed, unless they have 'mandatory' attribute
EventAction()
{
actionType = eActionType_Regular;
}
void Reset()
{
name.clear();
action = nullptr;
p_param_ = nullptr;
bIsMandatory = false;
bIsCritical = false;
}
EventAction& operator = (const EventAction& eventAction)
{
this->name.assign(eventAction.name);
this->action = eventAction.action;
if (eventAction.p_param_ != nullptr)
{
this->p_param_ = eventAction.p_param_;
}
return *this;
}
eEventActionType getActionType()
{
return actionType;
}
/**
* activating the action
*
* @param activateActionData
* @return
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
virtual RetStat ActivateAction(ActivateActionData& activateActionData)
{
activateActionData.boolWasStateChanged = false;
if (this->action != nullptr)
return this->action(p_param_);
// else // backward support for xml callflow builder
// return (RetStat) this.action.invoke(activateActionData.object, param);
}
bool isActionMandatory() { return bIsMandatory; }
bool isActionCritical() { return bIsCritical; }
};
/**
* data for the next state
*
* @author amir
*
*/
struct NextState
{
StateIndex stateIndex;
string stateName;
void Reset()
{
stateIndex.Reset();
stateName.clear();
}
NextState& operator = (const NextState& nextState)
{
this->stateIndex = nextState.stateIndex;
this->stateName.assign(nextState.stateName);
return *this;
}
bool IsValid() { return !stateName.empty(); }
string& getStateName() { return stateName; }
void setStateName(string& stateName) {
this->stateName.assign(stateName);
}
void setStateName(char* stateName) {
this->stateName.assign(stateName);
}
};
/**
* Contains the event data: the list of actions to activate, the next state
* and the event name
*
* @author amir
*
*/
struct EventData
{
// vector < tEventAction*> ta_Actions;
// test - amir
vector<EventAction> actions;
NextState nextState;
string eventName;
void Reset()
{
actions.clear();
nextState.Reset();
eventName.clear();
}
int getNumOfActions()
{
return actions.size();
}
EventData& operator = (const EventData& eventData)
{
if (!eventData.actions.empty())
this->actions = eventData.actions;
this->nextState = eventData.nextState;
this->eventName.assign(eventData.eventName);
return *this;
}
void AddAction(EventAction& action)
{
actions.push_back(action);
}
bool Empty() { return actions.empty(); }
bool NextStateValid() { return nextState.IsValid(); }
};
/**
* contains basic handling for activating complex actions
*
* @author amir
*
*/
struct ComplexEventAction: public EventAction
{
RetStat retStat;
ComplexEventAction(): EventAction()
{
}
RetStat ActivateActions(EventData& eventData,
ActivateActionData& activateActionData,
bool bMoveToNextState);
};
struct EventIfAction: public ComplexEventAction
{
EventData trueActions;
EventData falseActions;
EventIfAction() { this->actionType = eActionType_If; }
void Reset();
RetStat ActivateAction(ActivateActionData& activateActionData);
EventIfAction& operator = (const EventIfAction& eventIfAction)
{
this->operator=(eventIfAction);
trueActions = eventIfAction.trueActions;
falseActions = eventIfAction.falseActions;
return *this;
}
};
struct EventWhileAction: public ComplexEventAction
{
EventData whileActions;
EventWhileAction() { this->actionType = eActionType_While; }
void Reset();
RetStat ActivateAction(ActivateActionData& activateActionData);
EventWhileAction& operator = (const EventWhileAction& eventAction)
{
this->operator=(eventAction);
whileActions = eventAction.whileActions;
return *this;
}
};
struct EventSwitchAction: public ComplexEventAction
{
vector<EventData> switchActions;
//short numOfCases;
EventSwitchAction() { this->actionType = eActionType_Switch; }
void Reset();
RetStat ActivateAction(ActivateActionData& activateActionData);
EventSwitchAction& operator = (const EventSwitchAction& eventSwitchAction)
{
this->operator=(eventSwitchAction);
// numOfCases = eventSwitchAction.numOfCases;
switchActions = eventSwitchAction.switchActions;
return *this;
}
};
struct State
{
map<string,EventData> eventsMap;
string stateName;
NextState baseState; // the base state for this state (optional)
State()
{
Reset();
}
void Reset()
{
eventsMap.clear();
stateName.clear();
baseState.Reset();
}
};
struct CallFlow
{
int flowIndex = 0;
vector<State> stateArray;
int iNumOfStates;
string flowFileName;
IBaseSEH* p_baseSEHObject;
void Reset()
{
flowIndex = 0;
stateArray.clear();
flowFileName.clear();
iNumOfStates = 0;
p_baseSEHObject = nullptr;
}
string& GetFlowFileNameStr()
{
return flowFileName;
}
const char* GetFlowFileName()
{
return flowFileName.c_str();
}
};
struct ICallFlowBuilder {
virtual RetStat BuildFlowTableFromFile(string& flowFileName, CallFlow *p_callFlow, IBaseSEH *p_baseSEHObject) = 0;
virtual RetStat BuildFlowTableFromString(string& flowFSM, CallFlow* p_callFlow, IBaseSEH *baseSEHObject) = 0;
};
#endif //SEH_SEH_TYPES_H
This diff is collapsed. Click to expand it.
//
// Created by amir on 07/09/16.
//
#include "JsonCallFlowBuilder.h"
#include <document.h>
#include <fstream>
#include <sstream>
RetStat JsonCallFlowBuilder::BuildFlowTableFromFile(string& flowFileName, CallFlow *p_callFlow,
IBaseSEH *p_baseSEHObject) {
RetStat retStat;
int iCurrentState = 0;
this->p_callFlow_ = p_callFlow;
this->p_baseSEHObject_ = p_baseSEHObject;
this->flowFileName_.assign(flowFileName);
//defaultSEHParam = this.baseSEHObject.getNewSEHParam();
/*********************************************
* copying the file name and reading the file
********************************************/
this->p_callFlow_->flowFileName.assign(flowFileName);
std::ifstream jsonFile(flowFileName);
if(jsonFile.is_open())
{
std::stringstream buffer;
buffer << jsonFile.rdbuf();
p_flowDoc_ = new Document();
if (!p_flowDoc_->Parse<0>(buffer.str().c_str()).HasParseError())
{
retStat = CreateCallFlow(flowFileName, iCurrentState);
} else
{
retStat.SetFail(string("Failed to parse File: ").append(flowFileName));
}
}
else
{
retStat.SetFail(string("Failed to open File: ").append(flowFileName));
}
return retStat;
}
RetStat JsonCallFlowBuilder::BuildFlowTableFromString(string& flowFSM, CallFlow* p_callFlow, IBaseSEH *p_baseSEHObject) {
RetStat retStat;
int iCurrentState = 0;
this->p_callFlow_ = p_callFlow;
this->p_baseSEHObject_ = p_baseSEHObject;
//this->flowFileName_.assign(flowFileName);
//defaultSEHParam = this.baseSEHObject.getNewSEHParam();
/*********************************************
* copying the file name and reading the file
********************************************/
//this->p_callFlow_->flowFileName.assign(flowFileName);
p_flowDoc_ = new Document();
if (!p_flowDoc_->Parse<0>(flowFSM.c_str()).HasParseError())
{
retStat = CreateCallFlow(this->flowFileName_, iCurrentState);
} else
{
retStat.SetFail(string("Failed to parse flow string").append(""));
}
return retStat;
}
JsonCallFlowBuilder::JsonCallFlowBuilder() {
this->eventAction_.Reset();
this->eventData_.Reset();
this->flowFileName_.clear();
}
RetStat JsonCallFlowBuilder::CreateCallFlow(string& flowFileName, int iCurrentState) {
RetStat retStat;
State* p_state;
Document& flowDoc = *p_flowDoc_;
//JsonNode currentStateNodePtr;
/*************************************************
* Going over the tree: - Counting the number of states - Allocating
* the states - going over each state and reading it's data
************************************************/
const Value& statesArrayNode = flowDoc[nsConstants::C_STATES.c_str()];
/************************************
* - Counting the number of states and setting the node to the first
* child
*************************************/
if (statesArrayNode.IsArray() )
p_callFlow_->iNumOfStates = statesArrayNode.Size();
/***************************
* - Allocating the states
***************************/
if (p_callFlow_->iNumOfStates > 0)
{
//p_callFlow_->stateArray = new State[p_callFlow_->iNumOfStates];
/*
* allocating each cell
*/
// for (int i = 0; i < p_callFlow_->iNumOfStates; i++)
// p_callFlow_->stateArray[i] = new State();
/*************************************
* Going over the States and Setting the State Names
************************************/
for (Value::ConstValueIterator itr = statesArrayNode.Begin(); itr != statesArrayNode.End(); ++itr)
{
Document* p_currentStateNode = (Document*)itr; //stateNode;
State state;
p_state = &state;//p_callFlow_->stateArray[iCurrentState];
//p_currentStateNode = stateNode;
/*
* Getting the <Name> tag - first child
*/
p_state->stateName = (*p_currentStateNode)[nsConstants::C_NAME.c_str()].GetString();//.asText();
/*
* Getting the State data
*/
retStat = GetState(*p_currentStateNode, p_state );
if (retStat.Success())
{
/****************************
* Going to the next state
****************************/
iCurrentState++;
}
else
{
if (retStat.GetError().empty())
retStat.SetFail(string("JsonCallFlowBuilder.BuildFlowTable-\tFailed in State: ").append(p_state->stateName));
break;
}
/*********************
* pushing the state
*******************/
p_callFlow_->stateArray.push_back(state);
}
}
else
{
retStat.SetFail(string("JsonCallFlowBuilder.BuildFlowTable-\tno States for ").append(flowFileName));
}
return retStat;
}
RetStat JsonCallFlowBuilder::GetState(Document &stateNode, State *p_State) {
RetStat retStat;
/***************************
* Getting the State Events
**************************/
/*
* checking for BaseState tags
*/
auto& baseStateNode = stateNode[nsConstants::C_BASE_STATE.c_str()];
if (baseStateNode.IsString())
{
p_State->baseState.Reset();
// Getting the base state name
p_State->baseState.stateName = baseStateNode.GetString();
}
auto& eventsArray = stateNode[nsConstants::C_EVENTS.c_str()];
if (eventsArray.IsArray())
{
for (auto eventNodePtr = eventsArray.Begin(); eventNodePtr != eventsArray.End(); ++eventNodePtr)
{
Document& eventNode = *(Document*)eventNodePtr;
/****************************
* Getting the Event
****************************/
retStat = GetEvent(eventNode );
if (retStat.Fail())
{
if (retStat.GetError().empty())
retStat.SetFail("JsonCallFlowBuilder.GetState-\tFailed Getting the event");
return retStat;
}
/*
* adding the event to map
*/
EventData eventData = this->eventData_;
p_State->eventsMap[this->eventData_.eventName] = eventData;
}
}
else
{
retStat.SetFail(string("JsonCallFlowBuilder.GetState-\tno events node for state: ")
.append(stateNode[nsConstants::C_NAME.c_str()].GetString())
.append(", file: ").append(this->flowFileName_));
}
return retStat;
}
RetStat JsonCallFlowBuilder::GetEvent(Document &eventNode) {
return RetStat();
}
//
// Created by amir on 07/09/16.
//
#ifndef SEH_JSONCALLFLOWBUILDER_H
#define SEH_JSONCALLFLOWBUILDER_H
#include <document.h>
#include "../defs/seh_types.h"
using namespace std;
using namespace rapidjson;
class JsonCallFlowBuilder : public ICallFlowBuilder {
private:
EventData eventData_;
EventAction eventAction_;
EventAction* p_eventAction_;
CallFlow* p_callFlow_;
IBaseSEH* p_baseSEHObject_;
string flowFileName_;
Document* p_flowDoc_;
public:
JsonCallFlowBuilder();
virtual RetStat BuildFlowTableFromFile(string& flowFileName, CallFlow *p_callFlow, IBaseSEH *p_baseSEHObject) override;
virtual RetStat BuildFlowTableFromString(string& flowFSM, CallFlow* p_callFlow, IBaseSEH *baseSEHObject) override;
RetStat CreateCallFlow(string &basic_string, int iCurrentState);
RetStat GetState(Document &stateNode, State *p_State);
RetStat GetEvent(Document &eventNode);
};
#endif //SEH_JSONCALLFLOWBUILDER_H
//
// Created by amir on 07/09/16.
//
#include "XMLCallFlowBuilder.h"
RetStat XMLCallFlowBuilder::BuildFlowTableFromFile(string& flowFileName, CallFlow *p_callFlow, IBaseSEH *p_baseSEHObject) {
return RetStat();
}
RetStat XMLCallFlowBuilder::BuildFlowTableFromString(string& flowFSM, CallFlow* p_callFlow, IBaseSEH *baseSEHObject) {
return RetStat();
}
//
// Created by amir on 07/09/16.
//
#ifndef SEH_XMLCALLFLOWBUILDER_H
#define SEH_XMLCALLFLOWBUILDER_H
#include "../defs/seh_types.h"
class XMLCallFlowBuilder : public ICallFlowBuilder{
public:
virtual RetStat BuildFlowTableFromFile(string& flowFileName, CallFlow *p_callFlow, IBaseSEH *p_baseSEHObject) override;
virtual RetStat BuildFlowTableFromString(string& flowFSM, CallFlow* p_callFlow, IBaseSEH *baseSEHObject) override;
};
#endif //SEH_XMLCALLFLOWBUILDER_H
// Created by amir on 07/09/16.
//
#ifndef SEH_SEH_ENGINE_H
#define SEH_SEH_ENGINE_H
#include "../defs/seh_types.h"
using namespace std;
class SehEngine {
private:
ICallFlowBuilder* p_callFlowBuilder_;
string flowsFileName_;
vector<CallFlow*> callFlowArray_;
map<string, CallFlow*> callFlowMap_;
map<string, string> flowFilesMap_;
int currentCallFlowIndex;
int maxNumberOfCallFlows_;
int startChildCallFlows;
State* p_currentFirstState_;
EventAction eventAction_;
EventData eventData_;
StateIndex* p_stateIndex_;
State* p_state_;
EventData* p_eventData_;
ActivateActionData activateActionData_;
//TreeModel xmlTreeModel;
string errorMsg_;
int currentFlowNumOfStates_;
string actionName_;
string eventName_;
IBaseSEH* p_baseSEHObject_;
map<string, IBaseSEH*> baseSEHObjectMap_;
AFP actionFunc_;
map<string,StateIndex> stateIndexMap_;
EventAction* p_eventAction_;
void Reset();
void InitMembers();
/**
* Reading the flows from the file and parsing each flow
*
* @return RetStat
*/
RetStat BuildMultiCallFlowTables(map<string, string>& flowFilesMap);
/**
* Reading and parsing a single flow file
*
* @return
*/
RetStat BuildSingleFlowTable(string flowPrefix, string flowFile);
ICallFlowBuilder* createCallFlowBuilder(string flowFile);
RetStat ReadAndCreateFlowsFromFile();
/**
* Resolving the next state index from the state name here there is only one
* call flow so wre don't need to resolve which call flow (for now)
*/
RetStat ResolveNextStateIndex(NextState& nextState);
/**
* Resolving the state index from the state name + flow name : Going over
* the valid call-flows, going over each state and its events and resolving
* the actions next state
*/
RetStat ResolveNextStateIndexes();
/**
* Resolves complex actions that have next state inside them like
* switch/if/while actions
*
* @param actionPtr
* @return
*/
RetStat ResolveComplexActionNextState(EventAction& actionRef);
/**
* activating the actions and moving to the next state
*
* @param nextStateIndex
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
RetStat ActivateActions(StateIndex& nextStateIndex);
public:
SehEngine();
/**
* Initialize the engine with a list of flows , each flow is attached to a
* BaseSEH class
*
* @param flowsFileName
* @param baseSehMap
* @param iMaxNumOfCallFlows
* @return
* @throws SecurityException
* @throws NoSuchMethodException
*/
RetStat InitMultiFlows(string& flowsFileName, map<string, IBaseSEH*>& baseSehMap);
RetStat InitMultiFlows(map<string, string>& flowFilesMap, map<string, IBaseSEH*>& baseSehMap);
/**
* 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
* state
*
* @param stateIndex
* @param iEvent
* @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
* state
* @param stateIndex
* @param eventStr
* @param p_appData
* @return
*/
RetStat HandleEvent(StateIndex stateIndex, string& eventStr /*int iEvent */, void* p_appData)
{
this->p_baseSEHObject_->setAppData(p_appData);
return HandleEvent(stateIndex, eventStr);
}
/**
* Getting the state name from the stateIndex
*
* @param stateIndex
* @return
*/
const string& GetStateName(StateIndex& stateIndex);
int GetCurrentNumOfCallFlows() { return maxNumberOfCallFlows_; }
/**
* Getting the stateIndex from the State Name and flow file
*
* @param stateIndex
* @param flowFileName
* @param ba_StateName
* @return
*/
RetStat GetStateIndex(StateIndex& stateIndex, string& stateName);
};
#endif //SEH_SEH_ENGINE_H
//
// Created by amir on 04/09/16.
//
#include <iostream>
#include <functional>
#include <vector>
typedef std::function<int (int, int)> INTINT_FUNC;
using namespace std::placeholders;
class TestAdd
{
public:
int adding(int a, int b) { return a + b; }
INTINT_FUNC resolveFunc() { return std::bind(&TestAdd::adding,this,_1,_2); }
};
class TestSub
{
public:
int subbing (int a, int b) { return a - b; }
INTINT_FUNC resolveFunc() { return std::bind(&TestSub::subbing,this,_1,_2); }
};
void testArrays()
{
struct IntPtr
{
int a;
void* p;
IntPtr(int a) : a(a) {}
IntPtr() {}
};
std::vector<IntPtr> intPtrArray;
for (int i = 0; i < 10; ++i) {
IntPtr ip;
ip.a = i;
intPtrArray.push_back(ip);
}
for (auto itr : intPtrArray)
std::cout << itr.a << std::endl;
}
int main() {
INTINT_FUNC func;
testArrays();
return 0;
std::cout << "Hello, World!" << std::endl;
TestAdd testAdd;
TestSub testSub;
func = testAdd.resolveFunc();
std::cout << "result is: " << func(20,10) << std::endl;
func = testSub.resolveFunc();
std::cout << "result is: " << func(20,10) << std::endl;
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