pax_global_header00006660000000000000000000000064125266075260014525gustar00rootroot0000000000000052 comment=337b6f5e10ea6e0b21e22c7e5788dd3883ae73ff sabre-event-2.0.2/000077500000000000000000000000001252660752600137415ustar00rootroot00000000000000sabre-event-2.0.2/.gitignore000066400000000000000000000002201252660752600157230ustar00rootroot00000000000000#composer vendor composer.lock #binaries bin/sabre-cs-fixer bin/php-cs-fixer bin/phpunit #vim lock files .*.swp #development stuff tests/cov sabre-event-2.0.2/.travis.yml000066400000000000000000000003541252660752600160540ustar00rootroot00000000000000language: php php: - 5.4 - 5.5 - 5.6 - 7 - hhvm matrix: fast_finish: true allow_failures: - php: 7 script: - ./bin/phpunit - ./bin/sabre-cs-fixer fix . --dry-run --diff before_script: composer install --dev sabre-event-2.0.2/CHANGELOG.md000066400000000000000000000024101252660752600155470ustar00rootroot00000000000000ChangeLog ========= 2.0.2 (2015-05-19) ------------------ * This release has no functional changes. It's just been brought up to date with the latest coding standards. 2.0.1 (2014-10-06) ------------------ * Fixed: `$priority` was ignored in `EventEmitter::once` method. * Fixed: Breaking the event chain was not possible in `EventEmitter::once`. 2.0.0 (2014-06-21) ------------------ * Added: When calling emit, it's now possible to specify a callback that will be triggered after each method handled. This is dubbed the 'continueCallback' and can be used to implement strategy patterns. * Added: Promise object! * Changed: EventEmitter::listeners now returns just the callbacks for an event, and no longer returns the list by reference. The list is now automatically sorted by priority. * Update: Speed improvements. * Updated: It's now possible to remove all listeners for every event. * Changed: Now uses psr-4 autoloading. 1.0.1 (2014-06-12) ------------------ * hhvm compatible! * Fixed: Issue #4. Compatiblitiy for PHP < 5.4.14. 1.0.0 (2013-07-19) ------------------ * Added: removeListener, removeAllListeners * Added: once, to only listen to an event emitting once. * Added README.md. 0.0.1-alpha (2013-06-29) ------------------------ * First version! sabre-event-2.0.2/LICENSE000066400000000000000000000030411252660752600147440ustar00rootroot00000000000000Copyright (C) 2013-2015 fruux GmbH (https://fruux.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name Sabre nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. sabre-event-2.0.2/README.md000066400000000000000000000030531252660752600152210ustar00rootroot00000000000000sabre/event =========== A lightweight library for event-based development in PHP. This library provides two patterns: 1. EventEmitter 2. Promises Full documentation can be found on [the website][1]. Installation ------------ Make sure you have [composer][3] installed, and then run: composer require sabre/event "~2.0.0" For legacy reasons, we also provide a unsupported [PHP 5.3 compatible version][6]. We recommend that you update your servers and use the regular version instead, though. Build status ------------ | branch | status | | ------ | ------ | | master | [![Build Status](https://travis-ci.org/fruux/sabre-event.svg?branch=master)](https://travis-ci.org/fruux/sabre-event) | | 2.0 | [![Build Status](https://travis-ci.org/fruux/sabre-event.svg?branch=2.0)](https://travis-ci.org/fruux/sabre-event) | | 1.0 | [![Build Status](https://travis-ci.org/fruux/sabre-event.svg?branch=1.0)](https://travis-ci.org/fruux/sabre-event) | | php53 | [![Build Status](https://travis-ci.org/fruux/sabre-event.svg?branch=php53)](https://travis-ci.org/fruux/sabre-event) | Questions? ---------- Head over to the [sabre/dav mailinglist][4], or you can also just open a ticket on [GitHub][5]. Made at fruux ------------- This library is being developed by [fruux](https://fruux.com/). Drop us a line for commercial services or enterprise support. [1]: http://sabre.io/event/ [3]: http://getcomposer.org/ [4]: http://groups.google.com/group/sabredav-discuss [5]: https://github.com/fruux/sabre-event/issues/ [6]: https://github.com/fruux/sabre-event/tree/php53 sabre-event-2.0.2/bin/000077500000000000000000000000001252660752600145115ustar00rootroot00000000000000sabre-event-2.0.2/bin/.empty000066400000000000000000000000001252660752600156360ustar00rootroot00000000000000sabre-event-2.0.2/composer.json000066400000000000000000000016741252660752600164730ustar00rootroot00000000000000{ "name": "sabre/event", "description": "sabre/event is a library for lightweight event-based programming", "keywords": [ "Events", "EventEmitter", "Promise", "Hooks", "Plugin", "Signal" ], "homepage": "http://sabre.io/event/", "license": "BSD-3-Clause", "require": { "php": ">=5.4.1" }, "authors": [ { "name": "Evert Pot", "email": "me@evertpot.com", "homepage": "http://evertpot.com/", "role": "Developer" } ], "support": { "forum": "https://groups.google.com/group/sabredav-discuss", "source": "https://github.com/fruux/sabre-event" }, "autoload": { "psr-4": { "Sabre\\Event\\": "lib/" } }, "require-dev": { "sabre/cs": "~0.0.1", "phpunit/phpunit" : "*" }, "config" : { "bin-dir" : "bin/" } } sabre-event-2.0.2/lib/000077500000000000000000000000001252660752600145075ustar00rootroot00000000000000sabre-event-2.0.2/lib/EventEmitter.php000066400000000000000000000006251252660752600176360ustar00rootroot00000000000000listeners[$eventName])) { $this->listeners[$eventName] = [ true, // If there's only one item, it's sorted [$priority], [$callBack] ]; } else { $this->listeners[$eventName][0] = false; // marked as unsorted $this->listeners[$eventName][1][] = $priority; $this->listeners[$eventName][2][] = $callBack; } } /** * Subscribe to an event exactly once. * * @param string $eventName * @param callable $callBack * @param int $priority * @return void */ function once($eventName, callable $callBack, $priority = 100) { $wrapper = null; $wrapper = function() use ($eventName, $callBack, &$wrapper) { $this->removeListener($eventName, $wrapper); return call_user_func_array($callBack, func_get_args()); }; $this->on($eventName, $wrapper, $priority); } /** * Emits an event. * * This method will return true if 0 or more listeners were succesfully * handled. false is returned if one of the events broke the event chain. * * If the continueCallBack is specified, this callback will be called every * time before the next event handler is called. * * If the continueCallback returns false, event propagation stops. This * allows you to use the eventEmitter as a means for listeners to implement * functionality in your application, and break the event loop as soon as * some condition is fulfilled. * * Note that returning false from an event subscriber breaks propagation * and returns false, but if the continue-callback stops propagation, this * is still considered a 'successful' operation and returns true. * * Lastly, if there are 5 event handlers for an event. The continueCallback * will be called at most 4 times. * * @param string $eventName * @param array $arguments * @param callback $continueCallBack * @return bool */ function emit($eventName, array $arguments = [], callable $continueCallBack = null) { if (is_null($continueCallBack)) { foreach ($this->listeners($eventName) as $listener) { $result = call_user_func_array($listener, $arguments); if ($result === false) { return false; } } } else { $listeners = $this->listeners($eventName); $counter = count($listeners); foreach ($listeners as $listener) { $counter--; $result = call_user_func_array($listener, $arguments); if ($result === false) { return false; } if ($counter > 0) { if (!$continueCallBack()) break; } } } return true; } /** * Returns the list of listeners for an event. * * The list is returned as an array, and the list of events are sorted by * their priority. * * @param string $eventName * @return callable[] */ function listeners($eventName) { if (!isset($this->listeners[$eventName])) { return []; } // The list is not sorted if (!$this->listeners[$eventName][0]) { // Sorting array_multisort($this->listeners[$eventName][1], SORT_NUMERIC, $this->listeners[$eventName][2]); // Marking the listeners as sorted $this->listeners[$eventName][0] = true; } return $this->listeners[$eventName][2]; } /** * Removes a specific listener from an event. * * If the listener could not be found, this method will return false. If it * was removed it will return true. * * @param string $eventName * @param callable $listener * @return bool */ function removeListener($eventName, callable $listener) { if (!isset($this->listeners[$eventName])) { return false; } foreach ($this->listeners[$eventName][2] as $index => $check) { if ($check === $listener) { unset($this->listeners[$eventName][1][$index]); unset($this->listeners[$eventName][2][$index]); return true; } } return false; } /** * Removes all listeners. * * If the eventName argument is specified, all listeners for that event are * removed. If it is not specified, every listener for every event is * removed. * * @param string $eventName * @return void */ function removeAllListeners($eventName = null) { if (!is_null($eventName)) { unset($this->listeners[$eventName]); } else { $this->listeners = []; } } } sabre-event-2.0.2/lib/Promise.php000066400000000000000000000160061252660752600166410ustar00rootroot00000000000000fulfill and $this->reject. * Using the executor is optional. * * @param callable $executor */ function __construct(callable $executor = null) { if ($executor) { $executor( [$this, 'fulfill'], [$this, 'reject'] ); } } /** * This method allows you to specify the callback that will be called after * the promise has been fulfilled or rejected. * * Both arguments are optional. * * This method returns a new promise, which can be used for chaining. * If either the onFulfilled or onRejected callback is called, you may * return a result from this callback. * * If the result of this callback is yet another promise, the result of * _that_ promise will be used to set the result of the returned promise. * * If either of the callbacks return any other value, the returned promise * is automatically fulfilled with that value. * * If either of the callbacks throw an exception, the returned promise will * be rejected and the exception will be passed back. * * @param callable $onFulfilled * @param callable $onRejected * @return Promise */ function then(callable $onFulfilled = null, callable $onRejected = null) { $subPromise = new self(); switch ($this->state) { case self::PENDING : $this->subscribers[] = [$subPromise, $onFulfilled, $onRejected]; break; case self::FULFILLED : $this->invokeCallback($subPromise, $onFulfilled); break; case self::REJECTED : $this->invokeCallback($subPromise, $onRejected); break; } return $subPromise; } /** * Add a callback for when this promise is rejected. * * I would have used the word 'catch', but it's a reserved word in PHP, so * we're not allowed to call our function that. * * @param callable $onRejected * @return Promise */ function error(callable $onRejected) { return $this->then(null, $onRejected); } /** * Marks this promise as fulfilled and sets its return value. * * @param mixed $value * @return void */ function fulfill($value = null) { if ($this->state !== self::PENDING) { throw new PromiseAlreadyResolvedException('This promise is already resolved, and you\'re not allowed to resolve a promise more than once'); } $this->state = self::FULFILLED; $this->value = $value; foreach ($this->subscribers as $subscriber) { $this->invokeCallback($subscriber[0], $subscriber[1]); } } /** * Marks this promise as rejected, and set it's rejection reason. * * @param mixed $reason * @return void */ function reject($reason = null) { if ($this->state !== self::PENDING) { throw new PromiseAlreadyResolvedException('This promise is already resolved, and you\'re not allowed to resolve a promise more than once'); } $this->state = self::REJECTED; $this->value = $reason; foreach ($this->subscribers as $subscriber) { $this->invokeCallback($subscriber[0], $subscriber[2]); } } /** * It's possible to send an array of promises to the all method. This * method returns a promise that will be fulfilled, only if all the passed * promises are fulfilled. * * @param Promise[] $promises * @return Promise */ static function all(array $promises) { return new self(function($success, $fail) use ($promises) { $successCount = 0; $completeResult = []; foreach ($promises as $promiseIndex => $subPromise) { $subPromise->then( function($result) use ($promiseIndex, &$completeResult, &$successCount, $success, $promises) { $completeResult[$promiseIndex] = $result; $successCount++; if ($successCount === count($promises)) { $success($completeResult); } return $result; } )->error( function($reason) use ($fail) { $fail($reason); } ); } }); } /** * This method is used to call either an onFulfilled or onRejected callback. * * This method makes sure that the result of these callbacks are handled * correctly, and any chained promises are also correctly fulfilled or * rejected. * * @param Promise $subPromise * @param callable $callBack * @return void */ protected function invokeCallback(Promise $subPromise, callable $callBack = null) { if (is_callable($callBack)) { try { $result = $callBack($this->value); if ($result instanceof self) { $result->then([$subPromise, 'fulfill'], [$subPromise, 'reject']); } else { $subPromise->fulfill($result); } } catch (Exception $e) { $subPromise->reject($e); } } else { if ($this->state === self::FULFILLED) { $subPromise->fulfill($this->value); } else { $subPromise->reject($this->value); } } } } sabre-event-2.0.2/lib/PromiseAlreadyResolvedException.php000066400000000000000000000006431252660752600235260ustar00rootroot00000000000000 tests/ ./lib/ sabre-event-2.0.2/tests/000077500000000000000000000000001252660752600151035ustar00rootroot00000000000000sabre-event-2.0.2/tests/ContinueCallbackTest.php000066400000000000000000000036131252660752600216600ustar00rootroot00000000000000on('foo', $bla); $ee->on('foo', $bla); $ee->on('foo', $bla); $continueCounter = 0; $r = $ee->emit('foo', [], function() use (&$continueCounter) { $continueCounter++; return true; }); $this->assertTrue($r); $this->assertEquals(3, $handlerCounter); $this->assertEquals(2, $continueCounter); } function testContinueCallBackBreak() { $ee = new EventEmitter(); $handlerCounter = 0; $bla = function() use (&$handlerCounter) { $handlerCounter++; }; $ee->on('foo', $bla); $ee->on('foo', $bla); $ee->on('foo', $bla); $continueCounter = 0; $r = $ee->emit('foo', [], function() use (&$continueCounter) { $continueCounter++; return false; }); $this->assertTrue($r); $this->assertEquals(1, $handlerCounter); $this->assertEquals(1, $continueCounter); } function testContinueCallBackBreakByHandler() { $ee = new EventEmitter(); $handlerCounter = 0; $bla = function() use (&$handlerCounter) { $handlerCounter++; return false; }; $ee->on('foo', $bla); $ee->on('foo', $bla); $ee->on('foo', $bla); $continueCounter = 0; $r = $ee->emit('foo', [], function() use (&$continueCounter) { $continueCounter++; return false; }); $this->assertFalse($r); $this->assertEquals(1, $handlerCounter); $this->assertEquals(0, $continueCounter); } } sabre-event-2.0.2/tests/EventEmitterTest.php000066400000000000000000000131611252660752600210710ustar00rootroot00000000000000assertInstanceOf('Sabre\\Event\\EventEmitter', $ee); } function testListeners() { $ee = new EventEmitter(); $callback1 = function() { }; $callback2 = function() { }; $ee->on('foo', $callback1, 200); $ee->on('foo', $callback2, 100); $this->assertEquals([$callback2, $callback1], $ee->listeners('foo')); } /** * @depends testInit */ function testHandleEvent() { $argResult = null; $ee = new EventEmitter(); $ee->on('foo', function($arg) use (&$argResult) { $argResult = $arg; }); $this->assertTrue( $ee->emit('foo', ['bar']) ); $this->assertEquals('bar', $argResult); } /** * @depends testHandleEvent */ function testCancelEvent() { $argResult = 0; $ee = new EventEmitter(); $ee->on('foo', function($arg) use (&$argResult) { $argResult = 1; return false; }); $ee->on('foo', function($arg) use (&$argResult) { $argResult = 2; }); $this->assertFalse( $ee->emit('foo', ['bar']) ); $this->assertEquals(1, $argResult); } /** * @depends testCancelEvent */ function testPriority() { $argResult = 0; $ee = new EventEmitter(); $ee->on('foo', function($arg) use (&$argResult) { $argResult = 1; return false; }); $ee->on('foo', function($arg) use (&$argResult) { $argResult = 2; return false; }, 1); $this->assertFalse( $ee->emit('foo', ['bar']) ); $this->assertEquals(2, $argResult); } /** * @depends testPriority */ function testPriority2() { $result = []; $ee = new EventEmitter(); $ee->on('foo', function() use (&$result) { $result[] = 'a'; }, 200); $ee->on('foo', function() use (&$result) { $result[] = 'b'; }, 50); $ee->on('foo', function() use (&$result) { $result[] = 'c'; }, 300); $ee->on('foo', function() use (&$result) { $result[] = 'd'; }); $ee->emit('foo'); $this->assertEquals(['b', 'd', 'a', 'c'], $result); } function testRemoveListener() { $result = false; $callBack = function() use (&$result) { $result = true; }; $ee = new EventEmitter(); $ee->on('foo', $callBack); $ee->emit('foo'); $this->assertTrue($result); $result = false; $this->assertTrue( $ee->removeListener('foo', $callBack) ); $ee->emit('foo'); $this->assertFalse($result); } function testRemoveUnknownListener() { $result = false; $callBack = function() use (&$result) { $result = true; }; $ee = new EventEmitter(); $ee->on('foo', $callBack); $ee->emit('foo'); $this->assertTrue($result); $result = false; $this->assertFalse($ee->removeListener('bar', $callBack)); $ee->emit('foo'); $this->assertTrue($result); } function testRemoveListenerTwice() { $result = false; $callBack = function() use (&$result) { $result = true; }; $ee = new EventEmitter(); $ee->on('foo', $callBack); $ee->emit('foo'); $this->assertTrue($result); $result = false; $this->assertTrue( $ee->removeListener('foo', $callBack) ); $this->assertFalse( $ee->removeListener('foo', $callBack) ); $ee->emit('foo'); $this->assertFalse($result); } function testRemoveAllListeners() { $result = false; $callBack = function() use (&$result) { $result = true; }; $ee = new EventEmitter(); $ee->on('foo', $callBack); $ee->emit('foo'); $this->assertTrue($result); $result = false; $ee->removeAllListeners('foo'); $ee->emit('foo'); $this->assertFalse($result); } function testRemoveAllListenersNoArg() { $result = false; $callBack = function() use (&$result) { $result = true; }; $ee = new EventEmitter(); $ee->on('foo', $callBack); $ee->emit('foo'); $this->assertTrue($result); $result = false; $ee->removeAllListeners(); $ee->emit('foo'); $this->assertFalse($result); } function testOnce() { $result = 0; $callBack = function() use (&$result) { $result++; }; $ee = new EventEmitter(); $ee->once('foo', $callBack); $ee->emit('foo'); $ee->emit('foo'); $this->assertEquals(1, $result); } /** * @depends testCancelEvent */ function testPriorityOnce() { $argResult = 0; $ee = new EventEmitter(); $ee->once('foo', function($arg) use (&$argResult) { $argResult = 1; return false; }); $ee->once('foo', function($arg) use (&$argResult) { $argResult = 2; return false; }, 1); $this->assertFalse( $ee->emit('foo', ['bar']) ); $this->assertEquals(2, $argResult); } } sabre-event-2.0.2/tests/PromiseTest.php000066400000000000000000000112361252660752600200750ustar00rootroot00000000000000fulfill(1); $promise->then(function($value) use (&$finalValue) { $finalValue = $value + 2; }); $this->assertEquals(3, $finalValue); } function testFail() { $finalValue = 0; $promise = new Promise(); $promise->reject(1); $promise->then(null, function($value) use (&$finalValue) { $finalValue = $value + 2; }); $this->assertEquals(3, $finalValue); } function testChain() { $finalValue = 0; $promise = new Promise(); $promise->fulfill(1); $promise->then(function($value) use (&$finalValue) { $finalValue = $value + 2; return $finalValue; })->then(function($value) use (&$finalValue) { $finalValue = $value + 4; return $finalValue; }); $this->assertEquals(7, $finalValue); } function testChainPromise() { $finalValue = 0; $promise = new Promise(); $promise->fulfill(1); $subPromise = new Promise(); $promise->then(function($value) use ($subPromise) { return $subPromise; })->then(function($value) use (&$finalValue) { $finalValue = $value + 4; return $finalValue; }); $subPromise->fulfill(2); $this->assertEquals(6, $finalValue); } function testPendingResult() { $finalValue = 0; $promise = new Promise(); $promise->then(function($value) use (&$finalValue) { $finalValue = $value + 2; }); $promise->fulfill(4); $this->assertEquals(6, $finalValue); } function testPendingFail() { $finalValue = 0; $promise = new Promise(); $promise->then(null, function($value) use (&$finalValue) { $finalValue = $value + 2; }); $promise->reject(4); $this->assertEquals(6, $finalValue); } function testExecutorSuccess() { $promise = (new Promise(function($success, $fail) { $success('hi'); }))->then(function($result) use (&$realResult) { $realResult = $result; }); $this->assertEquals('hi', $realResult); } function testExecutorFail() { $promise = (new Promise(function($success, $fail) { $fail('hi'); }))->then(function($result) use (&$realResult) { $realResult = 'incorrect'; }, function($reason) use (&$realResult) { $realResult = $reason; }); $this->assertEquals('hi', $realResult); } /** * @expectedException \Sabre\Event\PromiseAlreadyResolvedException */ function testFulfillTwice() { $promise = new Promise(); $promise->fulfill(1); $promise->fulfill(1); } /** * @expectedException \Sabre\Event\PromiseAlreadyResolvedException */ function testRejectTwice() { $promise = new Promise(); $promise->reject(1); $promise->reject(1); } function testFromFailureHandler() { $ok = 0; $promise = new Promise(); $promise->error(function($reason) { $this->assertEquals('foo', $reason); throw new \Exception('hi'); })->then(function() use (&$ok) { $ok = -1; }, function() use (&$ok) { $ok = 1; }); $this->assertEquals(0, $ok); $promise->reject('foo'); $this->assertEquals(1, $ok); } function testAll() { $promise1 = new Promise(); $promise2 = new Promise(); $finalValue = 0; Promise::all([$promise1, $promise2])->then(function($value) use (&$finalValue) { $finalValue = $value; }); $promise1->fulfill(1); $this->assertEquals(0, $finalValue); $promise2->fulfill(2); $this->assertEquals([1, 2], $finalValue); } function testAllReject() { $promise1 = new Promise(); $promise2 = new Promise(); $finalValue = 0; Promise::all([$promise1, $promise2])->then( function($value) use (&$finalValue) { $finalValue = 'foo'; return 'test'; }, function($value) use (&$finalValue) { $finalValue = $value; } ); $promise1->reject(1); $this->assertEquals(1, $finalValue); $promise2->reject(2); $this->assertEquals(1, $finalValue); } } sabre-event-2.0.2/tests/benchmark/000077500000000000000000000000001252660752600170355ustar00rootroot00000000000000sabre-event-2.0.2/tests/benchmark/bench.php000066400000000000000000000036201252660752600206260ustar00rootroot00000000000000setUp(); $this->startTime = microtime(true); $this->test(); $this->totalTime = microtime(true) - $this->startTime; return $this->totalTime; } } class OneCallBack extends BenchMark { protected $emitter; protected $iterations = 100000; function setUp() { $this->emitter = new EventEmitter(); $this->emitter->on('foo', function() { // NOOP }); } function test() { for ($i = 0;$i < $this->iterations;$i++) { $this->emitter->emit('foo', []); } } } class ManyCallBacks extends BenchMark { protected $emitter; function setUp() { $this->emitter = new EventEmitter(); for ($i = 0;$i < 100;$i++) { $this->emitter->on('foo', function() { // NOOP }); } } function test() { for ($i = 0;$i < $this->iterations;$i++) { $this->emitter->emit('foo', []); } } } class ManyPrioritizedCallBacks extends BenchMark { protected $emitter; function setUp() { $this->emitter = new EventEmitter(); for ($i = 0;$i < 100;$i++) { $this->emitter->on('foo', function() { }, 1000 - $i); } } function test() { for ($i = 0;$i < $this->iterations;$i++) { $this->emitter->emit('foo', []); } } } $tests = [ 'OneCallBack', 'ManyCallBacks', 'ManyPrioritizedCallBacks', ]; foreach ($tests as $test) { $testObj = new $test(); $result = $testObj->go(); echo $test . " " . $result . "\n"; }