Jive reference manual
List of all members | Public Types | Public Member Functions | Static Public Attributes | Related Functions
jem::util::Event< A, B, C > Class Template Reference

Encapsulates a list of call-back functions that are invoked when a specific event occurs. More...

#include <jem/util/Event.h>

Public Types

typedef EventArguments< A, B, C > Arguments
 A struct for bundling the arguments of an event. More...
 

Public Member Functions

 Event ()
 Creates a new event. More...
 
 ~Event ()
 Deallocates resources. More...
 
void emit () const
 Invokes all delegates connected to this event. More...
 
void emit (A a) const
 Invokes all delegates with a given argument. More...
 
void emit (A a, B b) const
 Invokes all delegates with two given arguments. More...
 
void emit (A a, B b, C c) const
 Invokes all delegates with three given arguments. More...
 
bool enable (bool flag=true)
 Enables or disables this event. More...
 
void clear ()
 Clears the list of delegates. More...
 
bool isConnected () const
 Tests whether the list of delegates is not empty. More...
 
void connectTo (Delegate< Arguments > *d)
 Adds a delegate to this event. More...
 
void disconnectFrom (Delegate< Arguments > *d)
 Removes a delegate from this event. More...
 

Static Public Attributes

static const int ARGUMENT_COUNT = Arguments::ARGUMENT_COUNT
 The number of arguments of this event. More...
 

Related Functions

(Note that these are not member functions.)

template<class E , class F >
void connect (E &e, F func)
 Connects an event to a function. More...
 
template<class E , class T , class M >
void connect (E &e, T *obj, M mfunc)
 Connects an event to a member function. More...
 
template<class E , class T , class M >
void connect (E &e, const Ref< T > &obj, M mfunc)
 Connects an event to a member function. More...
 
template<class E , class F >
void disconnect (E &e, F func)
 Disconnects an event from a function. More...
 
template<class E , class T , class M >
void disconnect (E &e, T *obj, M mfunc)
 Disconnects an event from a member function. More...
 
template<class E , class T , class M >
void disconnect (E &e, const Ref< T > &obj, M mfunc)
 Disconnects an event from a member function. More...
 

Detailed Description

template<class A = Nil, class B = Nil, class C = Nil>
class jem::util::Event< A, B, C >

An Event object encapsulates a list of call-back functions, named delegates, that are invoked when the emit() member function is called. Events can be used, among others, to connect independent software components and to implement the model-view-controller pattern.

The emit() member function accepts up to three arguments that are passed on to each delegate. The argument types are equal to the three template parameters A, B and C of the Event class. The number of arguments accepted by the emit() function is equal to the number of template parameters that are not equal to the type Nil. For instance, the emit() member function accepts only one argument if the template parameters B and C are both equal to Nil. Since Nil is the default value of each template parameter, the number of arguments accepted by emit() is simply equal to the number of template parameters that have been specified. This is illustrated in the following example:

Event<> e0;
Event<int> e1;
Event<int,float> e2;
e0.emit (); // OK: event has no arguments.
e1.emit ( 0 ); // OK: event has a single int argument.
e2.emit ( 0, 1.0 ); // OK: event has an int and a float argument.
e2.emit ( 1 ); // Error: float argument is missing.

For convenience, the arguments accepted by the emit() member function are said to be the arguments of an event.

To be useful, an event should be connected to one or more delegates by calling the non-member function connect(). A delegate can be a regular function or a non-static member function – called a method – of a collectable class (that is, a class derived from the Collectable class). The argument types of the delegate must be compatible with the arguments types of the event. Thus, one can not connect an event with an argument of type int to a delegate with an argument of type int*. One can, however, connect an event to a delegate that has less arguments than the event. In this case, the last few arguments of the event will be discarded when the delegate is called. Here is an example:

void printValue ( int value )
{
System::out() << value;
}
class Foo : public Collectable
{
public:
void setValue ( float value )
{
value_ = value;
}
private:
float value_;
};
int main ()
{
Ref<Foo> foo = newInstance<Foo> ();
Event<int,int> e1;
Event<const char*> e2;
// The following call is valid: the second int argument will be
// discarded.
connect ( e1, & printValue );
// The following call is also valid: the second int argument will
// be discarded, and the first int argument will be converted to a
// float.
connect ( e1, foo, & Foo::setValue );
// This will not compile: an argument of type const char* can not
// be converted to an argument of type int.
connect ( e2, & printValue );
return 0;
}

An event can also be connected to a regular function that acts as a method of a collectable class. Such a function is called a proxy method. The page Proxy methods explains why proxy methods are useful and how proxy methods are defined.

If an event is connected to a method or proxy method of a collectable object, the event will store a WeakRef instead of a Ref that points to the object. This means that the collectable object will be deleted if there are no more Ref instances that point to that object. In other words, an event will not prevent the destruction of a collectable object.

