diff --git a/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java b/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java index d8ef064..4057796 100644 --- a/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java +++ b/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java @@ -31,7 +31,6 @@ public class ProgressiaLauncher { arguments = args.clone(); setupCrashReports(); proxy.initialize(); - TaskManager.getInstance().startLoading(); } private static void setupCrashReports() { diff --git a/src/main/java/ru/windcorp/progressia/client/ClientProxy.java b/src/main/java/ru/windcorp/progressia/client/ClientProxy.java index 1d154e7..ec6a592 100644 --- a/src/main/java/ru/windcorp/progressia/client/ClientProxy.java +++ b/src/main/java/ru/windcorp/progressia/client/ClientProxy.java @@ -28,6 +28,7 @@ import ru.windcorp.progressia.client.graphics.font.Typefaces; import ru.windcorp.progressia.client.graphics.texture.Atlases; import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.client.localization.Localizer; +import ru.windcorp.progressia.common.modules.TaskManager; import ru.windcorp.progressia.common.resource.ResourceManager; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.server.ServerState; @@ -57,6 +58,8 @@ public class ClientProxy implements Proxy { Atlases.loadAllAtlases(); AudioSystem.initialize(); + TaskManager.getInstance().startLoading(); + ServerState.startServer(); ClientState.connectToLocalServer(); diff --git a/src/main/java/ru/windcorp/progressia/client/audio/AudioSystem.java b/src/main/java/ru/windcorp/progressia/client/audio/AudioSystem.java index 24cc2de..c85dcc3 100644 --- a/src/main/java/ru/windcorp/progressia/client/audio/AudioSystem.java +++ b/src/main/java/ru/windcorp/progressia/client/audio/AudioSystem.java @@ -18,14 +18,25 @@ package ru.windcorp.progressia.client.audio; +import ru.windcorp.progressia.common.modules.Module; +import ru.windcorp.progressia.common.modules.Task; +import ru.windcorp.progressia.common.modules.TaskManager; import ru.windcorp.progressia.common.resource.ResourceManager; public class AudioSystem { static public void initialize() { + Module audioModule = new Module("AudioModule:System"); AudioManager.initAL(); Thread shutdownHook = new Thread(AudioManager::closeAL, "AL Shutdown Hook"); Runtime.getRuntime().addShutdownHook(shutdownHook); - loadAudioData(); + Task t = new Task("Task:InitializeAudio") { + @Override + protected void perform() { + loadAudioData(); + } + }; + audioModule.addTask(t); + TaskManager.getInstance().registerModule(audioModule); } static void loadAudioData() { diff --git a/src/main/java/ru/windcorp/progressia/common/modules/Module.java b/src/main/java/ru/windcorp/progressia/common/modules/Module.java index 7929b69..d8f27c2 100644 --- a/src/main/java/ru/windcorp/progressia/common/modules/Module.java +++ b/src/main/java/ru/windcorp/progressia/common/modules/Module.java @@ -9,9 +9,9 @@ import ru.windcorp.progressia.common.util.namespaces.Namespaced; public class Module extends Namespaced { - private List tasks = new ArrayList<>(); - private Map meta = new HashMap<>(); - private boolean done = false; + private final List tasks = new ArrayList<>(); + private final Map meta = new HashMap<>(); + private final boolean done = false; public Module(String id) { diff --git a/src/main/java/ru/windcorp/progressia/common/modules/ModuleBuilder.java b/src/main/java/ru/windcorp/progressia/common/modules/ModuleBuilder.java new file mode 100644 index 0000000..303b7f1 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/modules/ModuleBuilder.java @@ -0,0 +1,14 @@ +package ru.windcorp.progressia.common.modules; + +public class ModuleBuilder { + private final Module module; + + public ModuleBuilder(String id) { + module = new Module(id); + } + + public ModuleBuilder AddTask(Task task) { + module.addTask(task); + return this; + } +} diff --git a/src/main/java/ru/windcorp/progressia/common/modules/Task.java b/src/main/java/ru/windcorp/progressia/common/modules/Task.java index 76ef83c..fe2f747 100644 --- a/src/main/java/ru/windcorp/progressia/common/modules/Task.java +++ b/src/main/java/ru/windcorp/progressia/common/modules/Task.java @@ -1,12 +1,10 @@ package ru.windcorp.progressia.common.modules; +import ru.windcorp.progressia.common.util.namespaces.Namespaced; + import java.util.ArrayList; import java.util.List; -import ru.windcorp.jputil.chars.StringUtil; -import ru.windcorp.progressia.common.util.crash.CrashReports; -import ru.windcorp.progressia.common.util.namespaces.Namespaced; - public abstract class Task extends Namespaced implements Runnable @@ -23,23 +21,9 @@ public abstract class Task @Override public void run() { - if (!canRun()) { - - ArrayList undoneTasks = new ArrayList<>(); - for (Task j : requiredTasks) { - if (!j.isDone()) { - undoneTasks.add(j); - } - } - - throw CrashReports.report(new Throwable(), - "The following required Tasks are not done:\n%s", - StringUtil.iterableToString(undoneTasks, "\n")); - } else { - isActive = true; - perform(); - isDone = true; - } + isActive = true; + perform(); + isDone = true; } // This method will be invoked by Run() diff --git a/src/main/java/ru/windcorp/progressia/common/modules/TaskManager.java b/src/main/java/ru/windcorp/progressia/common/modules/TaskManager.java index 3ce345a..a08966c 100644 --- a/src/main/java/ru/windcorp/progressia/common/modules/TaskManager.java +++ b/src/main/java/ru/windcorp/progressia/common/modules/TaskManager.java @@ -1,100 +1,101 @@ package ru.windcorp.progressia.common.modules; -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import ru.windcorp.progressia.common.util.crash.CrashReports; +import ru.windcorp.progressia.common.state.StateFieldBuilder; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; + +import static java.util.concurrent.Executors.newFixedThreadPool; public class TaskManager { private static final TaskManager instance = new TaskManager(); private final List tasks = new ArrayList<>(); private final List modules = new ArrayList<>(); - private final ThreadFactory threadFactory = new ThreadFactoryBuilder() - .setNameFormat("LogicCore-%d") - .build(); - private boolean wakeUpFlag = false; + private boolean loadingDone; + private int activeThreadsCount; - private TaskManager() {} + private final ExecutorService executorService; + private TaskManager() { + loadingDone = false; + activeThreadsCount = 0; + executorService = newFixedThreadPool( + Runtime.getRuntime().availableProcessors(), Thread::new); + } + public static TaskManager getInstance() { return instance; } - //Thread pool with size of logical cores of CPU - private final ExecutorService executorService = - Executors.newFixedThreadPool( - Runtime.getRuntime().availableProcessors() - , threadFactory); - public void registerModule(Module module) { tasks.addAll(module.getTasks()); modules.add(module); } + public boolean isLoadingDone() { + return loadingDone; + } + public void startLoading() { - System.out.println("Loader is started"); - for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) { + + for(int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) { executorService.submit(() -> { - while (!tasks.isEmpty()) { + while(!loadingDone) { Task t = getRunnableTask(); - if (t == null) { - while (!wakeUpFlag) { - try { - synchronized (tasks) { - tasks.wait(); - } - } catch (InterruptedException e) { - e.printStackTrace(); - } + if (t != null) { + synchronized (this) { + activeThreadsCount++; } - wakeUpFlag = false; - } - else if (!t.isActive()) { t.run(); - removeTask(t); - wakeUpFlag = true; - synchronized (tasks) { - tasks.notifyAll(); + synchronized (this) { + activeThreadsCount--; + notifyAll(); + } + } else if (activeThreadsCount > 0) { + try { + synchronized (this) { + this.wait(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } else { + synchronized (this) { + loadingDone = true; } } } }); } - for (Module m : modules) { - if (!m.done()) { - throw CrashReports.crash(new Exception("Modules loading failed"), - null); - } - } - while(true) { - try { - executorService.shutdown(); - if (executorService.awaitTermination(5, TimeUnit.SECONDS)) break; - } catch (InterruptedException e) { - e.printStackTrace(); - } - }; - System.out.println("Loader has completed its job"); + waitForLoadingEnd(); + executorService.shutdownNow(); } - private void removeTask(Task task) { - synchronized (tasks) { - tasks.remove(task); + public synchronized Task getRunnableTask() { + if(!tasks.isEmpty()) { + for (Task t : + tasks) { + if(t.canRun()) { + tasks.remove(t); + return t; + } + } + } + return null; + } + + private void waitForLoadingEnd() { + synchronized (this) { + while(!loadingDone) { + try { + this.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } } } - public Task getRunnableTask() { - synchronized (tasks) { - for (Task t : tasks) { - if (t.canRun()) return t; - } - return null; - } - } }