mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-16 08:05:34 -04:00
Fix: synchronize method bodies instead of completely relying on synchronized colelctions
Should prevent ConcurrentModificationExceptions and runtime corruption
This commit is contained in:
parent
3004503b84
commit
246bf5c1dc
@ -1,19 +1,15 @@
|
||||
package net.kdt.pojavlaunch.progresskeeper;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class ProgressKeeper {
|
||||
private static final ConcurrentHashMap<String, ConcurrentLinkedQueue<ProgressListener>> sProgressListeners = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentHashMap<String, ProgressState> sProgressStates = new ConcurrentHashMap<>();
|
||||
private static final List<TaskCountListener> sTaskCountListeners = Collections.synchronizedList(new ArrayList<>());
|
||||
private static final HashMap<String, List<ProgressListener>> sProgressListeners = new HashMap<>();
|
||||
private static final HashMap<String, ProgressState> sProgressStates = new HashMap<>();
|
||||
private static final List<TaskCountListener> sTaskCountListeners = new ArrayList<>();
|
||||
|
||||
public static void submitProgress(String progressRecord, int progress, int resid, Object... va) {
|
||||
public static synchronized void submitProgress(String progressRecord, int progress, int resid, Object... va) {
|
||||
ProgressState progressState = sProgressStates.get(progressRecord);
|
||||
boolean shouldCallStarted = progressState == null;
|
||||
boolean shouldCallEnded = resid == -1 && progress == -1;
|
||||
@ -31,7 +27,7 @@ public class ProgressKeeper {
|
||||
progressState.varArg = va;
|
||||
}
|
||||
|
||||
ConcurrentLinkedQueue<ProgressListener> progressListeners = sProgressListeners.get(progressRecord);
|
||||
List<ProgressListener> progressListeners = sProgressListeners.get(progressRecord);
|
||||
if(progressListeners != null)
|
||||
for(ProgressListener listener : progressListeners) {
|
||||
if(shouldCallStarted) listener.onProgressStarted();
|
||||
@ -40,14 +36,14 @@ public class ProgressKeeper {
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateTaskCount() {
|
||||
private static synchronized void updateTaskCount() {
|
||||
int count = sProgressStates.size();
|
||||
for(TaskCountListener listener : sTaskCountListeners) {
|
||||
listener.onUpdateTaskCount(count);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addListener(String progressRecord, ProgressListener listener) {
|
||||
public static synchronized void addListener(String progressRecord, ProgressListener listener) {
|
||||
ProgressState state = sProgressStates.get(progressRecord);
|
||||
if(state != null && (state.resid != -1 || state.progress != -1)) {
|
||||
listener.onProgressStarted();
|
||||
@ -55,32 +51,32 @@ public class ProgressKeeper {
|
||||
}else{
|
||||
listener.onProgressEnded();
|
||||
}
|
||||
ConcurrentLinkedQueue<ProgressListener> listenerWeakReferenceList = sProgressListeners.get(progressRecord);
|
||||
if(listenerWeakReferenceList == null) sProgressListeners.put(progressRecord, (listenerWeakReferenceList = new ConcurrentLinkedQueue<>()));
|
||||
List<ProgressListener> listenerWeakReferenceList = sProgressListeners.get(progressRecord);
|
||||
if(listenerWeakReferenceList == null) sProgressListeners.put(progressRecord, (listenerWeakReferenceList = new ArrayList<>()));
|
||||
listenerWeakReferenceList.add(listener);
|
||||
}
|
||||
|
||||
public static void removeListener(String progressRecord, ProgressListener listener) {
|
||||
ConcurrentLinkedQueue<ProgressListener> listenerWeakReferenceList = sProgressListeners.get(progressRecord);
|
||||
public static synchronized void removeListener(String progressRecord, ProgressListener listener) {
|
||||
List<ProgressListener> listenerWeakReferenceList = sProgressListeners.get(progressRecord);
|
||||
if(listenerWeakReferenceList != null) listenerWeakReferenceList.remove(listener);
|
||||
}
|
||||
|
||||
public static void addTaskCountListener(TaskCountListener listener) {
|
||||
public static synchronized void addTaskCountListener(TaskCountListener listener) {
|
||||
listener.onUpdateTaskCount(sProgressStates.size());
|
||||
if(!sTaskCountListeners.contains(listener)) sTaskCountListeners.add(listener);
|
||||
}
|
||||
public static void addTaskCountListener(TaskCountListener listener, boolean runUpdate) {
|
||||
public static synchronized void addTaskCountListener(TaskCountListener listener, boolean runUpdate) {
|
||||
if(runUpdate) listener.onUpdateTaskCount(sProgressStates.size());
|
||||
if(!sTaskCountListeners.contains(listener)) sTaskCountListeners.add(listener);
|
||||
}
|
||||
public static void removeTaskCountListener(TaskCountListener listener) {
|
||||
public static synchronized void removeTaskCountListener(TaskCountListener listener) {
|
||||
sTaskCountListeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until all tasks are done and runs the runnable, or if there were no pending process remaining
|
||||
* The runnable runs from the thread that updated the task count last, and it might be the UI thread,
|
||||
* so dont put long running processes in it
|
||||
* so don't put long running processes in it
|
||||
* @param runnable the runnable to run when no tasks are remaining
|
||||
*/
|
||||
public static void waitUntilDone(final Runnable runnable) {
|
||||
@ -101,7 +97,7 @@ public class ProgressKeeper {
|
||||
addTaskCountListener(listener);
|
||||
}
|
||||
|
||||
public static int getTaskCount() {
|
||||
public static synchronized int getTaskCount() {
|
||||
return sProgressStates.size();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user