Although jem currently supports only two types of delegates (or three, if you view a proxy method as a distinct type of delegate), you can easily implement other types of delegates. The documentation of the AbstractDelegate and Delegate classes explains how to do this.

Because the Event class is reentrant, an event may be emitted recursively. This means that one may connect an event to a delegate that emits the same event. One may even connect an event to a delegate that deletes the event.

The example below illustrates the power of events. It involves two independent classes that are connected to each other through an event. The first class, named EvolutionGraph represents a graph that dynamically displays the evolution of a given quantity. The second class, named PressureSensor, represents a device that measures the pressure at a given location. Each time it has taken a new measurement, it calls the emit() member of its event named newPressureEvent. The measured pressure is passed as an argument to the emit() function that passes it on to the member function addpoint() of the EvolutionGraph object that is connected to the event.

class EvolutionGraph : public Object
{
public:
void addPoint ( double value );
// More stuff ...
};
class PressureSensor : public Object
{
public:
Event<double> newPressureEvent;
void takeMeasurement ()
{
double p;
// Read pressure p from pressure sensor ...
newPressureEvent.emit ( p );
}
};
int main ()
{
Ref<EvolutionGraph> graph = newInstance<EvolutionGraph> ();
Ref<PressureSensor> sensor = newInstance<PressureSensor> ();
Time t;
connect ( sensor->newPressureEvent,
graph,
& EvolutionGraph::addPoint );
// Initialize the graph and sensor objects ...
// Take measurements for a period of 10.0 seconds. The measured
// pressure will be displayed by the graph object.
t = Time::now() + 10.0;
while ( Time::now() < t )
{
sensor->takeMeasurement ();
}
return 0;
}
See also
Delegate.
Examples:
Event.cpp.

Member Typedef Documentation

template<class A = Nil, class B = Nil, class C = Nil>
typedef EventArguments<A,B,C> jem::util::Event< A, B, C >::Arguments

The Arguments type is a struct that temporarily bundles the arguments passed to the emit() member function. You only have to deal with such a struct if you implement your own delegate type.

See also
Delegate

Constructor & Destructor Documentation

template<class A = Nil, class B = Nil, class C = Nil>
jem::util::Event< A, B, C >::Event ( )

Constructs an Event object that is not connected to any delegate.

template<class A = Nil, class B = Nil, class C = Nil>
jem::util::Event< A, B, C >::~Event ( )

The destructor deallocates the list of delegates that is encapsulated by this event. However, if the destructor is invoked during a call of the emit() function, the deallocation operation will be postponed until the emit() function has returned.

Member Function Documentation

template<class A = Nil, class B = Nil, class C = Nil>
void jem::util::Event< A, B, C >::emit ( ) const

Invokes each delegate connected to this event. No arguments are passed to the delegates. The order in which the delegates are called is unspecified.

Note that this function only exists if all template parameters are equal to Nil.

Precondition
ARGUMENT_COUNT == 0
template<class A = Nil, class B = Nil, class C = Nil>
void jem::util::Event< A, B, C >::emit ( a) const

Invokes each delegate connected to this event with the argument a. The order in which the delegates are called is unspecified.

Note that this function only exists if the last two template parameters are equal to Nil.

Parameters
a- the argument to be passed to each delegate.
Precondition
ARGUMENT_COUNT == 1
and the type A has a copy constructor.
template<class A = Nil, class B = Nil, class C = Nil>
void jem::util::Event< A, B, C >::emit ( a,
b 
) const

Invokes each delegate connected to this event with the arguments a and b. The order in which the delegates are called is unspecified.

Note that this function only exists if the last template parameter equals Nil.

Parameters
a- the first argument to be passed to each delegate.
b- the second argument to be passed to each delegate.
Precondition
ARGUMENT_COUNT == 2
and the types A and B have a copy constructor.
template<class A = Nil, class B = Nil, class C = Nil>
void jem::util::Event< A, B, C >::emit ( a,
b,
c 
) const

Invokes each delegate connected to this event with the arguments a, b and c. The order in which the delegates are called is unspecified.

Note that this function only exists if none of the template parameters equals Nil.

Parameters
a- the first argument to be passed to each delegate.
b- the second argument to be passed to each delegate.
c- the third argument to be passed to each delegate.
Precondition
ARGUMENT_COUNT == 3
and the types A, B and C have a copy constructor.
template<class A = Nil, class B = Nil, class C = Nil>
bool jem::util::Event< A, B, C >::enable ( bool  flag = true)

Enables or disables this event. If the parameter flag is true, then all subsequent invocations of the emit() member function will invoke the delegates to which this event has been connected. If flag equals false, on the other hand, then all subsequent invocations of emit() will have no effect. That is, the delegates will not be called.

