Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(499)

Unified Diff: sky/specs/events.md

Issue 919693007: Specs: Implement the Dispatcher classes. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | sky/specs/script.md » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/specs/events.md
diff --git a/sky/specs/events.md b/sky/specs/events.md
index d839c17059f205b963badcd5d981036cc334aa76..5ce435069c286b7f2363ca7deee714d4a8fcefa5 100644
--- a/sky/specs/events.md
+++ b/sky/specs/events.md
@@ -6,6 +6,107 @@ SKY MODULE
<!-- part of sky:core -->
<script>
+import 'dart:collection';
+import 'dart:async';
+
+class ExceptionAndStackTrace<T> {
+ const ExceptionAndStackTrace(this.exception, this.stackTrace);
+ final T exception;
+ final StackTrace stackTrace;
+}
+
+class ExceptionListException<T> extends Object with IterableMixin<ExceptionAndStackTrace<T>> implements Exception {
abarth-chromium 2015/02/12 00:28:13 extends Object seems a bit silly
Hixie 2015/02/12 21:31:43 Fixed. Turns out you just need extends IterableMix
+ List<ExceptionAndStackTrace<T>> _exceptions;
+ void add(T exception, [StackTrace stackTrace = null]) {
+ if (_exceptions == null)
+ _exceptions = new List<ExceptionAndStackTrace<T>>();
+ _exceptions.add(new ExceptionAndStackTrace<T>(exception, stackTrace));
+ }
+ int get length => _exceptions == null ? 0 : _exceptions.length;
+ Iterator<ExceptionAndStackTrace<T>> get iterator => _exceptions.iterator;
+}
+
+typedef bool Filter<T>(T t);
+typedef void Handler<T>(T t);
+
+class DispatcherController<T> {
+ Dispatcher<T> _dispatcher;
abarth-chromium 2015/02/12 00:28:13 final
Hixie 2015/02/12 21:31:43 Done.
+ Dispatcher<T> get dispatcher => _dispatcher;
+ DispatcherController() {
+ _dispatcher = new Dispatcher<T>._internal();
+ }
+ void add(T data) => _dispatcher._add(data);
+}
+
+class Dispatcher<T> {
+ Dispatcher.silent() { } // returns a dispatcher that never gets an event
+ Dispatcher._internal() { }
abarth-chromium 2015/02/12 00:28:13 Remove?
Hixie 2015/02/12 21:31:43 Done.
+
+ List<Handler> _listeners;
+ void listen(Handler<T> handler) {
+ // you should not throw out of this handler
+ if (_listeners == null)
+ _listeners = new List<Handler>();
+ _listeners.add(handler);
+ }
+ bool unlisten(Handler<T> handler) {
+ if (_listeners == null)
+ return false;
+ return _listeners.remove(handler);
+ }
+ void _add(T data) {
+ if (_listeners == null)
+ return;
+ ExceptionListException exceptions = new ExceptionListException();
+ // we make a copy of the list here so that the listeners can
+ // mutate our list without worry
+ _listeners.toList().forEach((Handler handler) {
+ try {
+ handler(data);
abarth-chromium 2015/02/12 00:28:13 Zone?
Hixie 2015/02/12 21:31:43 Done.
+ } catch (exception, stackTrace) {
+ exceptions.add(exception, stackTrace);
+ }
+ });
+ if (exceptions.length > 0)
+ throw exceptions;
+ }
+
+ Dispatcher<T> where(Filter<T> filter) {
+ var subdispatcher = new Dispatcher<T>._internal();
+ listen((T data) {
+ if (filter(data))
+ subdispatcher._add(data);
+ });
+ return subdispatcher;
+ }
+
+ Dispatcher<T> until(Filter<T> filter) {
+ var subdispatcher = new Dispatcher<T>._internal();
+ Handler handler;
+ handler = (T data) {
+ if (filter(data))
+ unlisten(handler);
+ else
+ subdispatcher._add(data);
+ };
+ listen(handler);
+ return subdispatcher;
+ }
+
+ Future<T> firstWhere(Filter<T> filter) {
+ Completer completer = new Completer();
+ Handler handler;
+ handler = (T data) {
+ if (filter(data)) {
+ completer.complete(data);
+ unlisten(handler);
+ }
+ };
+ listen(handler);
+ return completer.future;
+ }
+}
+
abstract class Event<ReturnType> {
Event() { init(); }
void init() { }
« no previous file with comments | « no previous file | sky/specs/script.md » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698