Skip to content

Commit

Permalink
Merge pull request #12 from petebankhead/strings
Browse files Browse the repository at this point in the history
Externalize strings, update junit dependency
  • Loading branch information
petebankhead authored Nov 30, 2023
2 parents 1d092bf + fa12ab4 commit 295aa9b
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 40 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ dependencies {
implementation "ai.djl:api:$djlVersion"

testImplementation libs.junit
testRuntimeOnly libs.junit.engine
testRuntimeOnly libs.junit.platform

}

Expand Down
17 changes: 2 additions & 15 deletions src/main/java/qupath/ext/djl/DjlTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -252,32 +252,19 @@ public static Engine getEngine(String name, boolean downloadIfNeeded) throws Ill
else
System.setProperty("offline", "true");

// If trying to instantiate a TensorFlow engine for the first time,
// we need to reset the javacpp platform properties for the preload
// path to be correctly identified
if (ENGINE_TENSORFLOW.equalsIgnoreCase(name) && !loadedEngines.contains(name)) {
try {
var f = Loader.class.getDeclaredField("platformProperties");
f.setAccessible(true);
f.set(null, null);
} catch (Exception e) {
logger.error("Unable to reset JavaCPP platform properties: " + e.getLocalizedMessage(), e);
}
}

var engine = Engine.getEngine(name);
if (engine != null)
loadedEngines.add(name);
return engine;
} catch (Exception e) {
if (downloadIfNeeded)
logger.error("Unable to get engine " + name + ": " + e.getLocalizedMessage(), e);
logger.error("Unable to get engine " + name + ": " + e.getMessage(), e);
else {
var msg = e.getLocalizedMessage();
if (msg == null)
logger.warn("Unable to get engine {}", name);
else
logger.warn("Unable to get engine {} ({})", name, e.getLocalizedMessage());
logger.warn("Unable to get engine {} ({})", name, e.getMessage());
}
return null;
} finally {
Expand Down
47 changes: 24 additions & 23 deletions src/main/java/qupath/ext/djl/ui/DjlEngineCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.layout.StackPane;
import javafx.scene.text.TextAlignment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -54,7 +55,6 @@
import javafx.scene.control.Tooltip;
import javafx.scene.layout.GridPane;
import javafx.scene.shape.Circle;
import javafx.stage.Modality;
import javafx.stage.Stage;
import qupath.ext.djl.DjlTools;
import qupath.fx.dialogs.Dialogs;
Expand Down Expand Up @@ -144,7 +144,9 @@ private void init() {

var status = available.computeIfAbsent(name, n -> new SimpleObjectProperty<>(EngineStatus.UNKNOWN));

var path = Utils.getEngineCacheDir(name);
// Names seem to be lower case in practice
// This matters on Linux, since otherwise the directory can't be found/opened
var path = Utils.getEngineCacheDir(name.toLowerCase());

String tooltip = String.format(bundle.getString("tooltip.engine"), name);
String labelNameText = name;
Expand Down Expand Up @@ -183,17 +185,17 @@ private void init() {
var tooltipDownload = new Tooltip();
tooltipDownload.textProperty().bind(Bindings.createStringBinding(() -> {
switch (status.get()) {
case AVAILABLE:
return name + " is available";
case UNAVAILABLE:
return name + " is not available - click to download it";
case FAILED:
return name + " download & initialization failed - you can try again, but it may not be supported on this platform";
case PENDING:
return name + " download pending";
case UNKNOWN:
default:
return name + " download status is unknown";
case AVAILABLE:
return String.format(bundle.getString("tooltip.download.available"), name);
case FAILED:
return String.format(bundle.getString("tooltip.download.failed"), name);
case PENDING:
return String.format(bundle.getString("tooltip.download.pending"), name);
case UNAVAILABLE:
return String.format(bundle.getString("tooltip.download.unavailable"), name);
case UNKNOWN:
default:
return String.format(bundle.getString("tooltip.download.unknown"), name);
}
}, status));
btnDownload.setTooltip(tooltipDownload);
Expand All @@ -216,7 +218,7 @@ private void init() {
logger.debug("Cannot open {} - directory does not exist", path);
});

var labelVersion = new Label("");
var labelVersion = new Label(bundle.getString("label.version.unknown"));
labelVersion.setMaxWidth(Double.MAX_VALUE);

var labelVersionLabel = createLabelForKey("label.version");
Expand All @@ -234,7 +236,9 @@ private void init() {
updateVersionFromStatus(n, name, labelVersion);
});

pane.add(circle, 0, row, 1, 2);
var circlePane = new StackPane(circle);
circlePane.setPadding(new Insets(5));
pane.add(circlePane, 0, row, 1, 2);

GridPaneUtils.addGridRow(pane, row++, 1, null, labelPathLabel, labelPath);
GridPaneUtils.addGridRow(pane, row++, 1, null, labelVersionLabel, labelVersion);
Expand All @@ -243,13 +247,13 @@ private void init() {
GridPaneUtils.setToExpandGridPaneWidth(labelName, labelPath, btnDownload);

// Update the engine status quietly
checkEngineStatus(name, status, -1, true);
// checkEngineStatus(name, status, -1, true);
}

stage = new Stage();
stage.setTitle(TITLE);
stage.initOwner(QuPathGUI.getInstance().getStage());
stage.initModality(Modality.APPLICATION_MODAL);
// stage.initModality(Modality.WINDOW_MODAL);
stage.setScene(new Scene(pane));
}

