design: update change_detection

This commit is contained in:
Misko Hevery 2014-09-30 15:50:20 -07:00
parent 64d3cc68f0
commit e3254d4a7d
2 changed files with 44 additions and 40 deletions

View File

@ -1,51 +1,43 @@
//import {ProtoWatchGroup, WatchGroup} from './watch_group'; //import * as wg from './watch_group';
import {FIELD} from 'facade/lang'; import {FIELD} from 'facade/lang';
/**
* For now we are dropping expression coelescence. We can always add it later, but
* real world numbers should that it does not provide significant benefits.
*/
export class ProtoRecord { export class ProtoRecord {
@FIELD('final watchGroup:ProtoWatchGroup') @FIELD('final watchGroup:wg.ProtoWatchGroup')
@FIELD('final fieldName:String') @FIELD('final fieldName:String')
/// order list of all records. Including head/tail markers /// order list of all records. Including head/tail markers
@FIELD('next:ProtoRecord') @FIELD('next:ProtoRecord')
@FIELD('prev:ProtoRecord') @FIELD('prev:ProtoRecord')
/// next record to dirty check // Opeque data which will be the target of notification.
@FIELD('_checkNext:ProtoRecord') // If the object is instance of Record, than it it is directly procssed
@FIELD('_checkPrev:ProtoRecord') // Otherwise it is the context used by WatchGroupDispatcher.
// next notifier @FIELD('memento')
@FIELD('_notifierNext:ProtoRecord')
// Opeque data which will be presented to WatchGroupDispatcher
@FIELD('dispatcherContext')
// IF we detect change, we have to update the _context of the
// next record.
@FIELD('_updateContext:ProtoRecord')
// May be removed if we don't support coelsence.
@FIELD('_updateContextNext:ProtoRecord')
@FIELD('_clone') @FIELD('_clone')
constructor(watchGroup/*:ProtoWatchGroup*/, fieldName:String) { constructor(watchGroup/*:wg.ProtoWatchGroup*/, fieldName:String, memento) {
this.watchGroup = watchGroup; this.watchGroup = watchGroup;
this.fieldName = fieldName; this.fieldName = fieldName;
this.memento = memento;
this.next = null; this.next = null;
this.prev = null; this.prev = null;
this._checkNext = null; this.changeNotifier = null;
this._checkPrev = null;
this._notifierNext = null;
this.dispatcherContext = null;
this._updateContext = null;
this._updateContextNext = null;
this._clone = null; this._clone = null;
} }
instantiate(watchGroup/*:WatchGroup*/):Record { instantiate(watchGroup/*:wg.WatchGroup*/):Record {
var record = this._clone = new Record(watchGroup, this); var record = this._clone = new Record(watchGroup, this);
record.prev = this.prev._clone; record.prev = this.prev._clone;
record._checkPrev = this._checkPrev._clone; record._checkPrev = this._prev._clone;
return _clone; return _clone;
} }
instantiateComplete():Record { instantiateComplete():Record {
var record = this._clone; var record = this._clone;
record.next = this.next._clone; record.next = this.next._clone;
record._checkNext = this._checkNext._clone; record._checkNext = this.next._clone;
this._clone = null; this._clone = null;
return this.next; return this.next;
} }
@ -80,14 +72,6 @@ export class Record {
@FIELD('_checkPrev:Record') @FIELD('_checkPrev:Record')
// next notifier // next notifier
@FIELD('_notifierNext:Record') @FIELD('_notifierNext:Record')
// notifier context will be present to the notifier to release
// the object from notification/watching.
@FIELD('_notifierContext')
// IF we detect change, we have to update the _context of the
// next record.
@FIELD('_updateContext:Record')
// May be removed if we don't support coelsence.
@FIELD('_updateContextNext:Record')
@FIELD('_mode:int') @FIELD('_mode:int')
@FIELD('_context') @FIELD('_context')
@ -95,7 +79,7 @@ export class Record {
@FIELD('_arguments') @FIELD('_arguments')
@FIELD('currentValue') @FIELD('currentValue')
@FIELD('previousValue') @FIELD('previousValue')
constructor(watchGroup/*:WatchGroup*/, protoRecord:ProtoRecord) { constructor(watchGroup/*:wg.WatchGroup*/, protoRecord:ProtoRecord) {
this.protoRecord = protoRecord; this.protoRecord = protoRecord;
this.watchGroup = watchGroup; this.watchGroup = watchGroup;
this.next = null; this.next = null;
@ -103,9 +87,6 @@ export class Record {
this._checkNext = null; this._checkNext = null;
this._checkPrev = null; this._checkPrev = null;
this._notifierNext = null; this._notifierNext = null;
this._notifierContext = null;
this._updateContext = null;
this._updateContextNext = null;
this._mode = MODE_STATE_MARKER; this._mode = MODE_STATE_MARKER;
this._context = null; this._context = null;
@ -143,7 +124,12 @@ export class Record {
return false return false
} }
this.previousValue = currentValue; this.previousValue = currentValue;
if (this.protoRecord.changeContext instanceof ProtoRecord) {
// forward propaget to the next record
} else {
// notify throught dispatcher
this.watchGroup.dispatcher.onRecordChange(this, this.protoRecord.dispatcherContext); this.watchGroup.dispatcher.onRecordChange(this, this.protoRecord.dispatcherContext);
}
return true; return true;
} }
} }

View File

@ -9,12 +9,20 @@ export class ProtoWatchGroup {
this._tailRecord = null; this._tailRecord = null;
} }
/**
* Parses [expression] into [ProtoRecord]s and adds them to [ProtoWatchGroup].
*
* @param expression The expression to watch
* @param memento an opeque object which will be bassed to WatchGroupDispatcher on
* detecting a change.
* @param shallow Should collections be shallow watched
*/
watch( watch(
expression:String, expression:String,
context, memento,
{isCollection}) {shallow/*=false*/}:{shallow:bool})
{ {
/// IMPREMENT /// IMPLEMENT
} }
instantiate(dispatcher:WatchGroupDispatcher):WatchGroup { instantiate(dispatcher:WatchGroupDispatcher):WatchGroup {
@ -39,6 +47,16 @@ export class ProtoWatchGroup {
watchGroup._tailRecord = tail; watchGroup._tailRecord = tail;
return watchGroup; return watchGroup;
} }
/**
* Sets the context (the object) on which the change detection expressions will
* dereference themselves on. Since the WatchGroup can be reused the context
* can be re-set many times during the lifetime of the WatchGroup.
*
* @param context the new context for change dection for the curren WatchGroup
*/
setContext(context) {
}
} }
export class WatchGroup { export class WatchGroup {