Sending basic control commands. Angular routing is hard.
This commit is contained in:
@@ -25,6 +25,7 @@ module.service('Breakpoint', function() {
|
||||
var Breakpoint = function(opt_id) {
|
||||
this.id = opt_id || uuid4();
|
||||
this.type = Breakpoint.Type.TEMP;
|
||||
this.fnAddress = 0;
|
||||
this.address = 0;
|
||||
this.enabled = true;
|
||||
};
|
||||
@@ -35,6 +36,7 @@ module.service('Breakpoint', function() {
|
||||
Breakpoint.fromJSON = function(json) {
|
||||
var breakpoint = new Breakpoint(json.id);
|
||||
breakpoint.type = json.type;
|
||||
breakpoint.fnAddress = json.fnAddress;
|
||||
breakpoint.address = json.address;
|
||||
breakpoint.enabled = json.enabled;
|
||||
return breakpoint;
|
||||
@@ -43,6 +45,7 @@ module.service('Breakpoint', function() {
|
||||
return {
|
||||
'id': this.id,
|
||||
'type': this.type,
|
||||
'fnAddress': this.fnAddress,
|
||||
'address': this.address,
|
||||
'enabled': this.enabled
|
||||
};
|
||||
@@ -52,8 +55,9 @@ module.service('Breakpoint', function() {
|
||||
|
||||
|
||||
module.service('DataSource', function($q) {
|
||||
var DataSource = function(source) {
|
||||
var DataSource = function(source, delegate) {
|
||||
this.source = source;
|
||||
this.delegate = delegate;
|
||||
this.online = false;
|
||||
this.status = 'disconnected';
|
||||
};
|
||||
@@ -129,12 +133,31 @@ module.service('DataSource', function($q) {
|
||||
});
|
||||
};
|
||||
|
||||
DataSource.prototype.continueExecution = function() {
|
||||
return this.issue({
|
||||
command: 'cpu.continue'
|
||||
});
|
||||
};
|
||||
|
||||
DataSource.prototype.breakExecution = function() {
|
||||
return this.issue({
|
||||
command: 'cpu.break'
|
||||
});
|
||||
};
|
||||
|
||||
DataSource.prototype.stepNext = function() {
|
||||
return this.issue({
|
||||
command: 'cpu.step'
|
||||
});
|
||||
};
|
||||
|
||||
return DataSource;
|
||||
});
|
||||
|
||||
module.service('RemoteDataSource', function($q, log, DataSource) {
|
||||
var RemoteDataSource = function(url) {
|
||||
DataSource.call(this, url);
|
||||
module.service('RemoteDataSource', function(
|
||||
$rootScope, $q, log, DataSource) {
|
||||
var RemoteDataSource = function(url, delegate) {
|
||||
DataSource.call(this, url, delegate);
|
||||
this.url = url;
|
||||
this.socket = null;
|
||||
this.nextRequestId_ = 1;
|
||||
@@ -152,22 +175,26 @@ module.service('RemoteDataSource', function($q, log, DataSource) {
|
||||
|
||||
this.socket = new WebSocket(url, []);
|
||||
this.socket.onopen = (function() {
|
||||
// TODO(benvanik): handshake
|
||||
$rootScope.$apply((function() {
|
||||
// TODO(benvanik): handshake
|
||||
|
||||
this.online = true;
|
||||
this.status = 'connected';
|
||||
d.resolve();
|
||||
this.online = true;
|
||||
this.status = 'connected';
|
||||
d.resolve();
|
||||
}).bind(this));
|
||||
}).bind(this);
|
||||
|
||||
this.socket.onclose = (function(e) {
|
||||
this.online = false;
|
||||
if (this.status == 'connecting') {
|
||||
this.status = 'disconnected';
|
||||
d.reject(e.code + ' ' + e.reason);
|
||||
} else {
|
||||
this.status = 'disconnected';
|
||||
log.info('Disconnected');
|
||||
}
|
||||
$rootScope.$apply((function() {
|
||||
this.online = false;
|
||||
if (this.status == 'connecting') {
|
||||
this.status = 'disconnected';
|
||||
d.reject(e.code + ' ' + e.reason);
|
||||
} else {
|
||||
this.status = 'disconnected';
|
||||
log.info('Disconnected');
|
||||
}
|
||||
}).bind(this));
|
||||
}).bind(this);
|
||||
|
||||
this.socket.onerror = (function(e) {
|
||||
@@ -175,27 +202,42 @@ module.service('RemoteDataSource', function($q, log, DataSource) {
|
||||
}).bind(this);
|
||||
|
||||
this.socket.onmessage = (function(e) {
|
||||
console.log('message', e.data);
|
||||
var json = JSON.parse(e.data);
|
||||
if (json.requestId) {
|
||||
// Response to a previous request.
|
||||
var request = this.pendingRequests_[json.requestId];
|
||||
if (request) {
|
||||
delete this.pendingRequests_[json.requestId];
|
||||
if (json.status) {
|
||||
request.deferred.resolve(json.result);
|
||||
} else {
|
||||
request.deferred.reject(json.result);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Notification.
|
||||
}
|
||||
$rootScope.$apply((function() {
|
||||
this.socketMessage(e);
|
||||
}).bind(this));
|
||||
}).bind(this);
|
||||
|
||||
return d.promise;
|
||||
};
|
||||
|
||||
RemoteDataSource.prototype.socketMessage = function(e) {
|
||||
console.log('message', e.data);
|
||||
var json = JSON.parse(e.data);
|
||||
if (json.requestId) {
|
||||
// Response to a previous request.
|
||||
var request = this.pendingRequests_[json.requestId];
|
||||
if (request) {
|
||||
delete this.pendingRequests_[json.requestId];
|
||||
if (json.status) {
|
||||
request.deferred.resolve(json.result);
|
||||
} else {
|
||||
request.deferred.reject(json.result);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Notification.
|
||||
switch (json.type) {
|
||||
case 'breakpoint':
|
||||
this.delegate.onBreakpointHit(
|
||||
json.breakpointId, json.threadId);
|
||||
break;
|
||||
default:
|
||||
log.error('Unknown notification type: ' + json.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
RemoteDataSource.prototype.dispose = function() {
|
||||
this.pendingRequests_ = {};
|
||||
this.online = false;
|
||||
@@ -221,8 +263,8 @@ module.service('RemoteDataSource', function($q, log, DataSource) {
|
||||
|
||||
|
||||
module.service('FileDataSource', function($q, DataSource) {
|
||||
var FileDataSource = function(file) {
|
||||
DataSource.call(this, file.name);
|
||||
var FileDataSource = function(file, delegate) {
|
||||
DataSource.call(this, file.name, delegate);
|
||||
this.file = file;
|
||||
};
|
||||
inherits(FileDataSource, DataSource);
|
||||
|
||||
@@ -98,13 +98,11 @@ module.config(function($stateProvider, $urlRouterProvider) {
|
||||
onExit: function() {}
|
||||
});
|
||||
$stateProvider.state('session.code.function', {
|
||||
url: '/:module/:function',
|
||||
url: '/:function?a',
|
||||
templateUrl: 'assets/ui/code/function-view.html',
|
||||
controller: function($scope, $stateParams) {
|
||||
$scope.moduleName = $stateParams.module;
|
||||
$scope.functionAddress = parseInt($stateParams.function, 16);
|
||||
$scope.$emit('xxx');
|
||||
$scope.$broadcast('yyy');
|
||||
$scope.highlightAddress = parseInt($stateParams.a, 16);
|
||||
},
|
||||
onEnter: function() {},
|
||||
onExit: function() {}
|
||||
|
||||
@@ -13,15 +13,18 @@ var module = angular.module('xe.session', []);
|
||||
|
||||
|
||||
module.service('Session', function(
|
||||
$rootScope, $q, $http, log,
|
||||
$rootScope, $q, $http, $state, log,
|
||||
Breakpoint, FileDataSource, RemoteDataSource) {
|
||||
var Session = function(id, opt_dataSource) {
|
||||
this.id = id;
|
||||
|
||||
this.breakpoints = {};
|
||||
this.breakpointsById = {};
|
||||
|
||||
this.dataSource = opt_dataSource || null;
|
||||
|
||||
this.paused = false;
|
||||
|
||||
this.loadState();
|
||||
};
|
||||
|
||||
@@ -31,7 +34,11 @@ module.service('Session', function(
|
||||
};
|
||||
|
||||
Session.prototype.loadState = function() {
|
||||
var json = JSON.parse(window.localStorage[this.id]);
|
||||
var raw = window.localStorage[this.id];
|
||||
if (!raw) {
|
||||
return;
|
||||
}
|
||||
var json = JSON.parse(raw);
|
||||
if (!json) {
|
||||
return;
|
||||
}
|
||||
@@ -40,8 +47,9 @@ module.service('Session', function(
|
||||
this.breakpoints = {};
|
||||
for (var n = 0; n < breakpointList.length; n++) {
|
||||
var breakpointJson = breakpointList[n];
|
||||
this.breakpoints[breakpointJson.address] =
|
||||
Breakpoint.fromJSON(breakpointJson);
|
||||
var breakpoint = Breakpoint.fromJSON(breakpointJson);
|
||||
this.breakpoints[breakpointJson.address] = breakpoint;
|
||||
this.breakpointsById[breakpoint.id] = breakpoint;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -50,8 +58,8 @@ module.service('Session', function(
|
||||
id: this.id,
|
||||
breakpoints: []
|
||||
};
|
||||
for (var key in this.breakpoints) {
|
||||
var breakpoint = this.breakpoints[key];
|
||||
for (var key in this.breakpointsById) {
|
||||
var breakpoint = this.breakpointsById[key];
|
||||
if (breakpoint.type != Breakpoint.TEMP) {
|
||||
json.breakpoints.push(breakpoint.toJSON());
|
||||
}
|
||||
@@ -97,7 +105,7 @@ module.service('Session', function(
|
||||
|
||||
var d = $q.defer();
|
||||
|
||||
var dataSource = new RemoteDataSource(url);
|
||||
var dataSource = new RemoteDataSource(url, this);
|
||||
var p = dataSource.open();
|
||||
p.then((function() {
|
||||
log.info('Connected!');
|
||||
@@ -167,6 +175,7 @@ module.service('Session', function(
|
||||
|
||||
Session.prototype.addBreakpoint = function(breakpoint) {
|
||||
this.breakpoints[breakpoint.address] = breakpoint;
|
||||
this.breakpointsById[breakpoint.id] = breakpoint;
|
||||
if (this.dataSource) {
|
||||
this.dataSource.addBreakpoint(breakpoint);
|
||||
}
|
||||
@@ -174,17 +183,19 @@ module.service('Session', function(
|
||||
return breakpoint;
|
||||
};
|
||||
|
||||
Session.prototype.addTempBreakpoint = function(address) {
|
||||
Session.prototype.addTempBreakpoint = function(fnAddress, address) {
|
||||
var breakpoint = new Breakpoint();
|
||||
breakpoint.type = Breakpoint.Type.TEMP;
|
||||
breakpoint.fnAddress = fnAddress;
|
||||
breakpoint.address = address;
|
||||
breakpoint.enabled = true;
|
||||
return this.addBreakpoint(breakpoint);
|
||||
};
|
||||
|
||||
Session.prototype.addCodeBreakpoint = function(address) {
|
||||
Session.prototype.addCodeBreakpoint = function(fnAddress, address) {
|
||||
var breakpoint = new Breakpoint();
|
||||
breakpoint.type = Breakpoint.Type.CODE;
|
||||
breakpoint.fnAddress = fnAddress;
|
||||
breakpoint.address = address;
|
||||
breakpoint.enabled = true;
|
||||
return this.addBreakpoint(breakpoint);
|
||||
@@ -192,6 +203,7 @@ module.service('Session', function(
|
||||
|
||||
Session.prototype.removeBreakpoint = function(breakpoint) {
|
||||
delete this.breakpoints[breakpoint.address];
|
||||
delete this.breakpointsById[breakpoint.id];
|
||||
if (this.dataSource) {
|
||||
this.dataSource.removeBreakpoint(breakpoint.id);
|
||||
}
|
||||
@@ -211,5 +223,60 @@ module.service('Session', function(
|
||||
this.saveState();
|
||||
};
|
||||
|
||||
Session.prototype.onBreakpointHit = function(breakpointId, threadId) {
|
||||
var breakpoint = this.breakpointsById[breakpointId];
|
||||
var thread = null; // TODO
|
||||
if (!breakpoint) {
|
||||
log.error('Breakpoint hit but not found');
|
||||
return;
|
||||
}
|
||||
|
||||
// Now paused!
|
||||
this.paused = true;
|
||||
|
||||
$state.go('session.code.function', {
|
||||
'function': breakpoint.fnAddress.toString(16).toUpperCase(),
|
||||
'a': breakpoint.address.toString(16).toUpperCase()
|
||||
}, {
|
||||
notify: false,
|
||||
reloadOnSearch: false
|
||||
});
|
||||
|
||||
//
|
||||
log.info('breakpoint!!');
|
||||
};
|
||||
|
||||
Session.prototype.continueExecution = function() {
|
||||
if (!this.dataSource) {
|
||||
return;
|
||||
}
|
||||
this.paused = false;
|
||||
this.dataSource.continueExecution().then(function() {
|
||||
}, function(e) {
|
||||
log.error('Unable to continue: ' + e);
|
||||
});
|
||||
};
|
||||
|
||||
Session.prototype.breakExecution = function() {
|
||||
if (!this.dataSource) {
|
||||
return;
|
||||
}
|
||||
this.dataSource.breakExecution().then(function() {
|
||||
}, function(e) {
|
||||
log.error('Unable to break: ' + e);
|
||||
});
|
||||
};
|
||||
|
||||
Session.prototype.stepNext = function() {
|
||||
if (!this.dataSource) {
|
||||
return;
|
||||
}
|
||||
this.paused = false;
|
||||
this.dataSource.breakExecution().then(function() {
|
||||
}, function(e) {
|
||||
log.error('Unable to step: ' + e);
|
||||
});
|
||||
};
|
||||
|
||||
return Session;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user