Skip to content

Commit 03093f8

Browse files
Damn Stop Button (#75)
* Bring back that damn stop button. * Add new lib procedure for stopping the build. * Handle thread interruption while populating resources. * Disable the build menu after cthread is constructed. * Enable the build menu in a finally block to ensure it gets enabled again.
1 parent c305acc commit 03093f8

File tree

4 files changed

+80
-47
lines changed

4 files changed

+80
-47
lines changed

org/enigma/EnigmaRunner.java

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,6 @@ public void run()
160160
});
161161

162162
setMenuEnabled(false);
163-
//stop.setVisible(false);
164-
//stopb.setVisible(false);
165163

166164
final Thread initthread = new Thread()
167165
{
@@ -397,27 +395,28 @@ public EnigmaSettings getInstance()
397395

398396
public void populateMenu()
399397
{
400-
//stopb = new JButton(); //$NON-NLS-1$
401-
//stopb.addActionListener(this);
402-
//stopb.setToolTipText(Messages.getString("EnigmaRunner.MENU_STOP"));
403-
//stopb.setIcon(LGM.getIconForKey("EnigmaPlugin.STOP"));
404-
//LGM.tool.add(stopb, 5);
398+
int toolPos = 4; // <- After "Save As" separator.
399+
stopb = new JButton(); //$NON-NLS-1$
400+
stopb.addActionListener(this);
401+
stopb.setToolTipText(Messages.getString("EnigmaRunner.MENU_STOP"));
402+
stopb.setIcon(LGM.getIconForKey("EnigmaPlugin.STOP"));
403+
LGM.tool.add(stopb, ++toolPos);
405404
runb = new JButton(); //$NON-NLS-1$
406405
runb.addActionListener(this);
407406
runb.setToolTipText(Messages.getString("EnigmaRunner.MENU_RUN"));
408407
runb.setIcon(LGM.getIconForKey("EnigmaPlugin.EXECUTE"));
409-
LGM.tool.add(runb, 5);
408+
LGM.tool.add(runb, ++toolPos);
410409
debugb = new JButton(); //$NON-NLS-1$
411410
debugb.addActionListener(this);
412411
debugb.setToolTipText(Messages.getString("EnigmaRunner.MENU_DEBUG"));
413412
debugb.setIcon(LGM.getIconForKey("EnigmaPlugin.DEBUG"));
414-
LGM.tool.add(debugb, 6);
413+
LGM.tool.add(debugb, ++toolPos);
415414
compileb = new JButton(); //$NON-NLS-1$
416415
compileb.addActionListener(this);
417416
compileb.setToolTipText(Messages.getString("EnigmaRunner.MENU_COMPILE"));
418417
compileb.setIcon(LGM.getIconForKey("EnigmaPlugin.COMPILE"));
419-
LGM.tool.add(compileb, 7);
420-
LGM.tool.add(new JToolBar.Separator(), 8);
418+
LGM.tool.add(compileb, ++toolPos);
419+
LGM.tool.add(new JToolBar.Separator(), ++toolPos);
421420

422421
JMenu menu = new GmMenu(Messages.getString("EnigmaRunner.MENU_BUILD")); //$NON-NLS-1$
423422
menu.setMnemonic('B');
@@ -445,11 +444,11 @@ public void populateMenu()
445444
compile.setAccelerator(KeyStroke.getKeyStroke(Messages.getKeyboardString("EnigmaRunner.COMPILE")));
446445
menu.add(compile);
447446
menu.addSeparator();
448-
//stop = addItem(Messages.getString("EnigmaRunner.MENU_STOP")); //$NON-NLS-1$
449-
//stop.addActionListener(this);
450-
//stop.setIcon(LGM.getIconForKey("EnigmaPlugin.STOP"));
451-
//stop.setAccelerator(KeyStroke.getKeyStroke(Messages.getKeyboardString("EnigmaRunner.STOP")));
452-
//menu.add(stop);
447+
stop = addItem(Messages.getString("EnigmaRunner.MENU_STOP")); //$NON-NLS-1$
448+
stop.addActionListener(this);
449+
stop.setIcon(LGM.getIconForKey("EnigmaPlugin.STOP"));
450+
stop.setAccelerator(KeyStroke.getKeyStroke(Messages.getKeyboardString("EnigmaRunner.STOP")));
451+
menu.add(stop);
453452
rebuild = addItem(Messages.getString("EnigmaRunner.MENU_REBUILD_ALL")); //$NON-NLS-1$
454453
rebuild.addActionListener(this);
455454
rebuild.setIcon(LGM.getIconForKey("EnigmaPlugin.REBUILD_ALL"));
@@ -631,10 +630,10 @@ public void setMenuEnabled(boolean en)
631630
run.setEnabled(en);
632631
debug.setEnabled(en);
633632
design.setEnabled(en);
634-
//stop.setEnabled(!en);
633+
stop.setEnabled(!en);
635634
compile.setEnabled(en);
636635
rebuild.setEnabled(en);
637-
//stopb.setEnabled(!en);
636+
stopb.setEnabled(!en);
638637
runb.setEnabled(en);
639638
debugb.setEnabled(en);
640639
compileb.setEnabled(en);
@@ -653,19 +652,22 @@ class CompilerThread extends Thread {
653652
}
654653

655654
public void run() {
656-
EnigmaRunner.addDefaultExceptionHandler();
657-
ef.open();
658-
ef.progress(10,Messages.getString("EnigmaRunner.POPULATING")); //$NON-NLS-1$
659-
EnigmaStruct es = EnigmaWriter.prepareStruct(LGM.currentFile,LGM.root);
660-
ef.progress(20,Messages.getString("EnigmaRunner.CALLING")); //$NON-NLS-1$
661-
System.out.println("Plugin: Delegating to ENIGMA (out of my hands now)");
662-
System.out.println(DRIVER.compileEGMf(es,efi == null ? null : getUnixPath(efi.getAbsolutePath()),mode));
663-
setupBaseKeywords();
664-
populateKeywords();
665-
666-
setMenuEnabled(true);
667-
//stop.setEnabled(false);
668-
//stopb.setEnabled(false);
655+
try {
656+
EnigmaRunner.addDefaultExceptionHandler();
657+
ef.open();
658+
ef.progress(10,Messages.getString("EnigmaRunner.POPULATING")); //$NON-NLS-1$
659+
EnigmaStruct es = EnigmaWriter.prepareStruct(LGM.currentFile,LGM.root);
660+
if (Thread.currentThread().isInterrupted()) return;
661+
ef.progress(20,Messages.getString("EnigmaRunner.CALLING")); //$NON-NLS-1$
662+
System.out.println("Plugin: Delegating to ENIGMA (out of my hands now)");
663+
System.out.println(DRIVER.compileEGMf(es,efi == null ? null : getUnixPath(efi.getAbsolutePath()),mode));
664+
setupBaseKeywords();
665+
populateKeywords();
666+
} finally {
667+
if (!stop.isEnabled())
668+
ef.progress(0, Messages.getString("EnigmaRunner.BUILD_STOPPED"));
669+
setMenuEnabled(true);
670+
}
669671
}
670672
}
671673

@@ -674,8 +676,6 @@ public void compile(final int mode)
674676
{
675677
if (!assertReady()) return;
676678

677-
//stop.setEnabled(true);
678-
//stopb.setEnabled(true);
679679
EnigmaSettings es = LGM.currentFile.resMap.get(EnigmaSettings.class).getResource();
680680

681681
if (es.targets.get(TargetHandler.COMPILER) == null)
@@ -723,7 +723,6 @@ else if (mode < MODE_DESIGN) //run/debug
723723
outname = new File(outname.getPath());
724724
}
725725

726-
setMenuEnabled(false);
727726
LGM.commitAll();
728727
//TODO: commit changes, have to do it because it's attached to game settings frame
729728
//and doesn't get told.
@@ -732,12 +731,7 @@ else if (mode < MODE_DESIGN) //run/debug
732731
//System.out.println("Compiling with " + enigma);
733732

734733
cthread = new CompilerThread(mode, outname);
735-
try {
736-
cthread.join();
737-
} catch (InterruptedException e1) {
738-
EnigmaRunner.showDefaultExceptionHandler(e1);
739-
}
740-
//cthread.run(outname);
734+
setMenuEnabled(false); // <- stop button needs cthread instance
741735
cthread.start();
742736

743737
if (mode == MODE_DESIGN) //design
@@ -768,10 +762,17 @@ public void actionPerformed(ActionEvent e)
768762
{
769763
if (!assertReady()) return;
770764
Object s = e.getSource();
771-
//if (s == stop || s == stopb) {
772-
// cthread.interrupt();
773-
// setMenuEnabled(true);
774-
//}
765+
if (s == stop || s == stopb) {
766+
if (cthread != null) cthread.interrupt();
767+
try {
768+
DRIVER.libStopBuild();
769+
} catch (UnsatisfiedLinkError err) {
770+
// enigma only added this recently
771+
// sink the error for now
772+
}
773+
stop.setEnabled(false);
774+
stopb.setEnabled(false);
775+
}
775776
if (s == run || s == runb) compile(MODE_RUN);
776777
if (s == debug || s == debugb) compile(MODE_DEBUG);
777778
if (s == design) compile(MODE_DESIGN);

org/enigma/EnigmaWriter.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ protected void populateStruct() {
162162
populateTimelines();
163163
populateObjects();
164164
populateRooms();
165+
166+
// leave if we were interrupted while writing any
167+
// resource group above
168+
if (Thread.currentThread().isInterrupted()) return;
165169

166170
// triggers not implemented
167171
o.triggerCount = 0;
@@ -371,6 +375,7 @@ protected void populateSprites() {
371375
org.lateralgm.resources.Sprite.class).toArray(
372376
new org.lateralgm.resources.Sprite[0]);
373377
for (int s = 0; s < size; s++) {
378+
if (Thread.currentThread().isInterrupted()) return;
374379
Sprite os = osl[s];
375380
org.lateralgm.resources.Sprite is = isl[s];
376381

@@ -467,6 +472,7 @@ protected void populateSounds() {
467472
org.lateralgm.resources.Sound.class).toArray(
468473
new org.lateralgm.resources.Sound[0]);
469474
for (int s = 0; s < size; s++) {
475+
if (Thread.currentThread().isInterrupted()) return;
470476
Sound os = osl[s];
471477
org.lateralgm.resources.Sound is = isl[s];
472478

@@ -507,6 +513,7 @@ protected void populateBackgrounds() {
507513
org.lateralgm.resources.Background.class).toArray(
508514
new org.lateralgm.resources.Background[0]);
509515
for (int s = 0; s < size; s++) {
516+
if (Thread.currentThread().isInterrupted()) return;
510517
Background ob = obl[s];
511518
org.lateralgm.resources.Background ib = ibl[s];
512519

@@ -542,6 +549,7 @@ protected void populatePaths() {
542549
org.lateralgm.resources.Path.class).toArray(
543550
new org.lateralgm.resources.Path[0]);
544551
for (int p = 0; p < size; p++) {
552+
if (Thread.currentThread().isInterrupted()) return;
545553
Path op = opl[p];
546554
org.lateralgm.resources.Path ip = ipl[p];
547555

@@ -585,6 +593,7 @@ protected void populateScripts() {
585593
org.lateralgm.resources.Script.class).toArray(
586594
new org.lateralgm.resources.Script[0]);
587595
for (int s = 0; s < isl.length; s++) {
596+
if (Thread.currentThread().isInterrupted()) return;
588597
Script oo = osl[s];
589598
org.lateralgm.resources.Script io = isl[s];
590599

@@ -594,6 +603,7 @@ protected void populateScripts() {
594603
}
595604

596605
for (int s = 0; s < qs.size(); s++) {
606+
if (Thread.currentThread().isInterrupted()) return;
597607
Script oo = osl[s + isl.length];
598608
oo.name = "lib" + qs.get(s).parentId + "_action" + qs.get(s).id; //$NON-NLS-1$ //$NON-NLS-2$
599609
oo.id = -s - 2;
@@ -614,6 +624,7 @@ protected void populateShaders() {
614624
org.lateralgm.resources.Shader.class).toArray(
615625
new org.lateralgm.resources.Shader[0]);
616626
for (int s = 0; s < isl.length; s++) {
627+
if (Thread.currentThread().isInterrupted()) return;
617628
Shader oo = osl[s];
618629
org.lateralgm.resources.Shader io = isl[s];
619630

@@ -667,6 +678,7 @@ protected void populateFonts() {
667678
org.lateralgm.resources.Font.class).toArray(
668679
new org.lateralgm.resources.Font[0]);
669680
for (int f = 1; f < size; f++) {
681+
if (Thread.currentThread().isInterrupted()) return;
670682
Font of = ofl[f];
671683
org.lateralgm.resources.Font ifont = ifl[f - 1];
672684

@@ -725,9 +737,21 @@ private static void populateGlyph(Glyph og, java.awt.Font fnt, int c, int aa) {
725737
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB };
726738
if (aa < 0 || aa >= aaHints.length)
727739
aa = 0;
728-
GlyphVector gv = fnt.createGlyphVector(new FontRenderContext(null,
729-
aaHints[aa], RenderingHints.VALUE_FRACTIONALMETRICS_OFF),
730-
new String(Character.toChars(c)));
740+
741+
// This is a workaround to an unreported JDK bug for
742+
// createGlyphVector sinking the interrupted status of the
743+
// calling thread causing the ENIGMA build to continue
744+
// until it causes native memory exceptions because the
745+
// resources were only half written.
746+
GlyphVector gv = null;
747+
synchronized (Thread.currentThread()) {
748+
if (Thread.currentThread().isInterrupted()) return;
749+
gv = fnt.createGlyphVector(new FontRenderContext(null,
750+
aaHints[aa], RenderingHints.VALUE_FRACTIONALMETRICS_OFF),
751+
new String(Character.toChars(c)));
752+
}
753+
if (gv == null) return;
754+
731755
Rectangle2D r = gv.getPixelBounds(null, 0, 0); // don't know why it
732756
// needs coordinates
733757
if (r.getWidth() <= 0 || r.getHeight() <= 0)
@@ -778,6 +802,7 @@ protected void populateTimelines() {
778802
org.lateralgm.resources.Timeline.class).toArray(
779803
new org.lateralgm.resources.Timeline[0]);
780804
for (int t = 0; t < size; t++) {
805+
if (Thread.currentThread().isInterrupted()) return;
781806
Timeline ot = otl[t];
782807
org.lateralgm.resources.Timeline it = itl[t];
783808

@@ -810,6 +835,7 @@ protected void populateObjects() {
810835
org.lateralgm.resources.GmObject.class).toArray(
811836
new org.lateralgm.resources.GmObject[0]);
812837
for (int s = 0; s < size; s++) {
838+
if (Thread.currentThread().isInterrupted()) return;
813839
GmObject oo = ool[s];
814840
org.lateralgm.resources.GmObject io = iol[s];
815841

@@ -888,6 +914,7 @@ protected void populateRooms() {
888914
org.lateralgm.resources.Room[] irl = irooms
889915
.toArray(new org.lateralgm.resources.Room[0]);
890916
for (int s = 0; s < size; s++) {
917+
if (Thread.currentThread().isInterrupted()) return;
891918
Room or = orly[s];
892919
org.lateralgm.resources.Room is = irl[s];
893920

@@ -989,6 +1016,7 @@ protected void populateRooms() {
9891016

9901017
or.instanceCount = ri.size();
9911018
if (or.instanceCount != 0) {
1019+
if (Thread.currentThread().isInterrupted()) return;
9921020
or.instances = new Instance.ByReference();
9931021
Instance[] oil = (Instance[]) or.instances.toArray(ri.size());
9941022
int i = 0;
@@ -1051,6 +1079,7 @@ protected void populateRooms() {
10511079

10521080
or.tileCount = is.tiles.size();
10531081
if (or.tileCount != 0) {
1082+
if (Thread.currentThread().isInterrupted()) return;
10541083
or.tiles = new Tile.ByReference();
10551084
Tile[] otl = (Tile[]) or.tiles.toArray(or.tileCount);
10561085
for (int t = 0; t < otl.length; t++) {

org/enigma/backend/EnigmaDriver.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ protected List<String> getFieldOrder()
3030
}
3131
}
3232

33+
public void libStopBuild();
34+
3335
public String libInit(EnigmaCallbacks ef);
3436

3537
public SyntaxError definitionsModified(String wscode, String yaml);

org/enigma/messages/messages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ EnigmaPlugin.SELALL=Select All
2222
EnigmaReader.UNKNOWN_VERSION=Unsupported version {0}
2323
EnigmaReader.UNKNOWN_ACTION= Unsupported action type {0}
2424

25+
EnigmaRunner.BUILD_STOPPED=Build Stopped
2526
EnigmaRunner.BUTTON_SYNTAX=Syntax
2627
EnigmaRunner.BUTTON_SYNTAX_TIP=Syntax
2728
EnigmaRunner.CALLING=Calling compiler.

0 commit comments

Comments
 (0)