/* * Copyright (C) 2004-2015 L2J Server * * This file is part of L2J Server. * * L2J Server is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * L2J Server is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package com.l2jserver.gameserver.taskmanager; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import com.l2jserver.Config; import com.l2jserver.gameserver.model.actor.L2Attackable; import com.l2jserver.gameserver.model.actor.L2Character; import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate; /** * @author NosBit */ public final class DecayTaskManager { private final ScheduledExecutorService _decayExecutor = Executors.newSingleThreadScheduledExecutor(); protected final Map> _decayTasks = new ConcurrentHashMap<>(); /** * Adds a decay task for the specified character.
*
* If the decay task already exists it cancels it and re-adds it. * @param character the character */ public void add(L2Character character) { if (character == null) { return; } long delay; if (character.getTemplate() instanceof L2NpcTemplate) { delay = ((L2NpcTemplate) character.getTemplate()).getCorpseTime(); } else { delay = Config.DEFAULT_CORPSE_TIME; } if ((character instanceof L2Attackable) && (((L2Attackable) character).isSpoiled() || ((L2Attackable) character).isSeeded())) { delay += Config.SPOILED_CORPSE_EXTEND_TIME; } add(character, delay, TimeUnit.SECONDS); } /** * Adds a decay task for the specified character.
*
* If the decay task already exists it cancels it and re-adds it. * @param character the character * @param delay the delay * @param timeUnit the time unit of the delay parameter */ public void add(L2Character character, long delay, TimeUnit timeUnit) { ScheduledFuture decayTask = _decayExecutor.schedule(new DecayTask(character), delay, TimeUnit.SECONDS); decayTask = _decayTasks.put(character, decayTask); // if decay task already existed cancel it so we use the new time if (decayTask != null) { if (!decayTask.cancel(false)) { // old decay task was completed while canceling it remove and cancel the new one decayTask = _decayTasks.remove(character); if (decayTask != null) { decayTask.cancel(false); } } } } /** * Cancels the decay task of the specified character. * @param character the character */ public void cancel(L2Character character) { final ScheduledFuture decayTask = _decayTasks.remove(character); if (decayTask != null) { decayTask.cancel(false); } } /** * Gets the remaining time of the specified character's decay task. * @param character the character * @return if a decay task exists the remaining time, {@code Long.MAX_VALUE} otherwise */ public long getRemainingTime(L2Character character) { final ScheduledFuture decayTask = _decayTasks.get(character); if (decayTask != null) { return decayTask.getDelay(TimeUnit.MILLISECONDS); } return Long.MAX_VALUE; } private class DecayTask implements Runnable { private final L2Character _character; protected DecayTask(L2Character character) { _character = character; } @Override public void run() { _decayTasks.remove(_character); _character.onDecay(); } } @Override public String toString() { StringBuilder ret = new StringBuilder(); ret.append("============= DecayTask Manager Report ============"); ret.append(Config.EOL); ret.append("Tasks count: "); ret.append(_decayTasks.size()); ret.append(Config.EOL); ret.append("Tasks dump:"); ret.append(Config.EOL); for (Entry> entry : _decayTasks.entrySet()) { ret.append("Class/Name: "); ret.append(entry.getKey().getClass().getSimpleName()); ret.append('/'); ret.append(entry.getKey().getName()); ret.append(" decay timer: "); ret.append(entry.getValue().getDelay(TimeUnit.MILLISECONDS)); ret.append(Config.EOL); } return ret.toString(); } public static DecayTaskManager getInstance() { return SingletonHolder._instance; } private static class SingletonHolder { protected static final DecayTaskManager _instance = new DecayTaskManager(); } }