rendered paste bodypackage 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();
}
}
}
}