Pixi的Runner是一个很精简的事件系统,用来处理pixi内部的信号、事件。

整体的实现跟一般的事件系统大同小异,有add, remove, emit等操作:

  • add的时候添加到listener数组里
  • emit的时候遍历listener中的函数然后执行

除此之外,在api方面,pixi不是直接add一个函数,而是add一个包含特定名字函数的对象,当然不太影响功能,但是这么设计不知道出于什么目的,可以todo下。
另外,pixi还为emit添加了两个别名:dispatch和run,这个直接添加到Runner的prototype上:

  1. Object.defineProperties(Runner.prototype, {
  2. dispatch: { value: Runner.prototype.emit },
  3. run: { value: Runner.prototype.emit },
  4. });

有一点值得注意,就是其中涉及的emit过程中修改监听的items时的操作。如果在循环执行items时,add/remove了item,那么可能导致原有的行为出问题,因此,需要对items拷贝并更新,不能在原来的基础上更新。

pixi里边用一个aliasCount标记是否处于运行状态,然后用ensureNonAliasedItems判断是否需要拷贝一下items数组:

private ensureNonAliasedItems(): void
{
    if (this._aliasCount > 0 && this.items.length > 1)
    {
        this._aliasCount = 0;
        this.items = this.items.slice(0);
    }
}

只有当_aliasCount > 0时才会复制,并重置counter。


TODO

  • API设计为add一个包含runner name的函数的对象,为何如此设计?