fixed profiler so updates after pause; nes presets; resize windows; dialog for gist share
This commit is contained in:
parent
ab1500ccb6
commit
733846af16
17
css/ui.css
17
css/ui.css
|
@ -431,3 +431,20 @@ div.markdown th {
|
||||||
height:100%;
|
height:100%;
|
||||||
overflow-y:auto;
|
overflow-y:auto;
|
||||||
}
|
}
|
||||||
|
div.profiler {
|
||||||
|
background-color: #333;
|
||||||
|
color: #ddd;
|
||||||
|
white-space: pre;
|
||||||
|
margin-top: 20px auto 0;
|
||||||
|
font-family: "Andale Mono", "Menlo", "Lucida Console", monospace;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
span.profiler-lineno {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
span.profiler-local {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
span.profiler-cident {
|
||||||
|
color: #99ffff;
|
||||||
|
}
|
||||||
|
|
30
index.html
30
index.html
|
@ -82,8 +82,9 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||||
<li class="dropdown dropdown-submenu">
|
<li class="dropdown dropdown-submenu">
|
||||||
<a tabindex="-1" href="#">Share</a>
|
<a tabindex="-1" href="#">Share</a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a class="dropdown-item" href="#" id="item_record_video">Record Video...</a></li>
|
<li><a class="dropdown-item" href="#" id="item_share_github">Share File on Github...</a></li>
|
||||||
<li><a class="dropdown-item" href="#" id="item_share_file">Share Playable Link...</a></li>
|
<li><a class="dropdown-item" href="#" id="item_share_file">Share Playable Link...</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#" id="item_record_video">Record Video...</a></li>
|
||||||
<li><a class="dropdown-item" href="#" id="item_export_cassette">Make Cassette Audio...</a></li>
|
<li><a class="dropdown-item" href="#" id="item_export_cassette">Make Cassette Audio...</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
@ -178,7 +179,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||||
<span id="verilog_bar" style="display:none">
|
<span id="verilog_bar" style="display:none">
|
||||||
<span class="label"><span id="settle_label"></span> evals/clk</span>
|
<span class="label"><span id="settle_label"></span> evals/clk</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="dropdown" style="float:right">
|
<span class="dropdown" style="float:right">
|
||||||
<span class="logo-gradient hidden-xs hidden-sm">8bitworkshop</span>
|
<span class="logo-gradient hidden-xs hidden-sm">8bitworkshop</span>
|
||||||
|
|
||||||
|
@ -292,6 +293,31 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="embedGistModal" class="modal fade">
|
||||||
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3 class="modal-title">Share Code on Github</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>If you have a Github account, you can share your code as a Github gist.</p>
|
||||||
|
<ul>
|
||||||
|
<li>Make sure the correct platform is selected.
|
||||||
|
<li>Go to <a href="https://gist.github.com/" target="_8bitgist">gist.github.com</a>
|
||||||
|
<li>Create a gist with your source code.
|
||||||
|
<li>Paste the final gist URL below.
|
||||||
|
</ul>
|
||||||
|
<textarea rows="2" cols="100" id="embedGistURL" class="cliptext"></textarea>
|
||||||
|
<p>The shareable URL will appear here:</p>
|
||||||
|
<textarea rows="2" cols="100" id="embedGistShareURL" class="cliptext"></textarea><br>
|
||||||
|
<button type="button" class="btn btn-primary" data-clipboard-target="#embedGistShareURL">Copy Shareable Link</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="jquery/jquery-3.3.1.min.js"></script>
|
<script src="jquery/jquery-3.3.1.min.js"></script>
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ word bcd_add(word a, word b) {
|
||||||
byte d = (a & 0xf) + (b & 0xf) + c;
|
byte d = (a & 0xf) + (b & 0xf) + c;
|
||||||
c = 0;
|
c = 0;
|
||||||
while (d >= 10) {
|
while (d >= 10) {
|
||||||
c++;
|
++c;
|
||||||
d -= 10;
|
d -= 10;
|
||||||
}
|
}
|
||||||
result |= d << shift;
|
result |= d << shift;
|
||||||
|
|
|
@ -2,9 +2,15 @@
|
||||||
#include "neslib.h"
|
#include "neslib.h"
|
||||||
#include "vrambuf.h"
|
#include "vrambuf.h"
|
||||||
|
|
||||||
|
#pragma bss-name(push,"ZEROPAGE")
|
||||||
|
#pragma data-name(push,"ZEROPAGE")
|
||||||
|
|
||||||
// index to end of buffer
|
// index to end of buffer
|
||||||
byte updptr = 0;
|
byte updptr = 0;
|
||||||
|
|
||||||
|
#pragma bss-name(pop)
|
||||||
|
#pragma data-name(pop)
|
||||||
|
|
||||||
// add EOF marker to buffer
|
// add EOF marker to buffer
|
||||||
void cendbuf(void) {
|
void cendbuf(void) {
|
||||||
updbuf[updptr] = NT_UPD_EOF;
|
updbuf[updptr] = NT_UPD_EOF;
|
||||||
|
@ -30,11 +36,12 @@ void cflushnow(void) {
|
||||||
// using horizontal increment
|
// using horizontal increment
|
||||||
void putbytes(word addr, const char* str, byte len) {
|
void putbytes(word addr, const char* str, byte len) {
|
||||||
if (updptr >= VBUFSIZE-4-len) cflushnow();
|
if (updptr >= VBUFSIZE-4-len) cflushnow();
|
||||||
updbuf[updptr++] = (addr >> 8) ^ NT_UPD_HORZ;
|
updbuf[updptr] = (addr >> 8) ^ NT_UPD_HORZ;
|
||||||
updbuf[updptr++] = addr & 0xff;
|
updbuf[++updptr] = addr & 0xff;
|
||||||
updbuf[updptr++] = len;
|
updbuf[++updptr] = len;
|
||||||
while (len--) {
|
while (len--) {
|
||||||
updbuf[updptr++] = *str++;
|
updbuf[++updptr] = *str++;
|
||||||
}
|
}
|
||||||
|
++updptr;
|
||||||
cendbuf();
|
cendbuf();
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,6 +157,31 @@ export abstract class BasePlatform {
|
||||||
this.recorder.recordFrame(this.saveState());
|
this.recorder.recordFrame(this.saveState());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
startProfiling() : ProfilerOutput {
|
||||||
|
var frame = null;
|
||||||
|
var output = {frame:null};
|
||||||
|
var i = 0;
|
||||||
|
var lastsl = 9999;
|
||||||
|
var start = 0;
|
||||||
|
(this as any).runEval((c:CpuState) => {
|
||||||
|
var sl = (this as any).getRasterScanline();
|
||||||
|
if (sl != lastsl) {
|
||||||
|
if (frame) {
|
||||||
|
frame.lines.push({start:start,end:i-1});
|
||||||
|
}
|
||||||
|
if (sl < lastsl) {
|
||||||
|
output.frame = frame;
|
||||||
|
frame = {iptab:new Uint32Array(0x8000), lines:[]}; // TODO: const
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
start = i;
|
||||||
|
lastsl = sl;
|
||||||
|
}
|
||||||
|
frame.iptab[i++] = c.EPC || c.PC;
|
||||||
|
return false; // profile forever
|
||||||
|
});
|
||||||
|
return output;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class BaseDebugPlatform extends BasePlatform {
|
export abstract class BaseDebugPlatform extends BasePlatform {
|
||||||
|
@ -208,29 +233,6 @@ export abstract class BaseDebugPlatform extends BasePlatform {
|
||||||
this.advance(novideo);
|
this.advance(novideo);
|
||||||
this.postFrame();
|
this.postFrame();
|
||||||
}
|
}
|
||||||
startProfiling() : ProfilerOutput {
|
|
||||||
var frame = null;
|
|
||||||
var output = {frame:null};
|
|
||||||
var i = 0;
|
|
||||||
var lastsl = 9999;
|
|
||||||
var start = 0;
|
|
||||||
(this as any).runEval((c:CpuState) => {
|
|
||||||
var sl = (this as any).getRasterScanline();
|
|
||||||
if (sl != lastsl) {
|
|
||||||
if (frame) frame.lines.push({start:start,end:i});
|
|
||||||
if (sl < lastsl) {
|
|
||||||
output.frame = frame;
|
|
||||||
frame = {iptab:new Uint32Array(14672), lines:[]};
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
start = i+1;
|
|
||||||
lastsl = sl;
|
|
||||||
}
|
|
||||||
frame.iptab[i++] = c.EPC || c.PC;
|
|
||||||
return false; // profile forever
|
|
||||||
});
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 6502
|
////// 6502
|
||||||
|
@ -1028,6 +1030,7 @@ export abstract class BasicZ80ScanlinePlatform extends BaseZ80Platform {
|
||||||
abstract getKeyboardMap();
|
abstract getKeyboardMap();
|
||||||
abstract startScanline(sl : number);
|
abstract startScanline(sl : number);
|
||||||
abstract drawScanline(sl : number);
|
abstract drawScanline(sl : number);
|
||||||
|
getRasterScanline() { return this.currentScanline; }
|
||||||
|
|
||||||
constructor(mainElement : HTMLElement) {
|
constructor(mainElement : HTMLElement) {
|
||||||
super();
|
super();
|
||||||
|
|
|
@ -231,30 +231,6 @@ const _JSNESPlatform = function(mainElement) {
|
||||||
getRasterScanline() : number {
|
getRasterScanline() : number {
|
||||||
return nes.ppu.scanline;
|
return nes.ppu.scanline;
|
||||||
}
|
}
|
||||||
startProfiling() : ProfilerOutput {
|
|
||||||
var frame0 = frameindex;
|
|
||||||
var frame = null;
|
|
||||||
var output = {frame:null};
|
|
||||||
var i = 0;
|
|
||||||
var lastsl = 9999;
|
|
||||||
var start = 0;
|
|
||||||
this.runEval((c) => {
|
|
||||||
var sl = this.getRasterScanline();
|
|
||||||
if (sl != lastsl) {
|
|
||||||
if (frame) frame.lines.push({start:start,end:i});
|
|
||||||
if (sl < lastsl) {
|
|
||||||
output.frame = frame;
|
|
||||||
frame = {iptab:new Uint32Array(14672), lines:[]};
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
start = i+1;
|
|
||||||
lastsl = sl;
|
|
||||||
}
|
|
||||||
frame.iptab[i++] = c.EPC || c.PC;
|
|
||||||
return false; //frameindex>frame0; // TODO
|
|
||||||
});
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
getCPUState() {
|
getCPUState() {
|
||||||
var c = nes.cpu.toJSON();
|
var c = nes.cpu.toJSON();
|
||||||
|
|
|
@ -153,6 +153,7 @@ class VCSPlatform extends BasePlatform {
|
||||||
Javatari.room.speaker.mute();
|
Javatari.room.speaker.mute();
|
||||||
}
|
}
|
||||||
isDebugging() : boolean {
|
isDebugging() : boolean {
|
||||||
|
// TODO: always true
|
||||||
return Javatari.room.console.onBreakpointHit != null;
|
return Javatari.room.console.onBreakpointHit != null;
|
||||||
}
|
}
|
||||||
clearDebug() {
|
clearDebug() {
|
||||||
|
|
78
src/ui.ts
78
src/ui.ts
|
@ -354,28 +354,24 @@ function getCurrentEditorFilename() : string {
|
||||||
}
|
}
|
||||||
|
|
||||||
function _shareFileAsGist(e) {
|
function _shareFileAsGist(e) {
|
||||||
loadScript("octokat.js/dist/octokat.js", () => {
|
var gisturl_ta = $("#embedGistURL");
|
||||||
if (current_output == null) { // TODO
|
var shareurl_ta = $("#embedGistShareURL");
|
||||||
alert("Please fix errors before sharing.");
|
loadClipboardLibrary();
|
||||||
return true;
|
gisturl_ta.change(() => {
|
||||||
}
|
var gisturl = gisturl_ta.val() + '';
|
||||||
var text = projectWindows.getCurrentText();
|
var pos = gisturl.lastIndexOf('/');
|
||||||
if (!text) return false;
|
if (pos >= 0) {
|
||||||
var github = new exports['Octokat']();
|
var gistkey = gisturl.substring(pos+1);
|
||||||
var files = {};
|
var embed = {
|
||||||
files[getCurrentEditorFilename()] = {"content": text};
|
platform: platform_id,
|
||||||
var gistdata = {
|
gistkey: gistkey
|
||||||
"description": '8bitworkshop.com {"platform":"' + platform_id + '"}',
|
};
|
||||||
"public": true,
|
var linkqs = $.param(embed);
|
||||||
"files": files
|
var fulllink = get8bitworkshopLink(linkqs, 'redir.html');
|
||||||
};
|
shareurl_ta.val(fulllink);
|
||||||
var gist = github.gists.create(gistdata).done(function(val) {
|
}
|
||||||
var url = "http://8bitworkshop.com/?gistkey=" + val.id;
|
|
||||||
window.prompt("Copy link to clipboard (Ctrl+C, Enter)", url);
|
|
||||||
}).fail(function(err) {
|
|
||||||
alert("Error sharing file: " + err.message);
|
|
||||||
});
|
});
|
||||||
});
|
$("#embedGistModal").modal('show');
|
||||||
}
|
}
|
||||||
|
|
||||||
function _shareEmbedLink(e) {
|
function _shareEmbedLink(e) {
|
||||||
|
@ -387,10 +383,7 @@ function _shareEmbedLink(e) {
|
||||||
alert("Can't share a Verilog executable yet. (It's not actually a ROM...)");
|
alert("Can't share a Verilog executable yet. (It's not actually a ROM...)");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
loadScript('lib/clipboard.min.js', () => {
|
loadClipboardLibrary();
|
||||||
var ClipboardJS = exports['ClipboardJS'];
|
|
||||||
new ClipboardJS(".btn");
|
|
||||||
});
|
|
||||||
loadScript('lib/liblzg.js', () => {
|
loadScript('lib/liblzg.js', () => {
|
||||||
// TODO: Module is bad var name (conflicts with MAME)
|
// TODO: Module is bad var name (conflicts with MAME)
|
||||||
var lzgrom = compressLZG( window['Module'], Array.from(<Uint8Array>current_output) );
|
var lzgrom = compressLZG( window['Module'], Array.from(<Uint8Array>current_output) );
|
||||||
|
@ -402,11 +395,7 @@ function _shareEmbedLink(e) {
|
||||||
r: lzgb64
|
r: lzgb64
|
||||||
};
|
};
|
||||||
var linkqs = $.param(embed);
|
var linkqs = $.param(embed);
|
||||||
console.log(linkqs);
|
var fulllink = get8bitworkshopLink(linkqs, 'embed.html');
|
||||||
var loc = window.location;
|
|
||||||
var prefix = loc.pathname.replace('index.html','');
|
|
||||||
var protocol = (loc.host == '8bitworkshop.com') ? 'https:' : loc.protocol;
|
|
||||||
var fulllink = protocol+'//'+loc.host+prefix+'embed.html?' + linkqs;
|
|
||||||
var iframelink = '<iframe width=640 height=600 src="' + fulllink + '">';
|
var iframelink = '<iframe width=640 height=600 src="' + fulllink + '">';
|
||||||
$("#embedLinkTextarea").text(fulllink);
|
$("#embedLinkTextarea").text(fulllink);
|
||||||
$("#embedIframeTextarea").text(iframelink);
|
$("#embedIframeTextarea").text(iframelink);
|
||||||
|
@ -419,6 +408,22 @@ function _shareEmbedLink(e) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadClipboardLibrary() {
|
||||||
|
loadScript('lib/clipboard.min.js', () => {
|
||||||
|
var ClipboardJS = exports['ClipboardJS'];
|
||||||
|
new ClipboardJS(".btn");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function get8bitworkshopLink(linkqs : string, fn : string) {
|
||||||
|
console.log(linkqs);
|
||||||
|
var loc = window.location;
|
||||||
|
var prefix = loc.pathname.replace('index.html','');
|
||||||
|
var protocol = (loc.host == '8bitworkshop.com') ? 'https:' : loc.protocol;
|
||||||
|
var fulllink = protocol+'//'+loc.host+prefix+fn+'?' + linkqs;
|
||||||
|
return fulllink;
|
||||||
|
}
|
||||||
|
|
||||||
function _downloadCassetteFile(e) {
|
function _downloadCassetteFile(e) {
|
||||||
if (current_output == null) { // TODO
|
if (current_output == null) { // TODO
|
||||||
alert("Please fix errors before exporting.");
|
alert("Please fix errors before exporting.");
|
||||||
|
@ -860,9 +865,15 @@ function getSymbolAtAddress(a : number) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var debugTickPaused = false;
|
||||||
|
|
||||||
function updateDebugWindows() {
|
function updateDebugWindows() {
|
||||||
if (platform.isRunning()) {
|
if (platform.isRunning()) {
|
||||||
projectWindows.tick();
|
projectWindows.tick();
|
||||||
|
debugTickPaused = false;
|
||||||
|
} else if (!debugTickPaused) { // final tick after pausing
|
||||||
|
projectWindows.tick();
|
||||||
|
debugTickPaused = true;
|
||||||
}
|
}
|
||||||
setTimeout(updateDebugWindows, 200);
|
setTimeout(updateDebugWindows, 200);
|
||||||
}
|
}
|
||||||
|
@ -1094,6 +1105,7 @@ function setupDebugControls(){
|
||||||
$(".dropdown-menu").collapse({toggle: false});
|
$(".dropdown-menu").collapse({toggle: false});
|
||||||
$("#item_new_file").click(_createNewFile);
|
$("#item_new_file").click(_createNewFile);
|
||||||
$("#item_upload_file").click(_uploadNewFile);
|
$("#item_upload_file").click(_uploadNewFile);
|
||||||
|
$("#item_share_github").click(_shareFileAsGist);
|
||||||
$("#item_share_file").click(_shareEmbedLink);
|
$("#item_share_file").click(_shareEmbedLink);
|
||||||
$("#item_reset_file").click(_revertFile);
|
$("#item_reset_file").click(_revertFile);
|
||||||
$("#item_rename_file").click(_renameFile);
|
$("#item_rename_file").click(_renameFile);
|
||||||
|
@ -1385,14 +1397,15 @@ function loadScript(scriptfn, onload) {
|
||||||
export function setupSplits() {
|
export function setupSplits() {
|
||||||
const splitName = 'workspace-split3-' + platform_id;
|
const splitName = 'workspace-split3-' + platform_id;
|
||||||
var sizes = [0, 50, 50];
|
var sizes = [0, 50, 50];
|
||||||
|
if (platform_id != 'vcs') // TODO
|
||||||
|
sizes = [12, 44, 44];
|
||||||
var sizesStr = hasLocalStorage && localStorage.getItem(splitName);
|
var sizesStr = hasLocalStorage && localStorage.getItem(splitName);
|
||||||
if (sizesStr) {
|
if (sizesStr) {
|
||||||
try {
|
try {
|
||||||
sizes = JSON.parse(sizesStr);
|
sizes = JSON.parse(sizesStr);
|
||||||
} catch (e) { console.log(e); }
|
} catch (e) { console.log(e); }
|
||||||
}
|
}
|
||||||
var split;
|
var split = Split(['#sidebar', '#workspace', '#emulator'], {
|
||||||
split = Split(['#sidebar', '#workspace', '#emulator'], {
|
|
||||||
sizes: sizes,
|
sizes: sizes,
|
||||||
minSize: [0, 250, 250],
|
minSize: [0, 250, 250],
|
||||||
onDrag: () => {
|
onDrag: () => {
|
||||||
|
@ -1401,6 +1414,7 @@ export function setupSplits() {
|
||||||
onDragEnd: () => {
|
onDragEnd: () => {
|
||||||
if (hasLocalStorage)
|
if (hasLocalStorage)
|
||||||
localStorage.setItem(splitName, JSON.stringify(split.getSizes()))
|
localStorage.setItem(splitName, JSON.stringify(split.getSizes()))
|
||||||
|
projectWindows.resize();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
58
src/views.ts
58
src/views.ts
|
@ -11,6 +11,7 @@ import { platform, platform_id, compparams, current_project, lastDebugState, pro
|
||||||
|
|
||||||
export interface ProjectView {
|
export interface ProjectView {
|
||||||
createDiv(parent:HTMLElement, text:string) : HTMLElement;
|
createDiv(parent:HTMLElement, text:string) : HTMLElement;
|
||||||
|
dispose?() : void;
|
||||||
refresh(moveCursor:boolean) : void;
|
refresh(moveCursor:boolean) : void;
|
||||||
tick?() : void;
|
tick?() : void;
|
||||||
getPath?() : string;
|
getPath?() : string;
|
||||||
|
@ -24,6 +25,7 @@ export interface ProjectView {
|
||||||
markErrors?(errors:WorkerError[]) : void;
|
markErrors?(errors:WorkerError[]) : void;
|
||||||
clearErrors?() : void;
|
clearErrors?() : void;
|
||||||
setTimingResult?(result:CodeAnalyzer) : void;
|
setTimingResult?(result:CodeAnalyzer) : void;
|
||||||
|
recreateOnResize? : boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
declare var CodeMirror;
|
declare var CodeMirror;
|
||||||
|
@ -36,6 +38,13 @@ function jumpToLine(ed, i:number) {
|
||||||
ed.scrollTo(null, t - middleHeight - 5);
|
ed.scrollTo(null, t - middleHeight - 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createTextSpan(text:string, className:string) : HTMLElement {
|
||||||
|
var span = document.createElement("span");
|
||||||
|
span.setAttribute("class", className);
|
||||||
|
span.appendChild(document.createTextNode(text));
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: https://stackoverflow.com/questions/10463518/converting-em-to-px-in-javascript-and-getting-default-font-size
|
// TODO: https://stackoverflow.com/questions/10463518/converting-em-to-px-in-javascript-and-getting-default-font-size
|
||||||
function getVisibleEditorLineHeight() : number{
|
function getVisibleEditorLineHeight() : number{
|
||||||
return $("#booksMenuButton").first().height();
|
return $("#booksMenuButton").first().height();
|
||||||
|
@ -119,9 +128,7 @@ export class SourceEditor implements ProjectView {
|
||||||
this.inspectWidget = null;
|
this.inspectWidget = null;
|
||||||
}
|
}
|
||||||
if (result) {
|
if (result) {
|
||||||
var infospan = document.createElement("span");
|
var infospan = createTextSpan(result, "tooltipinfoline");
|
||||||
infospan.setAttribute("class", "tooltipinfoline");
|
|
||||||
infospan.appendChild(document.createTextNode(result));
|
|
||||||
var line = this.editor.getCursor().line;
|
var line = this.editor.getCursor().line;
|
||||||
this.inspectWidget = this.editor.addLineWidget(line, infospan, {above:false});
|
this.inspectWidget = this.editor.addLineWidget(line, infospan, {above:false});
|
||||||
}
|
}
|
||||||
|
@ -156,9 +163,7 @@ export class SourceEditor implements ProjectView {
|
||||||
}
|
}
|
||||||
|
|
||||||
addErrorLine(line:number, msg:string) {
|
addErrorLine(line:number, msg:string) {
|
||||||
var errspan = document.createElement("span");
|
var errspan = createTextSpan(msg, "tooltiperrorline");
|
||||||
errspan.setAttribute("class", "tooltiperrorline");
|
|
||||||
errspan.appendChild(document.createTextNode(msg));
|
|
||||||
this.errorwidgets.push(this.editor.addLineWidget(line, errspan));
|
this.errorwidgets.push(this.editor.addLineWidget(line, errspan));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,7 +552,7 @@ export class ListingView extends DisassemblerView implements ProjectView {
|
||||||
var asmtext = this.assemblyfile.text;
|
var asmtext = this.assemblyfile.text;
|
||||||
var disasmview = this.getDisasmView();
|
var disasmview = this.getDisasmView();
|
||||||
disasmview.setValue(asmtext);
|
disasmview.setValue(asmtext);
|
||||||
var debugging = platform.isDebugging && platform.isDebugging();
|
var debugging = true; // TODO: platform.isDebugging && platform.isDebugging();
|
||||||
var findPC = debugging ? pc : -1;
|
var findPC = debugging ? pc : -1;
|
||||||
if (findPC >= 0 && this.assemblyfile) {
|
if (findPC >= 0 && this.assemblyfile) {
|
||||||
var lineno = this.assemblyfile.findLineForOffset(findPC, 15);
|
var lineno = this.assemblyfile.findLineForOffset(findPC, 15);
|
||||||
|
@ -570,6 +575,7 @@ export class MemoryView implements ProjectView {
|
||||||
dumplines;
|
dumplines;
|
||||||
maindiv : HTMLElement;
|
maindiv : HTMLElement;
|
||||||
static IGNORE_SYMS = {s__INITIALIZER:true, /* s__GSINIT:true, */ _color_prom:true};
|
static IGNORE_SYMS = {s__INITIALIZER:true, /* s__GSINIT:true, */ _color_prom:true};
|
||||||
|
recreateOnResize = true;
|
||||||
/*
|
/*
|
||||||
read(addr:number) {
|
read(addr:number) {
|
||||||
// TODO: b offset ?
|
// TODO: b offset ?
|
||||||
|
@ -727,6 +733,7 @@ export class BinaryFileView implements ProjectView {
|
||||||
maindiv : HTMLElement;
|
maindiv : HTMLElement;
|
||||||
path:string;
|
path:string;
|
||||||
data:Uint8Array;
|
data:Uint8Array;
|
||||||
|
recreateOnResize = true;
|
||||||
|
|
||||||
constructor(path:string, data:Uint8Array) {
|
constructor(path:string, data:Uint8Array) {
|
||||||
this.path = path;
|
this.path = path;
|
||||||
|
@ -841,10 +848,11 @@ export class ProfileView implements ProjectView {
|
||||||
prof : ProfilerOutput;
|
prof : ProfilerOutput;
|
||||||
maindiv : HTMLElement;
|
maindiv : HTMLElement;
|
||||||
symcache : {};
|
symcache : {};
|
||||||
|
recreateOnResize = true;
|
||||||
|
|
||||||
createDiv(parent : HTMLElement) {
|
createDiv(parent : HTMLElement) {
|
||||||
var div = document.createElement('div');
|
var div = document.createElement('div');
|
||||||
div.setAttribute("class", "memdump");
|
div.setAttribute("class", "profiler");
|
||||||
parent.appendChild(div);
|
parent.appendChild(div);
|
||||||
this.showMemoryWindow(parent, div);
|
this.showMemoryWindow(parent, div);
|
||||||
return this.maindiv = div;
|
return this.maindiv = div;
|
||||||
|
@ -857,9 +865,8 @@ export class ProfileView implements ProjectView {
|
||||||
itemHeight: getVisibleEditorLineHeight(),
|
itemHeight: getVisibleEditorLineHeight(),
|
||||||
totalRows: 262,
|
totalRows: 262,
|
||||||
generatorFn: (row : number) => {
|
generatorFn: (row : number) => {
|
||||||
var s = this.getProfileLineAt(row);
|
|
||||||
var linediv = document.createElement("div");
|
var linediv = document.createElement("div");
|
||||||
linediv.appendChild(document.createTextNode(s));
|
this.addProfileLine(linediv, row);
|
||||||
return linediv;
|
return linediv;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -868,13 +875,13 @@ export class ProfileView implements ProjectView {
|
||||||
this.tick();
|
this.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
getProfileLineAt(row : number) : string {
|
addProfileLine(div : HTMLElement, row : number) : void {
|
||||||
var s = lpad(row+': ',5);
|
div.appendChild(createTextSpan(lpad(row+':',4), "profiler-lineno"));
|
||||||
if (!this.prof) return s;
|
if (!this.prof) return;
|
||||||
var f = this.prof.frame;
|
var f = this.prof.frame;
|
||||||
if (!f) return s;
|
if (!f) return;
|
||||||
var l = f.lines[row];
|
var l = f.lines[row];
|
||||||
if (!l) return s;
|
if (!l) return;
|
||||||
var lastsym = '';
|
var lastsym = '';
|
||||||
for (var i=l.start; i<=l.end; i++) {
|
for (var i=l.start; i<=l.end; i++) {
|
||||||
var pc = f.iptab[i];
|
var pc = f.iptab[i];
|
||||||
|
@ -884,11 +891,14 @@ export class ProfileView implements ProjectView {
|
||||||
this.symcache[pc] = sym;
|
this.symcache[pc] = sym;
|
||||||
}
|
}
|
||||||
if (sym != lastsym) {
|
if (sym != lastsym) {
|
||||||
s += sym + ' ';
|
var cls = "profiler";
|
||||||
|
if (sym.startsWith('_')) cls = "profiler-cident";
|
||||||
|
else if (sym.startsWith('@')) cls = "profiler-local";
|
||||||
|
else if (/^\d*[.]/.exec(sym)) cls = "profiler-local";
|
||||||
|
div.appendChild(createTextSpan(' '+sym, cls));
|
||||||
lastsym = sym;
|
lastsym = sym;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
|
@ -900,15 +910,17 @@ export class ProfileView implements ProjectView {
|
||||||
$(this.maindiv).find('[data-index]').each( (i,e) => {
|
$(this.maindiv).find('[data-index]').each( (i,e) => {
|
||||||
var div = $(e);
|
var div = $(e);
|
||||||
var row = parseInt(div.attr('data-index'));
|
var row = parseInt(div.attr('data-index'));
|
||||||
var oldtext = div.text();
|
div.empty();
|
||||||
var newtext = this.getProfileLineAt(row);
|
this.addProfileLine(div[0], row);
|
||||||
if (oldtext != newtext)
|
|
||||||
div.text(newtext);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// TODO: better way to keep it profiling? also, it clears the buffer
|
// TODO: better way to keep it profiling single-frame? also, it clears the buffer
|
||||||
if (platform.isRunning()) {
|
if (platform.isRunning() /* && !platform.isDebugging()*/ ) {
|
||||||
this.prof = platform.startProfiling();
|
this.prof = platform.startProfiling();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispose() : void {
|
||||||
|
platform.clearDebug();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ type WindowCreateFunction = (id:string) => ProjectView;
|
||||||
export class ProjectWindows {
|
export class ProjectWindows {
|
||||||
containerdiv:HTMLElement;
|
containerdiv:HTMLElement;
|
||||||
project:CodeProject;
|
project:CodeProject;
|
||||||
|
|
||||||
id2window : {[id:string]:ProjectView} = {};
|
id2window : {[id:string]:ProjectView} = {};
|
||||||
id2createfn : {[id:string]:WindowCreateFunction} = {};
|
id2createfn : {[id:string]:WindowCreateFunction} = {};
|
||||||
id2div : {[id:string]:HTMLElement} = {};
|
id2div : {[id:string]:HTMLElement} = {};
|
||||||
|
@ -18,17 +17,17 @@ export class ProjectWindows {
|
||||||
activewnd : ProjectView;
|
activewnd : ProjectView;
|
||||||
activediv : HTMLElement;
|
activediv : HTMLElement;
|
||||||
lasterrors : WorkerError[];
|
lasterrors : WorkerError[];
|
||||||
|
|
||||||
constructor(containerdiv:HTMLElement, project:CodeProject) {
|
constructor(containerdiv:HTMLElement, project:CodeProject) {
|
||||||
this.containerdiv = containerdiv;
|
this.containerdiv = containerdiv;
|
||||||
this.project = project;
|
this.project = project;
|
||||||
}
|
}
|
||||||
// TODO: delete windows ever?
|
// TODO: delete windows ever?
|
||||||
|
|
||||||
setCreateFunc(id:string, createfn:WindowCreateFunction) : void {
|
setCreateFunc(id:string, createfn:WindowCreateFunction) : void {
|
||||||
this.id2createfn[id] = createfn;
|
this.id2createfn[id] = createfn;
|
||||||
}
|
}
|
||||||
|
|
||||||
createOrShow(id:string) : ProjectView {
|
createOrShow(id:string) : ProjectView {
|
||||||
var wnd = this.id2window[id];
|
var wnd = this.id2window[id];
|
||||||
if (!wnd) {
|
if (!wnd) {
|
||||||
|
@ -42,6 +41,8 @@ export class ProjectWindows {
|
||||||
if (this.activewnd != wnd) {
|
if (this.activewnd != wnd) {
|
||||||
if (this.activediv)
|
if (this.activediv)
|
||||||
$(this.activediv).hide();
|
$(this.activediv).hide();
|
||||||
|
if (this.activewnd && this.activewnd.dispose)
|
||||||
|
this.activewnd.dispose();
|
||||||
this.activediv = div;
|
this.activediv = div;
|
||||||
this.activewnd = wnd;
|
this.activewnd = wnd;
|
||||||
$(div).show();
|
$(div).show();
|
||||||
|
@ -55,13 +56,13 @@ export class ProjectWindows {
|
||||||
put(id:string, window:ProjectView) : void {
|
put(id:string, window:ProjectView) : void {
|
||||||
this.id2window[id] = window;
|
this.id2window[id] = window;
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh(moveCursor:boolean) : void {
|
refresh(moveCursor:boolean) : void {
|
||||||
// refresh current window
|
// refresh current window
|
||||||
if (this.activewnd && this.activewnd.refresh)
|
if (this.activewnd && this.activewnd.refresh)
|
||||||
this.activewnd.refresh(moveCursor);
|
this.activewnd.refresh(moveCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
tick() : void {
|
tick() : void {
|
||||||
if (this.activewnd && this.activewnd.tick)
|
if (this.activewnd && this.activewnd.tick)
|
||||||
this.activewnd.tick();
|
this.activewnd.tick();
|
||||||
|
@ -71,7 +72,7 @@ export class ProjectWindows {
|
||||||
this.lasterrors = errors;
|
this.lasterrors = errors;
|
||||||
this.refreshErrors();
|
this.refreshErrors();
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshErrors() : void {
|
refreshErrors() : void {
|
||||||
if (this.activewnd && this.activewnd.markErrors) {
|
if (this.activewnd && this.activewnd.markErrors) {
|
||||||
if (this.lasterrors && this.lasterrors.length)
|
if (this.lasterrors && this.lasterrors.length)
|
||||||
|
@ -80,9 +81,9 @@ export class ProjectWindows {
|
||||||
this.activewnd.clearErrors();
|
this.activewnd.clearErrors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getActive() : ProjectView { return this.activewnd; }
|
getActive() : ProjectView { return this.activewnd; }
|
||||||
|
|
||||||
getActiveID() : string { return this.activeid; }
|
getActiveID() : string { return this.activeid; }
|
||||||
|
|
||||||
getCurrentText() : string {
|
getCurrentText() : string {
|
||||||
|
@ -91,5 +92,13 @@ export class ProjectWindows {
|
||||||
else
|
else
|
||||||
alert("Please switch to an editor window.");
|
alert("Please switch to an editor window.");
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
resize() : void {
|
||||||
|
if (this.activeid && this.activewnd && this.activewnd.recreateOnResize) {
|
||||||
|
this.activewnd = null;
|
||||||
|
this.id2window[this.activeid] = null;
|
||||||
|
this.id2div[this.activeid] = null;
|
||||||
|
this.createOrShow(this.activeid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue