Skip to content

Instantly share code, notes, and snippets.

@xsist10
Last active January 21, 2017 17:28
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xsist10/824b559c4effaf43ddb3 to your computer and use it in GitHub Desktop.
Save xsist10/824b559c4effaf43ddb3 to your computer and use it in GitHub Desktop.
An event dispatcher in a tweet
<?php
// Version 1
// Minified
// class Dispatch{function add($e,$l){$this->l[$e][]=$l;}function trigger($e,$d){foreach ($this->l[$e] as $l)call_user_func_array($l, $d);}}
class Dispatch{
function add($e, $l) {
$this->l[$e][] = $l;
}
function trigger($e, $d) {
foreach ($this->l[$e] as $l) {
call_user_func_array($l, $d);
}
}
}
class Greeter {
public function greet($name) {
echo "Hello $name\n";
}
}
$dispatch = new Dispatch();
$dispatch->add('greet', array(new Greeter, 'greet'));
$dispatch->trigger('greet', array('Bob'));
<?php
// Version 2
// Minified
// class Dispatch{function add($e,$l){$this->l[$e][]=$l;}function trigger($e,$d){foreach($this->l[$e] as$l)$l($d);}}
class Dispatch {
function add($e, $l) { $this->l[$e][]=$l; }
function trigger($e, $d) { foreach ($this->l[$e] as $l) $l($d); }
}
$dispatch = new Dispatch();
$dispatch->add('greet', function ($name) {
echo "Hello $name\n";
});
$dispatch->trigger('greet', 'Bob');
@matthiasnoback
Copy link

Oooh that looks pritty nice, @mathiasverraes!

By the way, I really like this as an exercise since it exposes all kinds of hidden assumptions, like a preference for classes, and an aversion of using different function parameters to trigger different actions :)

@xsist10
Copy link
Author

xsist10 commented Oct 6, 2014

Nicked your update @mathiasverraes and used all that saved space you made to add event propagation control.

✔︎ It calls event listeners in the right order with event propagation

<?php

function e($n,$p,$c=0){static $a;@krsort($a[$n]);if($c)$a[$n][$p][]=$c;else foreach($a[$n] as$q)foreach($q as$r)if(!$r($p))return;}

function it($m,$p){echo ($p?'✔︎':'✘')." It $m\n"; if(!$p){$GLOBALS['f']=1;}}function done(){if(@$GLOBALS['f'])die(1);}

ob_start();
e(
    'event',
    0,
    function ($data) {
        echo "event, $data, priority 0;";
        return true;
    }
);
e(
    'event',
    10,
    function ($data) {
        echo "event, $data, priority 10;";
        return true;
    }
);
e(
    'other_event',
    -5,
    // Should not reach this event due to propagation termination
    function ($data) {
        echo "other_event, $data, priority -5;";
        return true;
    }
);
e(
    'other_event',
    5,
    function ($data) {
        echo "other_event, $data priority 5;";
        return false; // Will stop event propagation after this event
    }
);
e('event', 'dataX');
e('other_event', 'dataY');
$output = ob_get_contents();
ob_end_clean();

it(
    'calls event listeners in the right order with event propagation',
    $output === 'event, dataX, priority 10;event, dataX, priority 0;other_event, dataY priority 5;'
);

@liuggio
Copy link

liuggio commented Oct 22, 2014

maybe you are interested on a something like a framework ... https://github.com/liuggio/sized140

@jm42
Copy link

jm42 commented Oct 31, 2014

Dependency injection container in a tweet ... https://gist.github.com/jm42/3c32dd50bb9d09f57c4a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment