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

feat(scope): move domWrite and domRead from RootScope to Scope #1341

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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