Expand All @@ -270,7 +274,7 @@ private static void updateVersionFromStatus(EngineStatus status, String engineNa
logger.error("Error updating engine version: {}", e.getMessage(), e);
}
}
labelVersion.setText("");
labelVersion.setText(bundle.getString("label.version.unknown"));
labelVersion.setTooltip(null);
}

Expand Down Expand Up @@ -342,8 +346,7 @@ private void checkEngineStatus(String name, ObjectProperty<EngineStatus> status,
// Wait until the timeout - engine might already be available & return quickly
var result = future.get(timeoutMillis, TimeUnit.MILLISECONDS);
if (result != null && result.booleanValue()) {
Dialogs.showInfoNotification(TITLE, name + " is available!");
return;
Dialogs.showInfoNotification(TITLE, String.format(bundle.getString("notify.engine.available"), name));
} else
logger.debug("No engine available for {}", name);
} catch (InterruptedException e) {
Expand All @@ -368,7 +371,7 @@ private Boolean checkEngineAvailability(String name, ObjectProperty<EngineStatus

if (!GeneralTools.isLinux() && LINUX_ONLY.contains(name)) {
if (!doQuietly)
Dialogs.showErrorMessage(TITLE, name + " is only available on Linux, sorry");
Dialogs.showErrorMessage(TITLE, String.format(bundle.getString("notify.engine.linuxOnly"), name));
updateStatus(status, EngineStatus.UNAVAILABLE);
return Boolean.FALSE;
}
Expand Down Expand Up @@ -400,8 +403,6 @@ private Boolean checkEngineAvailability(String name, ObjectProperty<EngineStatus
isAvailable = DjlTools.getEngine(name, true) != null;
if (isAvailable) {
updateStatus(status, EngineStatus.AVAILABLE);
if (!doQuietly)
Dialogs.showInfoNotification(TITLE, name + " is now available!");
} else {
updateStatus(status, EngineStatus.UNAVAILABLE);
if (!doQuietly) {
Expand Down
10 changes: 9 additions & 1 deletion src/main/resources/qupath/ext/djl/ui/strings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,26 @@ cuda.appleSilicon = CUDA is not supported on Apple Silicon.\n\
label.defaultName = %s (default)
label.path = Path:
label.version = Version:
label.version.unknown = ?
label.cudaVersion = CUDA version:
label.computeCapability = Compute capability:
tooltip.engine = Engine: %s
tooltip.openPath = Double-click to open engine path
tooltip.pathMissing = Engine path does not exist
notify.engine.available = %s is available!
notify.engine.linuxOnly = %s is only available on Linux, sorry
button.download = Download
button.download.available = Available
button.download.failed = Try again
button.download.pending = Pending (please wait)
button.download.unknown = Check / Download
button.download.unavailable = Download
engines.title = Engines
tooltip.download.available = %s is available
tooltip.download.failed = %s download & initialization failed - you can try again, but it may not be supported on this platform
tooltip.download.pending = %s download pending
tooltip.download.unknown = %s download status is unknown
tooltip.download.unavailable = %s is not available - click to download it

0 comments on commit 295aa9b

Please sign in to comment.