Обратные вызовы в C++ | страница 92



добавляет запись в контейнер, метод deleteAlert удаляет ее. В строке 7 объявлен класс для запуска потока для отслеживания, в строке 8 объявлен индикатор выхода, в строке 9 объявлен мьютекс для синхронизации.

Отслеживание показаний реализовано в методе, объявленном в строке 10. Поток отслеживания вызывает этот метод, который циклически опрашивает назначенные датчики и в случае превышения пороговых значений осуществляет обратный вызов. Реализация приведена в Листинг 96.

Листинг 96. Отслеживание пороговых значений

>void Observer::poll()

>{

>  using namespace std::chrono_literals;


>  while (!exit_)  // (1)

>  {

>    std::this_thread::sleep_for(1s);           // (2)

>    std::lock_guard lock(mutex_);  // (3)


>    for (auto& item : containerAlert)  // (4)

>    {

>      Alert& alert = item.second;

>      alert.currentTimeout++;          // (5)

>      if (alert.checkTimeout != 0 && alert.currentTimeout >= alert.checkTimeout)  // (6)

>      {

>          bool triggerAlert = false;


>          if (alert.alertRule == AlertRule::More)  // (7)

>          {

>            triggerAlert = alert.sensor->getValue() > alert.alertValue;

>          }

>          else               // (8)

>          {

>            triggerAlert = alert.sensor->getValue() < alert.alertValue;

>          }


>          if (triggerAlert)  // (9)

>          {

>              alert.checkTimeout = alert.callback(item.first, alert.alertValue);  // (10)

>          }


>          alert.currentTimeout = 0;  // (11)

>        }

>    }

>  }

>}

В строке 1 объявлен цикл опроса, который выполняется, пока не выставлен индикатор завершения (выставляется в методе stop). В строке 2 поток засыпает на 1 секунду, т. е. интервал опроса равен 1 секунде. В строке 3 блокируется мьютекс, чтобы избежать коллизий добавления/удаления элементов в контейнере.

В строке 4 осуществляется опрос элементов, хранящихся в контейнере. Текущее время опроса в строке 5 увеличивается на единицу. Если уведомление разрешено, о чем говорит ненулевое значение timeout, и время последнего опроса превысило назначенное время (строка 6), то тогда проверяется, имелось ли превышение пороговых значений в соответствии с назначенными правилами (строки 6, 7). Если превышение зафиксировано (строка 9), то осуществляется обратный вызов (строка 10). Этот вызов возвращает следующий интервал опроса, после чего текущее время сбрасывается (строка 11).

6.2.8. Интерфейсный класс

Класс, объявляющий интерфейс для взаимодействия с приложением, представлен в Листинг 97.