An event is enabled by default.

Parameters
flag- a boolean indicating whether this event is to be enabled.
Returns
true if this event was enabled before this function was called, and false otherwise.
template<class A = Nil, class B = Nil, class C = Nil>
void jem::util::Event< A, B, C >::clear ( )

Deletes all delegates to which this event has been connected.

template<class A = Nil, class B = Nil, class C = Nil>
bool jem::util::Event< A, B, C >::isConnected ( ) const

Returns true if this event is connected to one or more delegates, and false otherwise.

Returns
true if the list of delegates is not empty, and false otherwise.
template<class A = Nil, class B = Nil, class C = Nil>
void jem::util::Event< A, B, C >::connectTo ( Delegate< Arguments > *  d)

Connects this event to the delegate d. The delegate will be called when the emit() member function is called. The delegate must have been created by the operator new; it will be deleted automatically when the destructor of this event is called or when the delegate is no longer valid. A delegate can not be added to more than one event.

You only need to use this function if you implement your own delegate type. Otherwise, you should use the non-member function connect().

Parameters
d- a Delegate that has been created by the operator new.
Precondition
The delegate d is not NULL.
template<class A = Nil, class B = Nil, class C = Nil>
void jem::util::Event< A, B, C >::disconnectFrom ( Delegate< Arguments > *  d)

Removes the delegate that is equal to the argument d from this event. That is, this function will iterate over all delegates connected to this event, and will remove the first one that is equal to d. Equality is tested by calling the member function equals.

The delegate d must have been created by the operator new; it will be deleted by this function.

You only need to use this function if you implement your own delegate type. Otherwise, you should use the non-member function disconnect().

Parameters
d- a Delegate that has been created by the operator new.
Precondition
The delegate d is not NULL.

Friends And Related Function Documentation

template<class E , class F >
void connect ( E &  e,
func 
)
related

Connects the event e to the function func. The arguments of the event and of the function must be compatible. The number of function arguments, however, may be less than the number of event arguments.

Parameters
e- an Event object.
func- a pointer to a function.
Precondition
The function func is either a non-member function or a static member function.
Examples:
Event.cpp.
template<class E , class T , class M >
void connect ( E &  e,
T *  obj,
mfunc 
)
related

Connects the event e to the method (non-static member function) or proxy method mfunc. If mfunc is a regular method, it will be invoked on the object obj whenever the event is emitted. The arguments of the method must be compatible with the arguments of the event. The number of method arguments may be less than the number of event arguments.

If mfunc is a proxy method, then it will be called with the object obj as the first arguments whenever the event is emitted. The other arguments of the proxy method must be compatible with the arguments of the event. The number of arguments of the proxy method – not counting the first argument – may be less than the number of event arguments.

Parameters
e- an Event object.
obj- a pointer to a collectable object.
mfunc- a pointer to a regular method or to a proxy method.
Precondition
The type T must be derived from the Collectable class.
template<class E , class T , class M >
void connect ( E &  e,
const Ref< T > &  obj,
mfunc 
)
related

Connects the event e to the method or proxy method mfunc. This function is similar to the connect function described above; the only difference is that it has a Ref object instead of a plain pointer as its second argument. Calling this function has the same effect as:

connect ( e, obj.get(), mfunc );
template<class E , class F >
void disconnect ( E &  e,
func 
)
related

Disconnects the event e from the function func. Note that if the event e has been connected to the function func multiple times, it must be disconnected as many times to completely disconnect the event from the function.

Parameters
e- an Event object.
func- a pointer to a function.
Precondition
The function func is either a non-member function or a static member function.
template<class E , class T , class M >
void disconnect ( E &  e,
T *  obj,
mfunc 
)
related

Disconnects the event e from the method (non-static member function) or proxy method mfunc. Note that if the event e has been connected to the method mfunc multiple times, it must be disconnected as many times to completely disconnect the event from the method.

Parameters
e- an Event object.
obj- a pointer to a collectable object.
mfunc- a pointer to a regular method or to a proxy method.
Precondition
The type T must be derived from the Collectable class.
template<class E , class T , class M >
void disconnect ( E &  e,
const Ref< T > &  obj,
mfunc 
)
related

Disconnects the event e from the method or proxy method mfunc. This function is similar to the disconnect function described above; the only difference is that it has a Ref object instead of a plain pointer as its second argument. Calling this function has the same effect as:

disconnect ( e, obj.get(), mfunc );

Member Data Documentation

template<class A = Nil, class B = Nil, class C = Nil>
const int jem::util::Event< A, B, C >::ARGUMENT_COUNT = Arguments::ARGUMENT_COUNT
static

The static constant ARGUMENT_COUNT equals the number of arguments that are passed by the emit() member function to the delegates connected to an event.