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

Commit c9f50e7

Browse files
committed
feat(scope): move domWrite and domRead from RootScope to Scope
Closes #1161
1 parent 0b0080b commit c9f50e7

File tree

3 files changed

+123
-46
lines changed

3 files changed

+123
-46
lines changed

lib/core/scope.dart

+80-45
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ class Scope {
157157

158158
Scope _parentScope;
159159

160+
_FunctionChain _domReadHead, _domReadTail;
161+
_FunctionChain _domWriteHead, _domWriteTail;
162+
160163
Scope get parentScope => _parentScope;
161164

162165
final ScopeStats _stats;
@@ -445,6 +448,72 @@ class Scope {
445448
}
446449
return counts;
447450
}
451+
452+
/**
453+
* Internal. Use [View.domWrite] instead.
454+
*/
455+
void domWrite(fn()) {
456+
var chain = new _FunctionChain(fn);
457+
if (_domWriteHead == null) {
458+
_domWriteHead = _domWriteTail = chain;
459+
} else {
460+
_domWriteTail = _domWriteTail._next = chain;
461+
}
462+
rootScope._domWriteCounter ++;
463+
}
464+
465+
/**
466+
* Internal. Use [View.domRead] instead.
467+
*/
468+
void domRead(fn()) {
469+
var chain = new _FunctionChain(fn);
470+
if (_domReadHead == null) {
471+
_domReadHead = _domReadTail = chain;
472+
} else {
473+
_domReadTail = _domReadTail._next = chain;
474+
}
475+
rootScope._domReadCounter ++;
476+
}
477+
478+
void _runDomWrites() {
479+
Scope child = _childHead;
480+
while (child != null) {
481+
child._runDomWrites();
482+
child = child._next;
483+
}
484+
485+
while (_domWriteHead != null) {
486+
try {
487+
_domWriteHead.fn();
488+
} catch (e, s) {
489+
_exceptionHandler(e, s);
490+
}
491+
rootScope._domWriteCounter --;
492+
_domWriteHead = _domWriteHead._next;
493+
}
494+
_domWriteTail = null;
495+
}
496+
497+
void _runDomReads() {
498+
Scope child = _childHead;
499+
while (child != null) {
500+
child._runDomReads();
501+
child = child._next;
502+
}
503+
504+
while (_domReadHead != null) {
505+
try {
506+
_domReadHead.fn();
507+
} catch (e, s) {
508+
_exceptionHandler(e, s);
509+
}
510+
rootScope._domReadCounter --;
511+
_domReadHead = _domReadHead._next;
512+
}
513+
}
514+
515+
516+
ExceptionHandler get _exceptionHandler => rootScope._exceptionHandler;
448517
}
449518

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

621690
_FunctionChain _runAsyncHead, _runAsyncTail;
622-
_FunctionChain _domWriteHead, _domWriteTail;
623-
_FunctionChain _domReadHead, _domReadTail;
624691

625692
final ScopeStats _scopeStats;
693+
int _domWriteCounter = 0;
694+
int _domReadCounter = 0;
626695

