Timer improvements.
Contributed by Liamxroy.
This commit is contained in:
parent
5f6f504fde
commit
8b5f046d73
@ -16,8 +16,9 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
@ -29,29 +30,52 @@ import com.l2jmobius.gameserver.model.events.timers.TimerHolder;
|
||||
*/
|
||||
public class TimersManager
|
||||
{
|
||||
private final Map<Integer, Set<TimerHolder<?>>> _timers = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, List<TimerHolder<?>>> _timers = new ConcurrentHashMap<>();
|
||||
|
||||
public void registerTimer(TimerHolder<?> timer)
|
||||
{
|
||||
final L2Npc npc = timer.getNpc();
|
||||
if (npc != null)
|
||||
{
|
||||
_timers.computeIfAbsent(npc.getObjectId(), key -> ConcurrentHashMap.newKeySet()).add(timer);
|
||||
final List<TimerHolder<?>> npcTimers = _timers.computeIfAbsent(npc.getObjectId(), key -> new ArrayList<>());
|
||||
synchronized (npcTimers)
|
||||
{
|
||||
npcTimers.add(timer);
|
||||
}
|
||||
}
|
||||
|
||||
final L2PcInstance player = timer.getPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
_timers.computeIfAbsent(player.getObjectId(), key -> ConcurrentHashMap.newKeySet()).add(timer);
|
||||
final List<TimerHolder<?>> playerTimers = _timers.computeIfAbsent(player.getObjectId(), key -> new ArrayList<>());
|
||||
synchronized (playerTimers)
|
||||
{
|
||||
playerTimers.add(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelTimers(int objectId)
|
||||
{
|
||||
final Set<TimerHolder<?>> timers = _timers.remove(objectId);
|
||||
final List<TimerHolder<?>> timers = _timers.remove(objectId);
|
||||
if (timers != null)
|
||||
{
|
||||
timers.forEach(TimerHolder::cancelTimer);
|
||||
synchronized (timers)
|
||||
{
|
||||
timers.forEach(TimerHolder::cancelTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterTimer(int objectId, TimerHolder<?> timer)
|
||||
{
|
||||
final List<TimerHolder<?>> timers = _timers.get(objectId);
|
||||
if (timers != null)
|
||||
{
|
||||
synchronized (timers)
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,13 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.model.events;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
@ -52,13 +55,7 @@ public final class TimerExecutor<T>
|
||||
public boolean addTimer(TimerHolder<T> holder)
|
||||
{
|
||||
final Set<TimerHolder<T>> timers = _timers.computeIfAbsent(holder.getEvent(), key -> ConcurrentHashMap.newKeySet());
|
||||
for (TimerHolder<T> timer : timers)
|
||||
{
|
||||
if (timer.equals(holder))
|
||||
{
|
||||
timer.cancelTimer();
|
||||
}
|
||||
}
|
||||
removeAndCancelTimers(timers, holder::isEqual);
|
||||
return timers.add(holder);
|
||||
}
|
||||
|
||||
@ -174,7 +171,7 @@ public final class TimerExecutor<T>
|
||||
}
|
||||
|
||||
// Remove the timer
|
||||
timers.removeIf(holder::equals);
|
||||
removeAndCancelTimers(timers, holder::isEqual);
|
||||
|
||||
// If there's no events inside that set remove it
|
||||
if (timers.isEmpty())
|
||||
@ -265,16 +262,7 @@ public final class TimerExecutor<T>
|
||||
return false;
|
||||
}
|
||||
|
||||
final Iterator<TimerHolder<T>> holders = timers.iterator();
|
||||
while (holders.hasNext())
|
||||
{
|
||||
final TimerHolder<T> holder = holders.next();
|
||||
if (holder.isEqual(event, npc, player))
|
||||
{
|
||||
holders.remove();
|
||||
return holder.cancelTimer();
|
||||
}
|
||||
}
|
||||
removeAndCancelTimers(timers, timer -> timer.isEqual(event, npc, player));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -284,7 +272,38 @@ public final class TimerExecutor<T>
|
||||
*/
|
||||
public void cancelTimersOf(L2Npc npc)
|
||||
{
|
||||
_timers.values().forEach(timers -> timers.stream().filter(holder -> holder.getNpc() == npc).forEach(TimerHolder::cancelTimer));
|
||||
removeAndCancelTimers(timer -> timer.getNpc() == npc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes and Cancels all timers matching the condition
|
||||
* @param condition
|
||||
*/
|
||||
private void removeAndCancelTimers(Predicate<TimerHolder<T>> condition)
|
||||
{
|
||||
Objects.requireNonNull(condition);
|
||||
final Collection<Set<TimerHolder<T>>> allTimers = _timers.values();
|
||||
for (Set<TimerHolder<T>> timers : allTimers)
|
||||
{
|
||||
removeAndCancelTimers(timers, condition);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeAndCancelTimers(Set<TimerHolder<T>> timers, Predicate<TimerHolder<T>> condition)
|
||||
{
|
||||
Objects.requireNonNull(timers);
|
||||
Objects.requireNonNull(condition);
|
||||
|
||||
final Iterator<TimerHolder<T>> it = timers.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
final TimerHolder<T> timer = it.next();
|
||||
if (condition.test(timer))
|
||||
{
|
||||
it.remove();
|
||||
timer.cancelTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,6 +107,16 @@ public class TimerHolder<T> implements Runnable
|
||||
*/
|
||||
public boolean cancelTimer()
|
||||
{
|
||||
// Make sure to unregister this timer even if the task is already completed (TimerExecutor#onTimerPostExecute calls this method).
|
||||
if (_npc != null)
|
||||
{
|
||||
TimersManager.getInstance().unregisterTimer(_npc.getObjectId(), this);
|
||||
}
|
||||
if (_player != null)
|
||||
{
|
||||
TimersManager.getInstance().unregisterTimer(_player.getObjectId(), this);
|
||||
}
|
||||
|
||||
if (_task.isCancelled() || _task.isDone())
|
||||
{
|
||||
return false;
|
||||
@ -145,6 +155,15 @@ public class TimerHolder<T> implements Runnable
|
||||
return _event.equals(event) && (_npc == npc) && (_player == player);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timer the other timer to be compared with.
|
||||
* @return {@code true} of both of timers' npc, event and player match, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isEqual(TimerHolder<T> timer)
|
||||
{
|
||||
return _event.equals(timer._event) && (_npc == timer._npc) && (_player == timer._player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
@ -155,24 +174,6 @@ public class TimerHolder<T> implements Runnable
|
||||
_eventScript.onTimerEvent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof TimerHolder))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final TimerHolder<T> holder = (TimerHolder<T>) obj;
|
||||
return isEqual(holder._event, holder._npc, holder._player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
@ -16,8 +16,9 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
@ -29,29 +30,52 @@ import com.l2jmobius.gameserver.model.events.timers.TimerHolder;
|
||||
*/
|
||||
public class TimersManager
|
||||
{
|
||||
private final Map<Integer, Set<TimerHolder<?>>> _timers = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, List<TimerHolder<?>>> _timers = new ConcurrentHashMap<>();
|
||||
|
||||
public void registerTimer(TimerHolder<?> timer)
|
||||
{
|
||||
final L2Npc npc = timer.getNpc();
|
||||
if (npc != null)
|
||||
{
|
||||
_timers.computeIfAbsent(npc.getObjectId(), key -> ConcurrentHashMap.newKeySet()).add(timer);
|
||||
final List<TimerHolder<?>> npcTimers = _timers.computeIfAbsent(npc.getObjectId(), key -> new ArrayList<>());
|
||||
synchronized (npcTimers)
|
||||
{
|
||||
npcTimers.add(timer);
|
||||
}
|
||||
}
|
||||
|
||||
final L2PcInstance player = timer.getPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
_timers.computeIfAbsent(player.getObjectId(), key -> ConcurrentHashMap.newKeySet()).add(timer);
|
||||
final List<TimerHolder<?>> playerTimers = _timers.computeIfAbsent(player.getObjectId(), key -> new ArrayList<>());
|
||||
synchronized (playerTimers)
|
||||
{
|
||||
playerTimers.add(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelTimers(int objectId)
|
||||
{
|
||||
final Set<TimerHolder<?>> timers = _timers.remove(objectId);
|
||||
final List<TimerHolder<?>> timers = _timers.remove(objectId);
|
||||
if (timers != null)
|
||||
{
|
||||
timers.forEach(TimerHolder::cancelTimer);
|
||||
synchronized (timers)
|
||||
{
|
||||
timers.forEach(TimerHolder::cancelTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterTimer(int objectId, TimerHolder<?> timer)
|
||||
{
|
||||
final List<TimerHolder<?>> timers = _timers.get(objectId);
|
||||
if (timers != null)
|
||||
{
|
||||
synchronized (timers)
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,13 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.model.events;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
@ -52,13 +55,7 @@ public final class TimerExecutor<T>
|
||||
public boolean addTimer(TimerHolder<T> holder)
|
||||
{
|
||||
final Set<TimerHolder<T>> timers = _timers.computeIfAbsent(holder.getEvent(), key -> ConcurrentHashMap.newKeySet());
|
||||
for (TimerHolder<T> timer : timers)
|
||||
{
|
||||
if (timer.equals(holder))
|
||||
{
|
||||
timer.cancelTimer();
|
||||
}
|
||||
}
|
||||
removeAndCancelTimers(timers, holder::isEqual);
|
||||
return timers.add(holder);
|
||||
}
|
||||
|
||||
@ -174,7 +171,7 @@ public final class TimerExecutor<T>
|
||||
}
|
||||
|
||||
// Remove the timer
|
||||
timers.removeIf(holder::equals);
|
||||
removeAndCancelTimers(timers, holder::isEqual);
|
||||
|
||||
// If there's no events inside that set remove it
|
||||
if (timers.isEmpty())
|
||||
@ -265,16 +262,7 @@ public final class TimerExecutor<T>
|
||||
return false;
|
||||
}
|
||||
|
||||
final Iterator<TimerHolder<T>> holders = timers.iterator();
|
||||
while (holders.hasNext())
|
||||
{
|
||||
final TimerHolder<T> holder = holders.next();
|
||||
if (holder.isEqual(event, npc, player))
|
||||
{
|
||||
holders.remove();
|
||||
return holder.cancelTimer();
|
||||
}
|
||||
}
|
||||
removeAndCancelTimers(timers, timer -> timer.isEqual(event, npc, player));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -284,7 +272,38 @@ public final class TimerExecutor<T>
|
||||
*/
|
||||
public void cancelTimersOf(L2Npc npc)
|
||||
{
|
||||
_timers.values().forEach(timers -> timers.stream().filter(holder -> holder.getNpc() == npc).forEach(TimerHolder::cancelTimer));
|
||||
removeAndCancelTimers(timer -> timer.getNpc() == npc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes and Cancels all timers matching the condition
|
||||
* @param condition
|
||||
*/
|
||||
private void removeAndCancelTimers(Predicate<TimerHolder<T>> condition)
|
||||
{
|
||||
Objects.requireNonNull(condition);
|
||||
final Collection<Set<TimerHolder<T>>> allTimers = _timers.values();
|
||||
for (Set<TimerHolder<T>> timers : allTimers)
|
||||
{
|
||||
removeAndCancelTimers(timers, condition);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeAndCancelTimers(Set<TimerHolder<T>> timers, Predicate<TimerHolder<T>> condition)
|
||||
{
|
||||
Objects.requireNonNull(timers);
|
||||
Objects.requireNonNull(condition);
|
||||
|
||||
final Iterator<TimerHolder<T>> it = timers.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
final TimerHolder<T> timer = it.next();
|
||||
if (condition.test(timer))
|
||||
{
|
||||
it.remove();
|
||||
timer.cancelTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,6 +107,16 @@ public class TimerHolder<T> implements Runnable
|
||||
*/
|
||||
public boolean cancelTimer()
|
||||
{
|
||||
// Make sure to unregister this timer even if the task is already completed (TimerExecutor#onTimerPostExecute calls this method).
|
||||
if (_npc != null)
|
||||
{
|
||||
TimersManager.getInstance().unregisterTimer(_npc.getObjectId(), this);
|
||||
}
|
||||
if (_player != null)
|
||||
{
|
||||
TimersManager.getInstance().unregisterTimer(_player.getObjectId(), this);
|
||||
}
|
||||
|
||||
if (_task.isCancelled() || _task.isDone())
|
||||
{
|
||||
return false;
|
||||
@ -145,6 +155,15 @@ public class TimerHolder<T> implements Runnable
|
||||
return _event.equals(event) && (_npc == npc) && (_player == player);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timer the other timer to be compared with.
|
||||
* @return {@code true} of both of timers' npc, event and player match, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isEqual(TimerHolder<T> timer)
|
||||
{
|
||||
return _event.equals(timer._event) && (_npc == timer._npc) && (_player == timer._player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
@ -155,24 +174,6 @@ public class TimerHolder<T> implements Runnable
|
||||
_eventScript.onTimerEvent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof TimerHolder))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final TimerHolder<T> holder = (TimerHolder<T>) obj;
|
||||
return isEqual(holder._event, holder._npc, holder._player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
@ -16,8 +16,9 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
@ -29,29 +30,52 @@ import com.l2jmobius.gameserver.model.events.timers.TimerHolder;
|
||||
*/
|
||||
public class TimersManager
|
||||
{
|
||||
private final Map<Integer, Set<TimerHolder<?>>> _timers = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, List<TimerHolder<?>>> _timers = new ConcurrentHashMap<>();
|
||||
|
||||
public void registerTimer(TimerHolder<?> timer)
|
||||
{
|
||||
final L2Npc npc = timer.getNpc();
|
||||
if (npc != null)
|
||||
{
|
||||
_timers.computeIfAbsent(npc.getObjectId(), key -> ConcurrentHashMap.newKeySet()).add(timer);
|
||||
final List<TimerHolder<?>> npcTimers = _timers.computeIfAbsent(npc.getObjectId(), key -> new ArrayList<>());
|
||||
synchronized (npcTimers)
|
||||
{
|
||||
npcTimers.add(timer);
|
||||
}
|
||||
}
|
||||
|
||||
final L2PcInstance player = timer.getPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
_timers.computeIfAbsent(player.getObjectId(), key -> ConcurrentHashMap.newKeySet()).add(timer);
|
||||
final List<TimerHolder<?>> playerTimers = _timers.computeIfAbsent(player.getObjectId(), key -> new ArrayList<>());
|
||||
synchronized (playerTimers)
|
||||
{
|
||||
playerTimers.add(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelTimers(int objectId)
|
||||
{
|
||||
final Set<TimerHolder<?>> timers = _timers.remove(objectId);
|
||||
final List<TimerHolder<?>> timers = _timers.remove(objectId);
|
||||
if (timers != null)
|
||||
{
|
||||
timers.forEach(TimerHolder::cancelTimer);
|
||||
synchronized (timers)
|
||||
{
|
||||
timers.forEach(TimerHolder::cancelTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterTimer(int objectId, TimerHolder<?> timer)
|
||||
{
|
||||
final List<TimerHolder<?>> timers = _timers.get(objectId);
|
||||
if (timers != null)
|
||||
{
|
||||
synchronized (timers)
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,13 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.model.events;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
@ -52,13 +55,7 @@ public final class TimerExecutor<T>
|
||||
public boolean addTimer(TimerHolder<T> holder)
|
||||
{
|
||||
final Set<TimerHolder<T>> timers = _timers.computeIfAbsent(holder.getEvent(), key -> ConcurrentHashMap.newKeySet());
|
||||
for (TimerHolder<T> timer : timers)
|
||||
{
|
||||
if (timer.equals(holder))
|
||||
{
|
||||
timer.cancelTimer();
|
||||
}
|
||||
}
|
||||
removeAndCancelTimers(timers, holder::isEqual);
|
||||
return timers.add(holder);
|
||||
}
|
||||
|
||||
@ -174,7 +171,7 @@ public final class TimerExecutor<T>
|
||||
}
|
||||
|
||||
// Remove the timer
|
||||
timers.removeIf(holder::equals);
|
||||
removeAndCancelTimers(timers, holder::isEqual);
|
||||
|
||||
// If there's no events inside that set remove it
|
||||
if (timers.isEmpty())
|
||||
@ -265,16 +262,7 @@ public final class TimerExecutor<T>
|
||||
return false;
|
||||
}
|
||||
|
||||
final Iterator<TimerHolder<T>> holders = timers.iterator();
|
||||
while (holders.hasNext())
|
||||
{
|
||||
final TimerHolder<T> holder = holders.next();
|
||||
if (holder.isEqual(event, npc, player))
|
||||
{
|
||||
holders.remove();
|
||||
return holder.cancelTimer();
|
||||
}
|
||||
}
|
||||
removeAndCancelTimers(timers, timer -> timer.isEqual(event, npc, player));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -284,7 +272,38 @@ public final class TimerExecutor<T>
|
||||
*/
|
||||
public void cancelTimersOf(L2Npc npc)
|
||||
{
|
||||
_timers.values().forEach(timers -> timers.stream().filter(holder -> holder.getNpc() == npc).forEach(TimerHolder::cancelTimer));
|
||||
removeAndCancelTimers(timer -> timer.getNpc() == npc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes and Cancels all timers matching the condition
|
||||
* @param condition
|
||||
*/
|
||||
private void removeAndCancelTimers(Predicate<TimerHolder<T>> condition)
|
||||
{
|
||||
Objects.requireNonNull(condition);
|
||||
final Collection<Set<TimerHolder<T>>> allTimers = _timers.values();
|
||||
for (Set<TimerHolder<T>> timers : allTimers)
|
||||
{
|
||||
removeAndCancelTimers(timers, condition);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeAndCancelTimers(Set<TimerHolder<T>> timers, Predicate<TimerHolder<T>> condition)
|
||||
{
|
||||
Objects.requireNonNull(timers);
|
||||
Objects.requireNonNull(condition);
|
||||
|
||||
final Iterator<TimerHolder<T>> it = timers.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
final TimerHolder<T> timer = it.next();
|
||||
if (condition.test(timer))
|
||||
{
|
||||
it.remove();
|
||||
timer.cancelTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,6 +107,16 @@ public class TimerHolder<T> implements Runnable
|
||||
*/
|
||||
public boolean cancelTimer()
|
||||
{
|
||||
// Make sure to unregister this timer even if the task is already completed (TimerExecutor#onTimerPostExecute calls this method).
|
||||
if (_npc != null)
|
||||
{
|
||||
TimersManager.getInstance().unregisterTimer(_npc.getObjectId(), this);
|
||||
}
|
||||
if (_player != null)
|
||||
{
|
||||
TimersManager.getInstance().unregisterTimer(_player.getObjectId(), this);
|
||||
}
|
||||
|
||||
if (_task.isCancelled() || _task.isDone())
|
||||
{
|
||||
return false;
|
||||
@ -145,6 +155,15 @@ public class TimerHolder<T> implements Runnable
|
||||
return _event.equals(event) && (_npc == npc) && (_player == player);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timer the other timer to be compared with.
|
||||
* @return {@code true} of both of timers' npc, event and player match, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isEqual(TimerHolder<T> timer)
|
||||
{
|
||||
return _event.equals(timer._event) && (_npc == timer._npc) && (_player == timer._player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
@ -155,24 +174,6 @@ public class TimerHolder<T> implements Runnable
|
||||
_eventScript.onTimerEvent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof TimerHolder))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final TimerHolder<T> holder = (TimerHolder<T>) obj;
|
||||
return isEqual(holder._event, holder._npc, holder._player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
@ -16,8 +16,9 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
@ -29,29 +30,52 @@ import com.l2jmobius.gameserver.model.events.timers.TimerHolder;
|
||||
*/
|
||||
public class TimersManager
|
||||
{
|
||||
private final Map<Integer, Set<TimerHolder<?>>> _timers = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, List<TimerHolder<?>>> _timers = new ConcurrentHashMap<>();
|
||||
|
||||
public void registerTimer(TimerHolder<?> timer)
|
||||
{
|
||||
final L2Npc npc = timer.getNpc();
|
||||
if (npc != null)
|
||||
{
|
||||
_timers.computeIfAbsent(npc.getObjectId(), key -> ConcurrentHashMap.newKeySet()).add(timer);
|
||||
final List<TimerHolder<?>> npcTimers = _timers.computeIfAbsent(npc.getObjectId(), key -> new ArrayList<>());
|
||||
synchronized (npcTimers)
|
||||
{
|
||||
npcTimers.add(timer);
|
||||
}
|
||||
}
|
||||
|
||||
final L2PcInstance player = timer.getPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
_timers.computeIfAbsent(player.getObjectId(), key -> ConcurrentHashMap.newKeySet()).add(timer);
|
||||
final List<TimerHolder<?>> playerTimers = _timers.computeIfAbsent(player.getObjectId(), key -> new ArrayList<>());
|
||||
synchronized (playerTimers)
|
||||
{
|
||||
playerTimers.add(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelTimers(int objectId)
|
||||
{
|
||||
final Set<TimerHolder<?>> timers = _timers.remove(objectId);
|
||||
final List<TimerHolder<?>> timers = _timers.remove(objectId);
|
||||
if (timers != null)
|
||||
{
|
||||
timers.forEach(TimerHolder::cancelTimer);
|
||||
synchronized (timers)
|
||||
{
|
||||
timers.forEach(TimerHolder::cancelTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterTimer(int objectId, TimerHolder<?> timer)
|
||||
{
|
||||
final List<TimerHolder<?>> timers = _timers.get(objectId);
|
||||
if (timers != null)
|
||||
{
|
||||
synchronized (timers)
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,13 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.model.events;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
@ -52,13 +55,7 @@ public final class TimerExecutor<T>
|
||||
public boolean addTimer(TimerHolder<T> holder)
|
||||
{
|
||||
final Set<TimerHolder<T>> timers = _timers.computeIfAbsent(holder.getEvent(), key -> ConcurrentHashMap.newKeySet());
|
||||
for (TimerHolder<T> timer : timers)
|
||||
{
|
||||
if (timer.equals(holder))
|
||||
{
|
||||
timer.cancelTimer();
|
||||
}
|
||||
}
|
||||
removeAndCancelTimers(timers, holder::isEqual);
|
||||
return timers.add(holder);
|
||||
}
|
||||
|
||||
@ -174,7 +171,7 @@ public final class TimerExecutor<T>
|
||||
}
|
||||
|
||||
// Remove the timer
|
||||
timers.removeIf(holder::equals);
|
||||
removeAndCancelTimers(timers, holder::isEqual);
|
||||
|
||||
// If there's no events inside that set remove it
|
||||
if (timers.isEmpty())
|
||||
@ -265,16 +262,7 @@ public final class TimerExecutor<T>
|
||||
return false;
|
||||
}
|
||||
|
||||
final Iterator<TimerHolder<T>> holders = timers.iterator();
|
||||
while (holders.hasNext())
|
||||
{
|
||||
final TimerHolder<T> holder = holders.next();
|
||||
if (holder.isEqual(event, npc, player))
|
||||
{
|
||||
holders.remove();
|
||||
return holder.cancelTimer();
|
||||
}
|
||||
}
|
||||
removeAndCancelTimers(timers, timer -> timer.isEqual(event, npc, player));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -284,7 +272,38 @@ public final class TimerExecutor<T>
|
||||
*/
|
||||
public void cancelTimersOf(L2Npc npc)
|
||||
{
|
||||
_timers.values().forEach(timers -> timers.stream().filter(holder -> holder.getNpc() == npc).forEach(TimerHolder::cancelTimer));
|
||||
removeAndCancelTimers(timer -> timer.getNpc() == npc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes and Cancels all timers matching the condition
|
||||
* @param condition
|
||||
*/
|
||||
private void removeAndCancelTimers(Predicate<TimerHolder<T>> condition)
|
||||
{
|
||||
Objects.requireNonNull(condition);
|
||||
final Collection<Set<TimerHolder<T>>> allTimers = _timers.values();
|
||||
for (Set<TimerHolder<T>> timers : allTimers)
|
||||
{
|
||||
removeAndCancelTimers(timers, condition);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeAndCancelTimers(Set<TimerHolder<T>> timers, Predicate<TimerHolder<T>> condition)
|
||||
{
|
||||
Objects.requireNonNull(timers);
|
||||
Objects.requireNonNull(condition);
|
||||
|
||||
final Iterator<TimerHolder<T>> it = timers.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
final TimerHolder<T> timer = it.next();
|
||||
if (condition.test(timer))
|
||||
{
|
||||
it.remove();
|
||||
timer.cancelTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,6 +107,16 @@ public class TimerHolder<T> implements Runnable
|
||||
*/
|
||||
public boolean cancelTimer()
|
||||
{
|
||||
// Make sure to unregister this timer even if the task is already completed (TimerExecutor#onTimerPostExecute calls this method).
|
||||
if (_npc != null)
|
||||
{
|
||||
TimersManager.getInstance().unregisterTimer(_npc.getObjectId(), this);
|
||||
}
|
||||
if (_player != null)
|
||||
{
|
||||
TimersManager.getInstance().unregisterTimer(_player.getObjectId(), this);
|
||||
}
|
||||
|
||||
if (_task.isCancelled() || _task.isDone())
|
||||
{
|
||||
return false;
|
||||
@ -145,6 +155,15 @@ public class TimerHolder<T> implements Runnable
|
||||
return _event.equals(event) && (_npc == npc) && (_player == player);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timer the other timer to be compared with.
|
||||
* @return {@code true} of both of timers' npc, event and player match, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isEqual(TimerHolder<T> timer)
|
||||
{
|
||||
return _event.equals(timer._event) && (_npc == timer._npc) && (_player == timer._player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
@ -155,24 +174,6 @@ public class TimerHolder<T> implements Runnable
|
||||
_eventScript.onTimerEvent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof TimerHolder))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final TimerHolder<T> holder = (TimerHolder<T>) obj;
|
||||
return isEqual(holder._event, holder._npc, holder._player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
@ -16,8 +16,9 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
@ -29,29 +30,52 @@ import com.l2jmobius.gameserver.model.events.timers.TimerHolder;
|
||||
*/
|
||||
public class TimersManager
|
||||
{
|
||||
private final Map<Integer, Set<TimerHolder<?>>> _timers = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, List<TimerHolder<?>>> _timers = new ConcurrentHashMap<>();
|
||||
|
||||
public void registerTimer(TimerHolder<?> timer)
|
||||
{
|
||||
final L2Npc npc = timer.getNpc();
|
||||
if (npc != null)
|
||||
{
|
||||
_timers.computeIfAbsent(npc.getObjectId(), key -> ConcurrentHashMap.newKeySet()).add(timer);
|
||||
final List<TimerHolder<?>> npcTimers = _timers.computeIfAbsent(npc.getObjectId(), key -> new ArrayList<>());
|
||||
synchronized (npcTimers)
|
||||
{
|
||||
npcTimers.add(timer);
|
||||
}
|
||||
}
|
||||
|
||||
final L2PcInstance player = timer.getPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
_timers.computeIfAbsent(player.getObjectId(), key -> ConcurrentHashMap.newKeySet()).add(timer);
|
||||
final List<TimerHolder<?>> playerTimers = _timers.computeIfAbsent(player.getObjectId(), key -> new ArrayList<>());
|
||||
synchronized (playerTimers)
|
||||
{
|
||||
playerTimers.add(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelTimers(int objectId)
|
||||
{
|
||||
final Set<TimerHolder<?>> timers = _timers.remove(objectId);
|
||||
final List<TimerHolder<?>> timers = _timers.remove(objectId);
|
||||
if (timers != null)
|
||||
{
|
||||
timers.forEach(TimerHolder::cancelTimer);
|
||||
synchronized (timers)
|
||||
{
|
||||
timers.forEach(TimerHolder::cancelTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterTimer(int objectId, TimerHolder<?> timer)
|
||||
{
|
||||
final List<TimerHolder<?>> timers = _timers.get(objectId);
|
||||
if (timers != null)
|
||||
{
|
||||
synchronized (timers)
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,13 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.model.events;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
@ -52,13 +55,7 @@ public final class TimerExecutor<T>
|
||||
public boolean addTimer(TimerHolder<T> holder)
|
||||
{
|
||||
final Set<TimerHolder<T>> timers = _timers.computeIfAbsent(holder.getEvent(), key -> ConcurrentHashMap.newKeySet());
|
||||
for (TimerHolder<T> timer : timers)
|
||||
{
|
||||
if (timer.equals(holder))
|
||||
{
|
||||
timer.cancelTimer();
|
||||
}
|
||||
}
|
||||
removeAndCancelTimers(timers, holder::isEqual);
|
||||
return timers.add(holder);
|
||||
}
|
||||
|
||||
@ -174,7 +171,7 @@ public final class TimerExecutor<T>
|
||||
}
|
||||
|
||||
// Remove the timer
|
||||
timers.removeIf(holder::equals);
|
||||
removeAndCancelTimers(timers, holder::isEqual);
|
||||
|
||||
// If there's no events inside that set remove it
|
||||
if (timers.isEmpty())
|
||||
@ -265,16 +262,7 @@ public final class TimerExecutor<T>
|
||||
return false;
|
||||
}
|
||||
|
||||
final Iterator<TimerHolder<T>> holders = timers.iterator();
|
||||
while (holders.hasNext())
|
||||
{
|
||||
final TimerHolder<T> holder = holders.next();
|
||||
if (holder.isEqual(event, npc, player))
|
||||
{
|
||||
holders.remove();
|
||||
return holder.cancelTimer();
|
||||
}
|
||||
}
|
||||
removeAndCancelTimers(timers, timer -> timer.isEqual(event, npc, player));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -284,7 +272,38 @@ public final class TimerExecutor<T>
|
||||
*/
|
||||
public void cancelTimersOf(L2Npc npc)
|
||||
{
|
||||
_timers.values().forEach(timers -> timers.stream().filter(holder -> holder.getNpc() == npc).forEach(TimerHolder::cancelTimer));
|
||||
removeAndCancelTimers(timer -> timer.getNpc() == npc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes and Cancels all timers matching the condition
|
||||
* @param condition
|
||||
*/
|
||||
private void removeAndCancelTimers(Predicate<TimerHolder<T>> condition)
|
||||
{
|
||||
Objects.requireNonNull(condition);
|
||||
final Collection<Set<TimerHolder<T>>> allTimers = _timers.values();
|
||||
for (Set<TimerHolder<T>> timers : allTimers)
|
||||
{
|
||||
removeAndCancelTimers(timers, condition);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeAndCancelTimers(Set<TimerHolder<T>> timers, Predicate<TimerHolder<T>> condition)
|
||||
{
|
||||
Objects.requireNonNull(timers);
|
||||
Objects.requireNonNull(condition);
|
||||
|
||||
final Iterator<TimerHolder<T>> it = timers.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
final TimerHolder<T> timer = it.next();
|
||||
if (condition.test(timer))
|
||||
{
|
||||
it.remove();
|
||||
timer.cancelTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,6 +107,16 @@ public class TimerHolder<T> implements Runnable
|
||||
*/
|
||||
public boolean cancelTimer()
|
||||
{
|
||||
// Make sure to unregister this timer even if the task is already completed (TimerExecutor#onTimerPostExecute calls this method).
|
||||
if (_npc != null)
|
||||
{
|
||||
TimersManager.getInstance().unregisterTimer(_npc.getObjectId(), this);
|
||||
}
|
||||
if (_player != null)
|
||||
{
|
||||
TimersManager.getInstance().unregisterTimer(_player.getObjectId(), this);
|
||||
}
|
||||
|
||||
if (_task.isCancelled() || _task.isDone())
|
||||
{
|
||||
return false;
|
||||
@ -145,6 +155,15 @@ public class TimerHolder<T> implements Runnable
|
||||
return _event.equals(event) && (_npc == npc) && (_player == player);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timer the other timer to be compared with.
|
||||
* @return {@code true} of both of timers' npc, event and player match, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isEqual(TimerHolder<T> timer)
|
||||
{
|
||||
return _event.equals(timer._event) && (_npc == timer._npc) && (_player == timer._player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
@ -155,24 +174,6 @@ public class TimerHolder<T> implements Runnable
|
||||
_eventScript.onTimerEvent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof TimerHolder))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final TimerHolder<T> holder = (TimerHolder<T>) obj;
|
||||
return isEqual(holder._event, holder._npc, holder._player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
@ -16,8 +16,9 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
@ -29,29 +30,52 @@ import com.l2jmobius.gameserver.model.events.timers.TimerHolder;
|
||||
*/
|
||||
public class TimersManager
|
||||
{
|
||||
private final Map<Integer, Set<TimerHolder<?>>> _timers = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, List<TimerHolder<?>>> _timers = new ConcurrentHashMap<>();
|
||||
|
||||
public void registerTimer(TimerHolder<?> timer)
|
||||
{
|
||||
final L2Npc npc = timer.getNpc();
|
||||
if (npc != null)
|
||||
{
|
||||
_timers.computeIfAbsent(npc.getObjectId(), key -> ConcurrentHashMap.newKeySet()).add(timer);
|
||||
final List<TimerHolder<?>> npcTimers = _timers.computeIfAbsent(npc.getObjectId(), key -> new ArrayList<>());
|
||||
synchronized (npcTimers)
|
||||
{
|
||||
npcTimers.add(timer);
|
||||
}
|
||||
}
|
||||
|
||||
final L2PcInstance player = timer.getPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
_timers.computeIfAbsent(player.getObjectId(), key -> ConcurrentHashMap.newKeySet()).add(timer);
|
||||
final List<TimerHolder<?>> playerTimers = _timers.computeIfAbsent(player.getObjectId(), key -> new ArrayList<>());
|
||||
synchronized (playerTimers)
|
||||
{
|
||||
playerTimers.add(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelTimers(int objectId)
|
||||
{
|
||||
final Set<TimerHolder<?>> timers = _timers.remove(objectId);
|
||||
final List<TimerHolder<?>> timers = _timers.remove(objectId);
|
||||
if (timers != null)
|
||||
{
|
||||
timers.forEach(TimerHolder::cancelTimer);
|
||||
synchronized (timers)
|
||||
{
|
||||
timers.forEach(TimerHolder::cancelTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterTimer(int objectId, TimerHolder<?> timer)
|
||||
{
|
||||
final List<TimerHolder<?>> timers = _timers.get(objectId);
|
||||
if (timers != null)
|
||||
{
|
||||
synchronized (timers)
|
||||
{
|
||||
timers.remove(timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,13 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.model.events;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
@ -52,13 +55,7 @@ public final class TimerExecutor<T>
|
||||
public boolean addTimer(TimerHolder<T> holder)
|
||||
{
|
||||
final Set<TimerHolder<T>> timers = _timers.computeIfAbsent(holder.getEvent(), key -> ConcurrentHashMap.newKeySet());
|
||||
for (TimerHolder<T> timer : timers)
|
||||
{
|
||||
if (timer.equals(holder))
|
||||
{
|
||||
timer.cancelTimer();
|
||||
}
|
||||
}
|
||||
removeAndCancelTimers(timers, holder::isEqual);
|
||||
return timers.add(holder);
|
||||
}
|
||||
|
||||
@ -174,7 +171,7 @@ public final class TimerExecutor<T>
|
||||
}
|
||||
|
||||
// Remove the timer
|
||||
timers.removeIf(holder::equals);
|
||||
removeAndCancelTimers(timers, holder::isEqual);
|
||||
|
||||
// If there's no events inside that set remove it
|
||||
if (timers.isEmpty())
|
||||
@ -265,16 +262,7 @@ public final class TimerExecutor<T>
|
||||
return false;
|
||||
}
|
||||
|
||||
final Iterator<TimerHolder<T>> holders = timers.iterator();
|
||||
while (holders.hasNext())
|
||||
{
|
||||
final TimerHolder<T> holder = holders.next();
|
||||
if (holder.isEqual(event, npc, player))
|
||||
{
|
||||
holders.remove();
|
||||
return holder.cancelTimer();
|
||||
}
|
||||
}
|
||||
removeAndCancelTimers(timers, timer -> timer.isEqual(event, npc, player));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -284,7 +272,38 @@ public final class TimerExecutor<T>
|
||||
*/
|
||||
public void cancelTimersOf(L2Npc npc)
|
||||
{
|
||||
_timers.values().forEach(timers -> timers.stream().filter(holder -> holder.getNpc() == npc).forEach(TimerHolder::cancelTimer));
|
||||
removeAndCancelTimers(timer -> timer.getNpc() == npc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes and Cancels all timers matching the condition
|
||||
* @param condition
|
||||
*/
|
||||
private void removeAndCancelTimers(Predicate<TimerHolder<T>> condition)
|
||||
{
|
||||
Objects.requireNonNull(condition);
|
||||
final Collection<Set<TimerHolder<T>>> allTimers = _timers.values();
|
||||
for (Set<TimerHolder<T>> timers : allTimers)
|
||||
{
|
||||
removeAndCancelTimers(timers, condition);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeAndCancelTimers(Set<TimerHolder<T>> timers, Predicate<TimerHolder<T>> condition)
|
||||
{
|
||||
Objects.requireNonNull(timers);
|
||||
Objects.requireNonNull(condition);
|
||||
|
||||
final Iterator<TimerHolder<T>> it = timers.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
final TimerHolder<T> timer = it.next();
|
||||
if (condition.test(timer))
|
||||
{
|
||||
it.remove();
|
||||
timer.cancelTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,6 +107,16 @@ public class TimerHolder<T> implements Runnable
|
||||
*/
|
||||
public boolean cancelTimer()
|
||||
{
|
||||
// Make sure to unregister this timer even if the task is already completed (TimerExecutor#onTimerPostExecute calls this method).
|
||||
if (_npc != null)
|
||||
{
|
||||
TimersManager.getInstance().unregisterTimer(_npc.getObjectId(), this);
|
||||
}
|
||||
if (_player != null)
|
||||
{
|
||||
TimersManager.getInstance().unregisterTimer(_player.getObjectId(), this);
|
||||
}
|
||||
|
||||
if (_task.isCancelled() || _task.isDone())
|
||||
{
|
||||
return false;
|
||||
@ -145,6 +155,15 @@ public class TimerHolder<T> implements Runnable
|
||||
return _event.equals(event) && (_npc == npc) && (_player == player);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timer the other timer to be compared with.
|
||||
* @return {@code true} of both of timers' npc, event and player match, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isEqual(TimerHolder<T> timer)
|
||||
{
|
||||
return _event.equals(timer._event) && (_npc == timer._npc) && (_player == timer._player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
@ -155,24 +174,6 @@ public class TimerHolder<T> implements Runnable
|
||||
_eventScript.onTimerEvent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof TimerHolder))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final TimerHolder<T> holder = (TimerHolder<T>) obj;
|
||||
return isEqual(holder._event, holder._npc, holder._player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user