CGAL 4.7 - Kinetic Framework: CGAL::Listener< Interface > Class Template Reference

\( \newcommand{\E}{\mathrm{E}} \) \( \newcommand{\A}{\mathrm{A}} \) \( \newcommand{\R}{\mathrm{R}} \) \( \newcommand{\N}{\mathrm{N}} \) \( \newcommand{\Q}{\mathrm{Q}} \) \( \newcommand{\Z}{\mathrm{Z}} \) \( \def\ccSum #1#2#3{ \sum_{#1}^{#2}{#3} } \def\ccProd #1#2#3{ \sum_{#1}^{#2}{#3} }\)

CGAL 4.7 - Kinetic Framework

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
List of all members
CGAL::Listener< Interface > Class Template Reference
Other Classes

`#include <CGAL/Kinetic/Listener.h>`

## Definition

The `Listener` class provides the core of the run time notification system used by the kinetic data structures package.

In short, notifications are handled through proxy objects called listeners. In order to listen for notifications from an object, called the notifier, you make define a small class called a listener proxy, which inherits from the Listener interface defined by the notifier. When constructing your listner poxy, you pass a reference counted pointer to the notifier, which is used to register the proxy for notifications. When a notification occurs, the notifier calls the `new_notification` method on the proxy, passing the type of the notification. The proxy stores a reference counted pointer to the notifier, ensuring that there are never any dangling pointers in the system.

The class `Listener` provides base class for listener proxy objects. A notifier should provide a class which inherits from this base. To use this base class, implement a class, here called `Interface`, which defines a type `Interface::Notification_type` and a type `Interface::Notifier_handle`.

The `Notification_type` is generally an enum with one value for each type of notification which can be used.

The `Notifier_handle` is the type of a (ref counted) pointer to the object providing the notifications. The ref counter pointer must provide a nested type `Pointer` which is the type of a raw pointer.

The `Listener` maintains a ref counted pointer to the object performing notifications. It is registered for notifications on construction and unregistered on destruction using the function `set_listener(Listener<Interface>*)` on the object providing the notifications. The use of ref counted pointers means that as long as the notification object exists, the object providing the notifications must exist, ensuring that the object providing the notifications is not prematurely destroyed.

These objects cannot be copied since the notifier only support one listener. If copying and more than one listener are desired, the `Multi_listener<Interface>` base class should be used instead.

As a side note, Boost provides a similar functionality in the Boost.Signal package. However, it is quite a bit more complex (and flexible). This complexity add significantly to compile time and (although I did not test this directly), I suspect it is much slower at runtime due to the overhead of worrying about signal orders and not supporting single signals. In addition, it does not get on well with Qt due to collisions with the Qt moc keywords.

There is also the TinyTL library which implements signals. As of writing it did not have any easy support for making sure all pointers are valid, so it did not seem to offer significant code saving over writing my own.

See Also
  `Multi_listener<Interface>`

Example

Here is a simplier class that provides notifications:

struct Notifier: public CGAL::Kinetic::Ref_counted<Notifier>
{
public:
Notifier(): data_(0), listener_(NULL){}
struct Listener_interface
{
public:
typedef enum Notification_type {DATA_CHANGED} Notification_type;
typedef Notifier::Handle Notifier_handle;
};
typedef CGAL::Kinetic::Listener<Listener_interface> Listener;
friend class CGAL::Kinetic::Listener<Listener_interface>;
void set_data(int d) {
data_=d;
if (listener_ != NULL) listener_->new_notification(Listener_interface::DATA_CHANGED);
}
protected:
void set_listener(Listener *l) {
listener_= l;
}
Listener* listener() const {return listener_;}
int data_;
Listener *listener_;
};

Now the listener:

struct My_listener: public Notifier::Listener, public CGAL::Kinetic::Ref_counted<My_listener>
{
typedef Notifier::Listener::Notifier_handle PP;
My_listener(PP p): P(p){}
void new_notification(P::Notification_type nt) {
...
}
};

## Types

typedef unspecified_type | Notifier_handle
| This type is inherited from the `Interface` template argument. More...
typedef unspecified_type | Notification_type
| The type (usually an enum) used to distinguish different types of notifications. More...

## Creation

| Listener (Notifier_handle np)
| The `Listener` subscribes to events coming from the notifier and stores a pointer to the notifier.

## Operations

Notifier_handle | notifier ()
| Return a pointer to the notifier.
virtual void | new_notification (Notification_type)
| This method is pure virtual. More...

## Member Typedef Documentation

template<typename Interface >

typedef unspecified_type CGAL::Listener< Interface >::Notification_type

The type (usually an enum) used to distinguish different types of notifications.

This is inherited from the `Interface` template argument.

template<typename Interface >

typedef unspecified_type CGAL::Listener< Interface >::Notifier_handle

This type is inherited from the `Interface` template argument.

It is a reference counted pointer type for the object providing notifications.

## Member Function Documentation

template<typename Interface >

virtual void CGAL::Listener< Interface >::new_notification | ( | Notification_type | ) |  |

virtual

This method is pure virtual.

A class which wishes to receive events must inherit from this class and implement this method. The method will then be called whenever there is a notification.