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%;
|
||||
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">
|
||||
<a tabindex="-1" href="#">Share</a>
|
||||
<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_record_video">Record Video...</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_export_cassette">Make Cassette Audio...</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
@ -178,7 +179,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||
<span id="verilog_bar" style="display:none">
|
||||
<span class="label"><span id="settle_label"></span> evals/clk</span>
|
||||
</span>
|
||||
|
||||
|
||||
<span class="dropdown" style="float:right">
|
||||
<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 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>
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ word bcd_add(word a, word b) {
|
|||
byte d = (a & 0xf) + (b & 0xf) + c;
|
||||
c = 0;
|
||||
while (d >= 10) {
|
||||
c++;
|
||||
++c;
|
||||
d -= 10;
|
||||
}
|
||||
result |= d << shift;
|
||||
|
|
|
@ -2,9 +2,15 @@
|
|||
#include "neslib.h"
|
||||
#include "vrambuf.h"
|
||||
|
||||
#pragma bss-name(push,"ZEROPAGE")
|
||||
#pragma data-name(push,"ZEROPAGE")
|
||||
|
||||
// index to end of buffer
|
||||
byte updptr = 0;
|
||||
|
||||
#pragma bss-name(pop)
|
||||
#pragma data-name(pop)
|
||||
|
||||
// add EOF marker to buffer
|
||||
void cendbuf(void) {
|
||||
updbuf[updptr] = NT_UPD_EOF;
|
||||
|
@ -30,11 +36,12 @@ void cflushnow(void) {
|
|||
// using horizontal increment
|
||||
void putbytes(word addr, const char* str, byte len) {
|
||||
if (updptr >= VBUFSIZE-4-len) cflushnow();
|
||||
updbuf[updptr++] = (addr >> 8) ^ NT_UPD_HORZ;
|
||||
updbuf[updptr++] = addr & 0xff;
|
||||
updbuf[updptr++] = len;
|
||||
updbuf[updptr] = (addr >> 8) ^ NT_UPD_HORZ;
|
||||
updbuf[++updptr] = addr & 0xff;
|
||||
updbuf[++updptr] = len;
|
||||
while (len--) {
|
||||
updbuf[updptr++] = *str++;
|
||||
updbuf[++updptr] = *str++;
|
||||
}
|
||||
++updptr;
|
||||
cendbuf();
|
||||
}
|
||||
|
|
|
@ -157,6 +157,31 @@ export abstract class BasePlatform {
|
|||
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 {
|
||||
|
@ -208,29 +233,6 @@ export abstract class BaseDebugPlatform extends BasePlatform {
|
|||
this.advance(novideo);
|
||||
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
|
||||
|
@ -1028,6 +1030,7 @@ export abstract class BasicZ80ScanlinePlatform extends BaseZ80Platform {
|
|||
abstract getKeyboardMap();
|
||||
abstract startScanline(sl : number);
|
||||
abstract drawScanline(sl : number);
|
||||
getRasterScanline() { return this.currentScanline; }
|
||||
|
||||
constructor(mainElement : HTMLElement) {
|
||||
super();
|
||||
|
|
|
@ -231,30 +231,6 @@ const _JSNESPlatform = function(mainElement) {
|
|||
getRasterScanline() : number {
|
||||
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() {
|
||||
var c = nes.cpu.toJSON();
|
||||
|
|
|
@ -153,6 +153,7 @@ class VCSPlatform extends BasePlatform {
|
|||
Javatari.room.speaker.mute();
|
||||
}
|
||||
isDebugging() : boolean {
|
||||
// TODO: always true
|
||||
return Javatari.room.console.onBreakpointHit != null;
|
||||
}
|
||||
clearDebug() {
|
||||
|
|
78
src/ui.ts
78
src/ui.ts
|
@ -354,28 +354,24 @@ function getCurrentEditorFilename() : string {
|
|||
}
|
||||
|
||||
function _shareFileAsGist(e) {
|
||||
loadScript("octokat.js/dist/octokat.js", () => {
|
||||
if (current_output == null) { // TODO
|
||||
alert("Please fix errors before sharing.");
|
||||
return true;
|
||||
}
|
||||
var text = projectWindows.getCurrentText();
|
||||
if (!text) return false;
|
||||
var github = new exports['Octokat']();
|
||||
var files = {};
|
||||
files[getCurrentEditorFilename()] = {"content": text};
|
||||
var gistdata = {
|
||||
"description": '8bitworkshop.com {"platform":"' + platform_id + '"}',
|
||||
"public": true,
|
||||
"files": files
|
||||
};
|
||||
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);
|
||||
var gisturl_ta = $("#embedGistURL");
|
||||
var shareurl_ta = $("#embedGistShareURL");
|
||||
loadClipboardLibrary();
|
||||
gisturl_ta.change(() => {
|
||||
var gisturl = gisturl_ta.val() + '';
|
||||
var pos = gisturl.lastIndexOf('/');
|
||||
if (pos >= 0) {
|
||||
var gistkey = gisturl.substring(pos+1);
|
||||
var embed = {
|
||||
platform: platform_id,
|
||||
gistkey: gistkey
|
||||
};
|
||||
var linkqs = $.param(embed);
|
||||
var fulllink = get8bitworkshopLink(linkqs, 'redir.html');
|
||||
shareurl_ta.val(fulllink);
|
||||
}
|
||||
});
|
||||
});
|
||||
$("#embedGistModal").modal('show');
|
||||
}
|
||||
|
||||
function _shareEmbedLink(e) {
|
||||
|
@ -387,10 +383,7 @@ function _shareEmbedLink(e) {
|
|||
alert("Can't share a Verilog executable yet. (It's not actually a ROM...)");
|
||||
return true;
|
||||
}
|
||||
loadScript('lib/clipboard.min.js', () => {
|
||||
var ClipboardJS = exports['ClipboardJS'];
|
||||
new ClipboardJS(".btn");
|
||||
});
|
||||
loadClipboardLibrary();
|
||||
loadScript('lib/liblzg.js', () => {
|
||||
// TODO: Module is bad var name (conflicts with MAME)
|
||||
var lzgrom = compressLZG( window['Module'], Array.from(<Uint8Array>current_output) );
|
||||
|
@ -402,11 +395,7 @@ function _shareEmbedLink(e) {
|
|||
r: lzgb64
|
||||
};
|
||||
var linkqs = $.param(embed);
|
||||
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+'embed.html?' + linkqs;
|
||||
var fulllink = get8bitworkshopLink(linkqs, 'embed.html');
|
||||
var iframelink = '<iframe width=640 height=600 src="' + fulllink + '">';
|
||||
$("#embedLinkTextarea").text(fulllink);
|
||||
$("#embedIframeTextarea").text(iframelink);
|
||||
|
@ -419,6 +408,22 @@ function _shareEmbedLink(e) {
|
|||
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) {
|
||||
if (current_output == null) { // TODO
|
||||
alert("Please fix errors before exporting.");
|
||||
|
@ -860,9 +865,15 @@ function getSymbolAtAddress(a : number) {
|
|||
return '';
|
||||
}
|
||||
|
||||
var debugTickPaused = false;
|
||||
|
||||
function updateDebugWindows() {
|
||||
if (platform.isRunning()) {
|
||||
projectWindows.tick();
|
||||
debugTickPaused = false;
|
||||
} else if (!debugTickPaused) { // final tick after pausing
|
||||
projectWindows.tick();
|
||||
debugTickPaused = true;
|
||||
}
|
||||
setTimeout(updateDebugWindows, 200);
|
||||
}
|
||||
|
@ -1094,6 +1105,7 @@ function setupDebugControls(){
|
|||
$(".dropdown-menu").collapse({toggle: false});
|
||||
$("#item_new_file").click(_createNewFile);
|
||||
$("#item_upload_file").click(_uploadNewFile);
|
||||
$("#item_share_github").click(_shareFileAsGist);
|
||||
$("#item_share_file").click(_shareEmbedLink);
|
||||
$("#item_reset_file").click(_revertFile);
|
||||
$("#item_rename_file").click(_renameFile);
|
||||
|
@ -1385,14 +1397,15 @@ function loadScript(scriptfn, onload) {
|
|||
export function setupSplits() {
|
||||
const splitName = 'workspace-split3-' + platform_id;
|
||||
var sizes = [0, 50, 50];
|
||||
if (platform_id != 'vcs') // TODO
|
||||
sizes = [12, 44, 44];
|
||||
var sizesStr = hasLocalStorage && localStorage.getItem(splitName);
|
||||
if (sizesStr) {
|
||||
try {
|
||||
sizes = JSON.parse(sizesStr);
|
||||
} catch (e) { console.log(e); }
|
||||
}
|
||||
var split;
|
||||
split = Split(['#sidebar', '#workspace', '#emulator'], {
|
||||
var split = Split(['#sidebar', '#workspace', '#emulator'], {
|
||||
sizes: sizes,
|
||||
minSize: [0, 250, 250],
|
||||
onDrag: () => {
|
||||
|
@ -1401,6 +1414,7 @@ export function setupSplits() {
|
|||
onDragEnd: () => {
|
||||
if (hasLocalStorage)
|
||||
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 {
|
||||
createDiv(parent:HTMLElement, text:string) : HTMLElement;
|
||||
dispose?() : void;
|
||||
refresh(moveCursor:boolean) : void;
|
||||
tick?() : void;
|
||||
getPath?() : string;
|
||||
|
@ -24,6 +25,7 @@ export interface ProjectView {
|
|||
markErrors?(errors:WorkerError[]) : void;
|
||||
clearErrors?() : void;
|
||||
setTimingResult?(result:CodeAnalyzer) : void;
|
||||
recreateOnResize? : boolean;
|
||||
};
|
||||
|
||||
declare var CodeMirror;
|
||||
|
@ -36,6 +38,13 @@ function jumpToLine(ed, i:number) {
|
|||
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
|
||||
function getVisibleEditorLineHeight() : number{
|
||||
return $("#booksMenuButton").first().height();
|
||||
|
@ -119,9 +128,7 @@ export class SourceEditor implements ProjectView {
|
|||
this.inspectWidget = null;
|
||||
}
|
||||
if (result) {
|
||||
var infospan = document.createElement("span");
|
||||
infospan.setAttribute("class", "tooltipinfoline");
|
||||
infospan.appendChild(document.createTextNode(result));
|
||||
var infospan = createTextSpan(result, "tooltipinfoline");
|
||||
var line = this.editor.getCursor().line;
|
||||
this.inspectWidget = this.editor.addLineWidget(line, infospan, {above:false});
|
||||
}
|
||||
|
@ -156,9 +163,7 @@ export class SourceEditor implements ProjectView {
|
|||
}
|
||||
|
||||
addErrorLine(line:number, msg:string) {
|
||||
var errspan = document.createElement("span");
|
||||
errspan.setAttribute("class", "tooltiperrorline");
|
||||
errspan.appendChild(document.createTextNode(msg));
|
||||
var errspan = createTextSpan(msg, "tooltiperrorline");
|
||||
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 disasmview = this.getDisasmView();
|
||||
disasmview.setValue(asmtext);
|
||||
var debugging = platform.isDebugging && platform.isDebugging();
|
||||
var debugging = true; // TODO: platform.isDebugging && platform.isDebugging();
|
||||
var findPC = debugging ? pc : -1;
|
||||
if (findPC >= 0 && this.assemblyfile) {
|
||||
var lineno = this.assemblyfile.findLineForOffset(findPC, 15);
|
||||
|
@ -570,6 +575,7 @@ export class MemoryView implements ProjectView {
|
|||
dumplines;
|
||||
maindiv : HTMLElement;
|
||||
static IGNORE_SYMS = {s__INITIALIZER:true, /* s__GSINIT:true, */ _color_prom:true};
|
||||
recreateOnResize = true;
|
||||
/*
|
||||
read(addr:number) {
|
||||
// TODO: b offset ?
|
||||
|
@ -727,6 +733,7 @@ export class BinaryFileView implements ProjectView {
|
|||
maindiv : HTMLElement;
|
||||
path:string;
|
||||
data:Uint8Array;
|
||||
recreateOnResize = true;
|
||||
|
||||
constructor(path:string, data:Uint8Array) {
|
||||
this.path = path;
|
||||
|
@ -841,10 +848,11 @@ export class ProfileView implements ProjectView {
|
|||
prof : ProfilerOutput;
|
||||
maindiv : HTMLElement;
|
||||
symcache : {};
|
||||
recreateOnResize = true;
|
||||
|
||||
createDiv(parent : HTMLElement) {
|
||||
var div = document.createElement('div');
|
||||
div.setAttribute("class", "memdump");
|
||||
div.setAttribute("class", "profiler");
|
||||
parent.appendChild(div);
|
||||
this.showMemoryWindow(parent, div);
|
||||
return this.maindiv = div;
|
||||
|
@ -857,9 +865,8 @@ export class ProfileView implements ProjectView {
|
|||
itemHeight: getVisibleEditorLineHeight(),
|
||||
totalRows: 262,
|
||||
generatorFn: (row : number) => {
|
||||
var s = this.getProfileLineAt(row);
|
||||
var linediv = document.createElement("div");
|
||||
linediv.appendChild(document.createTextNode(s));
|
||||
this.addProfileLine(linediv, row);
|
||||
return linediv;
|
||||
}
|
||||
});
|
||||
|
@ -868,13 +875,13 @@ export class ProfileView implements ProjectView {
|
|||
this.tick();
|
||||
}
|
||||
|
||||
getProfileLineAt(row : number) : string {
|
||||
var s = lpad(row+': ',5);
|
||||
if (!this.prof) return s;
|
||||
addProfileLine(div : HTMLElement, row : number) : void {
|
||||
div.appendChild(createTextSpan(lpad(row+':',4), "profiler-lineno"));
|
||||
if (!this.prof) return;
|
||||
var f = this.prof.frame;
|
||||
if (!f) return s;
|
||||
if (!f) return;
|
||||
var l = f.lines[row];
|
||||
if (!l) return s;
|
||||
if (!l) return;
|
||||
var lastsym = '';
|
||||
for (var i=l.start; i<=l.end; i++) {
|
||||
var pc = f.iptab[i];
|
||||
|
@ -884,11 +891,14 @@ export class ProfileView implements ProjectView {
|
|||
this.symcache[pc] = sym;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
refresh() {
|
||||
|
@ -900,15 +910,17 @@ export class ProfileView implements ProjectView {
|
|||
$(this.maindiv).find('[data-index]').each( (i,e) => {
|
||||
var div = $(e);
|
||||
var row = parseInt(div.attr('data-index'));
|
||||
var oldtext = div.text();
|
||||
var newtext = this.getProfileLineAt(row);
|
||||
if (oldtext != newtext)
|
||||
div.text(newtext);
|
||||
div.empty();
|
||||
this.addProfileLine(div[0], row);
|
||||
});
|
||||
}
|
||||
// TODO: better way to keep it profiling? also, it clears the buffer
|
||||
if (platform.isRunning()) {
|
||||
// TODO: better way to keep it profiling single-frame? also, it clears the buffer
|
||||
if (platform.isRunning() /* && !platform.isDebugging()*/ ) {
|
||||
this.prof = platform.startProfiling();
|
||||
}
|
||||
}
|
||||
|
||||
dispose() : void {
|
||||
platform.clearDebug();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ type WindowCreateFunction = (id:string) => ProjectView;
|
|||
export class ProjectWindows {
|
||||
containerdiv:HTMLElement;
|
||||
project:CodeProject;
|
||||
|
||||
id2window : {[id:string]:ProjectView} = {};
|
||||
id2createfn : {[id:string]:WindowCreateFunction} = {};
|
||||
id2div : {[id:string]:HTMLElement} = {};
|
||||
|
@ -18,17 +17,17 @@ export class ProjectWindows {
|
|||
activewnd : ProjectView;
|
||||
activediv : HTMLElement;
|
||||
lasterrors : WorkerError[];
|
||||
|
||||
|
||||
constructor(containerdiv:HTMLElement, project:CodeProject) {
|
||||
this.containerdiv = containerdiv;
|
||||
this.project = project;
|
||||
}
|
||||
// TODO: delete windows ever?
|
||||
|
||||
|
||||
setCreateFunc(id:string, createfn:WindowCreateFunction) : void {
|
||||
this.id2createfn[id] = createfn;
|
||||
}
|
||||
|
||||
|
||||
createOrShow(id:string) : ProjectView {
|
||||
var wnd = this.id2window[id];
|
||||
if (!wnd) {
|
||||
|
@ -42,6 +41,8 @@ export class ProjectWindows {
|
|||
if (this.activewnd != wnd) {
|
||||
if (this.activediv)
|
||||
$(this.activediv).hide();
|
||||
if (this.activewnd && this.activewnd.dispose)
|
||||
this.activewnd.dispose();
|
||||
this.activediv = div;
|
||||
this.activewnd = wnd;
|
||||
$(div).show();
|
||||
|
@ -55,13 +56,13 @@ export class ProjectWindows {
|
|||
put(id:string, window:ProjectView) : void {
|
||||
this.id2window[id] = window;
|
||||
}
|
||||
|
||||
|
||||
refresh(moveCursor:boolean) : void {
|
||||
// refresh current window
|
||||
if (this.activewnd && this.activewnd.refresh)
|
||||
this.activewnd.refresh(moveCursor);
|
||||
}
|
||||
|
||||
|
||||
tick() : void {
|
||||
if (this.activewnd && this.activewnd.tick)
|
||||
this.activewnd.tick();
|
||||
|
@ -71,7 +72,7 @@ export class ProjectWindows {
|
|||
this.lasterrors = errors;
|
||||
this.refreshErrors();
|
||||
}
|
||||
|
||||
|
||||
refreshErrors() : void {
|
||||
if (this.activewnd && this.activewnd.markErrors) {
|
||||
if (this.lasterrors && this.lasterrors.length)
|
||||
|
@ -80,9 +81,9 @@ export class ProjectWindows {
|
|||
this.activewnd.clearErrors();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getActive() : ProjectView { return this.activewnd; }
|
||||
|
||||
|
||||
getActiveID() : string { return this.activeid; }
|
||||
|
||||
getCurrentText() : string {
|
||||
|
@ -91,5 +92,13 @@ export class ProjectWindows {
|
|||
else
|
||||
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