Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy does my use of context<State>().method() violate statechart assertion?
    primarykey
    data
    text
    <p>I've developed some concept code for a project that I will be working on shortly. The project lends itself to a state machine design and I think boost::statechart will do a good job. I hit a roadblock when I tried to use context() however. Here's a sample (I'm happy to put more code up, but I think this is the relevant part):</p> <pre><code>struct Wait : fsm::simple_state&lt; Wait, Active &gt; { typedef mpl::list&lt;fsm::transition&lt; UnderflowEvent, Exec&gt; &gt; reactions; public: Wait() : m_wait_op() { std::cout &lt;&lt; "entering wait state." &lt;&lt; std::endl; wait(); } ~Wait() { std::cout &lt;&lt; "exiting wait state." &lt;&lt; std::endl; } private: default_wait m_wait_op; fsm::result wait() { if(context&lt;Active&gt;().underflow_condition()) { m_wait_op(); return transit&lt;Wait&gt;(); } else if(context&lt;Active&gt;().overflow_condition()) { return transit&lt;Exec&gt;(); } else { // undefined - keep waiting } } }; </code></pre> <p>The state Active has methods called "[over|under]flow_condition" which just return true at this point. Problems with my design aside, I am getting the following assertion failure when I instantiate thusly:</p> <pre><code>int main(void) { Throttler my_throttler; my_throttler.initiate(); return 0; } </code></pre> <p>and here's the assertion:</p> <blockquote> <p>assertion "get_pointer( stt.pContext_ ) != 0" failed</p> </blockquote> <p>I looked this assertion up in file "/usr/include/boost/statechart/simple_state.hpp", line 689 (boost 1.45) and the comments say that it is there to prevent simple_state from using contexts. This puzzled me when I revisited the stopwatch example and saw that the example was doing the very thing I was trying to do. So I compiled it and this assertion is not violated by the stopwatch code unsurprisingly. Am I missing something? Maybe there's something elsewhere in the code that I missed? Here's the entire header (please remember it's concept code... I'm not releasing this into the wild until it's been thoroughly genericized):</p> <pre><code> #ifndef _THROTTLER_H_ #define _THROTTLER_H_ #include&lt;queue&gt; #include&lt;vector&gt; #include&lt;ctime&gt; #include&lt;boost/statechart/event.hpp&gt; #include&lt;boost/statechart/transition.hpp&gt; #include&lt;boost/statechart/state_machine.hpp&gt; #include&lt;boost/statechart/simple_state.hpp&gt; #include&lt;boost/mpl/list.hpp&gt; #include&lt;iostream&gt; namespace mpl = boost::mpl; namespace fsm = boost::statechart; namespace { unsigned int DEFAULT_WAIT_TIME(1000); } struct noop { public: noop() { m_priority = (1 &lt;&lt; sizeof(int)); } noop(unsigned int priority) { m_priority = priority; } virtual ~noop() {} bool operator()(void) { return true; } friend bool operator&lt;(noop a, noop b); private: unsigned int m_priority; }; bool operator&lt;(noop a, noop b) { return a.m_priority &lt; b.m_priority; } struct compare_noops { bool operator()(noop a, noop b) { } }; struct default_wait { void operator()(unsigned long msecs = DEFAULT_WAIT_TIME) { std::clock_t endtime = std::clock() + (msecs*1000*CLOCKS_PER_SEC); while(clock() &lt; endtime); } }; struct OverflowEvent : fsm::event&lt; OverflowEvent &gt; {}; struct UnderflowEvent : fsm::event&lt; UnderflowEvent &gt; {}; struct ResetEvent : fsm::event&lt; ResetEvent &gt; {}; struct Active; struct Throttler : fsm::state_machine&lt; Throttler, Active &gt; {}; struct Wait; struct Active : fsm::simple_state&lt; Active, Throttler, Wait &gt; { public: typedef mpl::list&lt;fsm::transition&lt; ResetEvent, Active&gt; &gt; reactions; bool overflow_condition(void) { return true; } bool underflow_condition(void) { return true; } void queue_operation(noop op) { m_operation_queue.push(op); } void perform_operation(void) { noop op(m_operation_queue.top()); if(op()) m_operation_queue.pop(); else throw; } private: std::priority_queue&lt;noop, std::vector&lt;noop&gt;, compare_noops &gt; m_operation_queue; private: std::priority_queue&lt;noop, std::vector&lt;noop&gt;, compare_noops &gt; m_operation_queue; }; struct Exec : fsm::simple_state&lt; Exec, Active &gt; { typedef mpl::list&lt;fsm::transition&lt; OverflowEvent, Wait&gt; &gt; reactions; Exec() { std::cout &lt;&lt; "entering exec state." &lt;&lt; std::endl; } ~Exec() { std::cout &lt;&lt; "exiting exec state." &lt;&lt; std::endl; } }; struct Wait : fsm::simple_state&lt; Wait, Active &gt; { typedef mpl::list&lt;fsm::transition&lt; UnderflowEvent, Exec&gt; &gt; reactions; public: Wait() : m_wait_op() { std::cout &lt;&lt; "entering wait state." &lt;&lt; std::endl; wait(); } ~Wait() { std::cout &lt;&lt; "exiting wait state." &lt;&lt; std::endl; } private: default_wait m_wait_op; fsm::result wait() { if(context&lt;Active&gt;().underflow_condition()) { m_wait_op(); return transit&lt;Wait&gt;(); } else if(context&lt;Active&gt;().overflow_condition()) { return transit&lt;Exec&gt;(); } else { // undefined - keep waiting } } }; #endif </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload