diff --git a/debugger/assets/styles/app.css b/debugger/assets/styles/app.css index 3809a6847..f32f71643 100644 --- a/debugger/assets/styles/app.css +++ b/debugger/assets/styles/app.css @@ -48,6 +48,10 @@ body { right: 0; bottom: 0; } +.disconnected .app-body { + opacity: 0.25; + pointer-events: none; +} .tab-pane { position: absolute; left: 0; diff --git a/debugger/index.html b/debugger/index.html index bbfe95459..b407cdd40 100644 --- a/debugger/index.html +++ b/debugger/index.html @@ -13,7 +13,7 @@ -
+
diff --git a/debugger/src/base.js b/debugger/src/base.js index 352cac84a..172e9ae64 100644 --- a/debugger/src/base.js +++ b/debugger/src/base.js @@ -17,3 +17,45 @@ function inherits(childCtor, parentCtor) { childCtor.prototype = new tempCtor(); childCtor.prototype.constructor = childCtor; }; + +var EventEmitter = function() { + this.events_ = {}; +}; +EventEmitter.prototype.dispose = function() { + this.events_ = {}; +}; +EventEmitter.prototype.on = function(name, listener, opt_scope) { + var listeners = this.events_[name]; + if (!listeners) { + listeners = this.events_[name] = []; + } + listeners.push({ + callback: listener, + scope: opt_scope || null + }); +}; +EventEmitter.prototype.off = function(name, listener, opt_scope) { + var listeners = this.events_[name]; + if (!listeners) { + return; + } + for (var n = 0; n < listeners.length; n++) { + if (listeners[n].callback == listener) { + listeners.splice(n, 1); + if (!listeners.length) { + delete this.events_[name]; + } + return; + } + } +} +EventEmitter.prototype.emit = function(name, args) { + var listeners = this.events_[name]; + if (!listeners) { + return; + } + for (var n = 0; n < listeners.length; n++) { + var listener = listeners[n]; + listener.callback.apply(listener.scope, args); + } +}; diff --git a/debugger/src/datasources.js b/debugger/src/datasources.js index ccb1c7f62..27b2b266a 100644 --- a/debugger/src/datasources.js +++ b/debugger/src/datasources.js @@ -56,11 +56,13 @@ module.service('Breakpoint', function() { module.service('DataSource', function($q) { var DataSource = function(source, delegate) { + EventEmitter.call(this); this.source = source; this.delegate = delegate; this.online = false; this.status = 'disconnected'; }; + inherits(DataSource, EventEmitter); DataSource.prototype.open = function() {}; DataSource.prototype.dispose = function() {}; DataSource.prototype.issue = function(command) {}; @@ -181,6 +183,7 @@ module.service('RemoteDataSource', function( this.online = true; this.status = 'connected'; + this.emit('online'); d.resolve(); }).bind(this)); }).bind(this); @@ -194,6 +197,7 @@ module.service('RemoteDataSource', function( } else { this.status = 'disconnected'; log.info('Disconnected'); + this.emit('offline'); } }).bind(this)); }).bind(this); diff --git a/debugger/src/session.js b/debugger/src/session.js index 7340deb8e..07c08b112 100644 --- a/debugger/src/session.js +++ b/debugger/src/session.js @@ -146,6 +146,12 @@ module.service('Session', function( } this.dataSource = dataSource; + this.dataSource.on('online', function() { + // + }, this); + this.dataSource.on('offline', function() { + this.setDataSource(null); + }, this); var ps = []; diff --git a/src/xenia/debug/protocols/ws/ws_client.cc b/src/xenia/debug/protocols/ws/ws_client.cc index 211667032..e4fe21e16 100644 --- a/src/xenia/debug/protocols/ws/ws_client.cc +++ b/src/xenia/debug/protocols/ws/ws_client.cc @@ -508,7 +508,9 @@ json_t* WSClient::HandleMessage(const char* command, json_t* request, // Check debugger meta commands. if (xestrcmpa(target_name, "debug") == 0) { succeeded = true; - if (xestrcmpa(sub_command, "make_ready") == 0) { + if (xestrcmpa(sub_command, "ping") == 0) { + return json_true(); + } else if (xestrcmpa(sub_command, "make_ready") == 0) { MakeReady(); return json_true(); } else {