mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-17 08:35:37 -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;
|
package net.kdt.pojavlaunch.progresskeeper;
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
|
|
||||||
public class ProgressKeeper {
|
public class ProgressKeeper {
|
||||||
private static final ConcurrentHashMap<String, ConcurrentLinkedQueue<ProgressListener>> sProgressListeners = new ConcurrentHashMap<>();
|
private static final HashMap<String, List<ProgressListener>> sProgressListeners = new HashMap<>();
|
||||||
private static final ConcurrentHashMap<String, ProgressState> sProgressStates = new ConcurrentHashMap<>();
|
private static final HashMap<String, ProgressState> sProgressStates = new HashMap<>();
|
||||||
private static final List<TaskCountListener> sTaskCountListeners = Collections.synchronizedList(new ArrayList<>());
|
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);
|
ProgressState progressState = sProgressStates.get(progressRecord);
|
||||||
boolean shouldCallStarted = progressState == null;
|
boolean shouldCallStarted = progressState == null;
|
||||||
boolean shouldCallEnded = resid == -1 && progress == -1;
|
boolean shouldCallEnded = resid == -1 && progress == -1;
|
||||||
@ -31,7 +27,7 @@ public class ProgressKeeper {
|
|||||||
progressState.varArg = va;
|
progressState.varArg = va;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConcurrentLinkedQueue<ProgressListener> progressListeners = sProgressListeners.get(progressRecord);
|
List<ProgressListener> progressListeners = sProgressListeners.get(progressRecord);
|
||||||
if(progressListeners != null)
|
if(progressListeners != null)
|
||||||
for(ProgressListener listener : progressListeners) {
|
for(ProgressListener listener : progressListeners) {
|
||||||
if(shouldCallStarted) listener.onProgressStarted();
|
if(shouldCallStarted) listener.onProgressStarted();
|
||||||
@ -40,14 +36,14 @@ public class ProgressKeeper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void updateTaskCount() {
|
private static synchronized void updateTaskCount() {
|
||||||
int count = sProgressStates.size();
|
int count = sProgressStates.size();
|
||||||
for(TaskCountListener listener : sTaskCountListeners) {
|
for(TaskCountListener listener : sTaskCountListeners) {
|
||||||
listener.onUpdateTaskCount(count);
|
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);
|
ProgressState state = sProgressStates.get(progressRecord);
|
||||||
if(state != null && (state.resid != -1 || state.progress != -1)) {
|
if(state != null && (state.resid != -1 || state.progress != -1)) {
|
||||||
listener.onProgressStarted();
|
listener.onProgressStarted();
|
||||||
@ -55,32 +51,32 @@ public class ProgressKeeper {
|
|||||||
}else{
|
}else{
|
||||||
listener.onProgressEnded();
|
listener.onProgressEnded();
|
||||||
}
|
}
|
||||||
ConcurrentLinkedQueue<ProgressListener> listenerWeakReferenceList = sProgressListeners.get(progressRecord);
|
List<ProgressListener> listenerWeakReferenceList = sProgressListeners.get(progressRecord);
|
||||||
if(listenerWeakReferenceList == null) sProgressListeners.put(progressRecord, (listenerWeakReferenceList = new ConcurrentLinkedQueue<>()));
|
if(listenerWeakReferenceList == null) sProgressListeners.put(progressRecord, (listenerWeakReferenceList = new ArrayList<>()));
|
||||||
listenerWeakReferenceList.add(listener);
|
listenerWeakReferenceList.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeListener(String progressRecord, ProgressListener listener) {
|
public static synchronized void removeListener(String progressRecord, ProgressListener listener) {
|
||||||
ConcurrentLinkedQueue<ProgressListener> listenerWeakReferenceList = sProgressListeners.get(progressRecord);
|
List<ProgressListener> listenerWeakReferenceList = sProgressListeners.get(progressRecord);
|
||||||
if(listenerWeakReferenceList != null) listenerWeakReferenceList.remove(listener);
|
if(listenerWeakReferenceList != null) listenerWeakReferenceList.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addTaskCountListener(TaskCountListener listener) {
|
public static synchronized void addTaskCountListener(TaskCountListener listener) {
|
||||||
listener.onUpdateTaskCount(sProgressStates.size());
|
listener.onUpdateTaskCount(sProgressStates.size());
|
||||||
if(!sTaskCountListeners.contains(listener)) sTaskCountListeners.add(listener);
|
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(runUpdate) listener.onUpdateTaskCount(sProgressStates.size());
|
||||||
if(!sTaskCountListeners.contains(listener)) sTaskCountListeners.add(listener);
|
if(!sTaskCountListeners.contains(listener)) sTaskCountListeners.add(listener);
|
||||||
}
|
}
|
||||||
public static void removeTaskCountListener(TaskCountListener listener) {
|
public static synchronized void removeTaskCountListener(TaskCountListener listener) {
|
||||||
sTaskCountListeners.remove(listener);
|
sTaskCountListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waits until all tasks are done and runs the runnable, or if there were no pending process remaining
|
* 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,
|
* 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
|
* @param runnable the runnable to run when no tasks are remaining
|
||||||
*/
|
*/
|
||||||
public static void waitUntilDone(final Runnable runnable) {
|
public static void waitUntilDone(final Runnable runnable) {
|
||||||
@ -101,7 +97,7 @@ public class ProgressKeeper {
|
|||||||
addTaskCountListener(listener);
|
addTaskCountListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getTaskCount() {
|
public static synchronized int getTaskCount() {
|
||||||
return sProgressStates.size();
|
return sProgressStates.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user