86 lines
2.2 KiB
C++
86 lines
2.2 KiB
C++
/**
|
|
* @file stored_value_sensor.h
|
|
* @brief Base class for a sensor that has its value asynchronously
|
|
* set, then later retrieved by a consumer.
|
|
*
|
|
* @date September 12, 2019
|
|
* @author Matthew Kennedy, (c) 2019-2020
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "sensor.h"
|
|
|
|
#include "efitime.h"
|
|
|
|
/**
|
|
* @brief Base class for sensors that compute a value on one thread, and want
|
|
* to make it available to consumers asynchronously.
|
|
*
|
|
* Common examples include sensors that have to do heavy lifting to produce
|
|
* a reading, and don't want to perform that conversion at the time of
|
|
* consumption.
|
|
*
|
|
* To use this class, create a class for your sensor that inherits StoredValueSensor,
|
|
* and call Invalidate() and SetValidValue(float) as appropriate when readings are available
|
|
* (or known to be invalid) for your sensor.
|
|
*
|
|
* Consumers will retrieve the last set (or invalidated) value.
|
|
*/
|
|
class StoredValueSensor : public Sensor {
|
|
public:
|
|
SensorResult get() const final override {
|
|
auto result = m_result;
|
|
|
|
// Timeouts are disabled, return last value
|
|
if (Sensor::s_inhibitSensorTimeouts) {
|
|
return result;
|
|
}
|
|
|
|
// Result is already failed, return that so that we get the real error code instead of a timeout
|
|
if (!result) {
|
|
return result;
|
|
}
|
|
|
|
if (m_timeoutPeriod != 0) { // zero m_timeoutPeriod means value lasts forever
|
|
if (getTimeNowNt() - m_timeoutPeriod > m_lastUpdate) {
|
|
return UnexpectedCode::Timeout;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
StoredValueSensor(SensorType type, efitick_t timeoutNt)
|
|
: Sensor(type)
|
|
, m_result(unexpected)
|
|
, m_timeoutPeriod(timeoutNt)
|
|
{
|
|
}
|
|
|
|
// Invalidate the stored value.
|
|
void invalidate() {
|
|
m_result = unexpected;
|
|
}
|
|
|
|
// Invalidate the stored value with an error code
|
|
void invalidate(UnexpectedCode why) {
|
|
m_result = why;
|
|
}
|
|
|
|
// A new reading is available: set and validate a new value for the sensor.
|
|
void setValidValue(float value, efitick_t timestamp) {
|
|
// Set value before valid - so we don't briefly have the valid bit set on an invalid value
|
|
m_result = value;
|
|
m_lastUpdate = timestamp;
|
|
}
|
|
|
|
void showInfo(const char*) const override { }
|
|
|
|
private:
|
|
SensorResult m_result;
|
|
|
|
const efitick_t m_timeoutPeriod;
|
|
efitick_t m_lastUpdate = 0;
|
|
};
|