Skip to content

Commit 57171c7

Browse files
author
vakrilov
committed
WeakEvents with map
1 parent 54f6c35 commit 57171c7

8 files changed

Lines changed: 236 additions & 287 deletions

File tree

apps/tests/ui/helper.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ export function forceGC() {
225225
if (platform.device.os === platform.platformNames.ios) {
226226
// Could cause GC on the next call.
227227
new ArrayBuffer(4 * 1024 * 1024);
228+
TKUnit.wait(ASYNC);
228229
}
229230
utils.GC();
230231
}

apps/tests/weak-event-listener-tests.ts

Lines changed: 89 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -4,89 +4,64 @@ import observable = require("data/observable");
44
import weakEvents = require("ui/core/weak-event-listener");
55
import helper = require("./ui/helper");
66

7+
class Target {
8+
public counter: number = 0;
9+
public onEvent(data: observable.EventData) {
10+
this.counter++;
11+
}
12+
13+
}
14+
715
export function test_addWeakEventListener_throwsWhenCalledwitnInvalid_source() {
816
TKUnit.assertThrows(() => {
9-
weakEvents.WeakEventListener.addWeakEventListener({
10-
source: undefined,
11-
target: {},
12-
handler: emptyHandler,
13-
eventName: observable.Observable.propertyChangeEvent
14-
});
17+
weakEvents.addWeakEventListener(undefined, "eventName", emptyHandler, {});
1518
});
1619
}
1720

1821
export function test_addWeakEventListener_throwsWhenCalledwitnInvalid_target() {
1922
TKUnit.assertThrows(() => {
20-
weakEvents.WeakEventListener.addWeakEventListener({
21-
source: new observable.Observable(),
22-
target: undefined,
23-
handler: emptyHandler,
24-
eventName: observable.Observable.propertyChangeEvent
25-
});
23+
weakEvents.addWeakEventListener(new observable.Observable(), "eventName", emptyHandler, undefined);
2624
});
2725
}
2826

2927
export function test_addWeakEventListener_throwsWhenCalledwitnInvalid_handler() {
3028
TKUnit.assertThrows(() => {
31-
weakEvents.WeakEventListener.addWeakEventListener({
32-
source: new observable.Observable(),
33-
target: {},
34-
handler: undefined,
35-
eventName: observable.Observable.propertyChangeEvent
36-
});
29+
weakEvents.addWeakEventListener(new observable.Observable(), "eventName", undefined, {});
3730
});
3831
}
3932

4033
export function test_addWeakEventListener_throwsWhenCalledwitnInvalid_name() {
4134
TKUnit.assertThrows(() => {
42-
weakEvents.WeakEventListener.addWeakEventListener({
43-
source: new observable.Observable(),
44-
target: {},
45-
handler: emptyHandler,
46-
eventName: undefined
47-
});
35+
weakEvents.addWeakEventListener(new observable.Observable(), undefined, emptyHandler, {});
4836
});
4937
}
5038

5139
export function test_addWeakEventListener_listensForEvent() {
5240
var source = new observable.Observable();
53-
var target = new Object;
54-
var callbackCalled = false;
55-
var handler = function (args: observable.EventData) {
56-
callbackCalled = true;
57-
}
41+
var target = new Target();
5842

59-
weakEvents.WeakEventListener.addWeakEventListener({
60-
source: source,
61-
target: target,
62-
handler: handler,
63-
eventName: observable.Observable.propertyChangeEvent
64-
})
43+
weakEvents.addWeakEventListener(
44+
source,
45+
observable.Observable.propertyChangeEvent,
46+
target.onEvent,
47+
target);
48+
49+
helper.forceGC();
6550

6651
source.set("testProp", "some value");
6752

68-
TKUnit.assert(callbackCalled, "Handler not called.");
53+
TKUnit.assertEqual(target.counter, 1, "Handler not called.");
6954
}
7055

7156
export function test_removeWeakEventListener_StopsListeningForEvet() {
7257
var source = new observable.Observable();
73-
var target = new Object;
74-
var callbackCalled = false;
75-
var handler = function (args: observable.EventData) {
76-
callbackCalled = true;
77-
}
78-
79-
var listenerID = weakEvents.WeakEventListener.addWeakEventListener({
80-
source: source,
81-
target: target,
82-
handler: handler,
83-
eventName: observable.Observable.propertyChangeEvent
84-
})
58+
var target = new Target();
8559

86-
weakEvents.WeakEventListener.removeWeakEventListener(listenerID);
60+
weakEvents.addWeakEventListener(source, observable.Observable.propertyChangeEvent, target.onEvent, target);
61+
weakEvents.removeWeakEventListener(source, observable.Observable.propertyChangeEvent, target.onEvent, target)
8762

8863
source.set("testProp", "some value");
89-
TKUnit.assert(!callbackCalled, "Handler should not be called.");
64+
TKUnit.assertEqual(target.counter, 0, "Handler should not be called.");
9065
}
9166

