Debugger can now connect. AngularJS: I have no idea what I'm doing.

This commit is contained in:
Ben Vanik 2013-12-21 11:53:49 -08:00
parent da340891c4
commit a9378eb7eb
22 changed files with 1086 additions and 466 deletions

107
debugger/src/app.js Normal file
View file

@ -0,0 +1,107 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
var module = angular.module('app', [
'ui.bootstrap',
'ui.router',
'xe.datasources',
'xe.directives',
'xe.log',
'xe.router',
'xe.session',
'xe.ui.console',
'xe.ui.navbar'
]);
module.controller('AppController', function($scope, app) {
this.app = app;
});
module.service('app', function(
$rootScope, $q, $state, log, Session) {
var App = function() {
this.loading = false;
this.session = null;
};
App.prototype.setSession = function(session) {
this.close();
this.session = session;
};
App.prototype.close = function() {
this.loading = false;
if (this.session) {
this.session.dispose();
this.session = null;
}
};
App.prototype.open = function(sessionId) {
this.close();
var d = $q.defer();
this.loading = true;
log.info('Opening session ' + sessionId);
var session = new Session(sessionId);
this.loading = false;
this.setSession(session);
d.resolve(session);
return d.promise;
};
App.prototype.connect = function(opt_host) {
this.close();
var d = $q.defer();
this.loading = true;
Session.query(opt_host).then((function(infos) {
var info = infos[0];
var id = info.titleId;
if (id == '00000000') {
id = info.name;
}
var session = new Session(id);
var p = session.connect(opt_host);
p.then((function(session) {
this.loading = false;
this.setSession(session);
d.resolve(session);
}).bind(this), (function(e) {
this.loading = false;
d.reject(e);
}).bind(this), function(update) {
d.notify(update);
});
}).bind(this), (function(e) {
this.loading = false;
log.info('No sessions found at ' + Session.getHost(opt_host));
d.reject(e);
}).bind(this));
return d.promise;
};
return new App();
});
module.run(function($rootScope, app, log) {
$rootScope.app = app;
$rootScope.log = log;
});

19
debugger/src/base.js Normal file
View file

@ -0,0 +1,19 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
function inherits(childCtor, parentCtor) {
function tempCtor() {};
tempCtor.prototype = parentCtor.prototype;
childCtor.superClass_ = parentCtor.prototype;
childCtor.prototype = new tempCtor();
childCtor.prototype.constructor = childCtor;
};

122
debugger/src/datasources.js Normal file
View file

@ -0,0 +1,122 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
var module = angular.module('xe.datasources', []);
var DataSource = function(source) {
this.source = source;
this.online = false;
this.status = 'disconnected';
};
DataSource.prototype.open = function() {};
DataSource.prototype.dispose = function() {};
module.service('RemoteDataSource', function($q) {
var RemoteDataSource = function(url) {
DataSource.call(this, url);
this.url = url;
this.socket = null;
};
inherits(RemoteDataSource, DataSource);
RemoteDataSource.prototype.open = function() {
var url = this.url;
this.online = false;
this.status = 'connecting';
var d = $q.defer();
this.socket = new WebSocket(url, []);
this.socket.onopen = (function() {
// TODO(benvanik): handshake
this.online = true;
this.status = 'connected';
d.resolve();
}).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';
}
}).bind(this);
this.socket.onerror = (function(e) {
// ?
}).bind(this);
this.socket.onmessage = (function(e) {
console.log('message', e.data);
}).bind(this);
return d.promise;
};
RemoteDataSource.prototype.dispose = function() {
this.online = false;
this.status = 'disconnected';
if (this.socket) {
this.socket.close();
this.socket = null;
}
DataSource.prototype.dispose.call(this);
};
return RemoteDataSource;
});
module.service('FileDataSource', function($q) {
var FileDataSource = function(file) {
DataSource.call(this, file.name);
this.file = file;
};
inherits(FileDataSource, DataSource);
FileDataSource.prototype.open = function() {
this.status = 'connecting';
var d = $q.defer();
var self = this;
window.setTimeout(function() {
$scope.$apply((function() {
// TODO(benvanik): scan/load trace
this.online = true;
this.status = 'connected';
d.resolve();
}).bind(self));
});
return d.promise;
};
FileDataSource.prototype.dispose = function() {
this.online = false;
if (this.file) {
if (this.file.close) {
this.file.close();
}
this.file = null;
}
DataSource.prototype.dispose.call(this);
};
return FileDataSource;
});

View file

@ -0,0 +1,26 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
var module = angular.module('xe.directives', []);
module.directive('uiEnter', function() {
return function($scope, element, attrs) {
element.bind("keydown keypress", function(e) {
if(e.which === 13) {
$scope.$apply(function(){
$scope.$eval(attrs.uiEnter);
});
e.preventDefault();
}
});
};
});

45
debugger/src/log.js Normal file
View file

@ -0,0 +1,45 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
var module = angular.module('xe.log', []);
module.service('log', function($rootScope) {
var Log = function() {
this.lines = [];
this.progressActive = false;
this.progress = 0;
};
Log.prototype.appendLine = function(line) {
this.lines.push(line);
};
Log.prototype.info = function(line) {
this.appendLine('I ' + line);
};
Log.prototype.error = function(line) {
this.appendLine('E ' + line);
};
Log.prototype.setProgress = function(value) {
this.progressActive = true;
this.progress = value;
};
Log.prototype.clearProgress = function() {
this.progressActive = false;
};
return new Log();
});

