blob: 87b9da4a127a2c6ba5cf3e119578cb37669c0c3c [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
final AppContext _defaultContext = new AppContext();
/// A singleton for application functionality. This singleton can be different
/// on a per-Zone basis.
AppContext get context {
AppContext currentContext = Zone.current['context'];
return currentContext == null ? _defaultContext : currentContext;
}
class AppContext {
Map<Type, dynamic> _instances = <Type, dynamic>{};
bool isSet(Type type) {
if (_instances.containsKey(type))
return true;
AppContext parent = _calcParent(Zone.current);
return parent != null ? parent.isSet(type) : false;
}
dynamic getVariable(Type type) {
if (_instances.containsKey(type))
return _instances[type];
AppContext parent = _calcParent(Zone.current);
return parent?.getVariable(type);
}
void setVariable(Type type, dynamic instance) {
_instances[type] = instance;
}
dynamic operator[](Type type) => getVariable(type);
void operator[]=(Type type, dynamic instance) => setVariable(type, instance);
AppContext _calcParent(Zone zone) {
if (this == _defaultContext)
return null;
Zone parentZone = zone.parent;
if (parentZone == null)
return _defaultContext;
AppContext deps = parentZone['context'];
if (deps == this) {
return _calcParent(parentZone);
} else {
return deps != null ? deps : _defaultContext;
}
}
dynamic runInZone(dynamic method()) {
return runZoned(method, zoneValues: {'context': this});
}
}