Package lineage2.gameserver.taskmanager

Source Code of lineage2.gameserver.taskmanager.SpawnTaskManager$SpawnScheduler

/*
* This program 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.
*
* This program 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 <http://www.gnu.org/licenses/>.
*/
package lineage2.gameserver.taskmanager;

import java.util.ArrayList;
import java.util.List;

import lineage2.commons.lang.reference.HardReference;
import lineage2.commons.threading.RunnableImpl;
import lineage2.gameserver.ThreadPoolManager;
import lineage2.gameserver.model.Spawner;
import lineage2.gameserver.model.instances.NpcInstance;
import lineage2.gameserver.utils.Util;

/**
* @author Mobius
* @version $Revision: 1.0 $
*/
public class SpawnTaskManager
{
  /**
   * Field _spawnTasks.
   */
  SpawnTask[] _spawnTasks = new SpawnTask[500];
  /**
   * Field _spawnTasksSize.
   */
  int _spawnTasksSize = 0;
  /**
   * Field spawnTasks_lock.
   */
  final Object spawnTasks_lock = new Object();
  /**
   * Field _instance.
   */
  private static SpawnTaskManager _instance;
 
  /**
   * Constructor for SpawnTaskManager.
   */
  public SpawnTaskManager()
  {
    ThreadPoolManager.getInstance().scheduleAtFixedRate(new SpawnScheduler(), 2000, 2000);
  }
 
  /**
   * Method getInstance.
   * @return SpawnTaskManager
   */
  public static SpawnTaskManager getInstance()
  {
    if (_instance == null)
    {
      _instance = new SpawnTaskManager();
    }
    return _instance;
  }
 
  /**
   * Method addSpawnTask.
   * @param actor NpcInstance
   * @param interval long
   */
  public void addSpawnTask(NpcInstance actor, long interval)
  {
    removeObject(actor);
    addObject(new SpawnTask(actor, System.currentTimeMillis() + interval));
  }
 
  /**
   * @author Mobius
   */
  public class SpawnScheduler extends RunnableImpl
  {
    /**
     * Method runImpl.
     */
    @Override
    public void runImpl()
    {
      if (_spawnTasksSize > 0)
      {
        try
        {
          List<NpcInstance> works = new ArrayList<>();
          synchronized (spawnTasks_lock)
          {
            long current = System.currentTimeMillis();
            int size = _spawnTasksSize;
            for (int i = size - 1; i >= 0; i--)
            {
              try
              {
                SpawnTask container = _spawnTasks[i];
                if ((container != null) && (container.endtime > 0) && (current > container.endtime))
                {
                  NpcInstance actor = container.getActor();
                  if ((actor != null) && (actor.getSpawn() != null))
                  {
                    works.add(actor);
                  }
                  container.endtime = -1;
                }
                if ((container == null) || (container.getActor() == null) || (container.endtime < 0))
                {
                  if (i == (_spawnTasksSize - 1))
                  {
                    _spawnTasks[i] = null;
                  }
                  else
                  {
                    _spawnTasks[i] = _spawnTasks[_spawnTasksSize - 1];
                    _spawnTasks[_spawnTasksSize - 1] = null;
                  }
                  if (_spawnTasksSize > 0)
                  {
                    _spawnTasksSize--;
                  }
                }
              }
              catch (Exception e)
              {
                _log.error("", e);
              }
            }
          }
          for (NpcInstance work : works)
          {
            Spawner spawn = work.getSpawn();
            if (spawn == null)
            {
              continue;
            }
            spawn.decreaseScheduledCount();
            if (spawn.isDoRespawn())
            {
              spawn.respawnNpc(work);
            }
          }
        }
        catch (Exception e)
        {
          _log.error("", e);
        }
      }
    }
  }
 
  /**
   * Method toString.
   * @return String
   */
  @Override
  public String toString()
  {
    StringBuilder sb = new StringBuilder("============= SpawnTask Manager Report ============\n\r");
    sb.append("Tasks count: ").append(_spawnTasksSize).append("\n\r");
    sb.append("Tasks dump:\n\r");
    long current = System.currentTimeMillis();
    for (SpawnTask container : _spawnTasks)
    {
      sb.append("Class/Name: ").append(container.getClass().getSimpleName()).append('/').append(container.getActor());
      sb.append(" spawn timer: ").append(Util.formatTime((int) (container.endtime - current))).append("\n\r");
    }
    return sb.toString();
  }
 
  /**
   * @author Mobius
   */
  private class SpawnTask
  {
    /**
     * Field _npcRef.
     */
    private final HardReference<NpcInstance> _npcRef;
    /**
     * Field endtime.
     */
    public long endtime;
   
    /**
     * Constructor for SpawnTask.
     * @param cha NpcInstance
     * @param delay long
     */
    SpawnTask(NpcInstance cha, long delay)
    {
      _npcRef = cha.getRef();
      endtime = delay;
    }
   
    /**
     * Method getActor.
     * @return NpcInstance
     */
    public NpcInstance getActor()
    {
      return _npcRef.get();
    }
  }
 
  /**
   * Method addObject.
   * @param decay SpawnTask
   */
  private void addObject(SpawnTask decay)
  {
    synchronized (spawnTasks_lock)
    {
      if (_spawnTasksSize >= _spawnTasks.length)
      {
        SpawnTask[] temp = new SpawnTask[_spawnTasks.length * 2];
        System.arraycopy(_spawnTasks, 0, temp, 0, _spawnTasksSize);
        _spawnTasks = temp;
      }
      _spawnTasks[_spawnTasksSize] = decay;
      _spawnTasksSize++;
    }
  }
 
  /**
   * Method removeObject.
   * @param actor NpcInstance
   */
  public void removeObject(NpcInstance actor)
  {
    synchronized (spawnTasks_lock)
    {
      if (_spawnTasksSize > 1)
      {
        int k = -1;
        for (int i = 0; i < _spawnTasksSize; i++)
        {
          if (_spawnTasks[i].getActor() == actor)
          {
            k = i;
          }
        }
        if (k > -1)
        {
          _spawnTasks[k] = _spawnTasks[_spawnTasksSize - 1];
          _spawnTasks[_spawnTasksSize - 1] = null;
          _spawnTasksSize--;
        }
      }
      else if ((_spawnTasksSize == 1) && (_spawnTasks[0].getActor() == actor))
      {
        _spawnTasks[0] = null;
        _spawnTasksSize = 0;
      }
    }
  }
}
TOP

Related Classes of lineage2.gameserver.taskmanager.SpawnTaskManager$SpawnScheduler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.