144
debugger/src/router.js Normal file
View file

@ -0,0 +1,144 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
var module = angular.module('xe.router', [
'ui.router',
]);
module.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider.state('/', {
template: 'empty'
});
$stateProvider.state('session', {
url: '/:sessionId',
templateUrl: 'assets/ui/session.html',
resolve: {
app: 'app',
session: function($stateParams, $urlRouter, $state, $q, $timeout,
Session, app) {
// If we are given a session we assume the user is trying to connect to
// it. Attempt that now. If we fail we redirect to home, otherwise we
// check whether it's the same game down below.
var d = $q.defer();
if ($stateParams.sessionId) {
if (!app.session ||
app.session.id != $stateParams.sessionId) {
Session.query().then(function(infos) {
var id = (infos[0].titleId == '00000000') ?
infos[0].name : infos[0].titleId;
if (!app.session || app.session.id == id) {
// Same session, continue.
var p = app.connect();
p.then(function(session) {
d.resolve(session);
}, function(e) {
$state.go('session', {
'sessionId': session.id
}, {
notify: true
});
d.reject(e);
})
} else {
// Different session. Create without connection.
var p = app.open(id);
p.then(function(session) {
d.resolve(session);
}, function(e) {
d.reject(e);
});
}
}, function(e) {
var p = app.open($stateParams.sessionId);
p.then(function(session) {
d.resolve(session);
}, function(e) {
d.reject(e);
});
});
} else {
var p = app.open($stateParams.sessionId);
p.then(function(session) {
d.resolve(session);
}, function(e) {
d.reject(e);
});
}
} else {
d.resolve(null);
}
return d.promise;
}
},
controller: function($scope, $stateParams, $q, app, session) {
},
onEnter: function() {
},
onExit: function() {}
});
$stateProvider.state('session.code', {
url: '/code',
templateUrl: 'assets/ui/code/code-tab.html',
controller: function($stateParams) {
},
onEnter: function() {},
onExit: function() {}
});
$stateProvider.state('session.code.function', {
url: '/:module/:function',
templateUrl: 'assets/ui/code/function-view.html',
controller: function($stateParams) {
},
onEnter: function() {},
onExit: function() {}
});
$stateProvider.state('session.memory', {
url: '/memory',
templateUrl: 'assets/ui/memory/memory-tab.html',
controller: function($stateParams) {
},
onEnter: function() {},
onExit: function() {}
});
$stateProvider.state('session.kernel', {
url: '/kernel',
templateUrl: 'assets/ui/kernel/kernel-tab.html',
controller: function($stateParams) {
},
onEnter: function() {},
onExit: function() {}
});
$stateProvider.state('session.gpu', {
url: '/gpu',
templateUrl: 'assets/ui/gpu/gpu-tab.html',
controller: function($stateParams) {
},
onEnter: function() {},
onExit: function() {}
});
$stateProvider.state('session.apu', {
url: '/apu',
templateUrl: 'assets/ui/apu/apu-tab.html',
controller: function($stateParams) {
},
onEnter: function() {},
onExit: function() {}
});
});

92
debugger/src/session.js Normal file
View file

@ -0,0 +1,92 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
'use strict';
var module = angular.module('xe.session', []);
module.service('Session', function(
$q, $http, log, FileDataSource, RemoteDataSource) {
var Session = function(id, opt_dataSource) {
this.id = id;
this.dataSource = opt_dataSource || null;
};
Session.prototype.dispose = function() {
this.disconnect();
};
Session.DEFAULT_HOST = '127.0.0.1:6200';
Session.getHost = function(opt_host) {
return opt_host || Session.DEFAULT_HOST;
};
Session.query = function(opt_host) {
var url = 'http://' + Session.getHost(opt_host);
var p = $http({
method: 'GET',
url: url + '/sessions',
cache: false,
timeout: 500,
responseType: 'json'
});
var d = $q.defer();
p.then(function(response) {
if (!response.data || !response.data.length) {
d.reject(new Error('No session data'));
return;
}
d.resolve(response.data);
}, function(e) {
d.reject(e);
});
return d.promise;
};
Session.prototype.connect = function(opt_host) {
this.disconnect();
var url = 'ws://' + Session.getHost(opt_host);
log.info('Connecting to ' + url + '...');
log.setProgress(0);
var d = $q.defer();
var dataSource = new RemoteDataSource(url);
var p = dataSource.open();
p.then((function() {
log.info('Connected!');
log.clearProgress();
this.dataSource = dataSource;
d.resolve(this);
}).bind(this), (function(e) {
log.error('Unable to connect: ' + e);
log.clearProgress();
d.reject(e);
}).bind(this), function(update) {
log.setProgress(update.progress);
d.notify(update);
});
return d.promise;
};
Session.prototype.disconnect = function() {
if (this.dataSource) {
this.dataSource.dispose();
this.dataSource = null;
}
};
return Session;
});