All pastes #2075020 Raw Edit

Untitled

public text v1 · immutable
#2075020 ·published 2011-06-05 11:38 UTC
rendered paste body
package com.l2dc.gameserver.taskmanager;

import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.Stack;
import java.util.concurrent.ScheduledFuture;

import javolution.util.ReentrantLock;

import com.l2dc.gameserver.ThreadPoolManager;
import com.l2dc.gameserver.skills.structure.SkillOverTimeHolder;
import com.l2dc.util.GArray;

public class EffectTaskManager
{
	protected EffectContainer[] _dispelTasks = new EffectContainer[172800];
	protected Stack<EffectContainer> _pool = new Stack<EffectContainer>();
	protected ReentrantLock lock = new ReentrantLock();
	protected int _currentDispelCell = 0;
	@SuppressWarnings("unused")
	private ScheduledFuture<?> _task;

	private static EffectTaskManager _instance;

	private EffectTaskManager()
	{
		_task = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new DispelScheduler(), 1000, 1000);
	}

	public static EffectTaskManager getInstance()
	{
		return _instance != null ? _instance : (_instance = new EffectTaskManager());
	}

	/**
	 * in seconds!
	 */
	public EffectContainer addDispelTask(SkillOverTimeHolder e, int interval)
	{
		try
		{
			lock.lock();

			if (interval < 1)
				interval = 1;
			if (interval > _dispelTasks.length / 2)
			{
				System.out.println("ERROR: Effect " + e.getSkill().getName() + " I " + interval);
				interval = _dispelTasks.length - 1;
			}
			int cell = _currentDispelCell + interval;
			if (_dispelTasks.length <= cell)
				cell -= _dispelTasks.length;
			if (_dispelTasks[cell] == null)
				if (!_pool.isEmpty())
					_dispelTasks[cell] = _pool.pop();
				else
					_dispelTasks[cell] = new EffectContainer();
			_dispelTasks[cell].addEffect(e);

			return _dispelTasks[cell];
		}
		finally
		{
			lock.unlock();
		}
	}

	private class DispelScheduler implements Runnable
	{
		public DispelScheduler()
		{
		}

		@Override
		public void run()
		{
			GArray<SkillOverTimeHolder> works = new GArray<SkillOverTimeHolder>();

			lock.lock();
			try
			{
				if (_dispelTasks[_currentDispelCell] != null && !_dispelTasks[_currentDispelCell].getList().isEmpty())
					for (WeakReference<SkillOverTimeHolder> we : _dispelTasks[_currentDispelCell].getList())
						try
						{
							SkillOverTimeHolder eff = we.get();
							if (eff == null /* || eff.isFinished() */)
								continue;

							works.add(eff);

							// TODO checkA
							if (true/* !eff.isEnded() */)
								addDispelTask(eff, (int)(eff.getPeriod() / 1000));
						}
						catch (Exception e)
						{
							e.printStackTrace();
						}
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			finally
			{
				if (_dispelTasks[_currentDispelCell] != null)
				{
					_dispelTasks[_currentDispelCell].clear();
					_pool.push(_dispelTasks[_currentDispelCell]);
					_dispelTasks[_currentDispelCell] = null;
				}
				_currentDispelCell++;
				if (_currentDispelCell >= _dispelTasks.length)
					_currentDispelCell = 0;

				lock.unlock();
			}

			for (SkillOverTimeHolder work : works)
				try
				{
					work.scheduleEffect();
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
		}
	}

	private class EffectContainer
	{
		private LinkedList<WeakReference<SkillOverTimeHolder>> list = new LinkedList<WeakReference<SkillOverTimeHolder>>();

		public EffectContainer()
		{
		}

		public void addEffect(SkillOverTimeHolder e)
		{
			list.add(new WeakReference<SkillOverTimeHolder>(e));
		}

		public LinkedList<WeakReference<SkillOverTimeHolder>> getList()
		{
			return list;
		}

		public void clear()
		{
			synchronized (list)
			{
				list.clear();
			}
		}
	}
}