List related rework and cleanup.

This commit is contained in:
MobiusDevelopment
2021-12-06 19:00:16 +00:00
parent b5c2af483e
commit b0c1084bf1
194 changed files with 1957 additions and 10665 deletions

View File

@ -19,6 +19,7 @@ package org.l2jmobius.gameserver.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -414,15 +415,14 @@ public class World
final WorldRegion[] surroundingRegions = oldRegion.getSurroundingRegions();
for (int i = 0; i < surroundingRegions.length; i++)
{
final List<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
for (int j = 0; j < visibleObjects.size(); j++)
final Collection<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
if (visibleObjects.isEmpty())
{
continue;
}
for (WorldObject wo : visibleObjects)
{
final WorldObject wo = visibleObjects.get(j);
if (wo == null)
{
continue;
}
// Remove the WorldObject from the WorldObjectHashSet(WorldObject) _knownObjects of the surrounding WorldRegion Creatures
// If object is a Player, remove the WorldObject from the WorldObjectHashSet(Player) _knownPlayer of the surrounding WorldRegion Creatures
// If object is targeted by one of the surrounding WorldRegion Creatures, cancel ATTACK and cast
@ -488,21 +488,20 @@ public class World
}
// Create a list in order to contain all visible WorldObject
final List<WorldObject> result = new ArrayList<>();
final List<WorldObject> result = new LinkedList<>();
// Go through the list of region
final WorldRegion[] surroundingRegions = region.getSurroundingRegions();
for (int i = 0; i < surroundingRegions.length; i++)
{
final List<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
for (int j = 0; j < visibleObjects.size(); j++)
final Collection<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
if (visibleObjects.isEmpty())
{
continue;
}
for (WorldObject wo : visibleObjects)
{
final WorldObject wo = visibleObjects.get(j);
if (wo == null)
{
continue;
}
if (wo.equals(object))
{
continue; // skip our own character
@ -554,22 +553,21 @@ public class World
final int sqRadius = radius * radius;
// Create a list in order to contain all visible WorldObject
final List<WorldObject> result = new ArrayList<>();
final List<WorldObject> result = new LinkedList<>();
// Go through the list of region
final WorldRegion[] surroundingRegions = region.getSurroundingRegions();
for (int i = 0; i < surroundingRegions.length; i++)
{
// Go through visible objects of the selected region
final List<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
for (int j = 0; j < visibleObjects.size(); j++)
final Collection<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
if (visibleObjects.isEmpty())
{
continue;
}
for (WorldObject wo : visibleObjects)
{
final WorldObject wo = visibleObjects.get(j);
if (wo == null)
{
continue;
}
if (wo.equals(object))
{
continue; // skip our own character
@ -619,21 +617,20 @@ public class World
final int sqRadius = radius * radius;
// Create a list in order to contain all visible WorldObject
final List<WorldObject> result = new ArrayList<>();
final List<WorldObject> result = new LinkedList<>();
// Go through visible object of the selected region
final WorldRegion[] surroundingRegions = object.getWorldRegion().getSurroundingRegions();
for (int i = 0; i < surroundingRegions.length; i++)
{
final List<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
for (int j = 0; j < visibleObjects.size(); j++)
final Collection<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
if (visibleObjects.isEmpty())
{
continue;
}
for (WorldObject wo : visibleObjects)
{
final WorldObject wo = visibleObjects.get(j);
if (wo == null)
{
continue;
}
if (wo.equals(object))
{
continue; // skip our own character

View File

@ -17,8 +17,11 @@
package org.l2jmobius.gameserver.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
@ -39,19 +42,18 @@ import org.l2jmobius.gameserver.model.zone.ZoneManager;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.model.zone.type.PeaceZone;
import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager;
import org.l2jmobius.gameserver.util.UnboundArrayList;
public class WorldRegion
{
private static final Logger LOGGER = Logger.getLogger(WorldRegion.class.getName());
private final UnboundArrayList<WorldObject> _visibleObjects = new UnboundArrayList<>();
private final Set<WorldObject> _visibleObjects = ConcurrentHashMap.newKeySet();
private final List<Door> _doors = new ArrayList<>(1);
private final List<Fence> _fences = new ArrayList<>(1);
private WorldRegion[] _surroundingRegions;
private final int _regionX;
private final int _regionY;
private Boolean _active = Config.GRIDS_ALWAYS_ON;
private boolean _active = Config.GRIDS_ALWAYS_ON;
private ScheduledFuture<?> _neighborsTask = null;
private final AtomicInteger _activeNeighbors = new AtomicInteger();
private ZoneManager _zoneManager;
@ -125,18 +127,17 @@ public class WorldRegion
_zoneManager.onRevive(creature);
}
private void switchAI(Boolean isOn)
private void switchAI(boolean isOn)
{
if (_visibleObjects.isEmpty())
{
return;
}
if (!isOn)
{
for (int i = 0; i < _visibleObjects.size(); i++)
for (WorldObject wo : _visibleObjects)
{
final WorldObject wo = _visibleObjects.get(i);
if (wo == null)
{
continue;
}
if (wo instanceof Attackable)
{
final Attackable mob = (Attackable) wo;
@ -182,14 +183,8 @@ public class WorldRegion
}
else
{
for (int i = 0; i < _visibleObjects.size(); i++)
for (WorldObject wo : _visibleObjects)
{
final WorldObject wo = _visibleObjects.get(i);
if (wo == null)
{
continue;
}
if (wo instanceof Attackable)
{
// Start HP/MP/CP Regeneration task
@ -231,17 +226,22 @@ public class WorldRegion
final WorldRegion worldRegion = _surroundingRegions[i];
if (worldRegion.isActive())
{
final List<WorldObject> regionObjects = worldRegion.getVisibleObjects();
for (int j = 0; j < regionObjects.size(); j++)
final Collection<WorldObject> regionObjects = worldRegion.getVisibleObjects();
if (regionObjects.isEmpty())
{
final WorldObject wo = regionObjects.get(j);
if ((wo != null) && wo.isPlayable())
continue;
}
for (WorldObject wo : regionObjects)
{
if (wo.isPlayable())
{
return false;
}
}
}
}
return true;
}
@ -347,7 +347,7 @@ public class WorldRegion
return;
}
_visibleObjects.addIfAbsent(object);
_visibleObjects.add(object);
if (object.isDoor())
{
@ -410,7 +410,7 @@ public class WorldRegion
}
}
public List<WorldObject> getVisibleObjects()
public Collection<WorldObject> getVisibleObjects()
{
return _visibleObjects;
}
@ -478,14 +478,8 @@ public class WorldRegion
public synchronized void deleteVisibleNpcSpawns()
{
LOGGER.info("Deleting all visible NPCs in Region: " + getName());
for (int i = 0; i < _visibleObjects.size(); i++)
for (WorldObject wo : _visibleObjects)
{
final WorldObject wo = _visibleObjects.get(i);
if (wo == null)
{
continue;
}
if (wo instanceof Npc)
{
final Npc target = (Npc) wo;

View File

@ -16,8 +16,8 @@
*/
package org.l2jmobius.gameserver.model.itemcontainer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import org.l2jmobius.gameserver.model.actor.Player;
@ -81,7 +81,7 @@ public class PlayerFreight extends ItemContainer
@Override
public Collection<Item> getItems()
{
final List<Item> result = new ArrayList<>();
final List<Item> result = new LinkedList<>();
for (Item item : _items)
{
if ((item.getEquipSlot() == 0) || (item.getEquipSlot() == _activeLocationId))

View File

@ -19,18 +19,18 @@ package org.l2jmobius.gameserver.model.itemcontainer;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.l2jmobius.commons.database.DatabaseFactory;
import org.l2jmobius.gameserver.model.TradeList;
import org.l2jmobius.gameserver.model.TradeList.TradeItem;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.item.ItemTemplate;
import org.l2jmobius.gameserver.model.item.instance.Item;
import org.l2jmobius.gameserver.model.item.instance.Item.ItemLocation;
import org.l2jmobius.gameserver.model.item.type.EtcItemType;
import org.l2jmobius.gameserver.model.WorldObject;
public class PlayerInventory extends Inventory
{
@ -99,7 +99,7 @@ public class PlayerInventory extends Inventory
public List<Item> getUniqueItems(boolean allowAdena, boolean allowAncientAdena, boolean onlyAvailable, boolean allowEquipped)
{
final List<Item> list = new ArrayList<>();
final List<Item> list = new LinkedList<>();
for (Item item : _items)
{
if (!allowAdena && (item.getItemId() == 57))
@ -143,7 +143,7 @@ public class PlayerInventory extends Inventory
public List<Item> getUniqueItemsByEnchantLevel(boolean allowAdena, boolean allowAncientAdena, boolean onlyAvailable, boolean allowEquipped)
{
final List<Item> list = new ArrayList<>();
final List<Item> list = new LinkedList<>();
for (Item item : _items)
{
if (!allowAdena && (item.getItemId() == 57))
@ -181,7 +181,7 @@ public class PlayerInventory extends Inventory
*/
public List<Item> getAllItemsByItemId(int itemId)
{
final List<Item> list = new ArrayList<>();
final List<Item> list = new LinkedList<>();
for (Item item : _items)
{
if (item.getItemId() == itemId)
@ -200,7 +200,7 @@ public class PlayerInventory extends Inventory
*/
public List<Item> getAllItemsByItemId(int itemId, int enchantment)
{
final List<Item> list = new ArrayList<>();
final List<Item> list = new LinkedList<>();
for (Item item : _items)
{
if ((item.getItemId() == itemId) && (item.getEnchantLevel() == enchantment))
@ -218,7 +218,7 @@ public class PlayerInventory extends Inventory
*/
public List<Item> getAvailableItems(boolean allowAdena)
{
final List<Item> list = new ArrayList<>();
final List<Item> list = new LinkedList<>();
for (Item item : _items)
{
if ((item != null) && item.isAvailable(_owner, allowAdena, false))
@ -235,7 +235,7 @@ public class PlayerInventory extends Inventory
*/
public List<Item> getAugmentedItems()
{
final List<Item> list = new ArrayList<>();
final List<Item> list = new LinkedList<>();
for (Item item : _items)
{
if ((item != null) && item.isAugmented())
@ -253,7 +253,7 @@ public class PlayerInventory extends Inventory
*/
public List<TradeItem> getAvailableItems(TradeList tradeList)
{
final List<TradeItem> list = new ArrayList<>();
final List<TradeItem> list = new LinkedList<>();
for (Item item : _items)
{
if (item.isAvailable(_owner, false, false))

View File

@ -17,9 +17,11 @@
package org.l2jmobius.gameserver.taskmanager;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Logger;
@ -28,7 +30,6 @@ import org.l2jmobius.commons.util.Chronos;
import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.instancemanager.DayNightSpawnManager;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.util.UnboundArrayList;
/**
* Game Time task manager class.
@ -45,7 +46,7 @@ public class GameTimeTaskManager
protected static long _gameStartTime;
protected static boolean _isNight = false;
private static final UnboundArrayList<Creature> _movingObjects = new UnboundArrayList<>();
private static final Set<Creature> _movingObjects = ConcurrentHashMap.newKeySet();
protected static TimerThread _timer;
private final ScheduledFuture<?> _timerWatcher;
@ -102,7 +103,7 @@ public class GameTimeTaskManager
return;
}
_movingObjects.addIfAbsent(creature);
_movingObjects.add(creature);
}
/**
@ -119,30 +120,20 @@ public class GameTimeTaskManager
*/
protected void moveObjects()
{
List<Creature> finished = null;
for (int i = 0; i < _movingObjects.size(); i++)
final List<Creature> finished = new LinkedList<>();
for (Creature creature : _movingObjects)
{
final Creature creature = _movingObjects.get(i);
if (creature == null)
{
continue;
}
if (creature.updatePosition(_gameTicks))
{
if (finished == null)
{
finished = new ArrayList<>();
}
finished.add(creature);
}
}
if (finished != null)
if (!finished.isEmpty())
{
for (int i = 0; i < finished.size(); i++)
for (Creature creature : finished)
{
_movingObjects.remove(finished.get(i));
_movingObjects.remove(creature);
}
ThreadPool.execute(new MovingObjectArrived(finished));
}

View File

@ -1,336 +0,0 @@
/*
* Copyright (c) 2020 Pantelis Andrianakis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.l2jmobius.gameserver.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Consumer;
/**
* Unbound and synchronized implementation of the {@code ArrayList} class.<br>
* In addition to implementing the {@code ArrayList} class,<br>
* this class provides synchronization on adding and removing elements.<br>
* Further more, get() does not throw IndexOutOfBoundsException, a {@code null} element is returned instead.<br>
* An equivalent Iterator constructor is introduced under the same logic.
* @param <E> the type of elements in this list
* @version September 4th 2020
* @author Pantelis Andrianakis
*/
public class UnboundArrayList<E>extends ArrayList<E>
{
/**
* Returns the element at the specified position in this list.
* @param index index of the element to return
* @return the element at the specified position in this list,<br>
* or {@code null} if this list does not have this specified position.
*/
@Override
public E get(int index)
{
E element = null;
try
{
// The try performance impact itself is insignificant.
// Benchmark test on an i7-2600 machine with a list of 100.000.000 random elements.
// get: Execution time was 116 milliseconds.
// get with try: Execution time was 124 milliseconds.
element = super.get(index);
}
catch (Exception e)
{
// Continue with execution.
// This impacts performance only if the Exception is created.
// Benchmark test on an i7-2600 machine resulted with a 187 millisecond total delay,
// in a list of 10.000 elements, with IndexOutOfBoundsException thrown on 5.000 of them.
}
return element;
}
/**
* Replaces the element at the specified position in this list with the specified element.
* @param index index of the element to replace
* @param element element to be stored at the specified position
* @return the element previously at the specified position,<br>
* or {@code null} if this list does not have this specified position.
*/
@Override
public E set(int index, E element)
{
synchronized (this)
{
if ((index >= 0) && (index < size()))
{
return super.set(index, element);
}
return null;
}
}
/**
* Appends the specified element to the end of this list.
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
@Override
public boolean add(E e)
{
synchronized (this)
{
return super.add(e);
}
}
/**
* Inserts the specified element at the specified position in this list. Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices).
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
*/
@Override
public void add(int index, E element)
{
synchronized (this)
{
if ((index >= 0) && (index < size()))
{
super.add(index, element);
}
else
{
super.add(element);
}
}
}
/**
* Appends the specified element to the end of this list if this list does not contain the specified element.
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean addIfAbsent(E e)
{
synchronized (this)
{
if (!contains(e))
{
return super.add(e);
}
return false;
}
}
/**
* Removes the first occurrence of the specified element from this list, if it is present. If the list does not contain the element, it is unchanged. More formally, removes the element with the lowest index {@code i} such that {@code Objects.equals(o, get(i))} (if such an element exists).
* Returns {@code true} if this list contained the specified element (or equivalently, if this list changed as a result of the call).
* @param o element to be removed from this list, if present
* @return {@code true} if this list contained the specified element
*/
@Override
public boolean remove(Object o)
{
synchronized (this)
{
return super.remove(o);
}
}
/**
* Removes the element at the specified position in this list. Shifts any subsequent elements to the left (subtracts one from their indices).
* @param index the index of the element to be removed
* @return the element that was removed from the list,<br>
* or {@code null} if this list does not have this specified position.
*/
@Override
public E remove(int index)
{
synchronized (this)
{
if ((index >= 0) && (index < size()))
{
return super.remove(index);
}
return null;
}
}
/**
* Removes all of the elements from this list.<br>
* The list will be empty after this call returns.
*/
@Override
public void clear()
{
synchronized (this)
{
super.clear();
}
}
/**
* Appends all of the elements in the specified collection to the end of this list, in the order that they are returned by the specified collection's Iterator. The behavior of this operation is undefined if the specified collection is modified while the operation is in progress. (This implies
* that the behavior of this call is undefined if the specified collection is this list, and this list is nonempty.)
* @param c collection containing elements to be added to this list
* @return {@code true} if this list changed as a result of the call
* @throws NullPointerException if the specified collection is null
*/
@Override
public boolean addAll(Collection<? extends E> c)
{
synchronized (this)
{
return super.addAll(c);
}
}
/**
* Inserts all of the elements in the specified collection into this list, starting at the specified position. Shifts the element currently at that position (if any) and any subsequent elements to the right (increases their indices). The new elements will appear in the list in the order that
* they are returned by the specified collection's iterator.
* @param index index at which to insert the first element from the specified collection
* @param c collection containing elements to be added to this list
* @return {@code true} if this list changed as a result of the call
* @throws NullPointerException if the specified collection is null
*/
@Override
public boolean addAll(int index, Collection<? extends E> c)
{
synchronized (this)
{
if ((index >= 0) && (index < size()))
{
return super.addAll(index, c);
}
return super.addAll(c);
}
}
/**
* Removes from this list all of the elements whose index is between {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. Shifts any succeeding elements to the left (reduces their index). This call shortens the list by {@code (toIndex - fromIndex)} elements.
*/
@Override
protected void removeRange(int fromIndex, int toIndex)
{
synchronized (this)
{
if (fromIndex > size())
{
return;
}
super.removeRange(fromIndex < 0 ? 0 : fromIndex, size() < toIndex ? size() - 1 : toIndex);
}
}
/**
* Removes from this list all of its elements that are contained in the specified collection.
* @param c collection containing elements to be removed from this list
* @return {@code true} if this list changed as a result of the call
* @throws ClassCastException if the class of an element of this list is incompatible with the specified collection (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if this list contains a null element and the specified collection does not permit null elements (<a href="Collection.html#optional-restrictions">optional</a>), or if the specified collection is null
* @see Collection#contains(Object)
*/
@Override
public boolean removeAll(Collection<?> c)
{
synchronized (this)
{
return super.removeAll(c);
}
}
/**
* Retains only the elements in this list that are contained in the specified collection. In other words, removes from this list all of its elements that are not contained in the specified collection.
* @param c collection containing elements to be retained in this list
* @return {@code true} if this list changed as a result of the call
* @throws ClassCastException if the class of an element of this list is incompatible with the specified collection (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException if this list contains a null element and the specified collection does not permit null elements (<a href="Collection.html#optional-restrictions">optional</a>), or if the specified collection is null
* @see Collection#contains(Object)
*/
@Override
public boolean retainAll(Collection<?> c)
{
synchronized (this)
{
return super.retainAll(c);
}
}
/**
* Returns an iterator over the elements in this list in proper sequence.
* @return an iterator over the elements in this list in proper sequence.<br>
* Non existing elements are returned as null.
*/
@Override
public Iterator<E> iterator()
{
return new Itr();
}
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E>
{
private int _cursor = 0; // index of next element to return
// prevent creating a synthetic constructor
Itr()
{
}
@Override
public boolean hasNext()
{
return _cursor < size();
}
@Override
public E next()
{
return get(_cursor++);
}
@Override
public void remove()
{
UnboundArrayList.this.remove(get(_cursor - 1));
}
@Override
public void forEachRemaining(Consumer<? super E> action)
{
if (action == null)
{
return;
}
for (int i = _cursor; i < size(); i++)
{
final E next = get(i);
if (next != null)
{
action.accept(next);
}
_cursor++;
}
}
}
}