123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- #include "Atm_controller.hpp"
- const char Atm_controller::relOps[8] = "0=!<>-+";
- Atm_controller& Atm_controller::begin( bool initialState /* = false */ ) {
- // clang-format off
- const static state_t state_table[] PROGMEM = {
- /* ON_ENTER ON_LOOP ON_EXIT EVT_ON EVT_OFF EVT_INPUT ELSE */
- /* OFF */ ENT_OFF, -1, -1, ON, -1, OFF, -1,
- /* ON */ ENT_ON, -1, -1, -1, OFF, ON, -1,
- };
- // clang-format on
- Machine::begin( state_table, ELSE );
- last_state = -1;
- state( initialState ? ON : OFF );
- indicator = -1;
- return *this;
- }
- int Atm_controller::event( int id ) {
- switch ( id ) {
- case EVT_ON:
- return eval_all();
- case EVT_OFF:
- return !eval_all();
- }
- return 0;
- }
- void Atm_controller::action( int id ) {
- switch ( id ) {
- case ENT_OFF:
- connector[last_state == current ? ON_INPUT_FALSE : ON_CHANGE_FALSE].push( state() );
- if ( indicator > -1 ) digitalWrite( indicator, !LOW != !indicatorActiveLow );
- last_state = current;
- return;
- case ENT_ON:
- if ( last_state != -1 ) connector[( last_state == current ) ? ON_INPUT_TRUE : ON_CHANGE_TRUE].push( state() );
- if ( indicator > -1 ) digitalWrite( indicator, !HIGH != !indicatorActiveLow );
- last_state = current;
- return;
- }
- }
- bool Atm_controller::eval_one( atm_connector& connector ) {
- switch ( connector.relOp() ) {
- case atm_connector::REL_EQ:
- return connector.pull() == connector.event;
- case atm_connector::REL_NEQ:
- return connector.pull() != connector.event;
- case atm_connector::REL_LT:
- return connector.pull() < connector.event;
- case atm_connector::REL_GT:
- return connector.pull() > connector.event;
- case atm_connector::REL_LTE:
- return connector.pull() <= connector.event;
- case atm_connector::REL_GTE:
- return connector.pull() >= connector.event;
- }
- return connector.pull();
- }
- bool Atm_controller::eval_all() {
- bool r = eval_one( operand[0] );
- for ( uint8_t i = 1; i < ATM_CONDITION_OPERAND_MAX; i++ ) {
- if ( operand[i].mode() ) {
- switch ( operand[i].logOp() ) {
- case atm_connector::LOG_AND:
- r = r && eval_one( operand[i] );
- break;
- case atm_connector::LOG_OR:
- r = r || eval_one( operand[i] );
- break;
- case atm_connector::LOG_XOR:
- r = !r != !eval_one( operand[i] );
- break;
- }
- }
- }
- return r;
- }
- Atm_controller& Atm_controller::led( int led, bool activeLow /* = false */ ) {
- indicator = led;
- indicatorActiveLow = activeLow;
- pinMode( indicator, OUTPUT );
- return *this;
- }
- Atm_controller& Atm_controller::onChange( bool status, atm_cb_push_t callback, int idx /* = 0 */ ) {
- connector[status ? ON_CHANGE_TRUE : ON_CHANGE_FALSE].set( callback, idx );
- return *this;
- }
- Atm_controller& Atm_controller::onChange( bool status, Machine& machine, int event /* = 0 */ ) {
- connector[status ? ON_CHANGE_TRUE : ON_CHANGE_FALSE].set( &machine, event );
- return *this;
- }
- Atm_controller& Atm_controller::onChange( atm_cb_push_t callback, int idx /* = 0 */ ) {
- connector[ON_CHANGE_TRUE].set( callback, idx );
- connector[ON_CHANGE_FALSE].set( callback, idx );
- return *this;
- }
- Atm_controller& Atm_controller::onChange( Machine& machine, int event /* = 0 */ ) {
- connector[ON_CHANGE_TRUE].set( &machine, event );
- connector[ON_CHANGE_FALSE].set( &machine, event );
- return *this;
- }
- Atm_controller& Atm_controller::onInput( bool status, atm_cb_push_t callback, int idx /* = 0 */ ) {
- connector[status ? ON_INPUT_TRUE : ON_INPUT_FALSE].set( callback, idx );
- return *this;
- }
- Atm_controller& Atm_controller::onInput( bool status, Machine& machine, int event /* = 0 */ ) {
- connector[status ? ON_INPUT_TRUE : ON_INPUT_FALSE].set( &machine, event );
- return *this;
- }
- Atm_controller& Atm_controller::IF( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
- return OP( atm_connector::LOG_AND, machine, relOp, match );
- }
- Atm_controller& Atm_controller::IF( atm_cb_pull_t callback, int idx /* = 0 */ ) {
- return OP( atm_connector::LOG_AND, callback, idx );
- }
- Atm_controller& Atm_controller::AND( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
- return OP( atm_connector::LOG_AND, machine, relOp, match );
- }
- Atm_controller& Atm_controller::AND( atm_cb_pull_t callback, int idx /* = 0 */ ) {
- return OP( atm_connector::LOG_AND, callback, idx );
- }
- Atm_controller& Atm_controller::OR( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
- return OP( atm_connector::LOG_OR, machine, relOp, match );
- }
- Atm_controller& Atm_controller::OR( atm_cb_pull_t callback, int idx /* = 0 */ ) {
- return OP( atm_connector::LOG_OR, callback, idx );
- }
- Atm_controller& Atm_controller::XOR( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
- return OP( atm_connector::LOG_XOR, machine, relOp, match );
- }
- Atm_controller& Atm_controller::XOR( atm_cb_pull_t callback, int idx /* = 0 */ ) {
- return OP( atm_connector::LOG_XOR, callback, idx );
- }
- Atm_controller& Atm_controller::OP( char logOp, Machine& machine, char relOp, int match ) {
- for ( uint8_t i = 0; i < ATM_CONDITION_OPERAND_MAX; i++ ) {
- if ( operand[i].mode() == atm_connector::MODE_NULL ) { // Pick the first free slot
- operand[i].set( &machine, match, logOp, (int)( strchr( relOps, relOp ) - relOps ) );
- break;
- }
- }
- return *this;
- }
- Atm_controller& Atm_controller::OP( char logOp, atm_cb_pull_t callback, int idx ) {
- for ( uint8_t i = 0; i < ATM_CONDITION_OPERAND_MAX; i++ ) {
- if ( operand[i].mode() == atm_connector::MODE_NULL ) { // Pick the first free slot
- operand[i].set( callback, idx );
- break;
- }
- }
- return *this;
- }
- Atm_controller& Atm_controller::trace( Stream& stream ) {
- Machine::setTrace( &stream, atm_serial_debug::trace, "CONTROLLER\0EVT_ON\0EVT_OFF\0EVT_INPUT\0ELSE\0OFF\0ON" );
- return *this;
- }
|