package com.runner;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.jglfw.JglfwApplication;
import com.badlogic.gdx.backends.jglfw.JglfwApplicationConfiguration;
import com.kotcrab.vis.ui.VisUI;
import com.runner.exception.LibgdxInitException;
import com.runner.util.ConditionWaiter;
import org.apache.commons.io.FileUtils;
import org.junit.runner.Description;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
public class LibgdxRunner extends BlockJUnit4ClassRunner {
private Random random = new Random();
private static File prefs;
private static AtomicBoolean init = new AtomicBoolean(false);
public LibgdxRunner(Class<?> klass) throws InitializationError {
super(klass);
if (init.compareAndSet(false, true)) {
initApplication();
}
}
private void initApplication() {
try {
JglfwApplicationConfiguration cfg = new JglfwApplicationConfiguration();
cfg.preferencesLocation = String.format("tmp/%d/.prefs/", random.nextLong());
cfg.title = "Libgdx Runner";
cfg.width = 1;
cfg.height = 1;
cfg.forceExit = true;
new JglfwApplication(new TestApplicationListener(), cfg);
ConditionWaiter.wait(() -> Gdx.files != null, "Jglfw init failed.", 10);
prefs = new File(Gdx.files.getExternalStoragePath(), "tmp/");
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
safeCleanDir();
closeGdxApplication();
}));
} catch (Exception ex) {
throw new LibgdxInitException(ex);
}
}
private void safeCleanDir() {
try {
FileUtils.deleteDirectory(prefs);
} catch (IOException e) {
e.printStackTrace();
}
}
private void closeGdxApplication() {
Gdx.app.exit();
}
@Override
public void run(RunNotifier notifier) {
super.run(notifier);
}
@Override
protected void runChild(FrameworkMethod method, RunNotifier notifier) {
Description description = describeChild(method);
if (description.getAnnotation(NeedGL.class) != null) {
final AtomicBoolean running = new AtomicBoolean(true);
Gdx.app.postRunnable(() -> {
if (isIgnored(method)) {
notifier.fireTestIgnored(description);
} else {
runLeaf(methodBlock(method), description, notifier);
}
running.set(false);
});
ConditionWaiter.wait(() -> !running.get(), description, 30, () -> {
closeGdxApplication();
});
} else {
runLeaf(methodBlock(method), description, notifier);
}
}
private class TestApplicationListener extends ApplicationAdapter {
@Override
public void create() {
VisUI.load(Gdx.files.local("overlap2d/assets/style/uiskin.json"));
}
}
}