mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-11-15 23:05:12 +01:00
First BlockCache implementation using nodes.
(USe bounds instead of shape for the nodes as well.)
This commit is contained in:
parent
62455f4504
commit
cc538ee5a5
@ -23,7 +23,7 @@ import fr.neatmonster.nocheatplus.utilities.ds.map.CoordHashMap;
|
|||||||
import fr.neatmonster.nocheatplus.utilities.ds.map.CoordMap;
|
import fr.neatmonster.nocheatplus.utilities.ds.map.CoordMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access to type-ids and data using caching techniques.
|
* Access to block properties using caching technique (id, data, bounds).
|
||||||
*
|
*
|
||||||
* @author asofold
|
* @author asofold
|
||||||
*
|
*
|
||||||
@ -39,12 +39,12 @@ public abstract class BlockCache {
|
|||||||
|
|
||||||
public static final short FETCHED_ID = 0x01;
|
public static final short FETCHED_ID = 0x01;
|
||||||
public static final short FETCHED_DATA = 0x02;
|
public static final short FETCHED_DATA = 0x02;
|
||||||
public static final short FETCHED_SHAPE = 0x04;
|
public static final short FETCHED_BOUNDS = 0x04;
|
||||||
|
|
||||||
private short fetched = 0;
|
private short fetched = 0;
|
||||||
private int id = 0;
|
private int id = 0;
|
||||||
private int data = 0;
|
private int data = 0;
|
||||||
private double[] shape = null;
|
private double[] bounds = null;
|
||||||
|
|
||||||
public boolean isIdFetched() {
|
public boolean isIdFetched() {
|
||||||
return (fetched & FETCHED_ID) != 0;
|
return (fetched & FETCHED_ID) != 0;
|
||||||
@ -54,8 +54,8 @@ public abstract class BlockCache {
|
|||||||
return (fetched & FETCHED_DATA) != 0;
|
return (fetched & FETCHED_DATA) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isShapeFetched() {
|
public boolean isBoundsFetched() {
|
||||||
return (fetched & FETCHED_SHAPE) != 0;
|
return (fetched & FETCHED_BOUNDS) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
@ -66,8 +66,8 @@ public abstract class BlockCache {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double[] getShape() {
|
public double[] getBounds() {
|
||||||
return shape;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(int id) {
|
public void setId(int id) {
|
||||||
@ -80,36 +80,30 @@ public abstract class BlockCache {
|
|||||||
fetched |= FETCHED_DATA;
|
fetched |= FETCHED_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setShape(double[] shape) {
|
public void setBounds(double[] bounds) {
|
||||||
this.shape = shape;
|
this.bounds = bounds;
|
||||||
fetched |= FETCHED_SHAPE;
|
fetched |= FETCHED_BOUNDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(int id, int data, double[] shape) {
|
public void set(int id, int data, double[] bounds) {
|
||||||
setId(id);
|
setId(id);
|
||||||
setData(data);
|
setData(data);
|
||||||
setShape(shape);
|
setBounds(bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
fetched = 0;
|
fetched = 0;
|
||||||
id = 0;
|
id = 0;
|
||||||
data = 0;
|
data = 0;
|
||||||
shape = null;
|
bounds = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instance
|
// Instance
|
||||||
|
|
||||||
/** Cached type-ids. */
|
/** Nodes for cached block properties. */
|
||||||
private final CoordMap<Integer> idMap = new CoordHashMap<Integer>(23);
|
private final CoordMap<BlockCacheNode> nodeMap = new CoordHashMap<BlockCacheNode>(23);
|
||||||
|
|
||||||
/** Cached data values. */
|
|
||||||
private final CoordMap<Integer> dataMap = new CoordHashMap<Integer>(23);
|
|
||||||
|
|
||||||
/** Cached shape values. */
|
|
||||||
private final CoordMap<double[]> boundsMap = new CoordHashMap<double[]>(23);
|
|
||||||
|
|
||||||
/** The max block y. */
|
/** The max block y. */
|
||||||
protected int maxBlockY = 255;
|
protected int maxBlockY = 255;
|
||||||
@ -210,9 +204,33 @@ public abstract class BlockCache {
|
|||||||
* NOTE: You must delete world references with this one.
|
* NOTE: You must delete world references with this one.
|
||||||
*/
|
*/
|
||||||
public void cleanup() {
|
public void cleanup() {
|
||||||
idMap.clear();
|
nodeMap.clear();
|
||||||
dataMap.clear();
|
}
|
||||||
boundsMap.clear();
|
|
||||||
|
/**
|
||||||
|
* If there is no node stored, create a new node only with the type id set.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param z
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private BlockCacheNode getOrCreateNode(final int x, final int y, final int z) {
|
||||||
|
BlockCacheNode node = nodeMap.get(x, y, z);
|
||||||
|
if (node != null) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
final int id = (y < 0 || y > maxBlockY) ? ID_AIR : fetchTypeId(x, y, z);
|
||||||
|
// (Later: Static id-node map from config.)
|
||||||
|
if (id == ID_AIR) {
|
||||||
|
return airNode;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node = new BlockCacheNode();
|
||||||
|
node.id = id; // The id is always needed.
|
||||||
|
nodeMap.put(x, y, z, node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -253,13 +271,7 @@ public abstract class BlockCache {
|
|||||||
* @return the type id
|
* @return the type id
|
||||||
*/
|
*/
|
||||||
public int getTypeId(final int x, final int y, final int z) {
|
public int getTypeId(final int x, final int y, final int z) {
|
||||||
final Integer pId = idMap.get(x, y, z);
|
return getOrCreateNode(x, y, z).getId();
|
||||||
if (pId != null) {
|
|
||||||
return pId;
|
|
||||||
}
|
|
||||||
final Integer nId = (y < 0 || y > maxBlockY) ? ID_AIR : fetchTypeId(x, y, z);
|
|
||||||
idMap.put(x, y, z, nId);
|
|
||||||
return nId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -274,12 +286,12 @@ public abstract class BlockCache {
|
|||||||
* @return the data
|
* @return the data
|
||||||
*/
|
*/
|
||||||
public int getData(final int x, final int y, final int z) {
|
public int getData(final int x, final int y, final int z) {
|
||||||
final Integer pData = dataMap.get(x, y, z);
|
final BlockCacheNode node = getOrCreateNode(x, y, z);
|
||||||
if (pData != null) {
|
if (node.isDataFetched()) {
|
||||||
return pData;
|
return node.getData();
|
||||||
}
|
}
|
||||||
final Integer nData = (y < 0 || y > maxBlockY) ? 0 : fetchData(x, y, z);
|
final int nData = fetchData(x, y, z);
|
||||||
dataMap.put(x, y, z, nData);
|
node.setData(nData);
|
||||||
return nData;
|
return nData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,18 +310,27 @@ public abstract class BlockCache {
|
|||||||
* get cached.
|
* get cached.
|
||||||
*/
|
*/
|
||||||
public double[] getBounds(final int x, final int y, final int z) {
|
public double[] getBounds(final int x, final int y, final int z) {
|
||||||
final double[] pBounds = boundsMap.get(x, y, z);
|
final BlockCacheNode node = getOrCreateNode(x, y, z);
|
||||||
if (pBounds != null) {
|
if (node.isBoundsFetched()) {
|
||||||
return pBounds;
|
return node.getBounds();
|
||||||
}
|
}
|
||||||
|
final double[] nBounds = fetchBounds(x, y, z);
|
||||||
// TODO: Convention for null bounds -> full ?
|
// TODO: Convention for null bounds -> full ?
|
||||||
// TODO: fetchBounds(x, y, z, node)
|
node.setBounds(nBounds);
|
||||||
final double[] nBounds = (y < 0 || y > maxBlockY) ? null : fetchBounds(x, y, z);
|
|
||||||
boundsMap.put(x, y, z, nBounds);
|
|
||||||
return nBounds;
|
return nBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: public BlockCacheNode getBlockCacheNode(int x, int y, int z, boolean forceSetAll)
|
// TODO: Interface / Override annotation.
|
||||||
|
public BlockCacheNode getBlockCacheNode(int x, int y, int z, boolean forceSetAll) {
|
||||||
|
final BlockCacheNode node = getOrCreateNode(x, y, z);
|
||||||
|
if (!node.isDataFetched()) {
|
||||||
|
node.setData(fetchData(x, y, z));
|
||||||
|
}
|
||||||
|
if (!node.isBoundsFetched()) {
|
||||||
|
node.setBounds(fetchBounds(x, y, z));
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method to check if the bounds for a block cover the full
|
* Convenience method to check if the bounds for a block cover the full
|
||||||
|
Loading…
Reference in New Issue
Block a user