9267
export function test_handlerIsCalled_WithTargetAsThis() {
@@ -98,32 +73,18 @@ export function test_handlerIsCalled_WithTargetAsThis() {
9873
callbackCalled = true;
9974
}
10075

101-
weakEvents.WeakEventListener.addWeakEventListener({
102-
source: source,
103-
target: target,
104-
handler: handler,
105-
eventName: observable.Observable.propertyChangeEvent
106-
})
76+
weakEvents.addWeakEventListener(source, observable.Observable.propertyChangeEvent, handler, target);
10777

10878
source.set("testProp", "some value");
10979
TKUnit.assert(callbackCalled, "Handler not called.");
11080
}
11181

11282
export function test_listnerDoesNotRetainTarget() {
11383
var source = new observable.Observable();
114-
var target = new Object;
84+
var target = new Target();
11585
var callbackCalled = false;
116-
var handler = function (args: observable.EventData) {
117-
TKUnit.assertEqual(this, target, "this should be the target");
118-
callbackCalled = true;
119-
}
12086

121-
weakEvents.WeakEventListener.addWeakEventListener({
122-
source: source,
123-
target: target,
124-
handler: handler,
125-
eventName: observable.Observable.propertyChangeEvent
126-
})
87+
weakEvents.addWeakEventListener(source, observable.Observable.propertyChangeEvent, target.onEvent, target);
12788

12889
var targetRef = new WeakRef(target);
12990
target = undefined;
@@ -134,19 +95,10 @@ export function test_listnerDoesNotRetainTarget() {
13495

13596
export function test_listnerDoesNotRetainSource() {
13697
var source = new observable.Observable();
137-
var target = new Object();
98+
var target = new Target();
13899
var callbackCalled = false;
139-
var handler = function (args: observable.EventData) {
140-
TKUnit.assertEqual(this, target, "this should be the target");
141-
callbackCalled = true;
142-
}
143100

144-
weakEvents.WeakEventListener.addWeakEventListener({
145-
source: source,
146-
target: target,
147-
handler: handler,
148-
eventName: observable.Observable.propertyChangeEvent
149-
})
101+
weakEvents.addWeakEventListener(source, observable.Observable.propertyChangeEvent, target.onEvent, target);
150102

151103
var sourceRef = new WeakRef(source);
152104
source = undefined;
@@ -155,50 +107,74 @@ export function test_listnerDoesNotRetainSource() {
155107
TKUnit.assert(!sourceRef.get(), "Source should be released after GC");
156108
}
157109

158-
export function test_listnerIsCleared_WhenTargetIsDead() {
159-
var source = new observable.Observable();
110+
//export function test_listnerIsCleared_WhenTargetIsDead() {
111+
// var source = new observable.Observable();
160112

161-
var listenerID = addListenerWithSource(source);
162-
helper.forceGC();
113+
// var listenerID = addListenerWithSource(source);
114+
// helper.forceGC();
163115

164-
for (var i = 0; i < weakEvents.WeakEventListener.cleanDeadReferencesCountTrigger; i++) {
165-
addListenerWithSource(source);
166-
}
116+
// for (var i = 0; i < weakEvents.cleanDeadReferencesCountTrigger; i++) {
117+
// addListenerWithSource(source);
118+
// }
167119

168-
TKUnit.assert(types.isUndefined(weakEvents.WeakEventListener._weakEventListeners[listenerID]), "The first listener should be dead by now");
169-
}
120+
// TKUnit.assert(types.isUndefined(weakEvents._weakEventListeners[listenerID]), "The first listener should be dead by now");
121+
//}
170122

171-
export function test_listnerIsCleared_WhenSourceIsDead() {
172-
var target = {};
123+
//export function test_listnerIsCleared_WhenSourceIsDead() {
124+
// var target = {};
173125

174-
var listenerID = addListenerWithTarget(target);
175-
helper.forceGC();
126+
// var listenerID = addListenerWithTarget(target);
127+
// helper.forceGC();
176128

177-
for (var i = 0; i < weakEvents.WeakEventListener.cleanDeadReferencesCountTrigger; i++) {
178-
addListenerWithTarget(target);
179-
}
129+
// for (var i = 0; i < weakEvents.cleanDeadReferencesCountTrigger; i++) {
130+
// addListenerWithTarget(target);
131+
// }
180132

181-
TKUnit.assert(types.isUndefined(weakEvents.WeakEventListener._weakEventListeners[listenerID]), "The first listener should be dead by now");
182-
}
133+
// TKUnit.assert(types.isUndefined(weakEvents._weakEventListeners[listenerID]), "The first listener should be dead by now");
134+
//}
183135

184-
function addListenerWithSource(source: observable.Observable): number {
185-
return weakEvents.WeakEventListener.addWeakEventListener({
186-
source: source,
187-
target: {},
188-
handler: emptyHandler,
189-
eventName: observable.Observable.propertyChangeEvent
190-
})
191-
}
136+
//function addListenerWithSource(source: observable.Observable): number {
137+
// return weakEvents.addWeakEventListener({
138+
// source: source,
139+
// target: {},
140+
// handler: emptyHandler,
141+
// eventName: observable.Observable.propertyChangeEvent
142+
// })
143+
//}
192144

193-
function addListenerWithTarget(target: any): number {
194-
return weakEvents.WeakEventListener.addWeakEventListener({
195-
source: new observable.Observable(),
196-
target: target,
197-
handler: emptyHandler,
198-
eventName: observable.Observable.propertyChangeEvent
199-
})
200-
}
145+
//function addListenerWithTarget(target: any): number {
146+
// return weakEvents.addWeakEventListener({
147+
// source: new observable.Observable(),
148+
// target: target,
149+
// handler: emptyHandler,
150+
// eventName: observable.Observable.propertyChangeEvent
151+
// })
152+
//}
201153

202154
function emptyHandler(data: observable.EventData) {
203155
// Do nothing.
204-
}
156+
}
157+
158+
159+
160+
export function testWeakMap(): void {
161+
var source = new observable.Observable();
162+
var target = new Target();
163+
var targetRef = new WeakRef(target);
164+
var weakMap = new WeakMap<observable.Observable, Target>();
165+
166+
weakMap.set(source, target);
167+
TKUnit.assertEqual(weakMap.get(source), target, "target");
168+
169+
target = undefined;
170+
source = undefined;
171+
172+
helper.forceGC();
173+
TKUnit.wait(1);
174+
175+
TKUnit.waitUntilReady(function () {
176+
return false;
177+
})
178+
179+
TKUnit.assert(!targetRef.get(), "Target should be dead");
180+
}

ui/button/button-common.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import definition = require("ui/button");
44
import proxy = require("ui/core/proxy");
55
import formattedString = require("text/formatted-string");
66
import observable = require("data/observable");
7-
import weakEventListener = require("ui/core/weak-event-listener");
7+
import weakEvents = require("ui/core/weak-event-listener");
88

99
var textProperty = new dependencyObservable.Property(
1010
"text",
@@ -37,8 +37,6 @@ export class Button extends view.View implements definition.Button {
3737
public static textProperty = textProperty;
3838
public static formattedTextProperty = formattedTextProperty;
3939

40-
private _formattedTextWeakListenerId: number;
41-
4240
public _onBindingContextChanged(oldValue: any, newValue: any) {
4341
super._onBindingContextChanged(oldValue, newValue);
4442
if (this.formattedText) {
@@ -61,16 +59,11 @@ export class Button extends view.View implements definition.Button {
6159
set formattedText(value: formattedString.FormattedString) {
6260
if (this.formattedText !== value) {
6361
if (this.formattedText) {
64-
weakEventListener.WeakEventListener.removeWeakEventListener(this._formattedTextWeakListenerId);
62+
weakEvents.removeWeakEventListener(this.formattedText, observable.Observable.propertyChangeEvent, this.onFormattedTextChanged, this);
6563
}
6664
this._setValue(Button.formattedTextProperty, value);
6765
if (value) {
68-
this._formattedTextWeakListenerId = weakEventListener.WeakEventListener.addWeakEventListener({
69-
target: this,
70-
source: value,
71-
eventName: observable.Observable.propertyChangeEvent,
72-
handler: this.onFormattedTextChanged
73-
});
66+
weakEvents.addWeakEventListener(value, observable.Observable.propertyChangeEvent, this.onFormattedTextChanged, this);
7467
}
7568
}
7669
}

ui/core/bindable.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -162,12 +162,11 @@ export class Binding {
162162
if (this.sourceOptions) {
163163
var sourceOptionsInstance = this.sourceOptions.instance.get();
164164
if (sourceOptionsInstance instanceof observable.Observable) {
165-
this.weakEventId = weakEvents.WeakEventListener.addWeakEventListener({
166-
target: this,
167-
source: this.sourceOptions.instance.get(),
168-
eventName: observable.Observable.propertyChangeEvent,
169-
handler: this.onSourcePropertyChanged,
170-
});
165+
weakEvents.addWeakEventListener(
166+
sourceOptionsInstance,
167+
observable.Observable.propertyChangeEvent,
168+
this.onSourcePropertyChanged,
169+
this);
171170
}
172171
}
173172
}
@@ -177,8 +176,15 @@ export class Binding {
177176
return;
178177
}
179178

180-
weakEvents.WeakEventListener.removeWeakEventListener(this.weakEventId);
181-
delete this.weakEventId;
179+
if (this.sourceOptions) {
180+
var sourceOptionsInstance = this.sourceOptions.instance.get();
181+
if (sourceOptionsInstance) {
182+
weakEvents.removeWeakEventListener(sourceOptionsInstance,
183+
observable.Observable.propertyChangeEvent,
184+
this.onSourcePropertyChanged,
185+
this);
186+
}
187+
}
182188

183189
if (this.source) {
184190
this.source.clear();

0 commit comments

Comments
 (0)