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

Commit ab06f09

Browse files
committed
feat(scope): move domWrite and domRead from RootScope to Scope
Closes #1161
1 parent 6a6a7fe commit ab06f09

File tree

3 files changed

+123
-42
lines changed

3 files changed

+123
-42
lines changed

lib/core/scope.dart

Lines changed: 80 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ class Scope {
127127

128128
Scope _parentScope;
129129

130+
_FunctionChain _domReadHead, _domReadTail;
131+
_FunctionChain _domWriteHead, _domWriteTail;
132+
130133
Scope get parentScope => _parentScope;
131134

132135
final ScopeStats _stats;
@@ -413,6 +416,72 @@ class Scope {
413416
}
414417
return counts;
415418
}
419+
420+
/**
421+
* Internal. Use [View.domWrite] instead.
422+
*/
423+
void domWrite(fn()) {
424+
var chain = new _FunctionChain(fn);
425+
if (_domWriteHead == null) {
426+
_domWriteHead = _domWriteTail = chain;
427+
} else {
428+
_domWriteTail = _domWriteTail._next = chain;
429+
}
430+
rootScope._domWriteCounter ++;
431+
}
432+
433+
/**
434+
* Internal. Use [View.domRead] instead.
435+
*/
436+
void domRead(fn()) {
437+
var chain = new _FunctionChain(fn);
438+
if (_domReadHead == null) {
439+
_domReadHead = _domReadTail = chain;
440+
} else {
441+
_domReadTail = _domReadTail._next = chain;
442+
}
443+
rootScope._domReadCounter ++;
444+
}
445+
446+
void _runDomWrites() {
447+
Scope child = _childHead;
448+
while (child != null) {
449+
child._runDomWrites();
450+
child = child._next;
451+
}
452+
453+
while (_domWriteHead != null) {
454+
try {
455+
_domWriteHead.fn();
456+
} catch (e, s) {
457+
_exceptionHandler(e, s);
458+
}
459+
rootScope._domWriteCounter --;
460+
_domWriteHead = _domWriteHead._next;
461+
}
462+
_domWriteTail = null;
463+
}
464+
465+
void _runDomReads() {
466+
Scope child = _childHead;
467+
while (child != null) {
468+
child._runDomReads();
469+
child = child._next;
470+
}
471+
472+
while (_domReadHead != null) {
473+
try {
474+
_domReadHead.fn();
475+
} catch (e, s) {
476+
_exceptionHandler(e, s);
477+
}
478+
rootScope._domReadCounter --;
479+
_domReadHead = _domReadHead._next;
480+
}
481+
}
482+
483+
484+
ExceptionHandler get _exceptionHandler => rootScope._exceptionHandler;
416485
}
417486

418487
_mapEqual(Map a, Map b) => a.length == b.length &&
@@ -587,10 +656,10 @@ class RootScope extends Scope {
587656
final Map<String, AST> astCache = new HashMap<String, AST>();
588657

589658
_FunctionChain _runAsyncHead, _runAsyncTail;
590-
_FunctionChain _domWriteHead, _domWriteTail;
591-
_FunctionChain _domReadHead, _domReadTail;
592659

593660
final ScopeStats _scopeStats;
661+
int _domWriteCounter = 0;
662+
int _domReadCounter = 0;
594663

595664
String _state;
596665

@@ -734,37 +803,25 @@ class RootScope extends Scope {
734803
bool runObservers = true;
735804
try {
736805
do {
737-
if (_domWriteHead != null) _stats.domWriteStart();
738-
while (_domWriteHead != null) {
739-
try {
740-
_domWriteHead.fn();
741-
} catch (e, s) {
742-
_exceptionHandler(e, s);
743-
}
744-
_domWriteHead = _domWriteHead._next;
745-
if (_domWriteHead == null) _stats.domWriteEnd();
806+
if (_domWriteCounter > 0) {
807+
_stats.domWriteStart();
808+
_runDomWrites();
809+
_stats.domWriteEnd();
746810
}
747-
_domWriteTail = null;
748811
if (runObservers) {
749812
runObservers = false;
750813
readOnlyGroup.detectChanges(exceptionHandler:_exceptionHandler,
751814
fieldStopwatch: _scopeStats.fieldStopwatch,
752815
evalStopwatch: _scopeStats.evalStopwatch,
753816
processStopwatch: _scopeStats.processStopwatch);
754817
}
755-
if (_domReadHead != null) _stats.domReadStart();
756-
while (_domReadHead != null) {
757-
try {
758-
_domReadHead.fn();
759-
} catch (e, s) {
760-
_exceptionHandler(e, s);
761-
}
762-
_domReadHead = _domReadHead._next;
763-
if (_domReadHead == null) _stats.domReadEnd();
818+
if (_domReadCounter > 0) {
819+
_stats.domReadStart();
820+
_runDomReads();
821+
_stats.domReadEnd();
764822
}
765-
_domReadTail = null;
766823
_runAsyncFns();
767-
} while (_domWriteHead != null || _domReadHead != null || _runAsyncHead != null);
824+
} while (_domWriteCounter > 0 || _domReadCounter > 0 || _runAsyncHead != null);
768825
_stats.flushEnd();
769826
assert((() {
770827
_stats.flushAssertStart();
@@ -822,24 +879,6 @@ class RootScope extends Scope {
822879
return count;
823880
}
824881

825-
void domWrite(fn()) {
826-
var chain = new _FunctionChain(fn);
827-
if (_domWriteHead == null) {
828-
_domWriteHead = _domWriteTail = chain;
829-
} else {
830-
_domWriteTail = _domWriteTail._next = chain;
831-
}
832-
}
833-
834-
void domRead(fn()) {
835-
var chain = new _FunctionChain(fn);
836-
if (_domReadHead == null) {
837-
_domReadHead = _domReadTail = chain;
838-
} else {
839-
_domReadTail = _domReadTail._next = chain;
840-
}
841-
}
842-
843882
void destroy() {}
844883

845884
void _transitionState(String from, String to) {

lib/core_dom/view.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ class View {
2121
void registerEvent(String eventName) {
2222
eventHandler.register(eventName);
2323
}
24+
25+
void domWrite(fn()) {
26+
scope.domWrite(fn);
27+
}
28+
29+
void domRead(fn()) {
30+
scope.domRead(fn);
31+
}
2432
}
2533

2634
/**

test/core/scope_spec.dart

Lines changed: 35 additions & 1 deletion
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)