#include <chrono>
#include <future>
#include <mutex>
#include <condition_variable>
#include <iostream>
#include <thread>
using namespace std::chrono_literals;
class fsm_t
{
public:
void on_enter_doing_state()
{
start_activity();
}
void on_exit_doing_state()
{
cancel_activity();
}
private:
void start_activity()
{
m_activity_future = std::async(std::launch::async,[this]{ do_activity(); });
}
void cancel_activity()
{
{
std::unique_lock lock{m_mtx};
m_cancelled = true;
m_cv.notify_all();
}
// wait for activity to finish (cancelled)
m_activity_future.get();
}
void do_activity()
{
for(std::size_t n = 0; n < 50; ++n)
{
std::unique_lock lock{m_mtx};
m_cv.wait_for(lock,100ms, [&]{ return m_cancelled; });
//co-operative cancellation of activity!
if(m_cancelled)
{
std::cout << "\ncancelled\n";
return;
}
std::cout << (n%10) << std::flush;
}
// send activity finished event to fsm.
// send_event(event::done);
}
std::future<void> m_activity_future;
bool m_cancelled{false};
std::mutex m_mtx;
std::condition_variable m_cv;
};
int main()
{
fsm_t fsm;
fsm.on_enter_doing_state();
std::this_thread::sleep_for(2s);
fsm.on_exit_doing_state(); // will cancel, activity not finished yet (full activity will take 5s)
}