103 lines
2.3 KiB
C++
103 lines
2.3 KiB
C++
/*
|
||
* 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<typename T, unsigned size>
|
||
class PeriodicValueTable : public systemic::IProcess {
|
||
public:
|
||
|
||
typedef typename ValueTable<T, size>::Index Index;
|
||
static const Index val_size = ValueTable<T, size>::val_size;
|
||
static const Index sts_size = ValueTable<T, size>::sts_size;
|
||
|
||
PeriodicValueTable( ValueTable<T, size> & table, systemic::time_t timeouts[val_size], T low_value, T high_value );
|
||
|
||
void process();
|
||
|
||
private:
|
||
ValueTable<T, size> & 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<typename T, unsigned size>
|
||
inline schematic::PeriodicValueTable<T, size>::PeriodicValueTable(
|
||
ValueTable<T, size> & 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<typename T, unsigned size>
|
||
inline void schematic::PeriodicValueTable<T, size>::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<typename T, unsigned size>
|
||
inline bool schematic::PeriodicValueTable<T, size>::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_ */
|