From 86b432ba603ccfd310bd1703c7c5ce569236aff5 Mon Sep 17 00:00:00 2001 From: Christopher Garrett Date: Mon, 10 Sep 2018 14:25:17 -0700 Subject: [PATCH] convert listeners to objects --- packages/@ember/-internals/meta/lib/meta.ts | 69 ++++++++++++++------- yarn.lock | 12 +++- 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/packages/@ember/-internals/meta/lib/meta.ts b/packages/@ember/-internals/meta/lib/meta.ts index aa3457916ad..4d5d51474fb 100644 --- a/packages/@ember/-internals/meta/lib/meta.ts +++ b/packages/@ember/-internals/meta/lib/meta.ts @@ -39,6 +39,27 @@ const SOURCE_DESTROYING = 1 << 1; const SOURCE_DESTROYED = 1 << 2; const META_DESTROYED = 1 << 3; +const enum ListenerKind { + ADD = 0, + ONCE = 1, +} + +interface StringListener { + event: string; + target: null; + method: string; + kind: ListenerKind.ADD | ListenerKind.ONCE; +} + +interface FunctionListener { + event: string; + target: object | null; + method: Function; + kind: ListenerKind.ADD | ListenerKind.ONCE; +} + +type Listener = StringListener | FunctionListener; + export class Meta { _descriptors: any | undefined; _watching: any | undefined; @@ -435,16 +456,16 @@ export class Meta { } } - addToListeners( - eventName: string, - target: object | null, - method: Function | string, - once: boolean - ) { + addToListeners(event: string, target: object | null, method: Function | string, once: boolean) { if (this._listeners === undefined) { this._listeners = []; } - this._listeners.push(eventName, target, method, once); + this._listeners.push({ + event, + target, + method, + kind: once ? ListenerKind.ONCE : ListenerKind.ADD, + } as Listener); } _finalizeListeners() { @@ -468,24 +489,26 @@ export class Meta { this._listenersFinalized = true; } - removeFromListeners(eventName: string, target: any, method: Function | string): void { + removeFromListeners(event: string, target: any, method: Function | string): void { let pointer: Meta | null = this; while (pointer !== null) { let listeners = pointer._listeners; if (listeners !== undefined) { - for (let index = listeners.length - 4; index >= 0; index -= 4) { + for (let index = listeners.length - 1; index >= 0; index--) { + let listener = listeners[index]; + if ( - listeners[index] === eventName && - (!method || (listeners[index + 1] === target && listeners[index + 2] === method)) + listener.event === event && + (!method || (listener.target === target && listener.method === method)) ) { if (pointer === this) { - listeners.splice(index, 4); // we are modifying our own list, so we edit directly + listeners.splice(index, 1); // we are modifying our own list, so we edit directly } else { // we are trying to remove an inherited listener, so we do // just-in-time copying to detach our own listeners from // our inheritance chain. this._finalizeListeners(); - return this.removeFromListeners(eventName, target, method); + return this.removeFromListeners(event, target, method); } } } @@ -497,17 +520,19 @@ export class Meta { } } - matchingListeners(eventName: string) { + matchingListeners(event: string) { let pointer: Meta | null = this; // fix type let result: any[] | undefined; while (pointer !== null) { let listeners = pointer._listeners; if (listeners !== undefined) { - for (let index = 0; index < listeners.length; index += 4) { - if (listeners[index] === eventName) { + for (let index = 0; index < listeners.length; index++) { + let listener = listeners[index]; + + if (listener.event === event) { result = result || []; - pushUniqueListener(result, listeners, index); + pushUniqueListener(result, listener); } } } @@ -812,13 +837,15 @@ export { counters }; allocations, without even bothering to do deduplication -- we can save that for dispatch time, if an event actually happens. */ -function pushUniqueListener(destination: any[], source: any[], index: number) { - let target = source[index + 1]; - let method = source[index + 2]; +function pushUniqueListener(destination: any[], listener: Listener) { + let target = listener.target; + let method = listener.method; + for (let destinationIndex = 0; destinationIndex < destination.length; destinationIndex += 3) { if (destination[destinationIndex] === target && destination[destinationIndex + 1] === method) { return; } } - destination.push(target, method, source[index + 3]); + + destination.push(target, method, listener.kind === ListenerKind.ONCE); } diff --git a/yarn.lock b/yarn.lock index f2280866ef7..7068394768b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -112,6 +112,10 @@ version "0.0.38" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.38.tgz#c1be40aa933723c608820a99a373a16d215a1ca2" +"@types/node@^10.5.5": + version "10.9.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.9.4.tgz#0f4cb2dc7c1de6096055357f70179043c33e9897" + "@types/node@^9.6.0": version "9.6.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.0.tgz#d3480ee666df9784b1001a1872a2f6ccefb6c2d7" @@ -6401,9 +6405,11 @@ route-recognizer@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/route-recognizer/-/route-recognizer-0.3.3.tgz#1d365e27fa6995e091675f7dc940a8c00353bd29" -router_js@2.0.0-beta.4: - version "2.0.0-beta.4" - resolved "https://registry.yarnpkg.com/router_js/-/router_js-2.0.0-beta.4.tgz#b61821c9f6da70e3c6114a09ef8135b389b7d0d0" +router_js@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/router_js/-/router_js-3.0.0.tgz#fcbc928bfc918d9bf1ca6fc02632f2a7cf62e0c1" + dependencies: + "@types/node" "^10.5.5" rsvp@3.0.14: version "3.0.14"