Zend - The PHP Company




Miscellaneous

Add Code


Signals & Slots  

Type: code fragment
Added by: zak
Entered: 16/10/2001
Last modified: 01/11/2000
Rating: - (fewer than 3 votes)
Views: 4390
Slots and Signals ================= This code is a simple implementation of the slots/signals concept. Slots and signals are used by the Qt toolkit as a kind of extra-powerful callback. The best source of information on them is the Qt toolkit docs see (http://doc.trolltech.com/3.0/signalsandslots.html) To briefly summarize, they allow you to bind a signal to one or more slots and/or signals. When a signal is 'emitted', all slots and signals bound to it are called. Each slot corresponds to a single function. When a signal is called by another signal, the called signal is emitted, calling the slots and signals that it is bound to. Any parameters passed when the signal is emitted are passed to the slots and signals that that are called. This easily allows you to write handler functions (slots) and bind them to events (signals) as needed - without having to make explicit function calls or rewrite handler functions just to accomodate minor modifications in how a function is called. I find slots and signals particular useful for message passing and error handling. Have Fun! :) Zak Greant


<?php
/*
   +----------------------------------------------------------------------+
   | Foo and Associates Library Code                                      |
   +----------------------------------------------------------------------+
   | Copyright (c) 2001 Foo and Associates, All Rights Reserved           |
   +----------------------------------------------------------------------+
   | This file is subject to version 1.00 of the Foo and Associates       |
   | license. A copy of this license is stored in the FOO-LICENCE file.   |
   | The licence can be viewed online at http://fooassociates.com/license |
   | Send email to license@fooassociate.com to receive a copy via email.  |
   +----------------------------------------------------------------------+
   | Authors: Zak Greant <zak@fooassociates.com>                          |
   +----------------------------------------------------------------------+
*/

/* $Id: slots.php,v 1.2 2001/10/16 07:26:42 zak Exp $ */

/* TODO: Add additional error handling/reporting */

/* Slots and Signals
** =================
** This code is a simple implementation of the slots/signals concept.
** Slots and signals are used by the Qt toolkit as a kind of extra-powerful callback.
** The best source of information on them is the Qt toolkit docs
**      see (http://doc.trolltech.com/3.0/signalsandslots.html)
**
** To briefly summarize, they allow you to bind a signal to one or more slots and/or signals.
** When a signal is 'emitted', all slots and signals bound to it are called. Each slot corresponds
** to a single function. When a signal is called by another signal, the called signal is emitted,
** calling the slots and signals that it is bound to.
**
** Any parameters passed when the signal is emitted are passed to the slots and signals that
** that are called. This easily allows you to write handler functions (slots) and bind them to events
** (signals) as needed - without having to make explicit function calls or rewrite handler functions
** just to accomodate minor modifications in how a function is called.
**
** I find slots and signals particular useful for message passing and error handling.
**
** Have Fun! :)
**
** Zak Greant
*/

function slot (                                             # Request or define a slot (one arg == request, two == define)
    
$name,                                                  # The name of the slot to request or define
    
$handler NULL                                         # The handler to bind to a slot when defining it (optional)
) {
    static 
$slots = array ();                               # A static array containing all defined slots

    
if (is_null ($handler)) {                               # If the function is called with 1 argument
        
if (isset ($slots[$name]))                          # and the slot name requested is defined
            
return array (                                  # Return the slot
                
'type' => 'slot',                           # Note that each slot is an array containing 3 elements
                
'name' => $name,
                
'handler' => $slots[$name]
            );

        return 
FALSE;                                       # If the slot name requested is not defined, exit
    
}
                                                            
# If the function has been called with 2 arguments
    
if (! function_exists ($handler)) {                     # Ensure that the function named in $handler is defined
        
trigger_error ("Cannot create slot '$name'. Function '$handler' is not defined.");
        return 
FALSE;
    }

    
$slots[(string) $name] = (string) $handler;             # Define the slot
    
return array (
        
'type' => 'slot',
        
'name' => $name,
        
'handler' => $slots[$name]
    );
}

function 
signal (                                           # Return a signal (and define if needed)
    
$name                                                   # The name of the signal to define (and return)
) {
    static 
$signals = array ();                             # A static array containing all signals

    
if (! isset ($signals[$name]))                          # If the called signal has not been defined, define it
        
$signals[$name] = TRUE;                             # Note that signals can easily be numeric values, allowing for numeric constants

    
return array (
        
'type' => 'signal',
        
'name' => $name
    
);
}

function 
signal_bind (                                      # Bind a signal to a slot or another signal signal (or list the bindings for a signal)
    
$signal,                                                # The signal to bind/unbind - should be a call to signal()
    
$slot_or_signal NULL                                  # The slot/signal to bind to the signal (optional)
) {
    static 
$bindings = array ();                            # A static array containing all the signal to signal/slot bindings

    
if (is_null ($slot_or_signal)) {                        # If called with one argument
        
if (is_array ($signal)
            && 
'signal' == $signal['type'])
            
$signal $signal['name'];

        if (isset (
$bindings[$signal]))
            return 
$bindings[$signal];                      # Return an array of signals and/or slots bound to $signal

        
return array ();                                    # Return an empty array if nothing is bound to $signal
    
}

    if (! 
is_array ($signal)
        || 
'signal' != $signal['type']                      # If $signal is not a valid signal
        
|| ! is_array ($slot_or_signal))                    # If $slot_or_signal can not be a valid signal or slot
        
return FALSE;

    
$bindings[$signal['name']][] = $slot_or_signal;         # Bind $slot_or_signal to $signal
    
return TRUE;
}

function 
emit (                                             # Call all the slots/signals bound to a signal
    
$signal                                                 # The signal to throw
) {
    
$args func_get_args ();                               # Get the arguments passed with the signal
    
array_shift ($args);                                    # Strip off the first argument - it contains the signal ($signal)

    
foreach (signal_bind ($signal) as $slot_or_signal) {    # Call every signal or slot bound to $signal
        
if ('signal' == $slot_or_signal['type']) {          # If the current bound item is a signal
            
array_unshift ($args$slot_or_signal['name']); # Pass the arguments to the signal called
            
call_user_func_array ('emit'$args);
            continue;
        }

        
call_user_func_array (                              # If the current bound item is not a signal
            
$slot_or_signal['handler'],                     # It must be a slot - call it
            
$args                                           # Pass the arguments to it
        
);
    }
}

/*  Basic usage examples
    Uncomment to perform some simple tests
function bar () {
    $args = func_get_args ();
    echo implode ('::', $args), "<br />";

}

slot ('argent', create_function ('', 'echo "Silver<br />";'));

signal_bind (signal ('foo'), slot ('bar', 'bar'));
signal_bind (signal ('foo'), slot ('bar'));
signal_bind (signal ('far'), signal ('foo'));
signal_bind (signal ('far'), slot ('argent'));
emit ('foo', 'a', 1, 2);
emit ('foo', 2, 1);
emit ('far', 'test', 'test2');
emit ('lar', 'loo');
*/
?>


?>


Usage Example




Rate This Script





Search



This Category All Categories