improved initializer resolver

master
Ondřej Hruška 10 years ago
parent 2398a4ee6a
commit 8e9a658098
  1. 92
      src/mightypork/gamecore/core/App.java
  2. 18
      src/mightypork/gamecore/core/AppBackend.java
  3. 5
      src/mightypork/gamecore/core/BasicMainLoop.java
  4. 8
      src/mightypork/gamecore/core/config/Config.java
  5. 21
      src/mightypork/gamecore/core/events/ShutdownRequest.java
  6. 8
      src/mightypork/gamecore/core/events/ShutdownRequestListener.java
  7. 168
      src/mightypork/gamecore/core/init/InitSequence.java
  8. 87
      src/mightypork/gamecore/core/init/InitTask.java
  9. 41
      src/mightypork/gamecore/core/init/InitTaskBackend.java
  10. 11
      src/mightypork/gamecore/core/init/InitTaskConfig.java
  11. 7
      src/mightypork/gamecore/core/init/InitTaskCrashHandler.java
  12. 2
      src/mightypork/gamecore/core/init/InitTaskDisplay.java
  13. 13
      src/mightypork/gamecore/core/init/InitTaskIonizables.java
  14. 16
      src/mightypork/gamecore/core/init/InitTaskLog.java
  15. 7
      src/mightypork/gamecore/core/init/InitTaskLogHeader.java
  16. 24
      src/mightypork/gamecore/core/init/InitTaskMainLoop.java
  17. 1
      src/mightypork/gamecore/core/init/InitTaskResourceLoader.java
  18. 9
      src/mightypork/gamecore/core/init/InitTaskResourceLoaderAsync.java
  19. 4
      src/mightypork/gamecore/core/init/InitTaskResourceLoaderNone.java
  20. 4
      src/mightypork/gamecore/core/init/InitTaskResources.java
  21. 42
      src/mightypork/gamecore/core/init/InitTaskScreens.java
  22. 51
      src/mightypork/gamecore/core/init/InitTaskUI.java
  23. 7
      src/mightypork/gamecore/core/init/InitTaskWorkdir.java
  24. 4
      src/mightypork/gamecore/gui/components/BaseComponent.java
  25. 6
      src/mightypork/gamecore/input/KeyStroke.java
  26. 4
      src/mightypork/gamecore/resources/BaseDeferredResource.java
  27. 7
      src/mightypork/gamecore/resources/loading/AsyncResourceLoader.java

