TaskManager bug fixes and code cleanup
This commit is contained in:
parent
5a06788652
commit
f520d4b2c6
@ -15,9 +15,10 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ru.windcorp.progressia.client.audio;
|
package ru.windcorp.progressia.client.audio;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
import ru.windcorp.progressia.common.modules.Module;
|
import ru.windcorp.progressia.common.modules.Module;
|
||||||
import ru.windcorp.progressia.common.modules.Task;
|
import ru.windcorp.progressia.common.modules.Task;
|
||||||
import ru.windcorp.progressia.common.modules.TaskManager;
|
import ru.windcorp.progressia.common.modules.TaskManager;
|
||||||
@ -29,10 +30,12 @@ public class AudioSystem {
|
|||||||
AudioManager.initAL();
|
AudioManager.initAL();
|
||||||
Thread shutdownHook = new Thread(AudioManager::closeAL, "AL Shutdown Hook");
|
Thread shutdownHook = new Thread(AudioManager::closeAL, "AL Shutdown Hook");
|
||||||
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
||||||
Task t = new Task("Task:InitializeAudio") {
|
|
||||||
|
Task t = new Task("AudioSystem:Initialize") {
|
||||||
@Override
|
@Override
|
||||||
protected void perform() {
|
protected void perform() {
|
||||||
loadAudioData();
|
loadAudioData();
|
||||||
|
LogManager.getLogger().info("Audio data is loaded");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
audioModule.addTask(t);
|
audioModule.addTask(t);
|
||||||
@ -41,9 +44,9 @@ public class AudioSystem {
|
|||||||
|
|
||||||
static void loadAudioData() {
|
static void loadAudioData() {
|
||||||
AudioManager.loadSound(
|
AudioManager.loadSound(
|
||||||
ResourceManager.getResource("assets/sounds/block_destroy_clap.ogg"),
|
ResourceManager.getResource("assets/sounds/block_destroy_clap.ogg"),
|
||||||
"Progressia:BlockDestroy",
|
"Progressia:BlockDestroy",
|
||||||
AudioFormat.MONO
|
AudioFormat.MONO
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,34 +1,35 @@
|
|||||||
package ru.windcorp.progressia.common.modules;
|
package ru.windcorp.progressia.common.modules;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
|
||||||
|
|
||||||
public class Module extends Namespaced {
|
public class Module extends Namespaced {
|
||||||
|
|
||||||
private final List<Task> tasks = new ArrayList<>();
|
private final List<Task> tasks = new ArrayList<>();
|
||||||
private final Map<String, String> meta = new HashMap<>();
|
private final Map<String, String> meta = new HashMap<>();
|
||||||
private final boolean done = false;
|
private final boolean done = false;
|
||||||
|
|
||||||
|
|
||||||
public Module(String id) {
|
public Module(String id) {
|
||||||
super(id);
|
super(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getMeta() {
|
public Map<String, String> getMeta() {
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Task> getTasks() {
|
public List<Task> getTasks() {
|
||||||
return tasks;
|
return tasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTask(Task task) {
|
public void addTask(Task task) {
|
||||||
tasks.add(task);
|
tasks.add(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return false - not all tasks are done
|
* @return false - not all tasks are done
|
||||||
*/
|
*/
|
||||||
@ -38,7 +39,7 @@ public class Module extends Namespaced {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,15 +5,13 @@ import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class Task
|
public abstract class Task
|
||||||
extends Namespaced
|
extends Namespaced
|
||||||
implements Runnable
|
implements Runnable {
|
||||||
{
|
|
||||||
|
List<Task> requiredTasks = new ArrayList<>();
|
||||||
private boolean isDone = false;
|
private boolean isDone = false;
|
||||||
private boolean isActive = false;
|
private boolean isActive = false;
|
||||||
|
|
||||||
List<Task> requiredTasks = new ArrayList<>();
|
|
||||||
|
|
||||||
protected Task(String id) {
|
protected Task(String id) {
|
||||||
super(id);
|
super(id);
|
||||||
@ -28,13 +26,15 @@ public abstract class Task
|
|||||||
|
|
||||||
// This method will be invoked by Run()
|
// This method will be invoked by Run()
|
||||||
protected abstract void perform();
|
protected abstract void perform();
|
||||||
|
|
||||||
public boolean isDone() {
|
public boolean isDone() {
|
||||||
return isDone;
|
return isDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isActive() { return isActive; }
|
public boolean isActive() {
|
||||||
|
return isActive;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean canRun() {
|
public boolean canRun() {
|
||||||
if (this.isActive) return false;
|
if (this.isActive) return false;
|
||||||
for (Task reqT : requiredTasks) {
|
for (Task reqT : requiredTasks) {
|
||||||
@ -42,8 +42,12 @@ public abstract class Task
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Task> getRequiredTasks() {
|
public List<Task> getRequiredTasks() {
|
||||||
return requiredTasks;
|
return requiredTasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addRequiredTask(Task task) {
|
||||||
|
requiredTasks.add(task);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,101 +1,107 @@
|
|||||||
package ru.windcorp.progressia.common.modules;
|
package ru.windcorp.progressia.common.modules;
|
||||||
|
|
||||||
import ru.windcorp.progressia.common.state.StateFieldBuilder;
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import static java.util.concurrent.Executors.newFixedThreadPool;
|
import static java.util.concurrent.Executors.newFixedThreadPool;
|
||||||
|
|
||||||
public class TaskManager {
|
public class TaskManager {
|
||||||
private static final TaskManager instance = new TaskManager();
|
private static final TaskManager instance = new TaskManager();
|
||||||
private final List<Task> tasks = new ArrayList<>();
|
private final List<Task> tasks = new ArrayList<>();
|
||||||
private final List<Module> modules = new ArrayList<>();
|
private final List<Module> modules = new ArrayList<>();
|
||||||
private boolean loadingDone;
|
private final ExecutorService executorService;
|
||||||
private int activeThreadsCount;
|
private final AtomicBoolean loadingDone;
|
||||||
|
private final AtomicInteger activeThreadsCount;
|
||||||
|
|
||||||
private final ExecutorService executorService;
|
private TaskManager() {
|
||||||
|
loadingDone = new AtomicBoolean(false);
|
||||||
|
activeThreadsCount = new AtomicInteger(0);
|
||||||
|
executorService = newFixedThreadPool(
|
||||||
|
Runtime.getRuntime().availableProcessors(), Thread::new);
|
||||||
|
}
|
||||||
|
|
||||||
private TaskManager() {
|
public static TaskManager getInstance() {
|
||||||
loadingDone = false;
|
return instance;
|
||||||
activeThreadsCount = 0;
|
}
|
||||||
executorService = newFixedThreadPool(
|
|
||||||
Runtime.getRuntime().availableProcessors(), Thread::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TaskManager getInstance() {
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerModule(Module module) {
|
public void registerModule(Module module) {
|
||||||
tasks.addAll(module.getTasks());
|
tasks.addAll(module.getTasks());
|
||||||
modules.add(module);
|
modules.add(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLoadingDone() {
|
public boolean isLoadingDone() {
|
||||||
return loadingDone;
|
return loadingDone.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startLoading() {
|
public void startLoading() {
|
||||||
|
LogManager.getLogger().info("Loading is started");
|
||||||
|
for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) {
|
||||||
|
executorService.submit(() -> {
|
||||||
|
while (!loadingDone.get()) {
|
||||||
|
Task t = getRunnableTask();
|
||||||
|
if (t != null) {
|
||||||
|
activeThreadsCount.incrementAndGet();
|
||||||
|
t.run();
|
||||||
|
activeThreadsCount.decrementAndGet();
|
||||||
|
synchronized (this) {
|
||||||
|
notifyAll();
|
||||||
|
}
|
||||||
|
} else if (activeThreadsCount.get() > 0) {
|
||||||
|
try {
|
||||||
|
synchronized (this) {
|
||||||
|
this.wait();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
loadingDone.set(true);
|
||||||
|
synchronized (this) {
|
||||||
|
notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
for(int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) {
|
waitForLoadingEnd();
|
||||||
executorService.submit(() -> {
|
if (!tasks.isEmpty()) {
|
||||||
while(!loadingDone) {
|
throw CrashReports.crash(new Exception("Loading is failed"), "");
|
||||||
Task t = getRunnableTask();
|
}
|
||||||
if (t != null) {
|
LogManager.getLogger().info("Loading is finished");
|
||||||
synchronized (this) {
|
executorService.shutdownNow();
|
||||||
activeThreadsCount++;
|
}
|
||||||
}
|
|
||||||
t.run();
|
|
||||||
synchronized (this) {
|
|
||||||
activeThreadsCount--;
|
|
||||||
notifyAll();
|
|
||||||
}
|
|
||||||
} else if (activeThreadsCount > 0) {
|
|
||||||
try {
|
|
||||||
synchronized (this) {
|
|
||||||
this.wait();
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
synchronized (this) {
|
|
||||||
loadingDone = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
waitForLoadingEnd();
|
public synchronized Task getRunnableTask() {
|
||||||
executorService.shutdownNow();
|
if (!tasks.isEmpty()) {
|
||||||
}
|
for (Task t :
|
||||||
|
tasks) {
|
||||||
|
if (t.canRun()) {
|
||||||
|
tasks.remove(t);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized Task getRunnableTask() {
|
private void waitForLoadingEnd() {
|
||||||
if(!tasks.isEmpty()) {
|
synchronized (this) {
|
||||||
for (Task t :
|
while (!loadingDone.get()) {
|
||||||
tasks) {
|
try {
|
||||||
if(t.canRun()) {
|
this.wait();
|
||||||
tasks.remove(t);
|
} catch (InterruptedException e) {
|
||||||
return t;
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void waitForLoadingEnd() {
|
|
||||||
synchronized (this) {
|
|
||||||
while(!loadingDone) {
|
|
||||||
try {
|
|
||||||
this.wait();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user