OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 17 matching lines...) Expand all Loading... |
28 "use strict"; | 28 "use strict"; |
29 | 29 |
30 var InternalObjectIsFrozen = $Object.isFrozen; | 30 var InternalObjectIsFrozen = $Object.isFrozen; |
31 var InternalObjectFreeze = $Object.freeze; | 31 var InternalObjectFreeze = $Object.freeze; |
32 | 32 |
33 var observationState = %GetObservationState(); | 33 var observationState = %GetObservationState(); |
34 if (IS_UNDEFINED(observationState.observerInfoMap)) { | 34 if (IS_UNDEFINED(observationState.observerInfoMap)) { |
35 observationState.observerInfoMap = %CreateObjectHashTable(); | 35 observationState.observerInfoMap = %CreateObjectHashTable(); |
36 observationState.objectInfoMap = %CreateObjectHashTable(); | 36 observationState.objectInfoMap = %CreateObjectHashTable(); |
37 observationState.notifierTargetMap = %CreateObjectHashTable(); | 37 observationState.notifierTargetMap = %CreateObjectHashTable(); |
38 observationState.activeObservers = new InternalArray; | 38 observationState.pendingObservers = new InternalArray; |
39 observationState.observerPriority = 0; | 39 observationState.observerPriority = 0; |
40 } | 40 } |
41 | 41 |
42 function InternalObjectHashTable(tableName) { | 42 function InternalObjectHashTable(tableName) { |
43 this.tableName = tableName; | 43 this.tableName = tableName; |
44 } | 44 } |
45 | 45 |
46 InternalObjectHashTable.prototype = { | 46 InternalObjectHashTable.prototype = { |
47 get: function(key) { | 47 get: function(key) { |
48 return %ObjectHashTableGet(observationState[this.tableName], key); | 48 return %ObjectHashTableGet(observationState[this.tableName], key); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 if (index < 0) | 110 if (index < 0) |
111 return; | 111 return; |
112 | 112 |
113 changeObservers.splice(index, 1); | 113 changeObservers.splice(index, 1); |
114 } | 114 } |
115 | 115 |
116 function EnqueueChangeRecord(changeRecord, observers) { | 116 function EnqueueChangeRecord(changeRecord, observers) { |
117 for (var i = 0; i < observers.length; i++) { | 117 for (var i = 0; i < observers.length; i++) { |
118 var observer = observers[i]; | 118 var observer = observers[i]; |
119 var observerInfo = observerInfoMap.get(observer); | 119 var observerInfo = observerInfoMap.get(observer); |
120 observationState.activeObservers[observerInfo.priority] = observer; | 120 observationState.pendingObservers[observerInfo.priority] = observer; |
121 %SetObserverDeliveryPending(); | 121 %SetObserverDeliveryPending(); |
122 if (IS_NULL(observerInfo.pendingChangeRecords)) { | 122 if (IS_NULL(observerInfo.pendingChangeRecords)) { |
123 observerInfo.pendingChangeRecords = new InternalArray(changeRecord); | 123 observerInfo.pendingChangeRecords = new InternalArray(changeRecord); |
124 } else { | 124 } else { |
125 observerInfo.pendingChangeRecords.push(changeRecord); | 125 observerInfo.pendingChangeRecords.push(changeRecord); |
126 } | 126 } |
127 } | 127 } |
128 } | 128 } |
129 | 129 |
130 function NotifyChange(type, object, name, oldValue) { | 130 function NotifyChange(type, object, name, oldValue) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 function DeliverChangeRecordsForObserver(observer) { | 193 function DeliverChangeRecordsForObserver(observer) { |
194 var observerInfo = observerInfoMap.get(observer); | 194 var observerInfo = observerInfoMap.get(observer); |
195 if (IS_UNDEFINED(observerInfo)) | 195 if (IS_UNDEFINED(observerInfo)) |
196 return; | 196 return; |
197 | 197 |
198 var pendingChangeRecords = observerInfo.pendingChangeRecords; | 198 var pendingChangeRecords = observerInfo.pendingChangeRecords; |
199 if (IS_NULL(pendingChangeRecords)) | 199 if (IS_NULL(pendingChangeRecords)) |
200 return; | 200 return; |
201 | 201 |
202 observerInfo.pendingChangeRecords = null; | 202 observerInfo.pendingChangeRecords = null; |
| 203 delete observationState.pendingObservers[observerInfo.priority]; |
203 var delivered = []; | 204 var delivered = []; |
204 %MoveArrayContents(pendingChangeRecords, delivered); | 205 %MoveArrayContents(pendingChangeRecords, delivered); |
205 try { | 206 try { |
206 %Call(void 0, delivered, observer); | 207 %Call(void 0, delivered, observer); |
207 } catch (ex) {} | 208 } catch (ex) {} |
208 } | 209 } |
209 | 210 |
210 function ObjectDeliverChangeRecords(callback) { | 211 function ObjectDeliverChangeRecords(callback) { |
211 if (!IS_SPEC_FUNCTION(callback)) | 212 if (!IS_SPEC_FUNCTION(callback)) |
212 throw MakeTypeError("observe_non_function", ["deliverChangeRecords"]); | 213 throw MakeTypeError("observe_non_function", ["deliverChangeRecords"]); |
213 | 214 |
214 DeliverChangeRecordsForObserver(callback); | 215 DeliverChangeRecordsForObserver(callback); |
215 } | 216 } |
216 | 217 |
217 function DeliverChangeRecords() { | 218 function DeliverChangeRecords() { |
218 while (observationState.activeObservers.length) { | 219 while (observationState.pendingObservers.length) { |
219 var activeObservers = observationState.activeObservers; | 220 var pendingObservers = observationState.pendingObservers; |
220 observationState.activeObservers = new InternalArray; | 221 observationState.pendingObservers = new InternalArray; |
221 for (var i in activeObservers) { | 222 for (var i in pendingObservers) { |
222 DeliverChangeRecordsForObserver(activeObservers[i]); | 223 DeliverChangeRecordsForObserver(pendingObservers[i]); |
223 } | 224 } |
224 } | 225 } |
225 } | 226 } |
226 | 227 |
227 function SetupObjectObserve() { | 228 function SetupObjectObserve() { |
228 %CheckIsBootstrapping(); | 229 %CheckIsBootstrapping(); |
229 InstallFunctions($Object, DONT_ENUM, $Array( | 230 InstallFunctions($Object, DONT_ENUM, $Array( |
230 "deliverChangeRecords", ObjectDeliverChangeRecords, | 231 "deliverChangeRecords", ObjectDeliverChangeRecords, |
231 "getNotifier", ObjectGetNotifier, | 232 "getNotifier", ObjectGetNotifier, |
232 "observe", ObjectObserve, | 233 "observe", ObjectObserve, |
233 "unobserve", ObjectUnobserve | 234 "unobserve", ObjectUnobserve |
234 )); | 235 )); |
235 InstallFunctions(notifierPrototype, DONT_ENUM, $Array( | 236 InstallFunctions(notifierPrototype, DONT_ENUM, $Array( |
236 "notify", ObjectNotifierNotify | 237 "notify", ObjectNotifierNotify |
237 )); | 238 )); |
238 } | 239 } |
239 | 240 |
240 SetupObjectObserve(); | 241 SetupObjectObserve(); |
OLD | NEW |