@ -1,17 +1,29 @@
package mightypork.gamecore.core;
import java.util.ArrayList;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import mightypork.gamecore.audio.AudioModule;
import mightypork.gamecore.core.config.Config;
import mightypork.gamecore.core.events.ShutdownEvent;
import mightypork.gamecore.core.events.MainLoopRequest;
import mightypork.gamecore.core.events.ShutdownRequest;
import mightypork.gamecore.core.init.InitSequence;
import mightypork.gamecore.core.init.InitTask;
import mightypork.gamecore.core.init.InitTaskBackend;
import mightypork.gamecore.core.init.InitTaskCrashHandler;
import mightypork.gamecore.core.init.InitTaskIonizables;
import mightypork.gamecore.core.init.InitTaskLog;
import mightypork.gamecore.core.init.InitTaskLogHeader;
import mightypork.gamecore.core.init.InitTaskMainLoop;
import mightypork.gamecore.core.init.InitTaskResourceLoaderAsync;
import mightypork.gamecore.core.init.InitTaskWorkdir;
import mightypork.gamecore.core.plugins.AppPlugin;
import mightypork.gamecore.graphics.GraphicsModule;
import mightypork.gamecore.graphics.Renderable;
import mightypork.gamecore.input.InputModule;
import mightypork.utils.Str;
import mightypork.utils.annotations.Stub;
import mightypork.utils.eventbus.EventBus;
import mightypork.utils.eventbus.clients.BusNode;
@ -37,7 +49,7 @@ public class App extends BusNode {
/** List of installed App plugins */
protected final DelegatingList plugins = new DelegatingList();
/** List of initializers */
protected final List<InitTask> initializers = new ArrayList<>();
protected final InitSequence initTasks = new InitSequence();
/** The used main loop instance */
protected MainLoop mainLoop;
@ -63,13 +75,28 @@ public class App extends BusNode {
this.eventBus.subscribe(this);
// create plugin registry attached to bus
this.eventBus.subscribe(this.plugins);
addChildClient(this.plugins);
// initialize and use backend
this.backend = backend;
this.backend.bind(this);
this.eventBus.subscribe(backend);
this.backend.initialize();
addChildClient(backend);
addDefaultInitTasks();
this.backend.addInitTasks();
}
private void addDefaultInitTasks()
{
addInitTask(new InitTaskCrashHandler());
addInitTask(new InitTaskWorkdir(new File("."), true));
addInitTask(new InitTaskLog());
addInitTask(new InitTaskBackend());
addInitTask(new InitTaskIonizables());
addInitTask(new InitTaskMainLoop());
addInitTask(new InitTaskResourceLoaderAsync());
addInitTask(new InitTaskLogHeader());
}
@ -99,7 +126,7 @@ public class App extends BusNode {
throw new IllegalStateException("App already started, cannot add initializers.");
}
initializers.add(initializer);
initTasks.addTask(initializer);
}
@ -111,7 +138,7 @@ public class App extends BusNode {
public void setMainLoop(MainLoop loop)
{
this.mainLoop = loop;
bus().subscribe(loop); // ?
addChildClient(loop); // ?
}
@ -176,8 +203,15 @@ public class App extends BusNode {
Log.f2("Running init tasks...");
// sort initializers by order.
final List<InitTask> orderedInitializers = InitTask.inOrder(initializers);
// sort initializers based on dependencies
final List<InitTask> orderedInitializers = initTasks.getSequence();
// detailed logging
Log.f3("=== Task overview ===");
for (final InitTask t : orderedInitializers) {
Log.f3("Task " + Str.pad(t.getName(), 20) + " class = " + Str.pad(Str.val(t), 30) + " prio = " + Str.pad("" + t.getPriority(), 12) + " deps = "
+ Arrays.toString(t.getDependencies()));
}
for (final InitTask initTask : orderedInitializers) {
Log.f1("Running init task \"" + initTask.getName() + "\"...");
@ -220,16 +254,37 @@ public class App extends BusNode {
}
/**
* Shut down the running instance.<br>
* Deinitialize backend modules and terminate the JVM.
*/
public static void requestShutdown()
{
if (instance == null) {
Log.w("App is not running.");
System.exit(0);
}
Log.i("Sending a shutdown request...");
bus().send(new ShutdownRequest());
}
/**
* Shut down the running instance.<br>
* Deinitialize backend modules and terminate the JVM.
*/
public static void shutdown()
{
if (instance != null) {
Log.i("Dispatching Shutdown event...");
if (instance == null) {
Log.w("App is not running.");
System.exit(0);
}
// It's safer to shutdown in rendering context
// (LWJGL backend has problems otherwise)
bus().send(new ShutdownEvent(new Runnable() {
App.bus().send(new MainLoopRequest(new Runnable() {
@Override
public void run()
@ -238,22 +293,17 @@ public class App extends BusNode {
final EventBus bus = bus();
if (bus != null) {
bus.send(new DestroyEvent());
bus.destroy();
}
} catch (final Throwable e) {
Log.e(e);
}
Log.i("Shutdown completed.");
System.exit(0);
}
}));
}, true));
} else {
Log.w("App is not running.");
Log.i("Shutdown completed.");
System.exit(0);
}
}
/**

@ -2,8 +2,10 @@ package mightypork.gamecore.core;
import mightypork.gamecore.audio.AudioModule;
import mightypork.gamecore.core.init.InitTaskBackend;
import mightypork.gamecore.graphics.GraphicsModule;
import mightypork.gamecore.input.InputModule;
import mightypork.utils.annotations.Stub;
import mightypork.utils.eventbus.clients.BusNode;
@ -11,7 +13,8 @@ import mightypork.utils.eventbus.clients.BusNode;
* Application backend interface (set of core modules).<br>
* The goal of this abstraction is to allow easy migration to different
* environment with different libraries etc. It should be as simple as using
* different backend.
* different backend.<br>
* The backend is initialized using {@link InitTaskBackend}.
*
* @author MightyPork
*/
@ -35,6 +38,19 @@ public abstract class AppBackend extends BusNode {
}
/**
* Add backend-specific init tasks or init task configurations.<br>
* This is run after default init tasks have been added, and before the init
* sequence is started.<br>
* The backend is already binded to the app.
*/
@Stub
public void addInitTasks()
{
//
}
/**
* Initialize backend modules, add them to event bus.
*/

@ -18,7 +18,7 @@ import mightypork.utils.math.timing.TimerDelta;
*
* @author Ondřej Hruška (MightyPork)
*/
public class DeltaMainLoop extends BusNode implements MainLoop {
public class BasicMainLoop extends BusNode implements MainLoop {
/**
* Max time spent on main loop tasks per cycle (s)
@ -75,6 +75,9 @@ public class DeltaMainLoop extends BusNode implements MainLoop {
}
}
// halt if tasks terminated the app.
if (!running) break;
beforeRender();
if (rootRenderable != null) {

@ -4,8 +4,8 @@ package mightypork.gamecore.core.config;
import java.util.HashMap;
import java.util.Map;
import mightypork.gamecore.core.events.ShutdownEvent;
import mightypork.gamecore.core.events.ShutdownListener;
import mightypork.gamecore.core.events.ShutdownRequest;
import mightypork.gamecore.core.events.ShutdownRequestListener;
import mightypork.gamecore.input.Key;
import mightypork.gamecore.input.KeyStroke;
import mightypork.utils.config.propmgr.Property;
@ -21,7 +21,7 @@ import mightypork.utils.logging.Log;
*
* @author Ondřej Hruška (MightyPork)
*/
public class Config implements ShutdownListener {
public class Config implements ShutdownRequestListener {
/** Array of configs registered for the app */
protected static Map<String, Config> configs = new HashMap<>();
@ -270,7 +270,7 @@ public class Config implements ShutdownListener {
@Override
public void onShutdown(ShutdownEvent event)
public void onShutdownRequested(ShutdownRequest event)
{
save(); // save changes done to the config
}

@ -15,26 +15,13 @@ import mightypork.utils.logging.Log;
*
* @author Ondřej Hruška (MightyPork)
*/
public class ShutdownEvent extends BusEvent<ShutdownListener> {
private final Runnable shutdownTask;
/**
* Make a shutdown event
*
* @param doShutdown Task that does the actual shutdown
*/
public ShutdownEvent(Runnable doShutdown)
{
this.shutdownTask = doShutdown;
}
public class ShutdownRequest extends BusEvent<ShutdownRequestListener> {
@Override
protected void handleBy(ShutdownListener handler)
protected void handleBy(ShutdownRequestListener handler)
{
handler.onShutdown(this);
handler.onShutdownRequested(this);
}
@ -44,7 +31,7 @@ public class ShutdownEvent extends BusEvent<ShutdownListener> {
if (!isConsumed()) {
Log.i("Shutting down...");
App.bus().send(new MainLoopRequest(shutdownTask, true));
App.shutdown();
} else {
Log.i("Shutdown aborted.");

@ -6,13 +6,13 @@ package mightypork.gamecore.core.events;
*
* @author Ondřej Hruška (MightyPork)
*/
public interface ShutdownListener {
public interface ShutdownRequestListener {
/**
* Intercept quit request.<br>
* Consume the event to abort shutdown (ie. ask user to save)
* Intercept shutdown request.<br>
* Consume the event to abort shutdown (ie. ask user to save).
*
* @param event quit request event.
*/
void onShutdown(ShutdownEvent event);
void onShutdownRequested(ShutdownRequest event);
}

@ -0,0 +1,168 @@
package mightypork.gamecore.core.init;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import mightypork.utils.Reflect;
import mightypork.utils.logging.Log;
/**
* initialization sequence that takes care of task dependencies and ordering.
*
* @author Ondřej Hruška (MightyPork)
*/
public class InitSequence {
private final Map<String, InitTask> taskMap = new HashMap<>();
/**
* Add a task. If a task with the name already exists, replace it.
*
* @param task task to add
*/
public void addTask(InitTask task)
{
final String name = task.getName();
// detailed logging
// if (taskMap.containsKey(name)) {
// Log.f3("REPL init " + Str.pad("\"" + name + "\"", 20) + " <" + Str.val(task) + ">");
// } else {
// Log.f3("ADD init " + Str.pad("\"" + name + "\"", 20) + " <" + Str.val(task) + ">");
// }
taskMap.put(name, task);
}
/**
* Get task sequence in proper order.
*
* @return initialization sequence
*/
public List<InitTask> getSequence()
{
final List<InitTask> remainingTasks = new ArrayList<>(taskMap.values());
final List<InitTask> orderedTasks = new ArrayList<>();
final Set<String> loadedTaskNames = new HashSet<>();
// resolve task order
InitTask taskToAdd = null;
do {
taskToAdd = null;
for (final InitTask task : remainingTasks) {
String[] deps = task.getDependencies();
if (deps == null) deps = new String[] {};
int missingDeps = deps.length;
for (final String d : deps) {
if (loadedTaskNames.contains(d)) missingDeps--;
}
if (missingDeps == 0) {
if (taskToAdd == null || taskToAdd.getPriority() < task.getPriority()) {
taskToAdd = task;
}
}
}
if (taskToAdd != null) {
orderedTasks.add(taskToAdd);
loadedTaskNames.add(taskToAdd.getName());
remainingTasks.remove(taskToAdd);
}
} while (taskToAdd != null);
checkLeftovers(loadedTaskNames, remainingTasks);
return orderedTasks;
}
public List<InitTask> getSequenceOldImpl()
{
final List<InitTask> remainingTasks = new ArrayList<>(taskMap.values());
final List<InitTask> orderedTasks = new ArrayList<>();
final Set<String> loadedTaskNames = new HashSet<>();
// resolve task order
int addedThisIteration = 0;
do {
addedThisIteration = 0;
for (final Iterator<InitTask> i = remainingTasks.iterator(); i.hasNext();) {
final InitTask task = i.next();
String[] deps = task.getDependencies();
if (deps == null) deps = new String[] {};
int missingDeps = deps.length;
for (final String d : deps) {
if (loadedTaskNames.contains(d)) missingDeps--;
}
if (missingDeps == 0) {
orderedTasks.add(task);
loadedTaskNames.add(task.getName());
i.remove();
addedThisIteration++;
}
}
} while (addedThisIteration > 0);
checkLeftovers(loadedTaskNames, remainingTasks);
return orderedTasks;
}
private void checkLeftovers(Collection<String> loadedTaskNames, Collection<InitTask> remainingTasks)
{
// check if any tasks are left out
if (remainingTasks.size() > 0) {
// build error message for each bad task
int badInitializers = 0;
for (final InitTask task : remainingTasks) {
if (Reflect.hasAnnotation(task.getClass(), OptionalInitTask.class)) {
continue;
}
badInitializers++;
String notSatisfied = "";
for (final String d : task.getDependencies()) {
if (!loadedTaskNames.contains(d)) {
if (!notSatisfied.isEmpty()) {
notSatisfied += ", ";
}
notSatisfied += d;
}
}
Log.w("InitTask \"" + task.getName() + "\" - missing dependencies: " + notSatisfied);
}
if (badInitializers > 0) throw new RuntimeException("Some InitTask dependencies could not be satisfied.");
}
}
}

@ -1,16 +1,8 @@
package mightypork.gamecore.core.init;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import mightypork.gamecore.core.App;
import mightypork.utils.Reflect;
import mightypork.utils.annotations.Stub;
import mightypork.utils.logging.Log;
/**
@ -22,6 +14,12 @@ import mightypork.utils.logging.Log;
*/
public abstract class InitTask {
protected static final int PRIO_FIRST = Integer.MAX_VALUE;
protected static final int PRIO_EARLY = 9000;
protected static final int PRIO_DEFAULT = 0;
protected static final int PRIO_LATE = -9000;
protected static final int PRIO_LAST = Integer.MIN_VALUE;
/** App instance assigned using <code>bind()</code> */
protected App app;
@ -102,75 +100,14 @@ public abstract class InitTask {
/**
* Order init tasks so that all dependencies are loaded before thye are
* needed by the tasks.
* Get priority in the init sequence. Tasks with higher priority are loaded
* earlier (but only after their dependencies are loaded).
*
* @param tasks task list
* @return task list ordered
* @return priority, higher = runs earlier
*/
public static List<InitTask> inOrder(List<InitTask> tasks)
@Stub
public int getPriority()
{
final List<InitTask> remaining = new ArrayList<>(tasks);
final List<InitTask> ordered = new ArrayList<>();
final Set<String> loaded = new HashSet<>();
// resolve task order
int addedThisIteration = 0;
do {
addedThisIteration = 0;
for (final Iterator<InitTask> i = remaining.iterator(); i.hasNext();) {
final InitTask task = i.next();
String[] deps = task.getDependencies();
if (deps == null) deps = new String[] {};
int unmetDepsCount = deps.length;
for (final String d : deps) {
if (loaded.contains(d)) unmetDepsCount--;
}
if (unmetDepsCount == 0) {
ordered.add(task);
loaded.add(task.getName());
i.remove();
addedThisIteration++;
}
}
} while (addedThisIteration > 0);
// check if any tasks are left out
if (remaining.size() > 0) {
// build error message for each bad task
int badInitializers = 0;
for (final InitTask task : remaining) {
if (Reflect.hasAnnotation(task.getClass(), OptionalInitTask.class)) {
continue;
}
badInitializers++;
String notSatisfied = "";
for (final String d : task.getDependencies()) {
if (!loaded.contains(d)) {
if (!notSatisfied.isEmpty()) {
notSatisfied += ", ";
}
notSatisfied += d;
}
}
Log.w("InitTask \"" + task.getName() + "\" - missing dependencies: " + notSatisfied);
}
if (badInitializers > 0) throw new RuntimeException("Some InitTask dependencies could not be satisfied.");
}
return ordered;
return PRIO_DEFAULT;
}
}

@ -0,0 +1,41 @@
package mightypork.gamecore.core.init;
import mightypork.gamecore.core.App;
/**
* Initialize backend. The main point of postponing this is to make sure the
* init is logged properly.
*
* @author Ondřej Hruška (MightyPork)
*/
public class InitTaskBackend extends InitTask {
@Override
public void run()
{
App.instance().getBackend().initialize();
}
@Override
public String getName()
{
return "backend";
}
@Override
public String[] getDependencies()
{
return new String[] { "log" };
}
@Override
public int getPriority()
{
return PRIO_EARLY;
}
}

@ -1,7 +1,7 @@
package mightypork.gamecore.core.config;
package mightypork.gamecore.core.init;
import mightypork.gamecore.core.init.InitTask;
import mightypork.gamecore.core.config.Config;
import mightypork.utils.annotations.Stub;
@ -72,4 +72,11 @@ public abstract class InitTaskConfig extends InitTask {
return new String[] { "workdir" };
}
@Override
public int getPriority()
{
return PRIO_FIRST;
}
}

@ -38,4 +38,11 @@ public class InitTaskCrashHandler extends InitTask implements UncaughtExceptionH
{
return "crash_handler";
}
@Override
public int getPriority()
{
return PRIO_FIRST;
}
}

@ -5,7 +5,7 @@ import mightypork.gamecore.graphics.GraphicsModule;
/**
* Setup main window.
* Setup main window / display with rendering context.
*
* @author Ondřej Hruška (MightyPork)
*/

@ -12,8 +12,8 @@ import mightypork.utils.math.algo.Move;
/**
* Register extra ionizables added by the game library (non-native ION types).<br>
* This initializer can be called anywhere in the initialization sequence.
* Register extra ionizables. More ionizables can be registered ie. in the
* <code>after()</code> hook.
*
* @author Ondřej Hruška (MightyPork)
*/
@ -67,7 +67,14 @@ public class InitTaskIonizables extends InitTask {
@Override
public String getName()
{
return "ion";
return "ionizables";
}
@Override
public int getPriority()
{
return PRIO_EARLY;
}
}

@ -4,21 +4,20 @@ package mightypork.gamecore.core.init;
import java.io.File;
import java.util.logging.Level;
import mightypork.utils.Str;
import mightypork.utils.files.WorkDir;
import mightypork.utils.logging.Log;
import mightypork.utils.logging.writers.LogWriter;
import mightypork.utils.string.StringUtil;
/**
* Init main logger and console log printing.<br>
* Must be called after workdir is initialized.
* Init logging system.
*
* @author Ondřej Hruška (MightyPork)
*/
public class InitTaskLog extends InitTask {
private String logDir = "log";
private String logDir = ".";
private String logName = "runtime";
private int archiveCount = 5;
@ -47,7 +46,7 @@ public class InitTaskLog extends InitTask {
*/
public void setLogName(String logName)
{
if (!StringUtil.isValidFilenameString(logName)) {
if (!Str.isValidFilenameString(logName)) {
throw new IllegalArgumentException("Invalid log name.");
}
@ -104,4 +103,11 @@ public class InitTaskLog extends InitTask {
{
return new String[] { "workdir" };
}
@Override
public int getPriority()
{
return PRIO_FIRST;
}
}

@ -49,4 +49,11 @@ public class InitTaskLogHeader extends InitTask {
{
return new String[] { "log", "workdir" };
}
@Override
public int getPriority()
{
return PRIO_FIRST;
}
}

@ -1,18 +1,19 @@
package mightypork.gamecore.core.init;
import mightypork.gamecore.core.BasicMainLoop;
import mightypork.gamecore.core.MainLoop;
import mightypork.utils.annotations.Stub;
/**
* Task to add a resource loader.<br>
* By default the async resource loader is used
* Task to add a main loop.
*
* @author Ondřej Hruška (MightyPork)
*/
public abstract class InitTaskMainLoop extends InitTask {
public class InitTaskMainLoop extends InitTask {
/** The loader. */
/** The loop, can be accessed in the after() method. */
protected MainLoop loop;
@ -25,11 +26,15 @@ public abstract class InitTaskMainLoop extends InitTask {
/**
* Create a loader impl
* Create a main loop
*
* @return loader
*/
protected abstract MainLoop getLoopImpl();
@Stub
protected MainLoop getLoopImpl()
{
return new BasicMainLoop();
}
@Override
@ -37,4 +42,11 @@ public abstract class InitTaskMainLoop extends InitTask {
{
return "main_loop";
}
@Override
public int getPriority()
{
return PRIO_EARLY;
}
}

@ -21,6 +21,7 @@ public abstract class InitTaskResourceLoader extends InitTask {
{
loader = getLoaderImpl();
if (loader != null) loader.init();
app.addChildClient(loader);
}

@ -6,8 +6,7 @@ import mightypork.gamecore.resources.loading.ResourceLoader;
/**
* Task to add a resource loader.<br>
* By default the async resource loader is used
* Add Async resource loader.
*
* @author Ondřej Hruška (MightyPork)
*/
@ -21,10 +20,6 @@ public class InitTaskResourceLoaderAsync extends InitTaskResourceLoader {
@Override
protected ResourceLoader getLoaderImpl()
{
final AsyncResourceLoader loader = new AsyncResourceLoader();
// could now configure the loader
return loader;
return new AsyncResourceLoader();
}
}

@ -5,8 +5,8 @@ import mightypork.gamecore.resources.loading.ResourceLoader;
/**
* Task to add a resource loader.<br>
* By default the async resource loader is used
* Add no resource loader. That will cause resources to be loaded on-demand. May
* cause lag if the resources are too large.
*
* @author Ondřej Hruška (MightyPork)
*/

@ -29,6 +29,10 @@ public abstract class InitTaskResources extends InitTask implements ResourceInit
@Override
public String[] getDependencies()
{
// main loop handles resource load rewuests that run in rendering context
// must be before, otherwise the requests would get lost.
return new String[] { "resource_loader", "main_loop" };
}
}

@ -1,42 +0,0 @@
package mightypork.gamecore.core.init;
import mightypork.gamecore.graphics.Renderable;
/**
* Task to init renderable screens (part of the main loop).<br>
* Resources must already be ready.
*
* @author Ondřej Hruška (MightyPork)
*/
public abstract class InitTaskScreens extends InitTask {
@Override
public void run()
{
app.setMainRenderable(getMainRenderableImpl());
}
/**
* Create a loader impl
*
* @return loader
*/
protected abstract Renderable getMainRenderableImpl();
@Override
public String getName()
{
return "renderables";
}
@Override
public String[] getDependencies()
{
return new String[] { "resources", "main_loop" };
}
}

@ -0,0 +1,51 @@
package mightypork.gamecore.core.init;
import mightypork.gamecore.graphics.Renderable;
import mightypork.gamecore.resources.Res;
/**
* Task to init main renderable (UI).<br>
* Resources are already registered in {@link Res}.
*
* @author Ondřej Hruška (MightyPork)
*/
public abstract class InitTaskUI extends InitTask {
@Override
public void run()
{
app.setMainRenderable(createMainRenderable());
}
/**
* Create a loader impl
*
* @return loader
*/
protected abstract Renderable createMainRenderable();
@Override
public String getName()
{
return "ui";
}
@Override
public String[] getDependencies()
{
// main loop queues layout change events, would lose them otherwise
return new String[] { "resources", "main_loop" };
}
@Override
public int getPriority()
{
return PRIO_LAST;
}
}

@ -133,4 +133,11 @@ public class InitTaskWorkdir extends InitTask {
{
return "workdir";
}
@Override
public int getPriority()
{
return PRIO_EARLY;
}
}

@ -5,7 +5,7 @@ import mightypork.gamecore.core.App;
import mightypork.gamecore.graphics.Renderable;
import mightypork.gamecore.gui.events.LayoutChangeEvent;
import mightypork.gamecore.gui.events.LayoutChangeListener;
import mightypork.utils.Support;
import mightypork.utils.Str;
import mightypork.utils.annotations.Stub;
import mightypork.utils.logging.Log;
import mightypork.utils.math.color.Color;
@ -88,7 +88,7 @@ public abstract class BaseComponent extends AbstractRectCache implements Compone
try {
poll();
} catch (final NullPointerException e) {
Log.e("Component is missing a bounding rect, at: " + Support.str(getClass()));
Log.e("Component is missing a bounding rect, at: " + Str.val(getClass()));
}
}

@ -1,7 +1,7 @@
package mightypork.gamecore.input;
import mightypork.utils.string.StringUtil;
import mightypork.utils.Str;
/**
@ -84,8 +84,8 @@ public class KeyStroke {
if (dataString1.contains("+")) {
final String keyStr = StringUtil.fromLastChar(dataString1, '+');
final String modStr = StringUtil.toLastChar(dataString1, '+');
final String keyStr = Str.fromLast(dataString1, '+');
final String modStr = Str.toLast(dataString1, '+');
setTo(Keys.stringToKey(keyStr), Keys.stringToMod(modStr));

@ -3,11 +3,11 @@ package mightypork.gamecore.resources;
import java.io.IOException;
import mightypork.utils.Str;
import mightypork.utils.annotations.Alias;
import mightypork.utils.interfaces.Destroyable;
import mightypork.utils.logging.Log;
import mightypork.utils.math.timing.Profiler;
import mightypork.utils.string.StringUtil;
/**
@ -107,7 +107,7 @@ public abstract class BaseDeferredResource implements DeferredResource, Destroya
@Override
public String toString()
{
return StringUtil.fromLastChar(resource, '/');
return Str.fromLast(resource, '/');
}

@ -9,7 +9,7 @@ import mightypork.gamecore.core.App;
import mightypork.gamecore.core.events.MainLoopRequest;
import mightypork.gamecore.resources.DeferredResource;
import mightypork.utils.Reflect;
import mightypork.utils.Support;
import mightypork.utils.Str;
import mightypork.utils.interfaces.Destroyable;
import mightypork.utils.logging.Log;
@ -40,7 +40,6 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr
@Override
public synchronized void init()
{
App.bus().subscribe(this);
setDaemon(true);
super.start();
}
@ -70,7 +69,7 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr
if (!mainLoopQueuing) {
// just let it be
} else {
Log.f3("(loader) Delegating to main thread: " + Support.str(resource));
Log.f3("(loader) Delegating to main thread: " + Str.val(resource));
App.bus().send(new MainLoopRequest(new Runnable() {
@ -102,7 +101,7 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr
if (!def.isLoaded()) {
Log.f3("(loader) Scheduling... " + Support.str(def));
Log.f3("(loader) Scheduling... " + Str.val(def));
exs.submit(new Runnable() {

Loading…
Cancel
Save