/* * PeriodicValueTable.hpp * * Created on: 22 окт. 2019 г. * Author: LeonidTitov */ #ifndef SOURCE_SCHEMATIC_PERIODICVALUETABLE_HPP_ #define SOURCE_SCHEMATIC_PERIODICVALUETABLE_HPP_ #include "ValueTable.hpp" #include "../systemic/Timer.hh" #include "../systemic/IProcess.hh" namespace schematic { template class PeriodicValueTable : public systemic::IProcess { public: typedef typename ValueTable::Index Index; static const Index val_size = ValueTable::val_size; static const Index sts_size = ValueTable::sts_size; PeriodicValueTable( ValueTable & table, systemic::time_t timeouts[val_size], T low_value, T high_value ); void process(); private: ValueTable & table; const T low_value; const T high_value; static const systemic::time_t max_timeout = -1; struct Period { systemic::Timer timer; systemic::time_t timeout; bool state = false; bool toggleEvent(); }; Period periods[val_size]; }; } template inline schematic::PeriodicValueTable::PeriodicValueTable( ValueTable & table, systemic::time_t timeouts[val_size], T low_value, T high_value ) : table(table), low_value(low_value), high_value(high_value) { for( Index i = 0; i < val_size; i++ ) periods[i].timeout = timeouts[i]; } template inline void schematic::PeriodicValueTable::process() { for( Index i = 0; i < val_size; i++ ) { Period & period = periods[i]; if( period.timeout == 0 ) table.set( low_value, i ); else if( period.timeout == max_timeout ) table.set( high_value, i ); else { if( period.toggleEvent() ) table.set( period.state ? high_value : low_value, i ); } } } template inline bool schematic::PeriodicValueTable::Period::toggleEvent() { bool is_previous_state_low = not timer.isActive() or timer.delayElapsed(); if( is_previous_state_low ) { state = not state; timer.start( timeout / 2 ); } return is_previous_state_low; } #endif /* SOURCE_SCHEMATIC_PERIODICVALUETABLE_HPP_ */