Yes I'm sure this question exist, but I have tried the answers and I guess I need a custom answer..
Anyway as the title suggest I'm getting a java.util.ConcurrentModificationException.
All this is called in it's own thread.
How I run the events :
private void setUpMainGameTimer() {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
try{
TickEvent.call();
} catch (Exception e){
e.printStackTrace();
}
}
}, 0, gameSpeed);
}
My stack trace.
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at net.njar.rpg.Event.EventCaller.call(EventCaller.java:15)
at net.njar.rpg.Event.TickEvent.call(TickEvent.java:10)
at net.njay.rpg.Main.Main$1.run(Main.java:213)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
Here is my EventCaller class.
public class EventCaller<Type extends Event> {
@SuppressWarnings("unchecked")
public void call(ArrayList<Listener> listeners, Event e){
//Iterate through all of the listeners
for (Listener h : listeners){
//Iterate through each method
for (Method m : h.getClass().getMethods()){
//check if @EventHandler is present
if (m.isAnnotationPresent(EventHandler.class)){
//get params
for (Class<?> param : m.getParameterTypes()){
//check if parameter is the same type as the passed event
if (param.equals(e.getClass())) {
try {
m.invoke(h, (Type) e);
} catch(Exception e1){
e1.printStackTrace();
}
}
}
}
}
}
}
}
And tick event:
public class TickEvent extends Event{
private static long id = 0;
public static void call(){
id++;
TickEvent e = new TickEvent();
EventCaller<TickEvent> caller = new EventCaller<TickEvent>();
caller.call(Event.getListeners(), e);
}
public long getTickID(){
return TickEvent.id;
}
public static long getcurrentTickID(){
return id;
}
}
Event Class:
public class Event {
private static ArrayList<Listener> listeners = new ArrayList<Listener>();
public static void addListener(Listener listener){
listeners.add(listener);
}
public synchronized static ArrayList<Listener> getListeners(){
return Event.listeners;
}
}
Just let me know what else you need.
In EventCaller
Class check your public void call(ArrayList<Listener> listeners, Event e)
method.
Inside the for loop
for (Listener h : listeners){...}
h is getting modifier before the iteration is completed. Specifically check what does m.invoke(h, (Type) e);
call does. It should not modify h.