diff --git a/build.gradle b/build.gradle index 5adae10..96134cd 100644 --- a/build.gradle +++ b/build.gradle @@ -111,7 +111,9 @@ switch (OperatingSystem.current()) { } dependencies { - implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion") + + implementation 'org.jetbrains:annotations:20.1.0' + implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion") implementation "org.lwjgl:lwjgl" implementation "org.lwjgl:lwjgl-glfw" diff --git a/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java b/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java index c8935fc..f8d886e 100644 --- a/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java +++ b/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java @@ -18,6 +18,8 @@ package ru.windcorp.progressia; +import ru.windcorp.progressia.common.modules.Task; +import ru.windcorp.progressia.common.modules.TaskManager; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.util.crash.analyzers.OutOfMemoryAnalyzer; import ru.windcorp.progressia.common.util.crash.providers.*; @@ -30,6 +32,7 @@ public class ProgressiaLauncher { arguments = args.clone(); setupCrashReports(); proxy.initialize(); + TaskManager.startLoading(); } private static void setupCrashReports() { 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 34262d8..e1d6b34 100644 --- a/src/main/java/ru/windcorp/progressia/common/modules/Module.java +++ b/src/main/java/ru/windcorp/progressia/common/modules/Module.java @@ -25,6 +25,9 @@ public class Module extends Namespaced { public List getTasks() { return tasks; } + public void addTask(Task task) { + tasks.add(task); + } /** * @return false - not all tasks are done 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 9411ee0..b9a602e 100644 --- a/src/main/java/ru/windcorp/progressia/common/modules/Task.java +++ b/src/main/java/ru/windcorp/progressia/common/modules/Task.java @@ -12,7 +12,8 @@ public abstract class Task implements Runnable { - private boolean done = false; + private boolean isDone = false; + private boolean isActive = false; List requiredTasks = new ArrayList<>(); @@ -34,19 +35,22 @@ public abstract class Task throw CrashReports.report(new Throwable(), "The following required Tasks are not done:\n%s", StringUtil.iterableToString(undoneTasks, "\n")); + } else { + perform(); + isDone = true; } - - perform(); - - done = true; } - + // This method will be invoked by Run() protected abstract void perform(); public boolean isDone() { - return done; + return isDone; } + + public boolean isActive() { return isActive; } + + public void setActive(boolean value) { isActive = value; } public boolean canRun() { for (Task t : requiredTasks) { diff --git a/src/main/java/ru/windcorp/progressia/common/modules/TaskManager.java b/src/main/java/ru/windcorp/progressia/common/modules/TaskManager.java new file mode 100644 index 0000000..bc8c395 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/modules/TaskManager.java @@ -0,0 +1,101 @@ +package ru.windcorp.progressia.common.modules; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; + +public class TaskManager { + private static final List tasks = new ArrayList<>(); + private static final List modules = new ArrayList<>(); + private static final ThreadFactory threadFactory = new ThreadFactoryBuilder() + .setNameFormat("LogicCore-%d") + .build(); + + //Thread pool with size of logical cores of CPU + private static final ExecutorService executorService = + Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors() + , threadFactory); + + public static void registerModule(Module module) { + tasks.addAll(module.getTasks()); + modules.add(module); + } + + public static void startLoading() { + Module mod = new Module("Module:Mod"); + Task task = new Task("Task:Task") { + @Override + protected void perform() { + int i = 0; + while(i < 1000000) { + i++; + } + System.out.println("Task " + getId() + "has been performed by" + Thread.currentThread().getName()); + } + }; + Task task1 = new Task("Task:Task1") { + @Override + protected void perform() { + int i = 0; + while(i < 1000000) { + i++; + } + System.out.println("Task " + getId() + "has been performed by" + Thread.currentThread().getName()); + } + }; + Task task2 = new Task("Task:Task2") { + @Override + protected void perform() { + int i = 0; + while(i < 1000000) { + i++; + } + System.out.println("Task " + getId() + "has been performed by" + Thread.currentThread().getName()); + } + }; + mod.addTask(task); + mod.addTask(task1); + mod.addTask(task2); + registerModule(mod); + + while (!tasks.isEmpty()) { + executorService.submit(() -> { + while (true) { + Task t = getRunnableTask(); + if(t == null) { + break; + } + else if (!t.isActive()) { + t.setActive(true); + removeTask(t); + t.run(); + } + } + System.out.println(Thread.currentThread().getName() + " has been stopped!"); + Thread.yield(); + }); + } + + executorService.shutdownNow(); + } + + private static void removeTask(Task task) { + synchronized (tasks) { + tasks.remove(task); + } + } + + public static Task getRunnableTask() { + synchronized (tasks) { + for (Task t : tasks) { + if (t.canRun()) return t; + } + return null; + } + } +}