content: /**
   * This file is part of Aion-Lightning <aion-lightning.org>.
   *
   *  Aion-Lightning 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.
   *
   *  Aion-Lightning 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 Aion-Lightning.
   *  If not, see <http://www.gnu.org/licenses/>.
   */
  package com.aionemu.gameserver.taskmanager;
  
  import java.util.Set;
  
  import com.aionemu.commons.utils.concurrent.RunnableStatsManager;
  
  import javolution.util.FastSet;
  
  /**
   * @author NB4L1
   */
  public abstract class AbstractIterativePeriodicTaskManager<T> extends AbstractPeriodicTaskManager {
  
  	private final Set<T> startList = new FastSet<T>();
  	private final Set<T> stopList = new FastSet<T>();
  	private final FastSet<T> activeTasks = new FastSet<T>();
  
  	protected AbstractIterativePeriodicTaskManager(int period) {
  		super(period);
  	}
  
  	public boolean hasTask(T task) {
  		readLock();
  		try {
  			if (stopList.contains(task)) {
  				return false;
  			}
  
  			return activeTasks.contains(task) || startList.contains(task);
  		}
  		finally {
  			readUnlock();
  		}
  	}
  
  	public void startTask(T task) {
  		writeLock();
  		try {
  			startList.add(task);
  
  			stopList.remove(task);
  		}
  		finally {
  			writeUnlock();
  		}
  	}
  
  	public void stopTask(T task) {
  		writeLock();
  		try {
  			stopList.add(task);
  
  			startList.remove(task);
  		}
  		finally {
  			writeUnlock();
  		}
  	}
  
  	@Override
  	public final void run() {
  		writeLock();
  		try {
  			activeTasks.addAll(startList);
  			activeTasks.removeAll(stopList);
  
  			startList.clear();
  			stopList.clear();
  		}
  		finally {
  			writeUnlock();
  		}
  
  		for (FastSet.Record r = activeTasks.head(), end = activeTasks.tail(); (r = r.getNext()) != end;) {
  			final T task = activeTasks.valueOf(r);
  			final long begin = System.nanoTime();
  
  			try {
  				callTask(task);
  			}
  			catch (RuntimeException e) {
  				log.warn("", e);
  			}
  			finally {
  				RunnableStatsManager.handleStats(task.getClass(), getCalledMethodName(), System.nanoTime() - begin);
  			}
  		}
  	}
  
  	protected abstract void callTask(T task);
  
  	protected abstract String getCalledMethodName();
  }
  