Skip to content

Commit

Permalink
convert listeners to objects
Browse files Browse the repository at this point in the history
  • Loading branch information
pzuraq committed Sep 10, 2018
1 parent 3353180 commit 86b432b
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 24 deletions.
69 changes: 48 additions & 21 deletions packages/@ember/-internals/meta/lib/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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() {
Expand All @@ -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);
}
}
}
Expand All @@ -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);
}
}
}
Expand Down Expand Up @@ -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);
}
12 changes: 9 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"

[email protected]:
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"

[email protected]:
version "3.0.14"
Expand Down

0 comments on commit 86b432b

Please sign in to comment.