mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
82 lines
2.0 KiB
Dart
82 lines
2.0 KiB
Dart
// 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';
|
|
|
|
typedef void ErrorHandler(dynamic error, StackTrace stackTrace);
|
|
|
|
/// A singleton for application functionality. This singleton can be different
|
|
/// on a per-Zone basis.
|
|
AppContext get context => Zone.current['context'];
|
|
|
|
class AppContext {
|
|
final Map<Type, dynamic> _instances = <Type, dynamic>{};
|
|
Zone _zone;
|
|
|
|
AppContext() : _zone = Zone.current;
|
|
|
|
bool isSet(Type type) {
|
|
if (_instances.containsKey(type))
|
|
return true;
|
|
|
|
final AppContext parent = _calcParent(_zone);
|
|
return parent != null ? parent.isSet(type) : false;
|
|
}
|
|
|
|
dynamic getVariable(Type type) {
|
|
if (_instances.containsKey(type))
|
|
return _instances[type];
|
|
|
|
final AppContext parent = _calcParent(_zone);
|
|
return parent?.getVariable(type);
|
|
}
|
|
|
|
void setVariable(Type type, dynamic instance) {
|
|
_instances[type] = instance;
|
|
}
|
|
|
|
dynamic operator[](Type type) => getVariable(type);
|
|
|
|
dynamic putIfAbsent(Type type, dynamic ifAbsent()) {
|
|
dynamic value = getVariable(type);
|
|
if (value != null) {
|
|
return value;
|
|
}
|
|
value = ifAbsent();
|
|
setVariable(type, value);
|
|
return value;
|
|
}
|
|
|
|
AppContext _calcParent(Zone zone) {
|
|
final Zone parentZone = zone.parent;
|
|
if (parentZone == null)
|
|
return null;
|
|
|
|
final AppContext parentContext = parentZone['context'];
|
|
return parentContext == this
|
|
? _calcParent(parentZone)
|
|
: parentContext;
|
|
}
|
|
|
|
Future<dynamic> runInZone(dynamic method(), {
|
|
ZoneBinaryCallback<dynamic, dynamic, StackTrace> onError
|
|
}) {
|
|
return runZoned(
|
|
() => _run(method),
|
|
zoneValues: <String, dynamic>{ 'context': this },
|
|
onError: onError
|
|
);
|
|
}
|
|
|
|
Future<dynamic> _run(dynamic method()) async {
|
|
final Zone previousZone = _zone;
|
|
try {
|
|
_zone = Zone.current;
|
|
return await method();
|
|
} finally {
|
|
_zone = previousZone;
|
|
}
|
|
}
|
|
}
|