Skip to content

Commit

Permalink
Seems working, taking snapshot. Many refactorings
Browse files Browse the repository at this point in the history
  • Loading branch information
shuvalov-mdb committed Oct 30, 2020
1 parent 84dc7d8 commit ec5fd24
Show file tree
Hide file tree
Showing 13 changed files with 663 additions and 318 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@ example-ping-pong/ping_sm.o
example-ping-pong/ping_test.o
example-ping-pong/ping_test
dist
demo-project/engineer_demo
demo-project/engineer_demo.o
demo-project/engineer_sm.o
demo-project/engineer_test
demo-project/engineer_test.o
18 changes: 18 additions & 0 deletions demo-project/SConscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
env = Environment()

LIBS =''

common_libs = ['gtest_main', 'gtest', 'pthread']
env.Append( LIBS = common_libs )
env.Append( CPPPATH = ['../'])

env.Append(CCFLAGS=['-fsanitize=address,undefined',
'-fno-omit-frame-pointer'],
LINKFLAGS='-fsanitize=address,undefined')

env.Program('engineer_test', ['engineer_sm.cpp', 'engineer_test.cpp'],
LIBS, LIBPATH='/opt/gtest/lib:/usr/local/lib', CXXFLAGS="-std=c++17")

env.Program('engineer_demo', ['engineer_sm.cpp', 'engineer_demo.cpp'],
LIBS, LIBPATH='/opt/gtest/lib:/usr/local/lib', CXXFLAGS="-std=c++17")

11 changes: 7 additions & 4 deletions demo-project/engineer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,26 @@ const engineerMachine = Machine({
exit: 'morningRoutine',
on: {
'TIMER': { target: 'working', actions: ['startHungryTimer', 'startTiredTimer'] },
'TIRED': { target: 'sleeping' }
}
},
working: {
entry: ['checkEmail', 'startHungryTimer' ],
entry: ['checkEmail', 'startHungryTimer', 'checkIfItsWeekend' ],
on: {
'HUNGRY': { target: 'eating', actions: ['checkEmail']},
'TIRED': { target: 'sleeping' }
'TIRED': { target: 'sleeping' },
'ENOUGH': { target: 'weekend' }
},
},
eating: {
entry: 'startShortTimer',
exit: [ 'checkEmail', 'startHungryTimer', 'startTiredTimer' ],
exit: [ 'checkEmail', 'startHungryTimer' ],
on: {
'TIMER': { target: 'working', actions: ['startHungryTimer'] },
'TIRED': { target: 'sleeping' }
}
},
weekend: {
type: 'final',
}
}
});
Expand Down
42 changes: 28 additions & 14 deletions demo-project/engineer_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,26 @@ struct EngineerSpec {
using EventTimerPayload = std::nullptr_t;
using EventHungryPayload = std::nullptr_t;
using EventTiredPayload = std::nullptr_t;
using EventEnoughPayload = std::nullptr_t;

/**
* This block is for transition actions.
*/
static void startHungryTimer (EngineerSM<EngineerSpec>* sm, EventTimerPayload* payload) {
static void startHungryTimer (EngineerSM<EngineerSpec>* sm, std::shared_ptr<EventTimerPayload> payload) {
std::clog << "Start HungryTimer from timer event" << std::endl;
startTimer([sm] {
std::clog << "Ok, I'm hungry" << std::endl;
sm->postEventHungry(std::nullptr_t());
}, 100);
}, 1000);
}
static void startTiredTimer (EngineerSM<EngineerSpec>* sm, EventTimerPayload* payload) {
static void startTiredTimer (EngineerSM<EngineerSpec>* sm, std::shared_ptr<EventTimerPayload> payload) {
std::clog << "Start TiredTimer from timer event" << std::endl;
startTimer([sm] {
std::clog << "Ok, I'm tired" << std::endl;
sm->postEventTired(std::nullptr_t());
}, 1000);
}, 2000);
}
static void checkEmail (EngineerSM<EngineerSpec>* sm, EventHungryPayload* payload) {
static void checkEmail (EngineerSM<EngineerSpec>* sm, std::shared_ptr<EventHungryPayload> payload) {
std::clog << "Checking Email, while being hugry! ok..." << std::endl;
}

Expand All @@ -57,25 +58,40 @@ struct EngineerSpec {
startTimer([sm] {
std::clog << "Hey wake up" << std::endl;
sm->postEventTimer(std::nullptr_t());
}, 1000);
}, 2000);
}
static void checkEmail (EngineerSM<EngineerSpec>* sm) {
std::clog << "Checking Email, hmmm..." << std::endl;
}

