Pimcore event

i rewrote the complete Pimcore_Event class internals. The class has the same "interface".

Here are some Benchmarks running on my Workstation: 

my
Benchmark testRegisterBenchmark took 				0.29848313331604 seconds
Benchmark testRegisterCallBenchmark took 			0.6698169708252 seconds
Benchmark testCallBenchmark took 				0.10555219650269 seconds
Benchmark testUnregisterBenchmark took 				0.75062298774719 seconds

Pimcore
Benchmark testRegisterBenchmark took 				35.438072919846 seconds
Benchmark testRegisterCallBenchmark took 			36.156630992889 seconds
Benchmark testCallBenchmark took 				0.1464319229126 seconds
Benchmark testUnregisterBenchmark took 				73.74832201004 seconds

i also changed that you cant register 2 events with the same priority.

here are all tests incl. 2 functions to show the difference between both implementations (testImprovement*)

i would like to add the tests to the main code but the current implementation of the tests confused me.

```php

<?php

require_once __DIR__.'/../../../pimcore/lib/Pimcore/Event.php';

class pimcore_mock {

    public static $invoced = 0;
    public static $callstack = array();

    function reset() {
        self::$invoced = 0;
        self::$callstack = array();
    }

    static function shutdown1() {
        self::$callstack[] = array(__FUNCTION__, func_get_args());
        self::$invoced++;
    }

    static function shutdown2() {
        self::$callstack[] = array(__FUNCTION__, func_get_args());
        self::$invoced++;
    }

    static function shutdown3() {
        self::$callstack[] = array(__FUNCTION__, func_get_args());
        self::$invoced++;
    }

    static function shutdown4() {
        self::$callstack[] = array(__FUNCTION__, func_get_args());
        self::$invoced++;
    }
}

class Test_Pimcore_Event extends PHPUnit_Framework_TestCase {

    function setUp() {
        pimcore_mock::reset();
        Pimcore_Event::reset();
    }

    function testRegisterFire() {

        Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown1"), array(), 999);
        $this->assertEquals(pimcore_mock::$invoced, 0);
        Pimcore_Event::fire("pimcore.shutdown");
        $this->assertEquals(pimcore_mock::$invoced, 1);
        Pimcore_Event::fire("pimcore.shutdown");
        $this->assertEquals(pimcore_mock::$invoced, 2);
    }

    function testOrder() {

        Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown1"), array(), 1);
        Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown2"), array(), 3);
        Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown3"), array(), 2);
        Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown4"), array());

        Pimcore_Event::fire("pimcore.shutdown");

        $this->assertEquals(pimcore_mock::$callstack[0][0], 'shutdown4');
        $this->assertEquals(pimcore_mock::$callstack[1][0], 'shutdown1');
        $this->assertEquals(pimcore_mock::$callstack[2][0], 'shutdown3');
        $this->assertEquals(pimcore_mock::$callstack[3][0], 'shutdown2');
    }

    function testUnregister() {
        Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown1"), array(), 1);
        Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown2"), array(), 2);
        Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown3"), array(), 3);

        Pimcore_Event::unregister('pimcore.shutdown', array("pimcore_mock", "shutdown2"));
        Pimcore_Event::fire("pimcore.shutdown");

        $this->assertEquals(pimcore_mock::$callstack[0][0], 'shutdown1');
        $this->assertEquals(pimcore_mock::$callstack[1][0], 'shutdown3');
        $this->assertFalse(isset(pimcore_mock::$callstack[2]));
    }

    function testUnregisterDoesntExists() {
        // just expects that there is no notice ir something like that
        Pimcore_Event::unregister('pimcore.shutdown', array("pimcore_mock", "shutdown2"));
    }

    function testUnknownFire() {
        // just expects that there is no notice ir something like that
        Pimcore_Event::fire("unknown");
    }

    function testClosure() {

        $ok = false;

        Pimcore_Event::register("pimcore.shutdown", function() use (&$ok) {
            $ok = true;
        });
        Pimcore_Event::fire("pimcore.shutdown");

        $this->assertTrue($ok);
    }

    /**
     * the old implementation fail here, you cant have more than 1000
     * events if you dont set the priority as a parameter
     */
    function testImprovementUnlimitRegistrations() {
        for($i=0;$i<1100;$i++)
            Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown1"), array());

        Pimcore_Event::fire("pimcore.shutdown");
        $this->assertEquals(pimcore_mock::$invoced, 1100);
    }

    /**
     * the old implementation fail here, you couldnt have more than 1 event for every priority
     */
    function testImprovementCantOverwriteEvents() {
        Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown1"), array(), 1);
        Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown1"), array(), 1);

        Pimcore_Event::fire("pimcore.shutdown");
        $this->assertEquals(pimcore_mock::$invoced, 2);
    }

    function testArgs() {
        $args = array('a', 'b', 'c');
        Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown1"), $args, 1);
        Pimcore_Event::fire("pimcore.shutdown");
        $this->assertEquals(pimcore_mock::$callstack[0][1], $args);
    }

    function testArgsOnFireMerge() {
        $args = array('a', 'b', 'c');
        Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown1"), $args, 1);
        Pimcore_Event::fire("pimcore.shutdown", array('d'));
        $this->assertEquals(pimcore_mock::$callstack[0][1], array('a', 'b', 'c', 'd'));
    }

    function testArgsOnFireReplace() {
        $args = array('a' => 'a', 'b' => 'b', 'c' => 'c');
        Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown1"), $args, 1);
        Pimcore_Event::fire("pimcore.shutdown", array('a' => 'd'));
        $this->assertEquals(pimcore_mock::$callstack[0][1], array('d', 'b', 'c'));
    }

    function testRegisterBenchmark() {

        $time = microtime(true);

        for($j=0; $j < 50; $j++) {

            Pimcore_Event::reset();
            pimcore_mock::reset();

            for($i = 0; $i < 333; $i++) {
                Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown1"), array());
                Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown2"), array());
                Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown3"), array());
            }
        }

        echo 'Benchmark '.__FUNCTION__.' took '."\t\t\t\t". ( microtime(true) - $time) .' seconds'."\n";
    }

    function testRegisterCallBenchmark() {

        $time = microtime(true);

        for($j=0; $j < 50; $j++) {

            Pimcore_Event::reset();
            pimcore_mock::reset();

            for($i = 0; $i < 333; $i++) {
                Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown1"), array());
                Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown2"), array());
                Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown3"), array());
            }

            Pimcore_Event::fire("pimcore.shutdown");
            $this->assertEquals(pimcore_mock::$invoced, 999);
        }

        echo 'Benchmark '.__FUNCTION__.' took '."\t\t\t". ( microtime(true) - $time) .' seconds'."\n";
    }

    function testCallBenchmark() {

        $time = microtime(true);

        Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown1"), array());

        for($i = 0; $i < 10000; $i++) {
            Pimcore_Event::fire("pimcore.shutdown");
        }

        echo 'Benchmark '.__FUNCTION__.' took '."\t\t\t\t\t". ( microtime(true) - $time) .' seconds'."\n";
    }

    function testUnregisterBenchmark() {

        $time = microtime(true);

        for($j=0; $j < 50; $j++) {

            Pimcore_Event::reset();
            pimcore_mock::reset();

            for($i = 0; $i < 999; $i++) {
                Pimcore_Event::register("pimcore.shutdown", array("pimcore_mock", "shutdown1"), array());
                Pimcore_Event::register("pimcore.shutdown2", array("pimcore_mock", "shutdown1"), array());
            }

            Pimcore_Event::unregister('pimcore.shutdown', array("pimcore_mock", "shutdown1"));
            Pimcore_Event::unregister('pimcore.shutdown', array("pimcore_mock", "shutdown1"));
        }

        echo 'Benchmark '.__FUNCTION__.' took '."\t\t\t\t". ( microtime(true) - $time) .' seconds'."\n";
    }

}

````