package com.gmail.zahusek.tinyprotocolapi.listener;
import org.bukkit.plugin.Plugin;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.*;
public class PacketHandlerList
{
private static ArrayList<PacketHandlerList> allLists = Lists.newArrayList();
private final EnumMap<PacketPriority, ArrayList<RegisteredPacket>> handlerslots = Maps.newEnumMap(PacketPriority.class);
private volatile RegisteredPacket[] handlers = null;
public PacketHandlerList ()
{
PacketPriority[] priority = PacketPriority.values();
for (int i = 0; i < priority.length; i++)
this.handlerslots.put(priority[i], new ArrayList<>());
synchronized (allLists)
{allLists.add(this);}
}
protected static void unregisterAll ()
{
synchronized (allLists)
{
for (PacketHandlerList handler : allLists)
{
synchronized (handler)
{
Collection<ArrayList<RegisteredPacket>> list = handler.handlerslots.values();
for (ArrayList<RegisteredPacket> packet : list)
packet.clear();
}
handler.handlers = null;
}
}
}
public static void unregisterAll (Plugin plugin)
{
synchronized (allLists)
{
for (PacketHandlerList packet : allLists)
packet.unregister(plugin);
}
}
public synchronized void register (RegisteredPacket listener)
{
if (handlerslots.get(listener.getPriority()).contains(listener))
return;
handlers = null;
handlerslots.get(listener.getPriority()).add(listener);
}
public void registerAll (Collection<RegisteredPacket> listeners)
{listeners.stream().forEach(this::register);}
public synchronized void unregister (Plugin plugin)
{
boolean changed = false;
for (List<RegisteredPacket> priority : handlerslots.values())
{
ListIterator<RegisteredPacket> i = priority.listIterator();
while (i.hasNext())
{
if (i.next().getPlugin().equals(plugin))
{
i.remove();
changed = true;
}
}
}
if (changed) this.handlers = null;
}
public RegisteredPacket[] getRegisteredPacketListeners ()
{
while (true)
{
RegisteredPacket[] handlers = this.handlers;
if (this.handlers != null) return handlers;
ArrayList<RegisteredPacket> entries = Lists.newArrayList();
this.handlerslots.entrySet().stream().forEach((map) -> entries.addAll(map.getValue()));
return this.handlers = entries.toArray(new RegisteredPacket[entries.size()]);
}
}
public static RegisteredPacket[] getAllRegisteredPacketListeners ()
{
int size = allLists.size();
RegisteredPacket[] listeners = new RegisteredPacket[size];
synchronized (allLists)
{
int i = 0;
for (PacketHandlerList handler : allLists)
for(RegisteredPacket packet : handler.getRegisteredPacketListeners())
listeners[i++] = packet;
}
return listeners;
}
}