static void checkIfItsWeekend (EngineerSM<EngineerSpec>* sm) {
bool post = false;
sm->accessContextLocked([&post] (StateMachineContext& userContext) {
if (userContext.wakeUpCount >= 6) {
std::clog << "Wow it's weekend!" << std::endl;
post = true;
}
});
if (post) {
// To avoid deadlock this should be invoked outside of the accessContextLocked() method.
sm->postEventEnough(std::nullptr_t());
}
}

static void startHungryTimer (EngineerSM<EngineerSpec>* sm) {
std::clog << "Start HungryTimer" << std::endl;
startTimer([sm] {
std::clog << "Ok, I'm hungry" << std::endl;
sm->postEventHungry(std::nullptr_t());
}, 100);
}, 800);
}

static void startShortTimer (EngineerSM<EngineerSpec>* sm) {
std::clog << "Start short Timer" << std::endl;
startTimer([sm] {
std::clog << "Hey, timer is ringing." << std::endl;
sm->postEventTimer(std::nullptr_t());
}, 10);
}, 100);
}

static void morningRoutine (EngineerSM<EngineerSpec>* sm) {
Expand All @@ -101,13 +117,11 @@ int main(int argc, char** argv) {
// Kick off the state machine with a timer event...
stateMachine.postEventTimer(std::nullptr_t());

int wakeUpCount = 0; // We end the week after waking up 7 times.
while (wakeUpCount < 7) {
stateMachine.accessContextLocked([&wakeUpCount] (engineer_demo::EngineerContext& userContext) {
wakeUpCount = userContext.wakeUpCount;
});
while (!stateMachine.isTerminated()) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
stateMachine.postEventTimer(std::nullptr_t());
}
std::clog << "State machine is terminated" << std::endl;
// Let outstanding timers to expire, simplified approach for the demo.
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
return 0;
}
24 changes: 19 additions & 5 deletions demo-project/engineer_sm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ std::string EngineerSMStateToString(EngineerSMState state) {
return "EngineerSMState::working";
case EngineerSMState::eating:
return "EngineerSMState::eating";
case EngineerSMState::weekend:
return "EngineerSMState::weekend";
default:
return "ERROR";
}
Expand All @@ -33,6 +35,7 @@ bool isValidEngineerSMState(EngineerSMState state) {
if (state == EngineerSMState::sleeping) { return true; }
if (state == EngineerSMState::working) { return true; }
if (state == EngineerSMState::eating) { return true; }
if (state == EngineerSMState::weekend) { return true; }
return false;
}

Expand All @@ -42,10 +45,12 @@ std::string EngineerSMEventToString(EngineerSMEvent event) {
return "UNDEFINED";
case EngineerSMEvent::TIMER:
return "EngineerSMEvent::TIMER";
case EngineerSMEvent::TIRED:
return "EngineerSMEvent::TIRED";
case EngineerSMEvent::HUNGRY:
return "EngineerSMEvent::HUNGRY";
case EngineerSMEvent::TIRED:
return "EngineerSMEvent::TIRED";
case EngineerSMEvent::ENOUGH:
return "EngineerSMEvent::ENOUGH";
default:
return "ERROR";
}
Expand All @@ -54,8 +59,9 @@ std::string EngineerSMEventToString(EngineerSMEvent event) {
bool isValidEngineerSMEvent(EngineerSMEvent event) {
if (event == EngineerSMEvent::UNDEFINED_OR_ERROR_EVENT) { return true; }
if (event == EngineerSMEvent::TIMER) { return true; }
if (event == EngineerSMEvent::TIRED) { return true; }
if (event == EngineerSMEvent::HUNGRY) { return true; }
if (event == EngineerSMEvent::TIRED) { return true; }
if (event == EngineerSMEvent::ENOUGH) { return true; }
return false;
}

Expand Down Expand Up @@ -92,8 +98,6 @@ EngineerSMValidTransitionsFromSleepingState() {
static const auto* transitions = new const std::vector<EngineerSMTransitionToStatesPair> {
{ EngineerSMEvent::TIMER, {
EngineerSMState::working } },
{ EngineerSMEvent::TIRED, {
EngineerSMState::sleeping } },
};
return *transitions;
}
Expand All @@ -106,6 +110,8 @@ EngineerSMValidTransitionsFromWorkingState() {
EngineerSMState::eating } },
{ EngineerSMEvent::TIRED, {
EngineerSMState::sleeping } },
{ EngineerSMEvent::ENOUGH, {
EngineerSMState::weekend } },
};
return *transitions;
}
Expand All @@ -122,6 +128,14 @@ EngineerSMValidTransitionsFromEatingState() {
return *transitions;
}

// static
const std::vector<EngineerSMTransitionToStatesPair>&
EngineerSMValidTransitionsFromWeekendState() {
static const auto* transitions = new const std::vector<EngineerSMTransitionToStatesPair> {
};
return *transitions;
}



} // namespace engineer_demo
Loading

0 comments on commit ec5fd24

Please sign in to comment.