parent
							
								
									2398a4ee6a
								
							
						
					
					
						commit
						8e9a658098
					
				| @ -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."); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @ -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,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; | ||||
| 	} | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue