| eZ Components - SignalSlot |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| .. contents:: Table of Contents |
| |
| Introduction |
| ============ |
| |
| The SignalSlot component implements a mechanism for inter- and intra-object |
| communication through the use of signals and slots. Signals are emitted through |
| instances of the ezcSignalCollection class and connected to as many functions |
| as needed. A function that is connected to a signal is called a slot. When the |
| signal is emitted, all connected slots will be run in the order they are |
| connected or in the order of the priorities specified when connecting to the signals. |
| |
| The SignalSlot library supports signals with arguments that are passed on to |
| the slot. Slots must accept all the parameters that are sent to it. The |
| SignalSlot component also supports prioritized slots. Using this mechanism, you can |
| ensure that a slot is run either before or after other slots. |
| |
| There are many different variations of the Signal/Slot model. The original |
| implementations required you to derive from the Signal class in order to have |
| signals or slots. This is acceptable for languages that support multiple |
| inheritance. Newer implemtentations circumvent this problem by representing signals |
| through one instance of the Signal class. In other words, a class that has two |
| signals will have two member variables holding instances of the Signals class. |
| This approach can lead to the creation of a lot of signal objects, which can be |
| especially problematic for scripting languages. As a result, our signal class |
| can represent several signals. |
| |
| Class overview |
| ============== |
| |
| This section gives you an overview of the main classes in the SignalSlot |
| component. |
| |
| ezcSignalCollection |
| This class represents a collection of signals. You can emit or connect to the |
| signals using the methods available in this class. |
| |
| ezcSignalStaticConnections |
| This class holds the static connections for your application. Static |
| connections are connections to signals that can be emitted by several |
| different instances of ezcSignalCollection. |
| |
| Usage |
| ===== |
| |
| A simple signal |
| --------------- |
| |
| This first example shows the simplest possible usage of the signal system. We |
| simply create a new ezcSignalCollection class, connect the "sayHello" signal to |
| the function "hello" and emit the signal. |
| |
| .. include:: tutorial_simple_signal_example.php |
| :literal: |
| |
| The output of this example yields the classic "Hello world". |
| |
| |
| Slot types |
| ---------- |
| Slots are not limited to normal functions. They are specified using the |
| pseudo type callback_. You can specify normal functions, class methods and |
| static class methods, as shown by these variations of the above example. |
| |
| .. _callback: http://php.net/callback |
| |
| 1. functions |
| |
| .. include:: tutorial_simple_signal_example.php |
| :literal: |
| |
| 2. class methods |
| |
| .. include:: tutorial_slot_types_example2.php |
| :literal: |
| |
| 3. static class methods |
| |
| .. include:: tutorial_slot_types_example3.php |
| :literal: |
| |
| |
| Signals in a class |
| ------------------ |
| |
| The typical usage of signals is to have classes emit them when certain events |
| occur. The following example shows a data object that emits a signal when its |
| data is changed. The signal is connected to the caching system, which clears the |
| cache when the data is changed. |
| |
| This example also shows how you can delay the construction of the |
| ezcSignalCollection object. This can be useful in applications where signals |
| are rarely used and you want to avoid the overhead of creating the object. |
| |
| .. include:: tutorial_signals_in_class_example.php |
| :literal: |
| |
| |
| Signals with parameters |
| ----------------------- |
| |
| Signals can have parameters that will be passed on to the receiving slots. The |
| next example is an extension of the previous example, where the data object |
| gives some information about the data that was changed. This information is |
| passed to the receiving slots as a parameter. |
| |
| .. include:: tutorial_signals_with_parameters_example.php |
| :literal: |
| |
| Note that slots must accept the parameters that are passed to them. You will |
| get errors / warnings if you provide too few parameters to the slots you have |
| connected to a signal. |
| |
| Also note that it is not possible to pass signal parameters by |
| reference except for object types, which are always references in PHP 5. |
| |
| |
| Multiple slots |
| -------------- |
| |
| It is possible to connect several slots to one signal. This is just a matter of |
| calling "connect" several times. You can freely mix the different slot types. |
| The following example adds another connection to our previous example. It |
| regenerates the cache after it has been deleted. |
| |
| .. include:: tutorial_multiple_slots_example.php |
| :literal: |
| |
| |
| Prioritized slots |
| ----------------- |
| |
| The previous example showed how to connect several slots to one signal and how |
| they are executed one after another. The example code is also dependent on the |
| order the slots are executed. Normally, slots are executed in the order they are |
| connected. Sometimes, it is not possible to connect slots in the order |
| you want them to be executed. To ensure that some slots are executed before |
| others, you can use the priority system. When connecting, you can specify a |
| priority for that connection. Priority numbers can be |
| specified using any positive integer. The lower the number, the higher the |
| priority. Higher priority connections are executed first. By default, |
| connections are made with a priority of 1000. |
| |
| This example shows how the connections from the previous example could have been |
| specified to ensure the order in which the slots are called. |
| |
| .. include:: tutorial_prioritized_slots_example.php |
| :literal: |
| |
| Excessive usage of the priority system can lead to unmaintainable code, since it |
| is hard to track the various priorities that are in use in a system. We do not |
| recommend using it unless absolutely neccessary. |
| |
| |
| Static connections |
| ------------------ |
| |
| Sometimes it is useful to connect a signal with a specific name, regardless of |
| the sender ezcSignalCollection, to a slot. Consider what would happen if the |
| Data class from our previous example was extended to a DataObject class with a |
| potential of thousands of instances. If you wanted the caching system to work, |
| you would have to connect each one to the caching system upon creation. |
| |
| This is both unpractical and time consuming. The solution is to use static |
| connections. When creating ezcSignalCollection objects, you can provide an |
| identifier to the constructor. Using ezcSignalStaticConnections, you can |
| connect to all signals from a source with a specific identifier. |
| |
| The following example shows how to use static connections to connect the signal |
| "dataChanged" from all objects of the type "DataObject" to the caching system. |
| |
| .. include:: tutorial_static_connections_example.php |
| :literal: |
| |
| |
| You can freely mix static connectons and normal connections. Static connections |
| with the same priority as normal connections are executed after the normal connections. |
| |
| Lazy initialization |
| ------------------- |
| |
| Lazy initialization is a mechanism to load and configure a component, only |
| when it is really used in your application. This mechanism saves time for |
| parsing the classes and configuration, when the component is not used at all |
| during one request. You can find a description how you can use it for your |
| own components and how it works in the `ezcBase tutorial`__. The keyword for |
| the signal slot component is *ezcInitSignalStaticConnections*. |
| |
| __ introduction_Base.html#lazy-initialization |
| |
| .. include:: tutorial_lazy_initialization.php |
| :literal: |
| |
| This example shows a very simple signal setup with only one signal mapped to a |
| custom function, which just dumps the passed data. The main difference, |
| compared to earlier examples, is that we roll out the configuration to an |
| own class, and define a callback using ezcBaseInit::setCallback to this class, |
| which will be called with the static connections manager as a parameter on the |
| first request for a yet uninitialized signal connection. |
| |
| ezcBaseInit::setCallback accepts as a first parameter a component specific |
| key, which lets the component later request the right configuration callback. |
| This class must implement the ezcBaseConfigurationInitializer class. |
| The second parameter is the name of the class to perform the static callback |
| on. Each component's lazy initialization calls the static method |
| configureObject() on the referenced class. |
| |
| When a signal connection is really created and used, like shown in line 22 of |
| the example, the collection will be configured by the custom configuration |
| class. The used identifier "default" may be used for the default signal |
| collection. It of course works for other signal collections, too, like the |
| example for static connections shows. |
| |
| |
| .. |
| Local Variables: |
| mode: rst |
| fill-column: 79 |
| End: |
| vim: et syn=rst tw=79 |