Центр уведомлений в C ++ - PullRequest
       70

Центр уведомлений в C ++

5 голосов
/ 05 ноября 2011

После программирования на какое-то время с помощью целевых платформ iOS и Mac я полюбил общий шаблон уведомлений, реализованный в классах NSNotificationCenter и NSNotification. Возвращаясь к C ++, который всегда был моим любимым языком для большинства вещей, я обнаружил, что пытаюсь воспроизвести этот шаблон и считаю, что действительно должна быть общая реализация подобных классов C ++, предлагающая его поддержку.

Кажется, что шаблон несколько сложнее реализовать в C ++, чем Objective C, из-за более динамичной природы последних, но он кажется далеко не невозможным. Я просмотрел библиотеки надстроек, так как они в целом потрясающие, и мне было грустно не найти свою удачу там. Хотя boost :: bind, boost :: lamda, boost :: function, похоже, выполняют большую часть работы. Я что-то упустил очевидное? Есть ли уже что-нибудь, что позволило бы мне легко повторить поведение NSNotification / NSNotificationCenter?

Ответы [ 3 ]

2 голосов
/ 06 февраля 2015

В дополнение к пакетам boost, упомянутым в других ответах, есть еще одна опция: poco::NotificationCenter.

Эта реализация ближе к структуре уведомлений Какао, как конкретно обсуждалось на Poco. документация :

Класс NotificationCenter - это в основном реализация C ++ класса NSNotificationCenter, найденного в Apple Cocoa (или OpenStep).

2 голосов
/ 05 ноября 2011

Теоретически вы можете создать класс, имеющий вектор указателей на функции, вызываемый при вызове определенного уведомления. - Класс, имеющий словарь, в котором объекты являются векторами функций, вызываемых при нажатии на уведомление

1 голос
/ 05 ноября 2011

Следуя рекомендации @ anno, чтобы посмотреть на boot :: signal, после проверки она кажется возможной, хотя, как и ожидалось, она не так проста, как объективные решения C. Просматривая учебник boost :: signal , я подумал, что расскажу о наиболее важных аспектах рассматриваемой проблемы.


Чтобы создать отправителей уведомлений:

Рассмотрим простую службу доставки новостей, где клиенты подключаются к поставщику новостей, который затем отправляет новости всем подключенным клиентам по мере поступления информации. Служба доставки новостей может быть построена так:

class NewsItem { /* ... */ };
boost::signal<void (const NewsItem&)> deliverNews;

Целью deliverNews является информирование наблюдателей о том, что NewsItem был сгенерирован.


Наблюдатели могут быть добавлены следующим образом (с использованием библиотеки boost :: bind):

Клиенты, которые хотят получать обновления новостей, должны только подключить функциональный объект, который может получать новости, к сигналу deliveryNews. Например, у нас может быть специальная область сообщений в нашем приложении специально для новостей, например:

struct NewsMessageArea : public MessageArea
{
public:
  // ...

  void displayNews(const NewsItem& news) const
  {
    messageText = news.text();
    update();
  }
};

// ...
NewsMessageArea newsMessageArea = new NewsMessageArea(/* ... */);
// ...
deliverNews.connect(boost::bind(&NewsMessageArea::displayNews, newsMessageArea, _1));

Для решения проблемы удаления наблюдателей, которые были освобождены из списка, boost :: signal предлагает следующее решение

Однако, что если пользователь закрывает область сообщения новостей, уничтожая объект newsMessageArea, о котором знает deliveryNews? Скорее всего, произойдет ошибка сегментации. Однако с Boost.Signals нужно только сделать отслеживание NewsMessageArea, а слот с участием newsMessageArea будет отключено, когда newsMessageArea будет уничтожены. Класс NewsMessageArea отслеживается путем получения публично из класса boost :: signal :: trackable, например ::1029*

struct NewsMessageArea : public MessageArea, public boost::signals::trackable
{
  // ...
};

В настоящее время существует значительное ограничение на использование отслеживаемых объекты в создании соединений слотов: функциональные объекты, построенные с использованием Boost.Bind понимаются так, что указатели или ссылки на отслеживаемые объекты, переданные в boost :: bind, будут найдены и отслежены.

...