627696
String _state;
628697
var _state_wtf_scope;
@@ -767,41 +836,25 @@ class RootScope extends Scope {
767836
bool runObservers = true;
768837
try {
769838
do {
770-
if (_domWriteHead != null) _stats.domWriteStart();
771-
var s = traceEnter(Scope_domWrite);
772-
while (_domWriteHead != null) {
773-
try {
774-
_domWriteHead.fn();
775-
} catch (e, s) {
776-
_exceptionHandler(e, s);
777-
}
778-
_domWriteHead = _domWriteHead._next;
779-
if (_domWriteHead == null) _stats.domWriteEnd();
839+
if (_domWriteCounter > 0) {
840+
_stats.domWriteStart();
841+
_runDomWrites();
842+
_stats.domWriteEnd();
780843
}
781-
traceLeave(s);
782-
_domWriteTail = null;
783844
if (runObservers) {
784845
runObservers = false;
785846
readOnlyGroup.detectChanges(exceptionHandler:_exceptionHandler,
786847
fieldStopwatch: _scopeStats.fieldStopwatch,
787848
evalStopwatch: _scopeStats.evalStopwatch,
788849
processStopwatch: _scopeStats.processStopwatch);
789850
}
790-
if (_domReadHead != null) _stats.domReadStart();
791-
s = traceEnter(Scope_domRead);
792-
while (_domReadHead != null) {
793-
try {
794-
_domReadHead.fn();
795-
} catch (e, s) {
796-
_exceptionHandler(e, s);
797-
}
798-
_domReadHead = _domReadHead._next;
799-
if (_domReadHead == null) _stats.domReadEnd();
851+
if (_domReadCounter > 0) {
852+
_stats.domReadStart();
853+
_runDomReads();
854+
_stats.domReadEnd();
800855
}
801-
_domReadTail = null;
802-
traceLeave(s);
803856
_runAsyncFns();
804-
} while (_domWriteHead != null || _domReadHead != null || _runAsyncHead != null);
857+
} while (_domWriteCounter > 0 || _domReadCounter > 0 || _runAsyncHead != null);
805858
_stats.flushEnd();
806859
assert((() {
807860
_stats.flushAssertStart();
@@ -861,24 +914,6 @@ class RootScope extends Scope {
861914
return count;
862915
}
863916

864-
void domWrite(fn()) {
865-
var chain = new _FunctionChain(fn);
866-
if (_domWriteHead == null) {
867-
_domWriteHead = _domWriteTail = chain;
868-
} else {
869-
_domWriteTail = _domWriteTail._next = chain;
870-
}
871-
}
872-
873-
void domRead(fn()) {
874-
var chain = new _FunctionChain(fn);
875-
if (_domReadHead == null) {
876-
_domReadHead = _domReadTail = chain;
877-
} else {
878-
_domReadTail = _domReadTail._next = chain;
879-
}
880-
}
881-
882917
void destroy() {}
883918

884919
void _transitionState(String from, String to) {

lib/core_dom/view.dart

+8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ class View {
2525
void addContent(Content content) {
2626
insertionPoints.add(content);
2727
}
28+
29+
void domWrite(fn()) {
30+
scope.domWrite(fn);
31+
}
32+
33+
void domRead(fn()) {
34+
scope.domRead(fn);
35+
}
2836
}
2937

3038
/**

test/core/scope_spec.dart

+35-1
Original file line numberDiff line numberDiff line change
@@ -1558,7 +1558,7 @@ void main() {
15581558
module.bind(ExceptionHandler, toImplementation: LoggingExceptionHandler);
15591559
});
15601560

1561-
it(r'should run writes before reads', (RootScope rootScope, Logger logger, ExceptionHandler e) {
1561+
it('should run writes before reads', (RootScope rootScope, Logger logger, ExceptionHandler e) {
15621562
LoggingExceptionHandler exceptionHandler = e as LoggingExceptionHandler;
15631563
rootScope.domWrite(() {
15641564
logger('write1');
@@ -1579,6 +1579,40 @@ void main() {
15791579
expect(exceptionHandler.errors[0].error).toEqual('write1');
15801580
expect(exceptionHandler.errors[1].error).toEqual('read1');
15811581
});
1582+
1583+
it("should run writes of child scopes first", (RootScope rootScope, Logger logger) {
1584+
final childScope = rootScope.createChild({});
1585+
childScope.domWrite(() {
1586+
logger("child1");
1587+
});
1588+
rootScope.domWrite(() {
1589+
logger("root");
1590+
});
1591+
childScope.domWrite(() {
1592+
logger("child2");
1593+
});
1594+
1595+
rootScope.flush();
1596+
1597+
expect(logger).toEqual(['child1', 'child2', 'root']);
1598+
});
1599+
1600+
it("should run reads of child scopes first", (RootScope rootScope, Logger logger) {
1601+
final childScope = rootScope.createChild({});
1602+
childScope.domRead(() {
1603+
logger("child1");
1604+
});
1605+
rootScope.domRead(() {
1606+
logger("root");
1607+
});
1608+
childScope.domRead(() {
1609+
logger("child2");
1610+
});
1611+
1612+
rootScope.flush();
1613+
1614+
expect(logger).toEqual(['child1', 'child2', 'root']);
1615+
});
15821616
});
15831617

15841618
describe('exceptionHander', () {

0 commit comments

Comments
 (0)