6.2.8. Интерфейсный класс
Класс, объявляющий интерфейс для взаимодействия с приложением, представлен в Листинг 97.
namespace sensor
{
class ISensorControl
{
public:
virtual ~ ISensorControl () = default;
virtual void initialize() = 0; // (1)
virtual void shutDown() = 0; // (2)
virtual void assignDriver(DriverPointer driver) = 0; // (3)
virtual DriverPointer getAssignedDriver() = 0; // (4)
virtual DriverPointer getSensorDriver(SensorNumber number) = 0; // (5)
virtual void addSensor(SensorType type, SensorNumber number) = 0; // (6)
virtual void deleteSensor(SensorNumber number) = 0; // (7)
virtual bool isSensorExist(SensorNumber number) = 0; // (8)
virtual bool isSensorOperable(SensorNumber number) = 0; // (9)
virtual SensorValue getSensorValue(SensorNumber number) = 0; // (10)
virtual void querySensorValue(SensorNumber number, SensorValueCallback callback) = 0; // (11)
virtual void readSensorValues(SensorValueCallback callback) = 0; // (12)
virtual SensorValue getMinValue(SensorNumber first, SensorNumber last) = 0; // (13)
virtual SensorValue getMaxValue(SensorNumber first, SensorNumber last) = 0; // (14)
virtual void setAlert(SensorNumber number, SensorAlertCallback callback, SensorValue alertValue, AlertRule alertRule, CheckAlertTimeout checkTimeoutSeс = 1) = 0; // (15)
virtual void resetAlert(SensorNumber number) = 0; // (16)
static ISensorControl* createControl(); // (17)
};
};
В строке 1 и 2 объявлены методы для запуска и останова. В строках 3 и 4 объявлены методы для назначения и получения драйвера. Этот драйвер должен быть создан и назначен в самом начале работы, поскольку он будет передаваться новым создаваемым датчикам. Узнать назначенный драйвер для соответствующего датчика можно в методе 5.
В строках 6 и 7 объявлены методы для добавления и удаления датчика. В методе 8 можно проверить, существует ли датчик с переданным номером, в методе 9 можно проверить, является ли датчик работоспособным.
В строке 10 объявлен метод для чтения текущего показания датчика. В методе 11 осуществляется асинхронный запрос показания датчика, значение будет возвращаться через передаваемый обратный вызов. В строке 12 осуществляется опрос показаний всех работоспособных датчиков, значения также возвращаются через обратный вызов. С помощью методов, объявленных в строках 13 и 14, можно получить минимальное и максимальное значение для набора датчиков с номерами из указанного диапазона.
В строке 15 назначается отслеживание пороговых значений, в строке 16 отслеживание выключается. С помощью метода, объявленного в строке 17, можно создать экземпляр соответствующего интерфейсного класса.
Класс, реализующий интерфейс, приведен в Листинг 98.
namespace sensor
{
class ISensor;
class IDriver;
class CommandQueue;
class AlertControl;
class SensorContainer;
class SensorControclass="underline" public ISensorControl
{
public:
SensorControl();
~SensorControl();
void initialize() override;
/* Other Interface methods – they are not displayed here*/
private:
SensorContainer* sensorContainer_; // (1)
CommandQueue* commandQueue_; // (2)
AlertControl* alertControl_; // (3)
bool isInitialized_; // (4)
DriverPointer driver_; // (5)
void checkInitialize(); // (6)
void checkDriver(); // (7)
};
}; //namespace sensor
В строке 1 объявлен контейнер для хранения датчиков, в строке 2 – класс для выполнения асинхронных запросов, в строке 3 – класс для отслеживания пороговых значений. Соответствующие указатели создаются в конструкторе и уничтожаются в деструкторе. Индикатор 4 указывает, была ли выполнена инициализация.
В строке 6 объявлен вспомогательный метод, который проверяет, была ли выполнена инициализация (если нет, выбрасывает исключение). В строке 7 аналогичный метод проверяет, был ли установлен драйвер.
Рассмотрим, как здесь используются обратные вызовы. Для начала самый простой случай – чтение показаний работоспособных датчиков (Листинг 99).