Chromium Code Reviews| Index: runtime/bin/vmservice/client/lib/src/app/application.dart |
| diff --git a/runtime/bin/vmservice/client/lib/src/app/application.dart b/runtime/bin/vmservice/client/lib/src/app/application.dart |
| index 183d6b18a77eeb3d0d240d1a3765691699ba8282..bd1a9c57b7b6a7199e5a9a0ba934c81ae6a1f90c 100644 |
| --- a/runtime/bin/vmservice/client/lib/src/app/application.dart |
| +++ b/runtime/bin/vmservice/client/lib/src/app/application.dart |
| @@ -4,148 +4,56 @@ |
| part of app; |
| -/// A [Pane] controls the user interface of Observatory. At any given time |
| -/// one pane will be the current pane. Panes are registered at startup. |
| -/// When the user navigates within the application, each pane is asked if it |
| -/// can handle the current location, the first pane to say yes, wins. |
| -abstract class Pane extends Observable { |
| - final ObservatoryApplication app; |
| - |
| - @observable ObservatoryElement element; |
| - |
| - Pane(this.app); |
| - |
| - /// Called when the pane is installed, this callback must initialize |
| - /// [element]. |
| - void onInstall(); |
| - |
| - /// Called when the pane is uninstalled, this callback must clear |
| - /// [element]. |
| - void onUninstall() { |
| - element = null; |
| - } |
| - |
| - /// Called when the pane should update its state based on [url]. |
| - /// NOTE: Only called when the pane is installed. |
| - void visit(String url); |
| - |
| - /// Called to test whether this pane can visit [url]. |
| - bool canVisit(String url); |
| -} |
| - |
| -/// A general service object viewer. |
| -class ServiceObjectPane extends Pane { |
| - ServiceObjectPane(app) : super(app); |
| - |
| - void onInstall() { |
| - if (element == null) { |
| - /// Lazily create pane. |
| - element = new Element.tag('service-view'); |
| - } |
| - } |
| - |
| - void visit(String url) { |
| - assert(element != null); |
| - assert(canVisit(url)); |
| - if (url == '') { |
| - // Nothing requested. |
| - return; |
| - } |
| - /// Request url from VM and display it. |
| - app.vm.get(url).then((obj) { |
| - ServiceObjectViewElement pane = element; |
| - pane.object = obj; |
| - }); |
| - } |
| - |
| - /// Catch all. |
| - bool canVisit(String url) => true; |
| -} |
| - |
| -/// Class tree pane. |
| -class ClassTreePane extends Pane { |
| - static const _urlPrefix = 'class-tree/'; |
| - |
| - ClassTreePane(app) : super(app); |
| - |
| - void onInstall() { |
| - if (element == null) { |
| - element = new Element.tag('class-tree'); |
| - } |
| - } |
| - |
| - void visit(String url) { |
| - assert(element != null); |
| - assert(canVisit(url)); |
| - // ClassTree urls are 'class-tree/isolate-id', chop off prefix, leaving |
| - // isolate url. |
| - url = url.substring(_urlPrefix.length); |
| - /// Request the isolate url. |
| - app.vm.get(url).then((i) { |
| - if (element != null) { |
| - /// Update the pane. |
| - ClassTreeElement pane = element; |
| - pane.isolate = i; |
| - } |
| - }); |
| - } |
| - |
| - /// Catch all. |
| - bool canVisit(String url) => url.startsWith(_urlPrefix); |
| -} |
| - |
| -class ErrorViewPane extends Pane { |
| - ErrorViewPane(app) : super(app); |
| - |
| - void onInstall() { |
| - if (element == null) { |
| - /// Lazily create pane. |
| - element = new Element.tag('service-view'); |
| - } |
| - } |
| - |
| - void visit(String url) { |
| - assert(element != null); |
| - assert(canVisit(url)); |
| - (element as ServiceObjectViewElement).object = app.lastErrorOrException; |
| - } |
| - |
| - bool canVisit(String url) => url.startsWith('error/'); |
| -} |
| - |
| /// The observatory application. Instances of this are created and owned |
| /// by the observatory_application custom element. |
| class ObservatoryApplication extends Observable { |
| + static ObservatoryApplication app; |
| final _paneRegistry = new List<Pane>(); |
| - ServiceObjectPane _serviceObjectPane; |
| Pane _currentPane; |
| @observable final LocationManager locationManager; |
| - @observable final VM vm; |
| + VM _vm; |
| + VM get vm => _vm; |
| + set vm(VM vm) { |
| + if (_vm == vm) { |
| + // Do nothing. |
| + return; |
| + } |
| + if (_vm != null) { |
| + // Disconnect from current VM. |
| + _vm.disconnect(); |
| + } |
| + if (vm != null) { |
| + Logger.root.info('Registering new VM callbacks'); |
| + vm.onConnect.then(_vmConnected); |
| + vm.onDisconnect.then(_vmDisconnected); |
| + vm.errors.stream.listen(_onError); |
| + vm.exceptions.stream.listen(_onException); |
| + } |
| + _vm = vm; |
| + } |
| + final TargetManager targets; |
| @observable Isolate isolate; |
| @reflectable final ObservatoryApplicationElement rootElement; |
| @reflectable ServiceObject lastErrorOrException; |
| - void _initOnce() { |
| + void _initOnce(bool chromium) { |
| + assert(app == null); |
| + app = this; |
| + _vm.errors.stream.listen(_onError); |
| + _vm.exceptions.stream.listen(_onException); |
|
turnidge
2014/07/01 00:27:47
Are the two above lines necessary now that these h
Cutch
2014/07/01 17:14:51
Done.
|
| _registerPanes(); |
| - vm.errors.stream.listen(_onError); |
| - vm.exceptions.stream.listen(_onException); |
| - location = locationManager; |
| locationManager._init(this); |
| } |
| void _registerPanes() { |
| - if (_serviceObjectPane != null) { |
| - // Already done. |
| - return; |
| - } |
| // Register ClassTreePane. |
| _paneRegistry.add(new ClassTreePane(this)); |
| + _paneRegistry.add(new VMConnectPane(this)); |
| _paneRegistry.add(new ErrorViewPane(this)); |
| // Note that ServiceObjectPane must be the last entry in the list as it is |
| // the catch all. |
| - _serviceObjectPane = new ServiceObjectPane(this); |
| - _paneRegistry.add(_serviceObjectPane); |
| + _paneRegistry.add(new ServiceObjectPane(this)); |
| } |
| void _onError(ServiceError error) { |
| @@ -155,7 +63,12 @@ class ObservatoryApplication extends Observable { |
| void _onException(ServiceException exception) { |
| lastErrorOrException = exception; |
| - _visit('error/', null); |
| + if (exception.kind == 'NetworkException') { |
| + // Got a network exception, visit the vm-connect pane. |
| + locationManager.go(locationManager.makeLink('/vm-connect/')); |
| + } else { |
| + _visit('error/', null); |
| + } |
| } |
| void _visit(String url, String args) { |
| @@ -174,17 +87,22 @@ class ObservatoryApplication extends Observable { |
| /// Set the Observatory application pane. |
| void _installPane(Pane pane) { |
| assert(pane != null); |
| - print('Installing $pane'); |
| if (_currentPane == pane) { |
| // Already isntalled. |
| return; |
| } |
| if (_currentPane != null) { |
| + Logger.root.info('Uninstalling pane: $_currentPane'); |
|
turnidge
2014/07/01 00:27:47
Are we keeping this logging in long-term?
Cutch
2014/07/01 17:14:51
Not sure. I like having info on pane switches. Sho
|
| _currentPane.onUninstall(); |
| + // Clear children. |
| + rootElement.children.clear(); |
| + } |
| + Logger.root.info('Installing pane: $pane'); |
| + try { |
| + pane.onInstall(); |
| + } catch (e) { |
| + Logger.root.severe('Failed to install pane: $e'); |
| } |
| - pane.onInstall(); |
| - // Clear children. |
| - rootElement.children.clear(); |
| // Add new pane. |
| rootElement.children.add(pane.element); |
| // Remember pane. |
| @@ -193,15 +111,30 @@ class ObservatoryApplication extends Observable { |
| ObservatoryApplication.devtools(this.rootElement) : |
| locationManager = new HashLocationManager(), |
| - vm = new DartiumVM() { |
| - _initOnce(); |
| + targets = null { |
| + vm = new PostMessageVM(); |
| + _initOnce(true); |
| } |
| ObservatoryApplication(this.rootElement) : |
| locationManager = new HashLocationManager(), |
| - vm = new HttpVM() { |
| - _initOnce(); |
| + targets = new TargetManager() { |
| + vm = new NetworkVM(targets.defaultTarget); |
| + _initOnce(false); |
| } |
| -} |
| -LocationManager location; |
| + _vmConnected(VM vm) { |
| + if (vm is NetworkVM) { |
| + targets.add(vm.target); |
| + } |
| + } |
| + |
| + _vmDisconnected(VM vm) { |
| + if (this.vm != vm) { |
| + // This disconnect event occured *after* a new VM was installed. |
| + return; |
| + } |
| + this.vm = null; |
| + locationManager.go(locationManager.makeLink('/vm-connect/')); |
| + } |
| +} |