Advertisement
fruffl

Signal/Slot

Oct 15th, 2012
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 10.30 KB | None | 0 0
  1. <?PHP
  2.     /**
  3.      * ILLI
  4.      *
  5.      * @category   ILLI_Core_Pattern
  6.      * @package    ILLI
  7.      * @link       http://illi.be
  8.      * @license    http://l.illi.be
  9.      * @copyright  ILLI Conference
  10.      */
  11.     NAMESPACE ILLI\Core\Pattern;
  12.     USE ILLI\Core\Pattern\Concrete\Signal   AS ConcreteSignal;
  13.     USE ILLI\Core\Member\Method     AS MemberMethod;
  14.     USE ILLI\Core\Invoke\Method     AS InvokeMethod;
  15.     USE ILLI\Core\Invoke\Closure        AS InvokeClosure;
  16.     USE Closure             AS __Closure;
  17.  
  18.     /**
  19.      * ILLI Pattern TRAIT Signal
  20.      *
  21.      * @category   ILLI_Core_Pattern
  22.      * @package    ILLI
  23.      * @subpackage Core\Pattern
  24.      * @namespace  ILLI\Core\Pattern
  25.      * @link       http://illi.be
  26.      * @license    http://l.illi.be
  27.      * @copyright  ILLI Conference
  28.      * @since      2.0.1
  29.      * @version    3.0.1
  30.      */
  31.     TRAIT tSignal
  32.     {
  33.         /**
  34.          * @var array trace adapters
  35.          */
  36.         private $__tSignal_tracesEnabled    = FALSE;
  37.        
  38.         /**
  39.          * @var array trace adapters
  40.          */
  41.         private $__tSignal_traces       = [];
  42.        
  43.         /**
  44.          * @var array signals: spl::method => event => slot => ILLI\Core\Pattern\Concrete\Signal
  45.          */
  46.         protected $__tSignal_hook       = [];
  47.        
  48.         /**
  49.          * @var array results: spl::method => event => slot => mixed
  50.          */
  51.         protected $__tSignal_results        = [];
  52.        
  53.         protected function tSignal_registerConcrete(ConcreteSignal $__ConcreteSignal)
  54.         {
  55.             $method = $__ConcreteSignal->getTrigger()->getMethod();
  56.             $event  = $__ConcreteSignal->getEvent();
  57.             $slot   = $__ConcreteSignal->getSlot();
  58.            
  59.             $stack = & $this->__tSignal_hook[$method][$event];
  60.            
  61.             if($slot === '*')
  62.             {
  63.                 $stack[] = $__ConcreteSignal;
  64.             }
  65.             else
  66.             {
  67.                 $stack[$slot] = $__ConcreteSignal;
  68.             }
  69.            
  70.             return $this;
  71.         }
  72.        
  73.         protected function tSignal_register
  74.         (
  75.             $__trigger,
  76.             $__event,
  77.             $__method,
  78.             & $__DelegateInstance = NULL,
  79.             array $__delegateConstructorArguments = [],
  80.             $__slot = '*'
  81.         )
  82.         {
  83.             if(is_string($__trigger))
  84.             {
  85.                 if(FALSE === strpos($__trigger, '::'))
  86.                     $__trigger = get_called_class().'::'.$__trigger;
  87.                
  88.                 $__trigger = new MemberMethod($__trigger);
  89.             }
  90.             else
  91.             if(FALSE === ($__trigger instanceOf MemberMethod))
  92.             {
  93.                 throw new \Exception('Type-Conflict in trigger');
  94.             }
  95.            
  96.             if(is_string($__method))
  97.             {
  98.                 if(FALSE === strpos($__method, '::'))
  99.                     $__method = get_called_class().'::'.$__method;
  100.                    
  101.                 $__method = new MemberMethod($__method);
  102.             }
  103.            
  104.             if($__method instanceOf MemberMethod)
  105.             {
  106.                 $__method = new InvokeMethod
  107.                 (
  108.                     $__method,
  109.                     ($__method->getClass() === get_called_class())
  110.                         ? $this
  111.                         : $__DelegateInstance,
  112.                     $__delegateConstructorArguments
  113.                 );
  114.             }
  115.             else
  116.             if($__method instanceOf __Closure)
  117.             {
  118.                 $__method = new InvokeClosure($__method, $this);
  119.             }
  120.             else
  121.             if(FALSE === ($__method instanceOf InvokeMethod))
  122.             {
  123.                 throw new \Exception('Type-Conflict in invoke');
  124.             }
  125.            
  126.             $this->tSignal_registerConcrete(new ConcreteSignal
  127.             (
  128.                 $__trigger,
  129.                 $__event,
  130.                 $__method,
  131.                 $__slot
  132.             ));
  133.            
  134.             return $this;
  135.         }
  136.        
  137.         protected function tSignal_unregister($__method, $__event, $__slot)
  138.         {
  139.             if(is_string($__method))
  140.             {
  141.                 if(FALSE === strpos($__method, '::'))
  142.                     $__method = get_called_class().'::'.$__method;
  143.                
  144.                 $__method = (new MemberMethod($__method))->getMethod();
  145.             }
  146.            
  147.             if(FALSE === $this->tSignal_exists($__method))
  148.                 return $this;
  149.                
  150.             if(FALSE === $this->tSignal_exists($__method, $__event))
  151.             {
  152.                 unset($this->__tSignal_hook[$__method]);
  153.                 return $this;
  154.             }
  155.                
  156.             if(FALSE === $this->tSignal_exists($__method, $__event, $__slot))
  157.             {
  158.                 unset($this->__tSignal_hook[$__method][$__event]);
  159.                 return $this;
  160.             }
  161.            
  162.             unset($this->__tSignal_hook[$__method][$__event][$__slot]);
  163.             return $this;
  164.         }
  165.        
  166.         protected function tSignal_exists($__method, $__event = NULL, $__slot = NULL)
  167.         {
  168.             if(is_string($__method))
  169.             {
  170.                 if(FALSE === strpos($__method, '::'))
  171.                     $__method = get_called_class().'::'.$__method;
  172.                
  173.                 $__method = (new MemberMethod($__method))->getMethod();
  174.             }
  175.            
  176.             $stack      = & $this->__tSignal_hook;
  177.             $m_exists   = array_key_exists($__method, $stack);
  178.            
  179.             if($__event === NULL
  180.             || FALSE === $m_exists)
  181.                 return $m_exists;
  182.                
  183.             $stack      = & $stack[$__method];
  184.             $e_exists   = array_key_exists($__event, $stack);
  185.            
  186.             if($__slot === NULL
  187.             || FALSE === $_exists)
  188.                 return $e_exists;
  189.                
  190.             $stack      = & $stack[$__method][$__event];
  191.             $s_exists   = array_key_exists($__slot, $stack);
  192.            
  193.             return $s_exists;
  194.         }
  195.        
  196.         protected function tSignal_send($__method, $__event)
  197.         {
  198.             if(is_string($__method))
  199.             {
  200.                 if(FALSE === strpos($__method, '::'))
  201.                     $__method = get_called_class().'::'.$__method;
  202.                
  203.                 $__method = (new MemberMethod($__method))->getMethod();
  204.             }
  205.            
  206.             if(FALSE === $this->tSignal_exists($__method, $__event))
  207.                 return $this;
  208.                
  209.             $args = func_get_args();
  210.             array_shift($args);
  211.             array_shift($args);
  212.            
  213.             $referenced_args = [];
  214.            
  215.             foreach($args as $key => &$arg)
  216.                 $referenced_args[$key] = &$arg;
  217.            
  218.             if(TRUE === $this->__tSignal_tracesEnabled)
  219.                 $this->__tSignal_traces[$__method][] = debug_backtrace(0, 2);
  220.                
  221.             $stack  = & $this->__tSignal_hook   [$__method][$__event];
  222.             $result = & $this->__tSignal_results    [$__method][$__event];
  223.            
  224.             foreach($stack as $slot => $Slot)
  225.                 $result[$slot] = $Slot->invoke($referenced_args);
  226.         }
  227.     }
  228.  
  229.  
  230.  
  231.     ABSTRACT CLASS aPage EXTENDS aController
  232.     {  
  233.         public function __construct($__method, $__DelegateInstance = NULL, array $__delegateConstructorArguments = [])
  234.         {
  235.             parent::__construct();
  236.             $this->tSignal_register('render', 'preRender', 'exec', $this, func_get_args(), -555);
  237.             $this->tSignal_register('render', 'postRender', 'finalize', $this, func_get_args(), -554);
  238.         }
  239.        
  240.         public function exec()
  241.         {
  242.             var_dump(__METHOD__);
  243.         }
  244.        
  245.         public function finalize($val)
  246.         {
  247.             var_dump(__METHOD__);
  248.             var_dump($val);
  249.         }
  250.        
  251.         public function render()
  252.         {
  253.             $this->tSignal_send('render', 'preRender');
  254.             var_dump(__METHOD__);
  255.             $this->tSignal_send('render', 'postRender', ['val']);
  256.         }
  257.     }
  258.  
  259.    
  260.     class foo extends \ILLI\Core\Web\Ctrl\aPage
  261.     {
  262.         public function myAction($test = null)
  263.         {
  264.             $this->br = $test;
  265.         }
  266.     }
  267.  
  268.     $f = new foo('my', null, ['foobarbaz']);
  269.     $f->render();
  270.     var_dump($f);
  271.  
  272.  
  273.  
  274. ?>
  275.  
  276. string(30) "ILLI\Core\Web\Ctrl\aPage::exec"
  277. string(32) "ILLI\Core\Web\Ctrl\aPage::render"
  278. string(34) "ILLI\Core\Web\Ctrl\aPage::finalize"
  279. array(1) {
  280.   [0]=>
  281.   string(3) "val"
  282. }
  283. object(localhost\illiFW\dev\foo)#18 (11) {
  284.   ["__tSignal_tracesEnabled":"ILLI\Core\Web\Ctrl\aController":private]=>
  285.   bool(false)
  286.   ["__tSignal_traces":"ILLI\Core\Web\Ctrl\aController":private]=>
  287.   array(0) {
  288.   }
  289.   ["__tSignal_hook":protected]=>
  290.   array(1) {
  291.     ["localhost\illiFW\dev\foo::render"]=>
  292.     array(2) {
  293.       ["preRender"]=>
  294.       array(1) {
  295.         [-555]=>
  296.         object(ILLI\Core\Pattern\Concrete\Signal)#321 (4) {
  297.           ["__Trigger":"ILLI\Core\Pattern\Concrete\Signal":private]=>
  298.           object(ILLI\Core\Member\Method)#315 (3) {
  299.             ["__function":protected]=>
  300.             string(6) "render"
  301.             ["__method":protected]=>
  302.             string(32) "localhost\illiFW\dev\foo::render"
  303.             ["__class":protected]=>
  304.             string(24) "localhost\illiFW\dev\foo"
  305.           }
  306.           ["__slot":"ILLI\Core\Pattern\Concrete\Signal":private]=>
  307.           int(-555)
  308.           ["__event":"ILLI\Core\Pattern\Concrete\Signal":private]=>
  309.           string(9) "preRender"
  310.           ["__Callable":protected]=>
  311.           object(ILLI\Core\Invoke\Method)#317 (3) {
  312.             ["__Instance":"ILLI\Core\Invoke\Method":private]=>
  313.             *RECURSION*
  314.             ["__Invokable":protected]=>
  315.             object(ILLI\Core\Member\Method)#316 (3) {
  316.               ["__function":protected]=>
  317.               string(4) "exec"
  318.               ["__method":protected]=>
  319.               string(30) "localhost\illiFW\dev\foo::exec"
  320.               ["__class":protected]=>
  321.               string(24) "localhost\illiFW\dev\foo"
  322.             }
  323.             ["__tConstructMethod__constructorArguments":protected]=>
  324.             array(3) {
  325.               [0]=>
  326.               string(2) "my"
  327.               [1]=>
  328.               NULL
  329.               [2]=>
  330.               array(1) {
  331.                 [0]=>
  332.                 string(9) "foobarbaz"
  333.               }
  334.             }
  335.           }
  336.         }
  337.       }
  338.       ["postRender"]=>
  339.       array(1) {
  340.         [-554]=>
  341.         object(ILLI\Core\Pattern\Concrete\Signal)#325 (4) {
  342.           ["__Trigger":"ILLI\Core\Pattern\Concrete\Signal":private]=>
  343.           object(ILLI\Core\Member\Method)#322 (3) {
  344.             ["__function":protected]=>
  345.             string(6) "render"
  346.             ["__method":protected]=>
  347.             string(32) "localhost\illiFW\dev\foo::render"
  348.             ["__class":protected]=>
  349.             string(24) "localhost\illiFW\dev\foo"
  350.           }
  351.           ["__slot":"ILLI\Core\Pattern\Concrete\Signal":private]=>
  352.           int(-554)
  353.           ["__event":"ILLI\Core\Pattern\Concrete\Signal":private]=>
  354.           string(10) "postRender"
  355.           ["__Callable":protected]=>
  356.           object(ILLI\Core\Invoke\Method)#324 (3) {
  357.             ["__Instance":"ILLI\Core\Invoke\Method":private]=>
  358.             *RECURSION*
  359.             ["__Invokable":protected]=>
  360.             object(ILLI\Core\Member\Method)#323 (3) {
  361.               ["__function":protected]=>
  362.               string(8) "finalize"
  363.               ["__method":protected]=>
  364.               string(34) "localhost\illiFW\dev\foo::finalize"
  365.               ["__class":protected]=>
  366.               string(24) "localhost\illiFW\dev\foo"
  367.             }
  368.             ["__tConstructMethod__constructorArguments":protected]=>
  369.             array(3) {
  370.               [0]=>
  371.               string(2) "my"
  372.               [1]=>
  373.               NULL
  374.               [2]=>
  375.               array(1) {
  376.                 [0]=>
  377.                 string(9) "foobarbaz"
  378.               }
  379.             }
  380.           }
  381.         }
  382.       }
  383.     }
  384.   }
  385.   ["__tSignal_results":protected]=>
  386.   array(1) {
  387.     ["localhost\illiFW\dev\foo::render"]=>
  388.     array(2) {
  389.       ["preRender"]=>
  390.       array(1) {
  391.         [-555]=>
  392.         NULL
  393.       }
  394.       ["postRender"]=>
  395.       array(1) {
  396.         [-554]=>
  397.         NULL
  398.       }
  399.     }
  400.   }
  401.     ...
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement