Constrain the FSM-transition to have at most one action.
Accepted By: @vladislavbelov Differential Revision: https://code.wildfiregames.com/D5059 This was SVN commit r27768.
This commit is contained in:
parent
1ff0b8f69f
commit
8b761fec29
@ -35,26 +35,10 @@ void CFsmEvent::SetParamRef(void* pParam)
|
|||||||
m_Param = pParam;
|
m_Param = pParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
CFsmTransition::CFsmTransition(unsigned int state)
|
CFsmTransition::CFsmTransition(const unsigned int state, const CallbackFunction action)
|
||||||
{
|
: m_CurrState{state},
|
||||||
m_CurrState = state;
|
m_Action{action}
|
||||||
}
|
{}
|
||||||
|
|
||||||
CFsmTransition::~CFsmTransition()
|
|
||||||
{
|
|
||||||
m_Actions.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CFsmTransition::RegisterAction(void* pAction, void* pContext)
|
|
||||||
{
|
|
||||||
CallbackFunction callback;
|
|
||||||
|
|
||||||
// Add action at the end of actions list
|
|
||||||
callback.pFunction = pAction;
|
|
||||||
callback.pContext = pContext;
|
|
||||||
|
|
||||||
m_Actions.push_back(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CFsmTransition::SetEvent(CFsmEvent* pEvent)
|
void CFsmTransition::SetEvent(CFsmEvent* pEvent)
|
||||||
{
|
{
|
||||||
@ -66,22 +50,10 @@ void CFsmTransition::SetNextState(unsigned int nextState)
|
|||||||
m_NextState = nextState;
|
m_NextState = nextState;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFsmTransition::RunActions() const
|
bool CFsmTransition::RunAction() const
|
||||||
{
|
{
|
||||||
bool result = true;
|
return !m_Action.pFunction ||
|
||||||
|
reinterpret_cast<Action*>(m_Action.pFunction)(m_Action.pContext, m_Event);
|
||||||
CallbackList::const_iterator it = m_Actions.begin();
|
|
||||||
for (; it != m_Actions.end(); ++it)
|
|
||||||
{
|
|
||||||
if (it->pFunction)
|
|
||||||
{
|
|
||||||
// Run action
|
|
||||||
Action* action = reinterpret_cast<Action*>(it->pFunction);
|
|
||||||
result &= action(it->pContext, m_Event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CFsm::CFsm()
|
CFsm::CFsm()
|
||||||
@ -150,7 +122,8 @@ CFsmEvent* CFsm::AddEvent(unsigned int eventType)
|
|||||||
return pEvent;
|
return pEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
CFsmTransition* CFsm::AddTransition(unsigned int state, unsigned int eventType, unsigned int nextState )
|
CFsmTransition* CFsm::AddTransition(unsigned int state, unsigned int eventType, unsigned int nextState,
|
||||||
|
void* pAction /* = nullptr */, void* pContext /* = nullptr*/)
|
||||||
{
|
{
|
||||||
// Make sure we store the current state
|
// Make sure we store the current state
|
||||||
AddState(state);
|
AddState(state);
|
||||||
@ -164,7 +137,7 @@ CFsmTransition* CFsm::AddTransition(unsigned int state, unsigned int eventType,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Create new transition
|
// Create new transition
|
||||||
CFsmTransition* pNewTransition = new CFsmTransition(state);
|
CFsmTransition* pNewTransition = new CFsmTransition(state, {pAction, pContext});
|
||||||
|
|
||||||
// Setup new transition
|
// Setup new transition
|
||||||
pNewTransition->SetEvent(pEvent);
|
pNewTransition->SetEvent(pEvent);
|
||||||
@ -176,20 +149,6 @@ CFsmTransition* CFsm::AddTransition(unsigned int state, unsigned int eventType,
|
|||||||
return pNewTransition;
|
return pNewTransition;
|
||||||
}
|
}
|
||||||
|
|
||||||
CFsmTransition* CFsm::AddTransition(unsigned int state, unsigned int eventType, unsigned int nextState,
|
|
||||||
void* pAction, void* pContext)
|
|
||||||
{
|
|
||||||
CFsmTransition* pTransition = AddTransition(state, eventType, nextState);
|
|
||||||
if (!pTransition)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
// If action specified, register it
|
|
||||||
if (pAction)
|
|
||||||
pTransition->RegisterAction(pAction, pContext);
|
|
||||||
|
|
||||||
return pTransition;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFsmTransition* CFsm::GetTransition(unsigned int state, unsigned int eventType) const
|
CFsmTransition* CFsm::GetTransition(unsigned int state, unsigned int eventType) const
|
||||||
{
|
{
|
||||||
if (!IsValidState(state))
|
if (!IsValidState(state))
|
||||||
@ -259,7 +218,7 @@ bool CFsm::Update(unsigned int eventType, void* pEventParam)
|
|||||||
// to override this)
|
// to override this)
|
||||||
SetNextState(pTransition->GetNextState());
|
SetNextState(pTransition->GetNextState());
|
||||||
|
|
||||||
if (!pTransition->RunActions())
|
if (!pTransition->RunAction())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SetCurrState(GetNextState());
|
SetCurrState(GetNextState());
|
||||||
|
@ -34,14 +34,13 @@ using Action = bool(void* pContext, const CFsmEvent* pEvent);
|
|||||||
|
|
||||||
struct CallbackFunction
|
struct CallbackFunction
|
||||||
{
|
{
|
||||||
void* pFunction;
|
void* pFunction{nullptr};
|
||||||
void* pContext;
|
void* pContext{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
using StateSet = std::set<unsigned int>;
|
using StateSet = std::set<unsigned int>;
|
||||||
using EventMap = std::map<unsigned int, CFsmEvent*>;
|
using EventMap = std::map<unsigned int, CFsmEvent*>;
|
||||||
using TransitionList = std::vector<CFsmTransition*>;
|
using TransitionList = std::vector<CFsmTransition*>;
|
||||||
using CallbackList = std::vector<CallbackFunction>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a signal in the state machine that a change has occurred.
|
* Represents a signal in the state machine that a change has occurred.
|
||||||
@ -81,16 +80,10 @@ class CFsmTransition
|
|||||||
{
|
{
|
||||||
NONCOPYABLE(CFsmTransition);
|
NONCOPYABLE(CFsmTransition);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CFsmTransition(unsigned int state);
|
|
||||||
~CFsmTransition();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers an action that will be executed when the transition occurs.
|
* @param action Object executed upon transition.
|
||||||
* @param pAction the function which will be executed.
|
|
||||||
* @param pContext data passed to the function.
|
|
||||||
*/
|
*/
|
||||||
void RegisterAction(void* pAction, void* pContext);
|
CFsmTransition(const unsigned int state, const CallbackFunction action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set event for which transition will occur.
|
* Set event for which transition will occur.
|
||||||
@ -115,23 +108,23 @@ public:
|
|||||||
return m_CurrState;
|
return m_CurrState;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CallbackList& GetActions() const
|
CallbackFunction GetAction() const
|
||||||
{
|
{
|
||||||
return m_Actions;
|
return m_Action;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes actions for the transition.
|
* Executes action for the transition.
|
||||||
* @note If there are no actions, assume true.
|
* @note If there are no action, assume true.
|
||||||
* @return whether all the actions returned true.
|
* @return whether the action returned true.
|
||||||
*/
|
*/
|
||||||
bool RunActions() const;
|
bool RunAction() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int m_CurrState;
|
unsigned int m_CurrState;
|
||||||
unsigned int m_NextState;
|
unsigned int m_NextState;
|
||||||
CFsmEvent* m_Event;
|
CFsmEvent* m_Event;
|
||||||
CallbackList m_Actions;
|
CallbackFunction m_Action;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -160,7 +153,7 @@ public:
|
|||||||
virtual void Setup();
|
virtual void Setup();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear event, action lists and reset state machine.
|
* Clear event, transition lists and reset state machine.
|
||||||
*/
|
*/
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
@ -181,14 +174,8 @@ public:
|
|||||||
* Adds a new transistion to the state machine.
|
* Adds a new transistion to the state machine.
|
||||||
* @return a pointer to the new transition.
|
* @return a pointer to the new transition.
|
||||||
*/
|
*/
|
||||||
CFsmTransition* AddTransition(unsigned int state, unsigned int eventType, unsigned int nextState );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a new transition to the state machine.
|
|
||||||
* @return a pointer to the new transition.
|
|
||||||
*/
|
|
||||||
CFsmTransition* AddTransition(unsigned int state, unsigned int eventType, unsigned int nextState,
|
CFsmTransition* AddTransition(unsigned int state, unsigned int eventType, unsigned int nextState,
|
||||||
void* pAction, void* pContext);
|
void* pAction = nullptr, void* pContext = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up the transition given the state, event and next state to transition to.
|
* Looks up the transition given the state, event and next state to transition to.
|
||||||
|
Loading…
Reference in New Issue
Block a user