Skip to content
This repository has been archived by the owner on Feb 22, 2018. It is now read-only.

Commit

Permalink
feat(scope): move domWrite and domRead from RootScope to Scope
Browse files Browse the repository at this point in the history
Closes #1161

Closes #1341
  • Loading branch information
vsavkin committed Sep 3, 2014
1 parent 5f8e276 commit c18a8f3
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 46 deletions.
129 changes: 84 additions & 45 deletions lib/core/scope.dart
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ class Scope {

Scope _parentScope;

_FunctionChain _domReadHead, _domReadTail;
_FunctionChain _domWriteHead, _domWriteTail;

Scope get parentScope => _parentScope;

final ScopeStats _stats;
Expand Down Expand Up @@ -445,6 +448,72 @@ class Scope {
}
return counts;
}

/**
* Internal. Use [View.domWrite] instead.
*/
void domWrite(fn()) {
var chain = new _FunctionChain(fn);
if (_domWriteHead == null) {
_domWriteHead = _domWriteTail = chain;
} else {
_domWriteTail = _domWriteTail._next = chain;
}
rootScope._domWriteCounter ++;
}

/**
* Internal. Use [View.domRead] instead.
*/
void domRead(fn()) {
var chain = new _FunctionChain(fn);
if (_domReadHead == null) {
_domReadHead = _domReadTail = chain;
} else {
_domReadTail = _domReadTail._next = chain;
}
rootScope._domReadCounter ++;
}

void _runDomWrites() {
Scope child = _childHead;
while (child != null) {
child._runDomWrites();
child = child._next;
}

while (_domWriteHead != null) {
try {
_domWriteHead.fn();
} catch (e, s) {
_exceptionHandler(e, s);
}
rootScope._domWriteCounter --;
_domWriteHead = _domWriteHead._next;
}
_domWriteTail = null;
}

void _runDomReads() {
Scope child = _childHead;
while (child != null) {
child._runDomReads();
child = child._next;
}

while (_domReadHead != null) {
try {
_domReadHead.fn();
} catch (e, s) {
_exceptionHandler(e, s);
}
rootScope._domReadCounter --;
_domReadHead = _domReadHead._next;
}
}


ExceptionHandler get _exceptionHandler => rootScope._exceptionHandler;
}

_mapEqual(Map a, Map b) => a.length == b.length &&
Expand Down Expand Up @@ -619,10 +688,10 @@ class RootScope extends Scope {
final Map<String, AST> astCache = new HashMap<String, AST>();

_FunctionChain _runAsyncHead, _runAsyncTail;
_FunctionChain _domWriteHead, _domWriteTail;
_FunctionChain _domReadHead, _domReadTail;

final ScopeStats _scopeStats;
int _domWriteCounter = 0;
int _domReadCounter = 0;

String _state;
var _state_wtf_scope;
Expand Down Expand Up @@ -767,41 +836,29 @@ class RootScope extends Scope {
bool runObservers = true;
try {
do {
if (_domWriteHead != null) _stats.domWriteStart();
var s = traceEnter(Scope_domWrite);
while (_domWriteHead != null) {
try {
_domWriteHead.fn();
} catch (e, s) {
_exceptionHandler(e, s);
}
_domWriteHead = _domWriteHead._next;
if (_domWriteHead == null) _stats.domWriteEnd();
if (_domWriteCounter > 0) {
_stats.domWriteStart();
var s = traceEnter(Scope_domWrite);
_runDomWrites();
traceLeave(s);
_stats.domWriteEnd();
}
traceLeave(s);
_domWriteTail = null;
if (runObservers) {
runObservers = false;
readOnlyGroup.detectChanges(exceptionHandler:_exceptionHandler,
fieldStopwatch: _scopeStats.fieldStopwatch,
evalStopwatch: _scopeStats.evalStopwatch,
processStopwatch: _scopeStats.processStopwatch);
}
if (_domReadHead != null) _stats.domReadStart();
s = traceEnter(Scope_domRead);
while (_domReadHead != null) {
try {
_domReadHead.fn();
} catch (e, s) {
_exceptionHandler(e, s);
}
_domReadHead = _domReadHead._next;
if (_domReadHead == null) _stats.domReadEnd();
if (_domReadCounter > 0) {
_stats.domReadStart();
var s = traceEnter(Scope_domRead);
_runDomReads();
traceLeave(s);
_stats.domReadEnd();
}
_domReadTail = null;
traceLeave(s);
_runAsyncFns();
} while (_domWriteHead != null || _domReadHead != null || _runAsyncHead != null);
} while (_domWriteCounter > 0 || _domReadCounter > 0 || _runAsyncHead != null);
_stats.flushEnd();
assert((() {
_stats.flushAssertStart();
Expand Down Expand Up @@ -861,24 +918,6 @@ class RootScope extends Scope {
return count;
}

void domWrite(fn()) {
var chain = new _FunctionChain(fn);
if (_domWriteHead == null) {
_domWriteHead = _domWriteTail = chain;
} else {
_domWriteTail = _domWriteTail._next = chain;
}
}

void domRead(fn()) {
var chain = new _FunctionChain(fn);
if (_domReadHead == null) {
_domReadHead = _domReadTail = chain;
} else {
_domReadTail = _domReadTail._next = chain;
}
}

void destroy() {}

void _transitionState(String from, String to) {
Expand Down
8 changes: 8 additions & 0 deletions lib/core_dom/view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ class View {
void addContent(Content content) {
insertionPoints.add(content);
}

void domWrite(fn()) {
scope.domWrite(fn);
}

void domRead(fn()) {
scope.domRead(fn);
}
}

/**
Expand Down
36 changes: 35 additions & 1 deletion test/core/scope_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1558,7 +1558,7 @@ void main() {
module.bind(ExceptionHandler, toImplementation: LoggingExceptionHandler);
});

it(r'should run writes before reads', (RootScope rootScope, Logger logger, ExceptionHandler e) {
it('should run writes before reads', (RootScope rootScope, Logger logger, ExceptionHandler e) {
LoggingExceptionHandler exceptionHandler = e as LoggingExceptionHandler;
rootScope.domWrite(() {
logger('write1');
Expand All @@ -1579,6 +1579,40 @@ void main() {
expect(exceptionHandler.errors[0].error).toEqual('write1');
expect(exceptionHandler.errors[1].error).toEqual('read1');
});

it("should run writes of child scopes first", (RootScope rootScope, Logger logger) {
final childScope = rootScope.createChild({});
childScope.domWrite(() {
logger("child1");
});
rootScope.domWrite(() {
logger("root");
});
childScope.domWrite(() {
logger("child2");
});

rootScope.flush();

expect(logger).toEqual(['child1', 'child2', 'root']);
});

it("should run reads of child scopes first", (RootScope rootScope, Logger logger) {
final childScope = rootScope.createChild({});
childScope.domRead(() {
logger("child1");
});
rootScope.domRead(() {
logger("root");
});
childScope.domRead(() {
logger("child2");
});

rootScope.flush();

expect(logger).toEqual(['child1', 'child2', 'root']);
});
});

describe('exceptionHander', () {
Expand Down

0 comments on commit c18a8f3

Please sign in to comment.