Added threaded loader to ComponentPresetDatabase following the pattern in ThrustCurveMotorDatabase. Moved the wait into the background thread so the UI starts much faster. Changed the ConcurrentLoadingThrustCurveMotorSetDataBase implementation to have longer timeouts and wait in the background thread.
This commit is contained in:
parent
5aa691c2ab
commit
9eed1653fb
@ -28,7 +28,12 @@ public class Application extends android.app.Application {
|
||||
|
||||
net.sf.openrocket.startup.Application.setPreferences( new PreferencesAdapter() );
|
||||
|
||||
net.sf.openrocket.startup.Application.setComponentPresetDao( new ComponentPresetDatabase() );
|
||||
net.sf.openrocket.startup.Application.setComponentPresetDao( new ComponentPresetDatabase(){
|
||||
@Override
|
||||
protected void load() {
|
||||
// We don't need components
|
||||
}
|
||||
} );
|
||||
|
||||
MotorDatabaseAdapter db = new MotorDatabaseAdapter(this);
|
||||
|
||||
|
@ -4,17 +4,34 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.openrocket.logging.LogHelper;
|
||||
import net.sf.openrocket.preset.ComponentPreset;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
public class ComponentPresetDatabase extends Database<ComponentPreset> implements ComponentPresetDao {
|
||||
public abstract class ComponentPresetDatabase extends Database<ComponentPreset> implements ComponentPresetDao {
|
||||
|
||||
private static final LogHelper logger = Application.getLogger();
|
||||
|
||||
private volatile boolean startedLoading = false;
|
||||
private volatile boolean endedLoading = false;
|
||||
private final boolean asynchronous;
|
||||
|
||||
/** Set to true the first time {@link #blockUntilLoaded()} is called. */
|
||||
protected volatile boolean inUse = false;
|
||||
|
||||
public ComponentPresetDatabase() {
|
||||
super();
|
||||
this.asynchronous = false;
|
||||
}
|
||||
|
||||
public ComponentPresetDatabase(boolean asynchronous ) {
|
||||
super();
|
||||
this.asynchronous = asynchronous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ComponentPreset> listAll() {
|
||||
blockUntilLoaded();
|
||||
return list;
|
||||
}
|
||||
|
||||
@ -25,6 +42,7 @@ public class ComponentPresetDatabase extends Database<ComponentPreset> implement
|
||||
|
||||
@Override
|
||||
public List<ComponentPreset> listForType( ComponentPreset.Type type ) {
|
||||
blockUntilLoaded();
|
||||
if ( type == null ) {
|
||||
return Collections.<ComponentPreset>emptyList();
|
||||
}
|
||||
@ -50,6 +68,7 @@ public class ComponentPresetDatabase extends Database<ComponentPreset> implement
|
||||
*/
|
||||
@Override
|
||||
public List<ComponentPreset> listForType( ComponentPreset.Type type, boolean favorite ) {
|
||||
blockUntilLoaded();
|
||||
|
||||
if ( !favorite ) {
|
||||
return listForType(type);
|
||||
@ -67,6 +86,7 @@ public class ComponentPresetDatabase extends Database<ComponentPreset> implement
|
||||
|
||||
@Override
|
||||
public List<ComponentPreset> listForTypes( ComponentPreset.Type ... type ) {
|
||||
blockUntilLoaded();
|
||||
|
||||
if( type == null || type.length == 0 ) {
|
||||
return Collections.<ComponentPreset>emptyList();
|
||||
@ -93,11 +113,13 @@ public class ComponentPresetDatabase extends Database<ComponentPreset> implement
|
||||
|
||||
@Override
|
||||
public List<ComponentPreset> listForTypes( List<ComponentPreset.Type> types ) {
|
||||
blockUntilLoaded();
|
||||
return listForTypes( (ComponentPreset.Type[]) types.toArray() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ComponentPreset> find(String manufacturer, String partNo) {
|
||||
blockUntilLoaded();
|
||||
List<ComponentPreset> presets = new ArrayList<ComponentPreset>();
|
||||
for( ComponentPreset preset : list ) {
|
||||
if ( preset.getManufacturer().getSimpleName().equals(manufacturer) && preset.getPartNo().equals(partNo) ) {
|
||||
@ -109,9 +131,71 @@ public class ComponentPresetDatabase extends Database<ComponentPreset> implement
|
||||
|
||||
@Override
|
||||
public void setFavorite( ComponentPreset preset, boolean favorite ) {
|
||||
blockUntilLoaded();
|
||||
preset.setFavorite(favorite);
|
||||
Application.getPreferences().setComponentFavorite( preset, favorite );
|
||||
this.fireAddEvent(preset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used for loading the component preset database. This method will be called in a background
|
||||
* thread to load the presets asynchronously.
|
||||
*/
|
||||
protected abstract void load();
|
||||
|
||||
/**
|
||||
* Start loading the presets.
|
||||
*
|
||||
* @throws IllegalStateException if this method has already been called.
|
||||
*/
|
||||
public void startLoading() {
|
||||
if (startedLoading) {
|
||||
throw new IllegalStateException("Already called startLoading");
|
||||
}
|
||||
startedLoading = true;
|
||||
if (asynchronous) {
|
||||
new LoadingThread().start();
|
||||
} else {
|
||||
load();
|
||||
}
|
||||
synchronized (this) {
|
||||
endedLoading = true;
|
||||
this.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Background thread for loading the presets.
|
||||
*/
|
||||
private class LoadingThread extends Thread {
|
||||
@Override
|
||||
public void run() {
|
||||
load();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Block the current thread until loading of the presets has been completed.
|
||||
*
|
||||
* @throws IllegalStateException if startLoading() has not been called.
|
||||
*/
|
||||
public void blockUntilLoaded() {
|
||||
inUse = true;
|
||||
if (!startedLoading) {
|
||||
throw new IllegalStateException("startLoading() has not been called");
|
||||
}
|
||||
if (!endedLoading) {
|
||||
synchronized (this) {
|
||||
while (!endedLoading) {
|
||||
try {
|
||||
this.wait();
|
||||
} catch (InterruptedException e) {
|
||||
logger.warn("InterruptedException occurred, ignoring", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,8 +41,14 @@ public class Quick3dMain {
|
||||
Application.setPreferences(new SwingPreferences());
|
||||
|
||||
// Must be done after localization is initialized
|
||||
ComponentPresetDatabase componentPresetDao = new ComponentPresetDatabase();
|
||||
componentPresetDao.load("datafiles", ".*csv");
|
||||
ComponentPresetDatabase componentPresetDao = new ComponentPresetDatabase() {
|
||||
|
||||
@Override
|
||||
protected void load() {
|
||||
// This test app doesn't need any presets loaded - just an empty database.
|
||||
}
|
||||
|
||||
};
|
||||
Application.setComponentPresetDao( componentPresetDao );
|
||||
|
||||
OpenRocketDocument doc = new OpenRocketLoader().loadFromStream(
|
||||
|
@ -9,6 +9,7 @@ import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import net.sf.openrocket.database.ThrustCurveMotorSet;
|
||||
import net.sf.openrocket.database.ThrustCurveMotorSetDatabase;
|
||||
@ -47,6 +48,9 @@ public class ConcurrentLoadingThrustCurveMotorSetDatabase extends ThrustCurveMot
|
||||
private static final LogHelper log = Application.getLogger();
|
||||
private final String thrustCurveDirectory;
|
||||
|
||||
/** Block motor loading for this many milliseconds */
|
||||
// Block motor loading for 1.5 seconds to allow window painting to be faster
|
||||
private static AtomicInteger blockLoading = new AtomicInteger(1500);
|
||||
|
||||
public ConcurrentLoadingThrustCurveMotorSetDatabase(String thrustCurveDirectory) {
|
||||
// configure ThrustCurveMotorSetDatabase as true so we get our own thread in
|
||||
@ -58,6 +62,18 @@ public class ConcurrentLoadingThrustCurveMotorSetDatabase extends ThrustCurveMot
|
||||
@Override
|
||||
protected void loadMotors() {
|
||||
|
||||
// Block loading until timeout occurs or database is taken into use
|
||||
log.info("Blocking motor loading while starting up");
|
||||
/*
|
||||
while (!inUse && blockLoading.addAndGet(-100) > 0) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
*/
|
||||
log.info("Blocking ended, inUse=" + inUse + " blockLoading=" + blockLoading.get());
|
||||
|
||||
BookKeeping keeper = new BookKeeping();
|
||||
keeper.start();
|
||||
|
||||
@ -162,9 +178,9 @@ public class ConcurrentLoadingThrustCurveMotorSetDatabase extends ThrustCurveMot
|
||||
private void waitForFinish() throws InterruptedException {
|
||||
try {
|
||||
loaderPool.shutdown();
|
||||
loaderPool.awaitTermination(10, TimeUnit.SECONDS);
|
||||
loaderPool.awaitTermination(30, TimeUnit.SECONDS);
|
||||
writerThread.shutdown();
|
||||
writerThread.awaitTermination(10, TimeUnit.SECONDS);
|
||||
writerThread.awaitTermination(30, TimeUnit.SECONDS);
|
||||
}
|
||||
finally {
|
||||
iterator.close();
|
||||
|
@ -84,11 +84,23 @@ public class Startup2 {
|
||||
Splash.init();
|
||||
|
||||
// Must be done after localization is initialized
|
||||
ComponentPresetDatabase componentPresetDao = new ComponentPresetDatabase();
|
||||
ConcurrentComponentPresetDatabaseLoader presetLoader = new ConcurrentComponentPresetDatabaseLoader( componentPresetDao );
|
||||
presetLoader.load();
|
||||
|
||||
ComponentPresetDatabase componentPresetDao = new ComponentPresetDatabase(true) {
|
||||
|
||||
@Override
|
||||
protected void load() {
|
||||
ConcurrentComponentPresetDatabaseLoader presetLoader = new ConcurrentComponentPresetDatabaseLoader( this );
|
||||
presetLoader.load();
|
||||
try {
|
||||
presetLoader.await();
|
||||
} catch ( InterruptedException iex) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
Application.setComponentPresetDao( componentPresetDao );
|
||||
|
||||
componentPresetDao.startLoading();
|
||||
|
||||
// Setup the uncaught exception handler
|
||||
log.info("Registering exception handler");
|
||||
@ -124,11 +136,6 @@ public class Startup2 {
|
||||
|
||||
Databases.fakeMethod();
|
||||
|
||||
try {
|
||||
presetLoader.await();
|
||||
} catch ( InterruptedException iex) {
|
||||
|
||||
}
|
||||
|
||||
// Starting action (load files or open new document)
|
||||
log.info("Opening main application window");
|
||||
|
Loading…
x
Reference in New Issue
Block a user