Implement a primitive thread safety mechanism to prohibit saving a rocket while simulation execution is pending.

This commit is contained in:
Kevin Ruland 2012-07-09 02:51:15 +00:00
parent 0ecd6110bf
commit d7d647d47d
4 changed files with 57 additions and 6 deletions

View File

@ -2,6 +2,8 @@ package net.sf.openrocket.android;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.OpenRocketDocument;
@ -21,6 +23,7 @@ public class CurrentRocket {
private RocketChangedEventHandler handler; private RocketChangedEventHandler handler;
private boolean isModified = false; private boolean isModified = false;
private Set<Integer> runningSims = new HashSet<Integer>();
public void setHandler( RocketChangedEventHandler handler ) { public void setHandler( RocketChangedEventHandler handler ) {
this.handler = handler; this.handler = handler;
@ -34,12 +37,35 @@ public class CurrentRocket {
} }
public void notifySimsChanged() { public void notifySimsChanged() {
isModified = true; synchronized ( this ) {
isModified = true;
}
if ( handler != null ) { if ( handler != null ) {
handler.simsChangedMessage(); handler.simsChangedMessage();
} }
} }
public void notifySimComplete() {
synchronized ( this ) {
isModified = true;
}
if ( handler != null ) {
handler.simCompleteMessage();
}
}
public synchronized void lockSimulation( int simulationId ) {
runningSims.add(simulationId);
}
public synchronized void unlockSimulation( int simulationId ) {
runningSims.remove(simulationId);
}
public synchronized Set<Integer> lockedSimulations() {
return new HashSet<Integer>(runningSims);
}
public void addNewSimulation() { public void addNewSimulation() {
Rocket rocket = rocketDocument.getRocket(); Rocket rocket = rocketDocument.getRocket();
// FIXME - hopefully the change to the Simulation object will be reverted soon. // FIXME - hopefully the change to the Simulation object will be reverted soon.
@ -55,7 +81,9 @@ public class CurrentRocket {
} }
public String addNewMotorConfig() { public String addNewMotorConfig() {
isModified = true; synchronized ( this ) {
isModified = true;
}
String configId = rocketDocument.getRocket().newMotorConfigurationID(); String configId = rocketDocument.getRocket().newMotorConfigurationID();
if ( handler != null ) { if ( handler != null ) {
handler.configsChangedMessage(); handler.configsChangedMessage();
@ -67,7 +95,9 @@ public class CurrentRocket {
*/ */
public void setRocketDocument(OpenRocketDocument rocketDocument) { public void setRocketDocument(OpenRocketDocument rocketDocument) {
this.rocketDocument = rocketDocument; this.rocketDocument = rocketDocument;
isModified = false; synchronized ( this ) {
isModified = false;
}
} }
public WarningSet getWarnings() { public WarningSet getWarnings() {
@ -90,6 +120,10 @@ public class CurrentRocket {
return this.isModified; return this.isModified;
} }
public boolean canSave() {
return this.isModified && this.runningSims.isEmpty();
}
public void saveOpenRocketDocument() throws IOException { public void saveOpenRocketDocument() throws IOException {
// Translate the fileUri if it happens to be a .rkt file. // Translate the fileUri if it happens to be a .rkt file.

View File

@ -23,7 +23,13 @@ public abstract class RocketChangedEventHandler extends Handler {
public static final int MOTOR_CONFIGS_CHANGED = 1; public static final int MOTOR_CONFIGS_CHANGED = 1;
public static final int SIMS_CHANGED = 2; public static final int SIMS_CHANGED = 2;
public static final int SIM_COMPLETE = 3;
public void simCompleteMessage() {
Message m = this.obtainMessage(SIM_COMPLETE);
this.sendMessage(m);
}
public void simsChangedMessage() { public void simsChangedMessage() {
Message m = this.obtainMessage(SIMS_CHANGED); Message m = this.obtainMessage(SIMS_CHANGED);
this.sendMessage(m); this.sendMessage(m);
@ -44,11 +50,16 @@ public abstract class RocketChangedEventHandler extends Handler {
case MOTOR_CONFIGS_CHANGED: case MOTOR_CONFIGS_CHANGED:
doMotorConfigsChanged(); doMotorConfigsChanged();
break; break;
case SIM_COMPLETE:
doSimComplete();
break;
default: default:
super.handleMessage(msg); super.handleMessage(msg);
} }
} }
protected abstract void doSimComplete();
protected abstract void doSimsChanged(); protected abstract void doSimsChanged();
protected abstract void doMotorConfigsChanged(); protected abstract void doMotorConfigsChanged();

View File

@ -111,7 +111,7 @@ implements Simulations.OnSimulationSelectedListener, OpenRocketSaverFragment.OnO
MenuInflater inflater = getSupportMenuInflater(); MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.rocket_viewer_option_menu, menu); inflater.inflate(R.menu.rocket_viewer_option_menu, menu);
MenuItem saveAction = menu.findItem(R.id.menu_save); MenuItem saveAction = menu.findItem(R.id.menu_save);
if ( CurrentRocketHolder.getCurrentRocket().isModified() ) { if ( CurrentRocketHolder.getCurrentRocket().canSave() ) {
saveAction.setVisible(true); saveAction.setVisible(true);
saveAction.setShowAsAction( MenuItem.SHOW_AS_ACTION_ALWAYS ); saveAction.setShowAsAction( MenuItem.SHOW_AS_ACTION_ALWAYS );
} else { } else {
@ -207,7 +207,7 @@ implements Simulations.OnSimulationSelectedListener, OpenRocketSaverFragment.OnO
private void saveRocketDocument() { private void saveRocketDocument() {
getSupportFragmentManager().beginTransaction() getSupportFragmentManager().beginTransaction()
.add( OpenRocketSaverFragment.newInstance(false), "saver") .add( OpenRocketSaverFragment.newInstance(true), "saver")
.commitAllowingStateLoss(); .commitAllowingStateLoss();
} }
@ -223,11 +223,16 @@ implements Simulations.OnSimulationSelectedListener, OpenRocketSaverFragment.OnO
private class RocketChangedEventHandler extends net.sf.openrocket.android.RocketChangedEventHandler { private class RocketChangedEventHandler extends net.sf.openrocket.android.RocketChangedEventHandler {
@Override @Override
protected void doSimsChanged() { protected void doSimComplete() {
if ( autoSaveEnabled ) { if ( autoSaveEnabled ) {
Toast.makeText(OpenRocketViewer.this, R.string.autoSaveMessage, Toast.LENGTH_SHORT).show(); Toast.makeText(OpenRocketViewer.this, R.string.autoSaveMessage, Toast.LENGTH_SHORT).show();
OpenRocketViewer.this.saveRocketDocument(); OpenRocketViewer.this.saveRocketDocument();
} }
doSimsChanged();
}
@Override
protected void doSimsChanged() {
invalidateOptionsMenu(); invalidateOptionsMenu();
Simulations sims = (Simulations) viewPagerAdapter.getFragmentAtPos(SIMS_POS); Simulations sims = (Simulations) viewPagerAdapter.getFragmentAtPos(SIMS_POS);
if ( sims != null ) { if ( sims != null ) {

View File

@ -39,6 +39,7 @@ public class SimulationService extends IntentService {
Simulation sim = CurrentRocketHolder.getCurrentRocket().getRocketDocument().getSimulation(t.simulationId); Simulation sim = CurrentRocketHolder.getCurrentRocket().getRocketDocument().getSimulation(t.simulationId);
AndroidLogWrapper.d(SimulationService.class, "simulating " + t.simulationId ); AndroidLogWrapper.d(SimulationService.class, "simulating " + t.simulationId );
sim.simulate(); sim.simulate();
CurrentRocketHolder.getCurrentRocket().unlockSimulation(t.simulationId);
CurrentRocketHolder.getCurrentRocket().notifySimsChanged(); CurrentRocketHolder.getCurrentRocket().notifySimsChanged();
} }
catch (SimulationException simex) { catch (SimulationException simex) {