partial Listener Registry progress

This commit is contained in:
BuildTools 2017-03-17 00:01:55 -04:00
parent f61093c29d
commit 6a1c51e417
9 changed files with 470 additions and 189 deletions

View file

@ -162,8 +162,7 @@ public class BitRegionUtil
* @param blocks
* @return
*/
public static int compareRegion(int minX1, int minZ1,
int maxX1, int maxZ1,
public static int compareRegion(int minX1, int minZ1, int maxX1, int maxZ1,
int maxX2, int maxZ2,
BitSet blocks
)
@ -370,8 +369,7 @@ public class BitRegionUtil
* @param blocks
* @return
*/
public static int compareRegion(int minX1, int minZ1, int minY1,
int maxX1, int maxZ1, int maxY1,
public static int compareRegion(int minX1, int minZ1, int minY1, int maxX1, int maxZ1, int maxY1,
int maxX2, int maxZ2, int maxY2,
BitSet blocks
)

View file

@ -1,6 +1,17 @@
package regions;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_11_R1.CraftServer;
import net.minecraft.server.v1_11_R1.WorldNBTStorage;
import net.minecraft.server.v1_11_R1.NBTTagCompound;
import net.minecraft.server.v1_11_R1.NBTTagDouble;
import net.minecraft.server.v1_11_R1.NBTTagList;
public abstract class Directory
{
@ -16,4 +27,74 @@ public abstract class Directory
this.children = children;
this.trees = trees;
}
/**
*
* @param coords
* @return
*/
public boolean testFor(int... coords)
{
for (Tree tree : trees)
if (tree.testFor(coords))
return true;
for (Directory child : children)
if (child.testFor(coords))
return true;
return false;
}
/*
MINECRAFT CONVENIENCE METHODS
*/
public static final WorldNBTStorage storage =
(WorldNBTStorage) ((CraftServer) Bukkit.getServer())
.getServer()
.worlds.get(0)
.getDataManager();
/**
* {@link #testFor() TestFor()} the block position described in the player's .dat file under "Pos."
* Returns false for new players, and for players without stored position values.
*
* @param uuid the player's UUID string
* @return whether or not any trees contain the player's position
*/
public boolean testForOfflinePlayer(UUID uuid)
{
NBTTagCompound nbt = storage.getPlayerData(uuid.toString());
if (nbt == null)
return false;
NBTTagList pos = nbt.getList("Pos", 6);
if (pos.size() != 3)
return false;
return testFor((int) ((NBTTagDouble) pos.h(0)).asDouble(),
(int) ((NBTTagDouble) pos.h(2)).asDouble(),
(int) ((NBTTagDouble) pos.h(1)).asDouble()
);
}
/**
* {@link #testFor() TestFor()} the coordinates of the given Location
*
* @param location the location to evaluate
* @return whether or not any trees contain this location
*/
public boolean testForLocation(Location location)
{
return testFor(location.getBlockX(), location.getBlockZ(), location.getBlockY());
}
}

View file

@ -0,0 +1,279 @@
package regions;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedList;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockEvent;
import org.bukkit.event.entity.EntityEvent;
import org.bukkit.event.hanging.HangingEvent;
import org.bukkit.event.inventory.InventoryEvent;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
/**
* TODO
*/
public abstract class ListenerProxy<T extends Event> implements Listener
{
/**
* Convenience class grouping a proxied Listener with its event-handling Method for easy invocation.
*/
public static class Proxy
{
public final Listener listener;
public final Method method;
public Proxy(Listener listener, Method method)
{
this.listener = listener;
this.method = method;
}
}
/*----------------------------------------------------------------------------
------------------------------------------------------------------------------
CONSTRUCTORS
------------------------------------------------------------------------------
----------------------------------------------------------------------------*/
protected final Class<?> type;
protected final Directory directory;
protected final LinkedList<Proxy> lowest = new LinkedList<Proxy>(),
low = new LinkedList<Proxy>(),
normal = new LinkedList<Proxy>(),
high = new LinkedList<Proxy>(),
highest = new LinkedList<Proxy>(),
monitor = new LinkedList<Proxy>();
public ListenerProxy(Class<?> type, Directory directory)
{
this.type = type;
this.directory = directory;
}
/*----------------------------------------------------------------------------
------------------------------------------------------------------------------
REGISTER LISTENERS
------------------------------------------------------------------------------
----------------------------------------------------------------------------*/
/**
* Register a Listener in the same way that Spigot registers listeners, except that ListenerProxy
* will only {@link #broadcastEvent(Event) broadcast} events occurring inside the specified region
* Directory. Events are broadcast by invoking the EventHandlers of each proxied Listener, in order
* of lowest to highest EventPriority (MONITOR being the highest).
*
* @param listener the Listener to register
* @see {@link #broadcastEvent(Event)}
*/
public void registerListener(Listener listener)
{
for (Method method : listener.getClass().getDeclaredMethods())
{
if (method.getParameterCount() == 1 &&
method.getParameterTypes()[0].equals(type) &&
method.isAnnotationPresent(EventHandler.class))
{
switch (method.getAnnotation(EventHandler.class).priority())
{
case LOWEST : lowest .add(new Proxy(listener, method)); break;
case LOW : low .add(new Proxy(listener, method)); break;
case NORMAL : normal .add(new Proxy(listener, method)); break;
case HIGH : high .add(new Proxy(listener, method)); break;
case HIGHEST : highest .add(new Proxy(listener, method)); break;
case MONITOR : monitor .add(new Proxy(listener, method)); break;
}
}
}
}
/*----------------------------------------------------------------------------
------------------------------------------------------------------------------
EVENT HANDLING
------------------------------------------------------------------------------
----------------------------------------------------------------------------*/
/**
* Extracts a coordinate position from an event, evaluates {@link #Directory.testFor()} for that
* position, and, if true, invokes {@link #broadcastEvent(Event)}. Implemented differently for
* various event types.
*
* @param event the event to evaluate
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
@EventHandler(priority = EventPriority.LOWEST)
public abstract void listen(T event) throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException;
/**
* Invoke event-handling methods of all proxied Listeners for this event, in order of lowest to
* highest EventPriority (with MONITOR being the highest).
*
* @param event the parameter to pass
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public void broadcastEvent(T event) throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
{
for (Proxy alias : lowest ) alias.method.invoke(alias.listener, alias.method);
for (Proxy alias : low ) alias.method.invoke(alias.listener, alias.method);
for (Proxy alias : normal ) alias.method.invoke(alias.listener, alias.method);
for (Proxy alias : high ) alias.method.invoke(alias.listener, alias.method);
for (Proxy alias : highest) alias.method.invoke(alias.listener, alias.method);
for (Proxy alias : monitor) alias.method.invoke(alias.listener, alias.method);
}
/*
EVENT SUBCLASS IMPLEMENTATIONS
*/
/**
* TODO
*
* @param <T> extends AsyncPlayerPreLoginEvent
*/
public static class For_AsyncPlayerPreLoginEvent<T extends AsyncPlayerPreLoginEvent> extends ListenerProxy<T>
{
public For_AsyncPlayerPreLoginEvent(Class<?> type, Directory directory){ super(type, directory); }
/**
* TODO
*
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
@Override
public void listen(T event) throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
{
if (directory.testForOfflinePlayer(event.getUniqueId()))
broadcastEvent(event);
}
}
/**
* TODO
*
* @param <T> extends BlockEvent
*/
public static class For_BlockEvent<T extends BlockEvent> extends ListenerProxy<T>
{
public For_BlockEvent(Class<?> type, Directory directory){ super(type, directory); }
/**
* TODO
*
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
@Override
public void listen(T event) throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
{
Block block = event.getBlock();
if (directory.testFor(block.getX(), block.getZ(), block.getY()))
broadcastEvent(event);
}
}
/**
* TODO
*
* @param <T> extends EntityEvent
*/
public static class For_EntityEvent<T extends EntityEvent> extends ListenerProxy<T>
{
public For_EntityEvent(Class<?> type, Directory directory){ super(type, directory); }
/**
* TODO
*/
@Override
public void listen(T event)
{
if (directory.testForLocation(event.getEntity().getLocation()))
broadcastEvent(event);
}
}
/**
* TODO
*
* @param <T>
*/
public static class For_HangingEvent<T extends HangingEvent> extends ListenerProxy<T>
{
public For_HangingEvent(Class<?> type, Directory directory){ super(type, directory); }
/**
* TODO
*/
@Override
public void listen(T event)
{
}
}
/**
* TODO
*
* @param <T>
*/
public static class For_InventoryEvent<T extends InventoryEvent> extends ListenerProxy<T>
{
public For_InventoryEvent(Class<?> type, Directory directory){ super(type, directory); }
/**
* TODO
*/
@Override
public void listen(T event)
{
}
}
// InventoryMoveItemEvent,
// InventoryPickupItemEvent,
// PlayerEvent,
// PlayerLeashEntityEvent,
// PlayerPreLoginEvent,
// ServerEvent,
// TabCompleteEvent,
// VehicleEvent,
// WeatherEvent,
// WorldEvent
}

View file

@ -4,5 +4,12 @@ import org.bukkit.plugin.java.JavaPlugin;
public class Main extends JavaPlugin
{
public void onEnable()
{
getServer().getPluginManager().registerEvents(listener, this);
}
HashMap<Event, Listener>
public void registerEvents
}

View file

@ -87,7 +87,7 @@ public class Octree extends Tree
@Override
public boolean contains(int... coords)
public boolean testFor(int... coords)
{
if (coords[0] < min[0] || coords[0] >= max[0] ||
coords[1] < min[1] || coords[1] >= max[1] ||
@ -176,7 +176,6 @@ public class Octree extends Tree
zMarginHalf = zMargin / 2,
yMarginHalf = yMargin / 2;
xMin += xMarginHalf;
zMin += zMarginHalf;
yMin += yMarginHalf;
@ -187,14 +186,13 @@ public class Octree extends Tree
if (zMargin % 2 == 1) if (zMin - zMinPercent > zMax - zMaxPercent) zMin++; else zMax++;
if (yMargin % 2 == 1) if (yMin - yMinPercent > yMax - yMaxPercent) yMin++; else yMax++;
int sideLength = max[0] - min[0];
{int sideLength = max[0] - min[0];
min[0] -= (sideLength * xMin);
min[1] -= (sideLength * zMin);
min[2] -= (sideLength * yMin);
max[0] += (sideLength * xMax);
max[1] += (sideLength * zMax);
max[2] += (sideLength * yMax);
max[2] += (sideLength * yMax);}
int index;
Node[] children;
@ -570,44 +568,6 @@ public class Octree extends Tree
----------------------------------------------------------------------------*/
/**
*
* @param node
* @param node_minX
* @param node_minZ
* @param node_minY
* @param node_maxX
* @param node_maxZ
* @param node_maxY
* @param sel_minX
* @param sel_minZ
* @param sel_minY
* @param sel_maxX
* @param sel_maxZ
* @param sel_maxY
* @param blocks
* @return
*/
protected static boolean attemptAdd(Node node,
int node_minX, int node_minZ, int node_minY, int node_maxX, int node_maxZ, int node_maxY,
int sel_minX, int sel_minZ, int sel_minY, int sel_maxX, int sel_maxZ, int sel_maxY,
BitSet blocks
)
{
int partial = _3D.compareRegion(node_minX, node_minZ, node_minY, node_maxX, node_maxZ, node_maxY,
sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY,
blocks
);
if (partial == 0) return false;
if (partial == 1) return true;
node.full = false;
node.children = null;
return true;
}
/**
*
* @param node
@ -635,14 +595,24 @@ public class Octree extends Tree
if (node.full ||
node_minX >= sel_maxX || node_maxX <= sel_minX ||
node_minZ >= sel_maxZ || node_maxZ <= sel_minZ ||
node_minY >= sel_maxY || node_maxY <= sel_minY ||
attemptAdd(node,
node_minX, node_minZ, node_minY, node_maxX, node_maxZ, node_maxY,
sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY,
blocks
))
node_minY >= sel_maxY || node_maxY <= sel_minY
)
return;
switch (_3D.compareRegion( node_minX, node_minZ, node_minY, node_maxX, node_maxZ, node_maxY,
sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY,
blocks
))
{
case 0 : break; // some blocks added
case 1 : return; // no blocks added
case 2 : node.full = true; // all blocks added
node.children = null;
return;
}
if (node.children == null)
node.children = Node.emptyNodeArray(8);
@ -1126,51 +1096,13 @@ public class Octree extends Tree
/*----------------------------------------------------------------------------
------------------------------------------------------------------------------
/*----------------------------------------------------------------------------TODO avoid redundant block checking
------------------------------------------------------------------------------(checking all parent blocks, then checking all children blocks)
remove() COMPLEX BOUNDED SELECTION
------------------------------------------------------------------------------
----------------------------------------------------------------------------*/
/**
*
* @param node
* @param node_minX
* @param node_minZ
* @param node_minY
* @param node_maxX
* @param node_maxZ
* @param node_maxY
* @param sel_minX
* @param sel_minZ
* @param sel_minY
* @param sel_maxX
* @param sel_maxZ
* @param sel_maxY
* @param blocks
* @return
*/
protected static boolean attemptRemove(Node node,
int node_minX, int node_minZ, int node_minY, int node_maxX, int node_maxZ, int node_maxY,
int sel_minX, int sel_minZ, int sel_minY, int sel_maxX, int sel_maxZ, int sel_maxY,
BitSet blocks
)
{
int partial = _3D.compareRegion(node_minX, node_minZ, node_minY, node_maxX, node_maxZ, node_maxY,
sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY,
blocks
);
if (partial == 0) return false;
if (partial == 1) return true;
node.full = false;
node.children = null;
return true;
}
/**
*
* @param node
@ -1197,14 +1129,24 @@ public class Octree extends Tree
if ((!node.full && node.children == null) ||
node_minX >= sel_maxX || node_maxX <= sel_minX ||
node_minZ >= sel_maxZ || node_maxZ <= sel_minZ ||
node_minY >= sel_maxY || node_maxY <= sel_minY ||
attemptRemove(node,
node_minX, node_minZ, node_minY, node_maxX, node_maxZ, node_maxY,
sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY,
blocks
))
node_minY >= sel_maxY || node_maxY <= sel_minY
)
return;
switch (_3D.compareRegion( node_minX, node_minZ, node_minY, node_maxX, node_maxZ, node_maxY,
sel_minX, sel_minZ, sel_minY, sel_maxX, sel_maxZ, sel_maxY,
blocks
))
{
case 0 : break; // some blocks removed
case 1 : return; // no blocks removed
case 2 : node.full = false; // all blocks removed
node.children = null;
return;
}
if (node.full)
{
node.full = false;

View file

@ -6,6 +6,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.BitSet;
import regions.BitRegionUtil._3D;
import regions.Tree.Node;
public class Quadtree extends Tree
@ -84,7 +85,7 @@ public class Quadtree extends Tree
----------------------------------------------------------------------------*/
@Override
public boolean contains(int... coords)
public boolean testFor(int... coords)
{
if (coords[0] < min[0] || coords[0] >= max[0] ||
coords[1] < min[1] || coords[1] >= max[1]
@ -120,12 +121,18 @@ public class Quadtree extends Tree
}
/*----------------------------------------------------------------------------
/*----------------------------------------------------------------------------TODO
------------------------------------------------------------------------------
contains() BOUNDED SELECTION
------------------------------------------------------------------------------
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------TODO
------------------------------------------------------------------------------
contains() COMPLEX BOUNDED SELECTION
------------------------------------------------------------------------------
----------------------------------------------------------------------------*/
/*
@ -166,7 +173,6 @@ public class Quadtree extends Tree
xMarginHalf = xMargin / 2,
zMarginHalf = zMargin / 2;
xMin += xMarginHalf;
zMin += zMarginHalf;
xMax += xMarginHalf;
@ -174,13 +180,24 @@ public class Quadtree extends Tree
if (xMargin % 2 == 1) if (xMin - xMinPercent > xMax - xMaxPercent) xMin++; else xMax++;
if (zMargin % 2 == 1) if (zMin - zMinPercent > zMax - zMaxPercent) zMin++; else zMax++;
{
int sideLength = max[0] - min[0];
min[0] -= (sideLength * xMin);
min[1] -= (sideLength * zMin);
max[0] += (sideLength * xMax);
max[1] += (sideLength * zMax);
}
{int sideLength = max[0] - min[0];
min[0] -= (sideLength * xMin);
min[1] -= (sideLength * zMin);
max[0] += (sideLength * xMax);
max[1] += (sideLength * zMax);}
/* child index:
X X
Z
0 1
2 3
Z */
int index;
Node[] children;
@ -479,40 +496,6 @@ public class Quadtree extends Tree
----------------------------------------------------------------------------*/
/**
*
* @param node
* @param node_minX
* @param node_minZ
* @param node_maxX
* @param node_maxZ
* @param sel_minX
* @param sel_minZ
* @param sel_maxX
* @param sel_maxZ
* @param blocks
* @return
*/
protected static boolean attemptAdd(Node node,
int node_minX, int node_minZ, int node_maxX, int node_maxZ,
int sel_minX, int sel_minZ, int sel_maxX, int sel_maxZ,
BitSet blocks
)
{
int partial = _2D.compareRegion(node_minX, node_minZ, node_maxX, node_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ,
blocks
);
if (partial == 0) return false;
if (partial == 1) return true;
node.full = true;
node.children = null;
return true;
}
/**
*
* @param node
@ -535,14 +518,24 @@ public class Quadtree extends Tree
{
if (node.full ||
node_minX >= sel_maxX || node_maxX <= sel_minX ||
node_minZ >= sel_maxZ || node_maxZ <= sel_minZ ||
attemptAdd(node,
node_minX, node_minZ, node_maxX, node_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ,
blocks
))
node_minZ >= sel_maxZ || node_maxZ <= sel_minZ
)
return;
switch (_2D.compareRegion( node_minX, node_minZ, node_maxX, node_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ,
blocks
))
{
case 0 : break; // some blocks added
case 1 : return; // no blocks added
case 2 : node.full = true; // all blocks added
node.children = null;
return;
}
if (node.children == null) node.children = Node.emptyNodeArray(4);
int midpointX = min[0] + half,
@ -942,14 +935,24 @@ public class Quadtree extends Tree
{
if ((!node.full && node.children == null) ||
node_minX >= sel_maxX || node_maxX <= sel_minX ||
node_minZ >= sel_maxZ || node_maxZ <= sel_minZ ||
attemptRemove(node,
node_minX, node_minZ, node_maxX, node_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ,
blocks
))
node_minZ >= sel_maxZ || node_maxZ <= sel_minZ
)
return;
switch (_2D.compareRegion( node_minX, node_minZ, node_maxX, node_maxZ,
sel_minX, sel_minZ, sel_maxX, sel_maxZ,
blocks
))
{
case 0 : break; // some blocks removed
case 1 : return; // no blocks removed
case 2 : node.full = false; // all blocks removed
node.children = null;
return;
}
if (node.children == null) node.children = Node.fullNodeArray(4);
int midpointX = min[0] + half,

View file

@ -306,7 +306,7 @@ public abstract class Tree extends BitRegionUtil
/**
*
* TODO
*
* @param file The source file, and save destination, for this Tree
* @param blocks BitSet representing all <tt>true</tt> points in the given volume
@ -359,6 +359,7 @@ public abstract class Tree extends BitRegionUtil
OVERLOADS : nextPowerOfTwo()
-------------------------------------*/
/**
* TODO
*
* @param a
* @return
@ -369,6 +370,7 @@ public abstract class Tree extends BitRegionUtil
}
/**
* TODO
*
* @param a
* @param b
@ -380,6 +382,7 @@ public abstract class Tree extends BitRegionUtil
}
/**
* TODO
*
* @param a
* @param b
@ -405,7 +408,7 @@ public abstract class Tree extends BitRegionUtil
* @param coords
* @return
*/
public abstract boolean contains(int... coords);
public abstract boolean testFor(int... coords);
/*----------------------------------------------------------------------------

View file

@ -1,14 +0,0 @@
package regions;
public class TreeBuilder<T extends Tree>
{
public TreeBuilder(int minX, int minZ)
{
}
public TreeBuilder(int minX, int minZ, int minY)
{
}
}

View file

@ -1,18 +0,0 @@
package regions;
/**
* Aggregator for all edits waiting to be added. Merges all incoming edits
* into a growing 'super-edit' that is periodically written to the tree and flushed.
*/
public class TreeEditor<T extends Tree>
{
public TreeEditor(Octree tree, int minX, int minZ, int minY)
{
}
public TreeEditor(Quadtree tree, int minX, int minZ)
{
}
}