From 9514245e14df545a9b10f558b246baead8d5a4eb Mon Sep 17 00:00:00 2001 From: Don Redhorse Date: Thu, 13 Feb 2014 12:43:16 +0000 Subject: [PATCH 1/7] Created new branch registry From 71a68e840e39392acb127fd3d0e525ca2c67c43a Mon Sep 17 00:00:00 2001 From: Don Redhorse Date: Fri, 9 May 2014 13:21:00 +0200 Subject: [PATCH 2/7] Initial commit for new BlockRegistry --- .../api/event/cause/MaterialCause.java | 6 +- .../api/generator/EmptyWorldGenerator.java | 6 +- .../api/generator/FlatWorldGenerator.java | 19 +- .../api/generator/LayeredWorldGenerator.java | 30 +- .../api/generator/SolidWorldGenerator.java | 13 +- .../flowpowered/api/geo/AreaBlockAccess.java | 109 ++- .../flowpowered/api/geo/AreaBlockSource.java | 10 +- .../com/flowpowered/api/geo/cuboid/Block.java | 59 +- .../api/material/BaseMaterial.java | 152 ++++ ...ckMaterial.java => BlockBaseMaterial.java} | 255 +++--- .../flowpowered/api/material/Material.java | 353 ------- .../api/material/MaterialRegistry.java | 123 +-- .../flowpowered/api/material/Placeable.java | 25 +- .../flowpowered/api/material/basic/Air.java | 13 +- .../flowpowered/api/material/basic/Solid.java | 6 +- .../api/material/block/BlockFullState.java | 29 +- .../api/material/block/BlockSnapshot.java | 22 +- .../cuboid/CuboidBlockMaterialBuffer.java | 33 +- .../ImmutableCuboidBlockMaterialBuffer.java | 9 +- .../flowpowered/engine/FlowSingleplayer.java | 111 ++- .../com/flowpowered/engine/geo/FlowBlock.java | 46 +- .../engine/geo/chunk/FlowChunk.java | 433 +++++---- .../engine/geo/region/FlowRegion.java | 859 +++++++++--------- .../engine/geo/snapshot/ChunkSnapshot.java | 337 +++---- .../geo/snapshot/ChunkSnapshotGroup.java | 119 +-- .../engine/geo/world/FlowWorld.java | 775 ++++++++-------- .../engine/registry/Attribute.java | 35 + .../engine/registry/AttributeGroup.java | 12 + .../engine/registry/BlockAttributes.java | 19 + .../engine/registry/BlockMaterial.java | 99 ++ .../registry/BlockMaterialRegistry.java | 147 +++ .../engine/registry/EntityAttributes.java | 13 + .../registry/GenericRegistryObject.java | 74 ++ .../engine/registry/MaterialMapper.java | 44 + .../engine/registry/TempEntityType.java | 23 + .../flowpowered/engine/registry/TempGame.java | 11 + .../render/mesher/StandardChunkMesher.java | 229 ++--- 37 files changed, 2475 insertions(+), 2183 deletions(-) create mode 100644 src/main/java/com/flowpowered/api/material/BaseMaterial.java rename src/main/java/com/flowpowered/api/material/{BlockMaterial.java => BlockBaseMaterial.java} (60%) delete mode 100644 src/main/java/com/flowpowered/api/material/Material.java create mode 100644 src/main/java/com/flowpowered/engine/registry/Attribute.java create mode 100644 src/main/java/com/flowpowered/engine/registry/AttributeGroup.java create mode 100644 src/main/java/com/flowpowered/engine/registry/BlockAttributes.java create mode 100644 src/main/java/com/flowpowered/engine/registry/BlockMaterial.java create mode 100644 src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java create mode 100644 src/main/java/com/flowpowered/engine/registry/EntityAttributes.java create mode 100644 src/main/java/com/flowpowered/engine/registry/GenericRegistryObject.java create mode 100644 src/main/java/com/flowpowered/engine/registry/MaterialMapper.java create mode 100644 src/main/java/com/flowpowered/engine/registry/TempEntityType.java create mode 100644 src/main/java/com/flowpowered/engine/registry/TempGame.java diff --git a/src/main/java/com/flowpowered/api/event/cause/MaterialCause.java b/src/main/java/com/flowpowered/api/event/cause/MaterialCause.java index 1267494..c6a80b6 100644 --- a/src/main/java/com/flowpowered/api/event/cause/MaterialCause.java +++ b/src/main/java/com/flowpowered/api/event/cause/MaterialCause.java @@ -23,12 +23,12 @@ */ package com.flowpowered.api.event.cause; +import com.flowpowered.api.geo.cuboid.Block; +import com.flowpowered.api.material.BaseMaterial; import com.flowpowered.events.Cause; -import com.flowpowered.api.geo.cuboid.Block; -import com.flowpowered.api.material.Material; +public class MaterialCause extends Cause { -public class MaterialCause extends Cause { private final T material; private final Block block; diff --git a/src/main/java/com/flowpowered/api/generator/EmptyWorldGenerator.java b/src/main/java/com/flowpowered/api/generator/EmptyWorldGenerator.java index 864dd29..40edfed 100644 --- a/src/main/java/com/flowpowered/api/generator/EmptyWorldGenerator.java +++ b/src/main/java/com/flowpowered/api/generator/EmptyWorldGenerator.java @@ -24,17 +24,17 @@ package com.flowpowered.api.generator; import com.flowpowered.api.geo.World; -import com.flowpowered.api.geo.cuboid.Chunk; -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.api.util.cuboid.CuboidBlockMaterialBuffer; /** * Generates an empty world using air blocks */ public class EmptyWorldGenerator implements WorldGenerator { + @Override public void generate(CuboidBlockMaterialBuffer blockData, World world) { - blockData.flood(BlockMaterial.AIR); + blockData.flood(BlockBaseMaterial.AIR); } @Override diff --git a/src/main/java/com/flowpowered/api/generator/FlatWorldGenerator.java b/src/main/java/com/flowpowered/api/generator/FlatWorldGenerator.java index 6f72bff..1e6a1ba 100644 --- a/src/main/java/com/flowpowered/api/generator/FlatWorldGenerator.java +++ b/src/main/java/com/flowpowered/api/generator/FlatWorldGenerator.java @@ -24,32 +24,33 @@ package com.flowpowered.api.generator; import com.flowpowered.api.geo.World; -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.api.util.cuboid.CuboidBlockMaterialBuffer; /** * Generates a flat world of a material */ public class FlatWorldGenerator implements WorldGenerator { - private final BlockMaterial material; + + private final BlockBaseMaterial material; public FlatWorldGenerator() { - material = BlockMaterial.SOLID_BLUE; + material = BlockBaseMaterial.SOLID_BLUE; } - public FlatWorldGenerator(BlockMaterial material) { + public FlatWorldGenerator(BlockBaseMaterial material) { this.material = material; } @Override public void generate(CuboidBlockMaterialBuffer blockData, World world) { - int flooredY = blockData.getBase().getFloorY(); + int flooredY = blockData.getBase().getFloorY(); if (flooredY < 0) { - blockData.setHorizontalLayer(flooredY, (blockData.getSize().getFloorY() / 2), material); + blockData.setHorizontalLayer(flooredY, (blockData.getSize().getFloorY() / 2), material); blockData.flood(material); } else { - blockData.flood(BlockMaterial.AIR); - } + blockData.flood(BlockBaseMaterial.AIR); + } } @Override @@ -60,5 +61,5 @@ public Populator[] getPopulators() { @Override public String getName() { return "FlatWorld"; - } + } } diff --git a/src/main/java/com/flowpowered/api/generator/LayeredWorldGenerator.java b/src/main/java/com/flowpowered/api/generator/LayeredWorldGenerator.java index 94d6ef7..7fdeedd 100644 --- a/src/main/java/com/flowpowered/api/generator/LayeredWorldGenerator.java +++ b/src/main/java/com/flowpowered/api/generator/LayeredWorldGenerator.java @@ -24,19 +24,18 @@ package com.flowpowered.api.generator; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import com.flowpowered.api.geo.World; -import com.flowpowered.api.geo.cuboid.Chunk; -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.api.util.cuboid.CuboidBlockMaterialBuffer; /** * A world generator that generates using previously-specified layers of blocks */ public class LayeredWorldGenerator implements WorldGenerator { + private List layers = new ArrayList<>(); private int minimum = Integer.MAX_VALUE; private int height = Integer.MIN_VALUE; @@ -94,14 +93,14 @@ public List getLayers() { * * @param material of the layer */ - protected void setFloorLayer(BlockMaterial material) { + protected void setFloorLayer(BlockBaseMaterial material) { this.setFloorLayer(material.getId(), material.getData()); } /** * Sets the floor layer material, the material for below the lowest layer
By default this layer is full of empty material (air) * - * @param id of the material of the layer + * @param id of the material of the layer * @param data of the layer */ protected void setFloorLayer(short id, short data) { @@ -112,10 +111,10 @@ protected void setFloorLayer(short id, short data) { /** * Stacks a new layer on top of a previous one
At least one layer added using addLayer should be defined before calling this method
Otherwise the y-coordinate of this layer will be incorrect * - * @param height of the new layer + * @param height of the new layer * @param material of the layer */ - protected void stackLayer(int height, BlockMaterial material) { + protected void stackLayer(int height, BlockBaseMaterial material) { this.addLayer(this.height, height, material); } @@ -123,8 +122,8 @@ protected void stackLayer(int height, BlockMaterial material) { * Stacks a new layer on top of a previous one
At least one layer added using addLayer should be defined before calling this method
Otherwise the y-coordinate of this layer will be incorrect * * @param height of the new layer - * @param id of the material of the layer - * @param data of the layer + * @param id of the material of the layer + * @param data of the layer */ protected void stackLayer(int height, short id, short data) { this.addLayer(this.height, height, id, data); @@ -133,21 +132,21 @@ protected void stackLayer(int height, short id, short data) { /** * Adds a single layer * - * @param y - coordinate of the start of the layer - * @param height of the layer + * @param y - coordinate of the start of the layer + * @param height of the layer * @param material of the layer */ - protected void addLayer(int y, int height, BlockMaterial material) { + protected void addLayer(int y, int height, BlockBaseMaterial material) { this.addLayer(y, height, material.getId(), material.getData()); } /** * Adds a single layer * - * @param y - coordinate of the start of the layer + * @param y - coordinate of the start of the layer * @param height of the layer - * @param id of the material of the layer - * @param data of the layer + * @param id of the material of the layer + * @param data of the layer */ protected void addLayer(int y, int height, short id, short data) { final Layer layer = new Layer(y, height, id, data); @@ -157,6 +156,7 @@ protected void addLayer(int y, int height, short id, short data) { } public static class Layer { + private final short id, data; private final int y, height, topy; diff --git a/src/main/java/com/flowpowered/api/generator/SolidWorldGenerator.java b/src/main/java/com/flowpowered/api/generator/SolidWorldGenerator.java index 5e2eace..e645047 100644 --- a/src/main/java/com/flowpowered/api/generator/SolidWorldGenerator.java +++ b/src/main/java/com/flowpowered/api/generator/SolidWorldGenerator.java @@ -24,26 +24,27 @@ package com.flowpowered.api.generator; import com.flowpowered.api.geo.World; -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.api.util.cuboid.CuboidBlockMaterialBuffer; /** * Generates a solid world of a material */ public class SolidWorldGenerator implements WorldGenerator { - private final BlockMaterial material; + + private final BlockBaseMaterial material; public SolidWorldGenerator() { - material = BlockMaterial.SOLID_BLUE; + material = BlockBaseMaterial.SOLID_BLUE; } - public SolidWorldGenerator(BlockMaterial material) { + public SolidWorldGenerator(BlockBaseMaterial material) { this.material = material; } @Override public void generate(CuboidBlockMaterialBuffer blockData, World world) { - blockData.flood(material); + blockData.flood(material); } @Override @@ -54,5 +55,5 @@ public Populator[] getPopulators() { @Override public String getName() { return "SolidWorld"; - } + } } diff --git a/src/main/java/com/flowpowered/api/geo/AreaBlockAccess.java b/src/main/java/com/flowpowered/api/geo/AreaBlockAccess.java index af90d47..4ad166d 100644 --- a/src/main/java/com/flowpowered/api/geo/AreaBlockAccess.java +++ b/src/main/java/com/flowpowered/api/geo/AreaBlockAccess.java @@ -23,21 +23,21 @@ */ package com.flowpowered.api.geo; -import com.flowpowered.events.Cause; - import com.flowpowered.api.geo.cuboid.Block; -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.api.util.cuboid.CuboidBlockMaterialBuffer; +import com.flowpowered.events.Cause; import com.flowpowered.math.vector.Vector3f; public interface AreaBlockAccess extends AreaBlockSource { + /** * Sets the data for the block at (x, y, z) to the given data. * - * @param x coordinate of the block - * @param y coordinate of the block - * @param z coordinate of the block - * @param data to set to + * @param x coordinate of the block + * @param y coordinate of the block + * @param z coordinate of the block + * @param data to set to * @param cause of the change, or null if non-specific cause */ public boolean setBlockData(int x, int y, int z, short data, Cause cause); @@ -45,24 +45,25 @@ public interface AreaBlockAccess extends AreaBlockSource { /** * Sets the material and data for the block at (x, y, z) to the given material and data. * - * @param x coordinate of the block - * @param y coordinate of the block - * @param z coordinate of the block - * @param data value to set to + * @param x coordinate of the block + * @param y coordinate of the block + * @param z coordinate of the block + * @param data value to set to * @param material to set to - * @param cause of the change, or null if non-specific cause + * @param cause of the change, or null if non-specific cause */ - public boolean setBlockMaterial(int x, int y, int z, BlockMaterial material, short data, Cause cause); + public boolean setBlockMaterial(int x, int y, int z, BlockBaseMaterial material, short data, Cause cause); /** * Sets the data of the block at (x, y, z) if the expected state matches * - * @param x coordinate of the block - * @param y coordinate of the block - * @param z coordinate of the block + * @param x coordinate of the block + * @param y coordinate of the block + * @param z coordinate of the block * @param expect is the state of the block it expects - * @param data to set to if it matches - * @param cause of the change, or null if non-specific cause + * @param data to set to if it matches + * @param cause of the change, or null if non-specific cause + * * @return whether setting was successful */ public boolean compareAndSetData(int x, int y, int z, int expect, short data, Cause cause); @@ -70,10 +71,11 @@ public interface AreaBlockAccess extends AreaBlockSource { /** * Sets the given bits in the data for the block at (x, y, z)

newData = oldData | (bits) * - * @param x coordinate of the block - * @param y coordinate of the block - * @param z coordinate of the block + * @param x coordinate of the block + * @param y coordinate of the block + * @param z coordinate of the block * @param bits the bits to set + * * @return the old data for the block */ public short setBlockDataBits(int x, int y, int z, int bits, Cause cause); @@ -81,11 +83,12 @@ public interface AreaBlockAccess extends AreaBlockSource { /** * Sets the given bits in the data for the block at (x, y, z)

newData = oldData | (bits)
or
newData = oldData & ~(bits) * - * @param x coordinate of the block - * @param y coordinate of the block - * @param z coordinate of the block + * @param x coordinate of the block + * @param y coordinate of the block + * @param z coordinate of the block * @param bits the bits to set or clear - * @param set true to set, false to clear + * @param set true to set, false to clear + * * @return the old data for the block */ public short setBlockDataBits(int x, int y, int z, int bits, boolean set, Cause source); @@ -93,11 +96,12 @@ public interface AreaBlockAccess extends AreaBlockSource { /** * Clears the given bits in the data for the block at (x, y, z)

newData = oldData & (~bits) * - * @param x coordinate of the block - * @param y coordinate of the block - * @param z coordinate of the block - * @param bits the bits to clear + * @param x coordinate of the block + * @param y coordinate of the block + * @param z coordinate of the block + * @param bits the bits to clear * @param cause of the change, or null if non-specific cause + * * @return the old data for the block */ public short clearBlockDataBits(int x, int y, int z, int bits, Cause source); @@ -105,10 +109,11 @@ public interface AreaBlockAccess extends AreaBlockSource { /** * Gets the data field from the block at (x, y, z)

field = (data & bits) >> (shift)

The shift value used shifts the least significant non-zero bit of bits to the LSB position * - * @param x coordinate of the block - * @param y coordinate of the block - * @param z coordinate of the block + * @param x coordinate of the block + * @param y coordinate of the block + * @param z coordinate of the block * @param bits the bits of the field + * * @return the field value */ public int getBlockDataField(int x, int y, int z, int bits); @@ -116,10 +121,11 @@ public interface AreaBlockAccess extends AreaBlockSource { /** * Gets if any of the indicated bits are set. * - * @param x coordinate of the block - * @param y coordinate of the block - * @param z coordinate of the block + * @param x coordinate of the block + * @param y coordinate of the block + * @param z coordinate of the block * @param bits the bits of the field + * * @return true if any of the given bits are set */ public boolean isBlockDataBitSet(int x, int y, int z, int bits); @@ -128,12 +134,13 @@ public interface AreaBlockAccess extends AreaBlockSource { * Sets the data field for the block at (x, y, z). This is the reverse operation to the getBlockDataField method.

newData = ((value << shift) & bits) | (oldData & (~bits))

The * shift value used shifts the least significant non-zero bit of bits to the LSB position * - * @param x coordinate of the block - * @param y coordinate of the block - * @param z coordinate of the block - * @param bits the bits of the field + * @param x coordinate of the block + * @param y coordinate of the block + * @param z coordinate of the block + * @param bits the bits of the field * @param value the new value of the field * @param cause of the change, or null if non-specific cause + * * @return the old value of the field */ public int setBlockDataField(int x, int y, int z, int bits, int value, Cause source); @@ -142,11 +149,12 @@ public interface AreaBlockAccess extends AreaBlockSource { * Adds a value to the data field for the block at (x, y, z). This is the reverse operation to the getBlockDataField method.

newData = (((oldData + (value << shift)) & bits) | (oldData & * ~bits))

The shift value used shifts the least significant non-zero bit of bits to the LSB position * - * @param x coordinate of the block - * @param y coordinate of the block - * @param z coordinate of the block - * @param bits the bits of the field + * @param x coordinate of the block + * @param y coordinate of the block + * @param z coordinate of the block + * @param bits the bits of the field * @param value to add to the value of the field + * * @return the old value of the field */ public int addBlockDataField(int x, int y, int z, int bits, int value, Cause source); @@ -157,6 +165,7 @@ public interface AreaBlockAccess extends AreaBlockSource { * @param x coordinate of the block * @param y coordinate of the block * @param z coordinate of the block + * * @return true if it is contained, false if not */ public boolean containsBlock(int x, int y, int z); @@ -167,6 +176,7 @@ public interface AreaBlockAccess extends AreaBlockSource { * @param x coordinate of the block * @param y coordinate of the block * @param z coordinate of the block + * * @return the Block */ public Block getBlock(float x, float y, float z); @@ -175,6 +185,7 @@ public interface AreaBlockAccess extends AreaBlockSource { * Gets a {@link Block} representing the block at the position given * * @param position of the block + * * @return the Block */ public Block getBlock(Vector3f position); @@ -223,12 +234,12 @@ public interface AreaBlockAccess extends AreaBlockSource { /** * Atomically gets the cuboid volume with the base located at the given coords of the given size.

Note: The block at the base coordinate is inside the buffer * - * @param bx base x-coordinate - * @param by base y-coordinate - * @param bz base z-coordinate - * @param sx size x-coordinate - * @param sy size y-coordinate - * @param sz size z-coordinate + * @param bx base x-coordinate + * @param by base y-coordinate + * @param bz base z-coordinate + * @param sx size x-coordinate + * @param sy size y-coordinate + * @param sz size z-coordinate * @param backBuffer true for a buffer with a back buffer */ public CuboidBlockMaterialBuffer getCuboid(int bx, int by, int bz, int sx, int sy, int sz, boolean backBuffer); diff --git a/src/main/java/com/flowpowered/api/geo/AreaBlockSource.java b/src/main/java/com/flowpowered/api/geo/AreaBlockSource.java index 888c37f..c688d22 100644 --- a/src/main/java/com/flowpowered/api/geo/AreaBlockSource.java +++ b/src/main/java/com/flowpowered/api/geo/AreaBlockSource.java @@ -23,18 +23,20 @@ */ package com.flowpowered.api.geo; -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; public interface AreaBlockSource { + /** * Gets the material for the block at (x, y, z) * * @param x coordinate of the block * @param y coordinate of the block * @param z coordinate of the block + * * @return the block's material from the snapshot */ - public BlockMaterial getBlockMaterial(int x, int y, int z); + public BlockBaseMaterial getBlockMaterial(int x, int y, int z); /** * Gets the packed BlockFullData for the block at (x, y, z). Handler methods are provided by the BlockFullState class. @@ -42,6 +44,7 @@ public interface AreaBlockSource { * @param x coordinate of the block * @param y coordinate of the block * @param z coordinate of the block + * * @return the block's full state from the snapshot */ public int getBlockFullState(int x, int y, int z); @@ -52,7 +55,8 @@ public interface AreaBlockSource { * @param x coordinate of the block * @param y coordinate of the block * @param z coordinate of the block + * * @return the block's data from the snapshot */ public short getBlockData(int x, int y, int z); -} \ No newline at end of file +} diff --git a/src/main/java/com/flowpowered/api/geo/cuboid/Block.java b/src/main/java/com/flowpowered/api/geo/cuboid/Block.java index 6bce6bd..09694a7 100644 --- a/src/main/java/com/flowpowered/api/geo/cuboid/Block.java +++ b/src/main/java/com/flowpowered/api/geo/cuboid/Block.java @@ -23,19 +23,19 @@ */ package com.flowpowered.api.geo.cuboid; -import com.flowpowered.events.Cause; - import com.flowpowered.api.component.ComponentOwner; import com.flowpowered.api.geo.World; import com.flowpowered.api.geo.WorldSource; import com.flowpowered.api.geo.discrete.Point; -import com.flowpowered.api.material.BlockMaterial; -import com.flowpowered.api.material.Material; +import com.flowpowered.api.material.BaseMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.api.material.block.BlockFace; +import com.flowpowered.events.Cause; import com.flowpowered.math.vector.Vector3f; import com.flowpowered.math.vector.Vector3i; public interface Block extends WorldSource, ComponentOwner { + /** * Gets the {@link Point} position of this block in the world * @@ -89,8 +89,9 @@ public interface Block extends WorldSource, ComponentOwner { /** * Translates this block using the offset and distance given * - * @param offset BlockFace to translate + * @param offset BlockFace to translate * @param distance to translate + * * @return a new Block instance */ Block translate(BlockFace offset, int distance); @@ -99,6 +100,7 @@ public interface Block extends WorldSource, ComponentOwner { * Translates this block using the offset given * * @param offset BlockFace to translate + * * @return a new Block instance */ Block translate(BlockFace offset); @@ -107,6 +109,7 @@ public interface Block extends WorldSource, ComponentOwner { * Translates this block using the offset given * * @param offset Vector to translate + * * @return a new Block instance */ Block translate(Vector3f offset); @@ -115,6 +118,7 @@ public interface Block extends WorldSource, ComponentOwner { * Translates this block using the offset given * * @param offset Vector to translate + * * @return a new Block instance */ Block translate(Vector3i offset); @@ -125,6 +129,7 @@ public interface Block extends WorldSource, ComponentOwner { * @param dx offset to translate * @param dy offset to translate * @param dz offset to translate + * * @return a new Block instance */ Block translate(int dx, int dy, int dz); @@ -134,7 +139,7 @@ public interface Block extends WorldSource, ComponentOwner { * * @return block material */ - BlockMaterial getMaterial(); + BlockBaseMaterial getMaterial(); /** * Gets the block data for this block @@ -147,14 +152,16 @@ public interface Block extends WorldSource, ComponentOwner { * Sets the data of this block to the given material's data * * @param data to set to + * * @return this Block */ - Block setData(BlockMaterial data); + Block setData(BlockBaseMaterial data); /** * Sets the data of this block * * @param data to set to + * * @return this Block */ Block setData(int data); @@ -162,8 +169,9 @@ public interface Block extends WorldSource, ComponentOwner { /** * Sets the data of this block * - * @param data to set to + * @param data to set to * @param cause of the change + * * @return this Block */ Block setData(int data, Cause cause); @@ -172,42 +180,47 @@ public interface Block extends WorldSource, ComponentOwner { * Sets the material of this block * * @param material to set to + * * @return whether the material set was successful */ - boolean setMaterial(BlockMaterial material); + boolean setMaterial(BlockBaseMaterial material); /** * Sets the material of this block * * @param material to set to - * @param cause of the change + * @param cause of the change + * * @return whether the material set was successful */ - boolean setMaterial(BlockMaterial material, Cause cause); + boolean setMaterial(BlockBaseMaterial material, Cause cause); /** * Sets the material and data of this block * * @param material to set to - * @param data to set to + * @param data to set to + * * @return whether the material set was successful */ - boolean setMaterial(BlockMaterial material, int data); + boolean setMaterial(BlockBaseMaterial material, int data); /** * Sets the material and data of this block * * @param material to set to - * @param data to set to - * @param cause of the change + * @param data to set to + * @param cause of the change + * * @return whether the material set was successful */ - boolean setMaterial(BlockMaterial material, int data, Cause cause); + boolean setMaterial(BlockBaseMaterial material, int data, Cause cause); /** * Sets the given bits in the data for the block

newData = oldData | (bits) * * @param bits the bits to set + * * @return the old data for the block */ short setDataBits(int bits); @@ -216,7 +229,8 @@ public interface Block extends WorldSource, ComponentOwner { * Sets the given bits in the data for the block

newData = oldData | (bits)
or
newData = oldData & ~(bits) * * @param bits the bits to set or clear - * @param set True to set the bits, False to clear + * @param set True to set the bits, False to clear + * * @return the old data for the block */ short setDataBits(int bits, boolean set); @@ -225,6 +239,7 @@ public interface Block extends WorldSource, ComponentOwner { * Clears the given bits in the data for the block

newData = oldData & (~bits) * * @param bits the bits to clear + * * @return the old data for the block */ short clearDataBits(int bits); @@ -233,6 +248,7 @@ public interface Block extends WorldSource, ComponentOwner { * Gets the data field from the block

field = (data & bits) >> (shift)

The shift value used shifts the least significant non-zero bit of bits to the LSB position * * @param bits the bits of the field + * * @return the field value */ int getDataField(int bits); @@ -241,6 +257,7 @@ public interface Block extends WorldSource, ComponentOwner { * Gets if any of the indicated bits are set. * * @param bits the bits to check + * * @return true if any of the given bits are set */ boolean isDataBitSet(int bits); @@ -249,8 +266,9 @@ public interface Block extends WorldSource, ComponentOwner { * Sets the data field for the block. This is the reverse operation to the getDataField method.

newData = ((value << shift) & bits) | (oldData & (~bits))

The shift value used * shifts the least significant non-zero bit of bits to the LSB position * - * @param bits the bits of the field + * @param bits the bits of the field * @param value the new value of the field + * * @return the old value of the field */ int setDataField(int bits, int value); @@ -259,11 +277,12 @@ public interface Block extends WorldSource, ComponentOwner { * Adds a value to the data field for the block. This is the reverse operation to the getBlockDataField method.

newData = (((oldData + (value << shift)) & bits) | (oldData & ~bits))
*
The shift value used shifts the least significant non-zero bit of bits to the LSB position * - * @param bits the bits of the field + * @param bits the bits of the field * @param value to add to the value of the field + * * @return the old value of the field */ int addDataField(int bits, int value); - boolean isMaterial(Material... materials); + boolean isMaterial(BaseMaterial... baseMaterials); } diff --git a/src/main/java/com/flowpowered/api/material/BaseMaterial.java b/src/main/java/com/flowpowered/api/material/BaseMaterial.java new file mode 100644 index 0000000..133a22a --- /dev/null +++ b/src/main/java/com/flowpowered/api/material/BaseMaterial.java @@ -0,0 +1,152 @@ +/* + * This file is part of Flow Engine, licensed under the MIT License (MIT). + * + * Copyright (c) 2013 Spout LLC + * + * 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 com.flowpowered.api.material; + +/** + * Defines the characteristics of Blocks or Items. + */ + +import com.flowpowered.commons.LogicUtil; + +public abstract class BaseMaterial { + + private final int id; + private final String name; + private String displayName; + private int maxStackSize = 64; + private MATERIAL_STATE materialState = MATERIAL_STATE.UNDEFINED; + + public static enum MATERIAL_STATE { + SOLID, LIQUID, GAS, UNDEFINED + } + + /** + * Creates a material with a name + */ + public BaseMaterial(String name) { + this.displayName = name; + this.name = getClass().getCanonicalName() + "_" + name.replace(' ', '_'); + this.id = (short) MaterialRegistry.register(this); + } + + /** + * Creates a material with a reserved id + * + * @param name of the material + * @param id to reserve + */ + protected BaseMaterial(String name, int id) { + this.displayName = name; + this.name = name.replace(' ', '_'); + this.id = MaterialRegistry.register(this, id); + } + + public final int getId() { + return this.id; + } + + /** + * Gets the name of this material + * + * @return the name + */ + public final String getName() { + return this.name; + } + + /** + * Gets the display name of this material + * + * @return the display name + */ + public final String getDisplayName() { + return this.displayName; + } + + /** + * Sets the display name of this material + * + * @param name the new display name + */ + public final void setDisplayName(String name) { + this.displayName = name; + } + + /** + * Gets the maximum size of a stack of this material + * + * @return the current max size + */ + public final int getMaxStackSize() { + return this.maxStackSize; + } + + /** + * Sets the maximum size of a stack of this material + * + * @param newValue the new maximum stack size + */ + public final void setMaxStackSize(int newValue) { + this.maxStackSize = newValue; + } + + public boolean isMaterial(BaseMaterial... baseMaterials) { + return LogicUtil.equalsAny(this, baseMaterials); + } + + @Override + public boolean equals(Object other) { + return other instanceof BaseMaterial && other == this; + } + + @Override + public String toString() { + return "BaseMaterial {" + getName() + "}"; + } + + /** + * Indicates that the dataMask covers the least significant bits.

This method is used when verifying that the dataMask is set correctly + */ + public boolean hasLSBDataMask() { + return true; + } + + /** + * Get the state of the Material + * + * @return + */ + public MATERIAL_STATE getMaterialState() { + return materialState; + } + + /** + * Set the state of the Material + * + * @param materialState to set + */ + public void setMaterialState(final MATERIAL_STATE materialState) { + this.materialState = materialState; + } +} diff --git a/src/main/java/com/flowpowered/api/material/BlockMaterial.java b/src/main/java/com/flowpowered/api/material/BlockBaseMaterial.java similarity index 60% rename from src/main/java/com/flowpowered/api/material/BlockMaterial.java rename to src/main/java/com/flowpowered/api/material/BlockBaseMaterial.java index 6493b0b..0e05aee 100644 --- a/src/main/java/com/flowpowered/api/material/BlockMaterial.java +++ b/src/main/java/com/flowpowered/api/material/BlockBaseMaterial.java @@ -25,40 +25,29 @@ import java.util.Set; -import com.flowpowered.commons.bit.ByteBitSet; -import com.flowpowered.events.Cause; - -import com.google.common.collect.ImmutableSet; - import com.flowpowered.api.component.block.BlockComponent; import com.flowpowered.api.entity.Entity; import com.flowpowered.api.event.cause.MaterialCause; import com.flowpowered.api.geo.cuboid.Block; import com.flowpowered.api.geo.discrete.Point; -import com.flowpowered.api.material.basic.Air; -import com.flowpowered.api.material.basic.Solid; import com.flowpowered.api.material.block.BlockFace; import com.flowpowered.api.material.block.BlockFaces; +import com.flowpowered.commons.bit.ByteBitSet; +import com.flowpowered.events.Cause; import com.flowpowered.math.GenericMath; import com.flowpowered.math.vector.Vector3f; +import com.google.common.collect.ImmutableSet; + import org.spout.physics.ReactDefaults; import org.spout.physics.collision.shape.CollisionShape; /** * Defines the specific characteristics of a Block */ -@SuppressWarnings ("unchecked") -public class BlockMaterial extends Material implements Placeable { - public static final BlockMaterial AIR = new Air(); - public static final BlockMaterial UNBREAKABLE = new Solid("Unbreakable"); - public static final BlockMaterial UNGENERATED = new Solid("Ungenerated").setInvisible(); - public static final BlockMaterial ERROR = new Solid("Missing Plugin"); - public static final BlockMaterial SOLID_BLUE = new Solid("SolidBlue"); - public static final BlockMaterial SOLID_BROWN = new Solid("SolidBrown"); - public static final BlockMaterial SOLID_GREEN = new Solid("SolidGreen"); - public static final BlockMaterial SOLID_LIGHTGREEN = new Solid("SolidLightGreen"); - public static final BlockMaterial SOLID_RED = new Solid("SolidRed"); - public static final BlockMaterial SOLID_SKYBLUE = new Solid("SolidSkyBlue"); +@SuppressWarnings("unchecked") +public class BlockBaseMaterial extends BaseMaterial implements Placeable { + + private BlockBaseMaterial destroyed_material; private final Set> components; private ByteBitSet occlusion = new ByteBitSet(BlockFaces.NESWBT); private float hardness = 0F; @@ -71,79 +60,18 @@ public class BlockMaterial extends Material implements Placeable { private float restitution = ReactDefaults.DEFAULT_RESTITUTION_COEFFICIENT; private boolean isGhost = false; - public BlockMaterial(short dataMask, String name, CollisionShape shape, Class... components) { - super(dataMask, name); - this.components = ImmutableSet.copyOf(components); - this.shape = shape; - } - - public BlockMaterial(String name, int data, Material parent, String model, CollisionShape shape, Class... components) { - super(name, data, parent, model); + public BlockBaseMaterial(String name, CollisionShape shape, Class... components) { + super(name); this.components = ImmutableSet.copyOf(components); this.shape = shape; } - protected BlockMaterial(String name, short id, CollisionShape shape, Class... components) { + protected BlockBaseMaterial(String name, int id, CollisionShape shape, Class... components) { super(name, id); this.components = ImmutableSet.copyOf(components); this.shape = shape; } - protected BlockMaterial(String name, CollisionShape shape, Class... components) { - super(name); - this.components = ImmutableSet.copyOf(components); - this.shape = shape; - } - - /** - * Gets the block material with the given id, or null if none found - * - * @param id to get - * @return block, or null if none found - */ - public static BlockMaterial get(short id) { - Material mat = Material.get(id); - if (!(mat instanceof BlockMaterial)) { - return null; - } - - return (BlockMaterial) mat; - } - - /** - * Gets the block (sub-)material with the given id and data, or null if none found - * - * @param id to get - * @return block, or null if none found - */ - public static BlockMaterial get(short id, short data) { - Material m = Material.get(id, data); - if (m instanceof BlockMaterial) { - return (BlockMaterial) m; - } - return null; - } - - /** - * Gets the associated block material with it's name. Case-insensitive. - * - * @param name to lookup - * @return material, or null if none found - */ - public static BlockMaterial get(String name) { - Material mat = Material.get(name); - if (!(mat instanceof BlockMaterial)) { - return null; - } - - return (BlockMaterial) mat; - } - - @Override - public BlockMaterial getSubMaterial(short data) { - return (BlockMaterial) super.getSubMaterial(data); - } - /** * Gets the hardness of this block * @@ -157,34 +85,26 @@ public float getHardness() { * Sets the hardness of this block * * @param hardness hardness value + * * @return this material */ - public BlockMaterial setHardness(float hardness) { + public BlockBaseMaterial setHardness(float hardness) { this.hardness = hardness; return this; } - /** - * Gets the amount of light this block emits - * - * @return light level - */ - public byte getLightLevel(short data) { - return 0; - } - /** * Gets the amount of light this block emits * * @return light level */ public byte getLightLevel() { - return getLightLevel(getData()); + return 0; } /** * Gets the amount of light blocked by this block. - * + *

* 0xF (15) represents a fully opaque block. * * @return opacity @@ -204,40 +124,41 @@ public boolean isOpaque() { /** * Sets the amount of light blocked by this block. - * + *

* 0xF (15) represents a fully opaque block. * * @param level of opacity, a value from 0 to 15 + * * @return this material */ - public BlockMaterial setOpacity(int level) { + public BlockBaseMaterial setOpacity(int level) { this.opacity = (byte) GenericMath.clamp(level, 0, 15); return this; } /** - * Turns this Block Material in a fully opaque block, not letting light through from any side
Sets opacity to 15 and sets occlusion to all faces + * Turns this Block BaseMaterial in a fully opaque block, not letting light through from any side
Sets opacity to 15 and sets occlusion to all faces * - * @return this Block Material + * @return this Block BaseMaterial */ - public BlockMaterial setOpaque() { + public BlockBaseMaterial setOpaque() { this.occlusion.set(BlockFaces.NESWBT); return this.setOpacity(15); } /** - * Turns this Block Material in a fully transparent block, letting light through from all sides
Sets the opacity to 0 and sets occlusion to none + * Turns this Block BaseMaterial in a fully transparent block, letting light through from all sides
Sets the opacity to 0 and sets occlusion to none * - * @return this Block Material + * @return this Block BaseMaterial */ - public BlockMaterial setTransparent() { + public BlockBaseMaterial setTransparent() { this.occlusion.set(BlockFaces.NONE); return this.setOpacity(0); } /** * True if this block acts as an obstacle when placing a block on it false if not. - * + *

* If the block is not an obstacle, placement will replace this block. * * @return if this block acts as a placement obstacle @@ -259,16 +180,18 @@ public boolean hasPhysics() { * Called when a block near to this material is changed.
* * @param oldMaterial the previous material, or null if the update was not due to a material change - * @param block that got updated + * @param block that got updated + * * @return true if the block was updated */ - public void onUpdate(BlockMaterial oldMaterial, Block block) { + public void onUpdate(BlockBaseMaterial oldMaterial, Block block) { } /** * Performs the block destroy procedure * * @param block to destroy + * * @return True if destroying was successful */ public boolean destroy(Block block, Cause cause) { @@ -283,10 +206,11 @@ public boolean destroy(Block block, Cause cause) { * Called when this block has to be destroyed.
This function performs the actual destruction of the block. * * @param block that got destroyed + * * @return true if the destruction occurred */ public boolean onDestroy(Block block, Cause cause) { - return block.setMaterial(AIR, cause); + return block.setMaterial(getDestroyed_material(), cause); } /** @@ -298,7 +222,7 @@ public void onPostDestroy(Block block) { } /** - * Gets the occluded faces of this Block Material for the data value specified
Occluded faces do not let light though and require rendering behind it at those faces + * Gets the occluded faces of this Block BaseMaterial for the data value specified
Occluded faces do not let light though and require rendering behind it at those faces * * @return the occluded faces */ @@ -307,24 +231,25 @@ public ByteBitSet getOcclusion() { } /** - * Sets the occludes faces of this Block Material
Occluded faces do not let light though and require rendering behind it at those faces + * Sets the occludes faces of this Block BaseMaterial
Occluded faces do not let light though and require rendering behind it at those faces + * + * @param faces to make this Block BaseMaterial occlude * - * @param data of this Block Material - * @param faces to make this Block Material occlude - * @return this Block Material + * @return this Block BaseMaterial */ - public BlockMaterial setOcclusion(BlockFaces faces) { + public BlockBaseMaterial setOcclusion(BlockFaces faces) { this.getOcclusion().set(faces); return this; } /** - * Sets the occludes face of this Block Material
Occluded faces do not let light though and require rendering behind it at those faces + * Sets the occludes face of this Block BaseMaterial
Occluded faces do not let light though and require rendering behind it at those faces * - * @param face to make this Block Material occlude - * @return this Block Material + * @param face to make this Block BaseMaterial occlude + * + * @return this Block BaseMaterial */ - public BlockMaterial setOcclusion(BlockFace face) { + public BlockBaseMaterial setOcclusion(BlockFace face) { this.getOcclusion().set(face); return this; } @@ -332,10 +257,10 @@ public BlockMaterial setOcclusion(BlockFace face) { /** * Gets if the material occludes the adjacent face (in other words, if that face is rendered on this material) * - * @param face the fact to render + * @param face the fact to render * @param material the material of the neighbouring block */ - public boolean occludes(BlockFace face, BlockMaterial material) { + public boolean occludes(BlockFace face, BlockBaseMaterial material) { return getOcclusion().isAny(face); } @@ -350,12 +275,14 @@ public void onPlacement(Block block, short data, BlockFace against, Vector3f cli } /** - * Checks the block to see if it can be created at that position
Orientation-specific checks are performed in the {@link #canPlace(com.flowpowered.api.geo.cuboid.Block, short, com.flowpowered.api.material.block.BlockFace, com.flowpowered.math.vector.Vector3f, boolean, com.flowpowered.api.event.Cause)} method
Use this method to see if creation is possible at a + * Checks the block to see if it can be created at that position
Orientation-specific checks are performed in the {@link #canPlace(com.flowpowered.api.geo.cuboid.Block, short, + * com.flowpowered.api.material.block.BlockFace, com.flowpowered.math.vector.Vector3f, boolean, com.flowpowered.events.Cause)} method
Use this method to see if creation is possible at a * given position when not placed * - * @param block this Block Material should be created in - * @param data for the material + * @param block this Block BaseMaterial should be created in + * @param data for the material * @param cause of this creation + * * @return True if creation is possible, False if not */ public boolean canCreate(Block block, short data, Cause cause) { @@ -363,11 +290,12 @@ public boolean canCreate(Block block, short data, Cause cause) { } /** - * Creates this Block Material at a block in the world
Orientation-specific changes are performed in the {@link #onPlacement(com.flowpowered.api.geo.cuboid.Block, short, com.flowpowered.api.material.block.BlockFace, com.flowpowered.math.vector.Vector3f, boolean, com.flowpowered.api.event.Cause)} method
Use this method to create the block at a given position + * Creates this Block BaseMaterial at a block in the world
Orientation-specific changes are performed in the {@link #onPlacement(com.flowpowered.api.geo.cuboid.Block, short, + * com.flowpowered.api.material.block.BlockFace, com.flowpowered.math.vector.Vector3f, boolean, com.flowpowered.events.Cause)} method
Use this method to create the block at a given position * when not placed * - * @param block to create this Block Material in - * @param data for the material + * @param block to create this Block BaseMaterial in + * @param data for the material * @param cause of this creation */ public void onCreate(Block block, short data, Cause cause) { @@ -386,7 +314,7 @@ public boolean isInvisible() { /** * Turns this material invisible and sets it as non-occluding. Invisible blocks are not rendered. */ - public BlockMaterial setInvisible() { + public BlockBaseMaterial setInvisible() { this.invisible = true; this.occlusion.set(BlockFaces.NONE); return this; @@ -405,33 +333,36 @@ public boolean isTransparent() { * Called by the dynamic block update system. If a material is changed into a material that it is not compatible with, then this will automatically trigger a block reset. * * @param m the other material + * * @return true if the two materials are compatible */ - public boolean isCompatibleWith(BlockMaterial m) { - return (m.getId() == getId() && ((m.getData() ^ getData()) & getDataMask()) == 0); + public boolean isCompatibleWith(BlockBaseMaterial m) { + return (m.getId() == getId()); } /** * Helper method to create a MaterialCause. - * + *

* Same as using new MaterialCause(material, block) * * @param block location of the event + * * @return cause */ - public Cause toCause(Block block) { + public Cause toCause(Block block) { return new MaterialCause<>(this, block); } /** * Helper method to create a MaterialCause. - * + *

* Same as using new MaterialCause(material, block) * * @param p location of the event + * * @return cause */ - public Cause toCause(Point p) { + public Cause toCause(Point p) { return new MaterialCause<>(this, p.getWorld().getBlock(p)); } @@ -440,7 +371,7 @@ public Set> getComponents() { } /** - * Returns if this BlockMaterial is a ghost object. + * Returns if this BlockBaseMaterial is a ghost object. * * @return True if ghost, false if not */ @@ -449,8 +380,10 @@ public boolean isGhost() { } /** - * Sets if this BlockMaterial should be a detector "ghost" material.

This means any collisions with this BlockMaterial will not incur adjustments for the {@link Entity} which collided: instead - * callbacks will be alerted and the Entity will be able to move freely through this BlockMaterial (by default).

If this BlockMaterial has a null {@link CollisionShape}, this setting will have no + * Sets if this BlockBaseMaterial should be a detector "ghost" material.

This means any collisions with this BlockBaseMaterial will not incur adjustments for the {@link Entity} which collided: + * instead + * callbacks will be alerted and the Entity will be able to move freely through this BlockBaseMaterial (by default).

If this BlockBaseMaterial has a null {@link CollisionShape}, this setting will + * have no * effect until a reference is set. */ public void setGhost(final boolean isGhost) { @@ -458,7 +391,7 @@ public void setGhost(final boolean isGhost) { } /** - * Get the mass of this BlockMaterial + * Get the mass of this BlockBaseMaterial * * @return The mass */ @@ -467,13 +400,15 @@ public float getMass() { } /** - * Sets the mass of this BlockMaterial + * Sets the mass of this BlockBaseMaterial * * @param mass The new mass + * * @return This material, for chaining + * * @throws IllegalArgumentException If provided mass is < 1f */ - public BlockMaterial setMass(final float mass) { + public BlockBaseMaterial setMass(final float mass) { if (mass < 1) { throw new IllegalArgumentException("Mass must be greater than or equal to 1f"); } @@ -482,7 +417,7 @@ public BlockMaterial setMass(final float mass) { } /** - * Get the friction of this BlockMaterial + * Get the friction of this BlockBaseMaterial * * @return The friction */ @@ -491,13 +426,15 @@ public float getFriction() { } /** - * Sets the friction of this BlockMaterial + * Sets the friction of this BlockBaseMaterial * * @param friction The new friction + * * @return This material, for chaining + * * @throws IllegalArgumentException If provided friction is < 0f */ - public BlockMaterial setFriction(final float friction) { + public BlockBaseMaterial setFriction(final float friction) { if (friction < 0 || friction > 1) { throw new IllegalArgumentException("Friction must be between 0 and 1 (inclusive)"); } @@ -506,7 +443,7 @@ public BlockMaterial setFriction(final float friction) { } /** - * Get the restitution of this BlockMaterial + * Get the restitution of this BlockBaseMaterial * * @return The restitution */ @@ -515,13 +452,15 @@ public float getRestitution() { } /** - * Sets the restitution of this BlockMaterial + * Sets the restitution of this BlockBaseMaterial * * @param restitution The new restitution + * * @return This material, for chaining + * * @throws IllegalArgumentException If provided restitution is < 0f */ - public BlockMaterial setRestitution(final float restitution) { + public BlockBaseMaterial setRestitution(final float restitution) { if (restitution < 0 || restitution > 1) { throw new IllegalArgumentException("Restitution must be between 0 and 1 (inclusive)"); } @@ -530,7 +469,7 @@ public BlockMaterial setRestitution(final float restitution) { } /** - * Gets the {@link CollisionShape} this BlockMaterial has. + * Gets the {@link CollisionShape} this BlockBaseMaterial has. * * @return the collision shape */ @@ -539,13 +478,35 @@ public CollisionShape getShape() { } /** - * Sets the {@link CollisionShape} this BlockMaterial has/ + * Sets the {@link CollisionShape} this BlockBaseMaterial has/ * * @param shape The new collision shape + * * @return This material, for chaining */ - public BlockMaterial setShape(final CollisionShape shape) { + public BlockBaseMaterial setShape(final CollisionShape shape) { this.shape = shape; return this; } + + /** + * Gets the material which is used in replacement for the destroyed original material + * + * @return material which is used in replacement for the destroyed original material + */ + public BlockBaseMaterial getDestroyed_material() { + return destroyed_material; + } + + /** + * Sets the material which is used in replacement for the destroyed original material + * + * @param destroyed_material which is used in replacement for the destroyed original material + * + * @return This material, for chaining + */ + public BlockBaseMaterial setDestroyed_material(final BlockBaseMaterial destroyed_material) { + this.destroyed_material = destroyed_material; + return this; + } } diff --git a/src/main/java/com/flowpowered/api/material/Material.java b/src/main/java/com/flowpowered/api/material/Material.java deleted file mode 100644 index 2de1965..0000000 --- a/src/main/java/com/flowpowered/api/material/Material.java +++ /dev/null @@ -1,353 +0,0 @@ -/* - * This file is part of Flow Engine, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Spout LLC - * - * 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 com.flowpowered.api.material; - -/** - * Defines the characteristics of Blocks or Items. - */ - -import com.flowpowered.commons.LogicUtil; - -import java.util.Arrays; -import java.util.concurrent.atomic.AtomicReference; - -import com.flowpowered.math.GenericMath; - -public abstract class Material extends MaterialRegistry { - private final short id; - private final short data; - private final String name; - private final boolean isSubMaterial; - private final Material parent; - private final Material root; - private String displayName; - private int maxStackSize = 64; - private short maxData = Short.MAX_VALUE; - private final AtomicReference subMaterials; - private Material[] submaterialsContiguous = null; - private volatile boolean submaterialsDirty = true; - private final short dataMask; - - /** - * Creates a material with a dataMask, name - */ - public Material(short dataMask, String name) { - this.isSubMaterial = false; - this.displayName = name; - this.name = getClass().getCanonicalName() + "_" + name.replace(' ', '_'); - this.parent = this; - this.data = 0; - this.id = (short) MaterialRegistry.register(this); - this.subMaterials = MaterialRegistry.getSubMaterialReference(this.id); - this.dataMask = dataMask; - this.root = this; - } - - /** - * Creates and registers a material - * - * @param name of the material - */ - public Material(String name) { - this((short) 0, name); - } - - /** - * Creates and registers a sub material - * - * @param name of the material - * @param parent material - */ - public Material(String name, int data, Material parent) { - this(name, data, parent, null); - } - - /** - * Creates and registers a sub material - * - * @param name of the material - * @param parent material - */ - public Material(String name, int data, Material parent, String model) { - this.isSubMaterial = true; - this.displayName = name; - this.name = name.replace(' ', '_'); - this.parent = parent; - this.data = (short) data; - this.id = (short) MaterialRegistry.register(this); - this.subMaterials = MaterialRegistry.getSubMaterialReference(this.id); - this.dataMask = parent.getDataMask(); - this.root = parent.getRoot(); - } - - /** - * Creates a material with a reserved id - * - * @param name of the material - * @param id to reserve - */ - protected Material(String name, short id) { - this.isSubMaterial = false; - this.displayName = name; - this.name = name.replace(' ', '_'); - this.parent = this; - this.data = 0; - this.id = (short) MaterialRegistry.register(this, id); - this.subMaterials = MaterialRegistry.getSubMaterialReference(this.id); - this.dataMask = 0; - this.root = this; - } - - public final short getId() { - return this.id; - } - - /** - * Gets the data value associated with this material. if this material does not have or is not a sub material, then (getData() & getDataMask()) is equal to zero. - * - * @return data value - */ - public final short getData() { - return this.data; - } - - /** - * Gets the data mask for this material, and sub-materials. When determining sub-material, this mask is applied to the data before the comparison is performed. - * - * @return data mask - */ - public final short getDataMask() { - return this.dataMask; - } - - /** - * Checks if this material is a sub material or not - * - * @return true if it is a sub material - */ - public final boolean isSubMaterial() { - return isSubMaterial; - } - - /** - * Checks if this material has other materials mapped by data - * - * @return true if this material has sub materials - */ - public final boolean hasSubMaterials() { - return this.subMaterials.get().length > 1; - } - - /** - * Gets all sub materials of this material - * - * @return an array of sub materials - */ - public final Material[] getSubMaterials() { - if (submaterialsDirty) { - int materialCount = 0; - Material[] sm = subMaterials.get(); - for (int i = 0; i < sm.length; i++) { - if (sm[i] != null) { - materialCount++; - } - } - Material[] newSubmaterials = new Material[materialCount]; - materialCount = 0; - for (int i = 0; i < sm.length; i++) { - if (sm[i] != null) { - newSubmaterials[materialCount++] = sm[i]; - } - } - this.submaterialsContiguous = newSubmaterials; - submaterialsDirty = false; - } - Material[] sm = submaterialsContiguous; - return Arrays.copyOf(sm, sm.length); - } - - /** - * Recursively gets the sub material mapped to the data value specified - * - * @param data to search for - * @return the sub material, or this material if not found - */ - public Material getSubMaterial(short data) { - short maskedData = (short) (data & dataMask); - return subMaterials.get()[maskedData]; - } - - /** - * Registers the sub material for this material - * - * @param material to register - */ - public final void registerSubMaterial(Material material) { - submaterialsDirty = true; - try { - int data = material.data & 0xFFFF; - if ((data & dataMask) != data) { - throw new IllegalArgumentException("Sub material of: " + material.getId() + " with data value: " + data + " is outside data mask: " + Integer.toHexString(dataMask)); - } - if (material.isSubMaterial) { - if (material.getParentMaterial() == this) { - boolean success = false; - while (!success) { - Material[] sm = subMaterials.get(); - if (data >= sm.length) { - int newSize = GenericMath.roundUpPow2(data + (data >> 1) + 1); - Material[] newSubmaterials = new Material[newSize]; - System.arraycopy(sm, 0, newSubmaterials, 0, sm.length); - success = subMaterials.compareAndSet(sm, newSubmaterials); - } else { - success = true; - } - } - Material[] sm = subMaterials.get(); - if (sm[data] == null) { - sm[data] = material; - } else { - throw new IllegalArgumentException("Two sub material registered for the same data value"); - } - } else { - throw new IllegalArgumentException("Sub Material is registered to a material different than the parent!"); - } - } else { - throw new IllegalArgumentException("Material is not a valid sub material!"); - } - } finally { - submaterialsDirty = true; - } - } - - /** - * Gets the parent of this sub material - * - * @return the material of the parent - */ - public Material getParentMaterial() { - return this.parent; - } - - /** - * Gets the root parent of this sub material - * - * @return the material root - */ - public Material getRoot() { - return this.root; - } - - /** - * Gets the name of this material - * - * @return the name - */ - public final String getName() { - return this.name; - } - - /** - * Gets the display name of this material - * - * @return the display name - */ - public final String getDisplayName() { - return this.displayName; - } - - /** - * Sets the display name of this material - * - * @param name the new display name - */ - public final void setDisplayName(String name) { - this.displayName = name; - } - - /** - * Gets the maximum size of a stack of this material - * - * @return the current max size - */ - public final int getMaxStackSize() { - return this.maxStackSize; - } - - /** - * Sets the maximum size of a stack of this material - * - * @param newValue the new maximum stack size - */ - public final void setMaxStackSize(int newValue) { - this.maxStackSize = newValue; - } - - /** - * Gets the maximum data a stack of this material can have - */ - public final short getMaxData() { - return this.maxData; - } - - /** - * Sets the maximum of the data value this material can have - * - * @param newValue the new maximum data - */ - public final void setMaxData(short newValue) { - this.maxData = newValue; - } - - public boolean isMaterial(Material... materials) { - if (LogicUtil.equalsAny(this, materials)) { - return true; - } - if (this.getRoot() != this && LogicUtil.equalsAny(this.getRoot(), materials)) { - return true; - } - return false; - } - - @Override - public boolean equals(Object other) { - if (other instanceof Material) { - return other == this; - } else { - return false; - } - } - - @Override - public String toString() { - return "Material {" + getName() + "}"; - } - - /** - * Indicates that the dataMask covers the least significant bits.

This method is used when verifying that the dataMask is set correctly - */ - public boolean hasLSBDataMask() { - return true; - } -} diff --git a/src/main/java/com/flowpowered/api/material/MaterialRegistry.java b/src/main/java/com/flowpowered/api/material/MaterialRegistry.java index 5ac9c73..b75c4a7 100644 --- a/src/main/java/com/flowpowered/api/material/MaterialRegistry.java +++ b/src/main/java/com/flowpowered/api/material/MaterialRegistry.java @@ -28,8 +28,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; -import com.flowpowered.api.Server; import com.flowpowered.api.Flow; +import com.flowpowered.api.Server; import com.flowpowered.api.material.block.BlockFullState; import com.flowpowered.api.util.SyncedStringMap; import com.flowpowered.commons.store.BinaryFileStore; @@ -40,24 +40,25 @@ * Handles all registered materials on the server statically. */ public abstract class MaterialRegistry { - private final static ConcurrentHashMap nameLookup = new ConcurrentHashMap<>(1000); + + private final static ConcurrentHashMap nameLookup = new ConcurrentHashMap<>(1000); private final static int MAX_SIZE = 1 << 16; - @SuppressWarnings ("unchecked") - private final static AtomicReference[] materialLookup = new AtomicReference[MAX_SIZE]; + @SuppressWarnings("unchecked") + private final static AtomicReference[] materialLookup = new AtomicReference[MAX_SIZE]; private static boolean setup = false; private static SyncedStringMap materialRegistry; - private final static Material[] NULL_MATERIAL_ARRAY = new Material[] {null}; + private final static BaseMaterial[] NULL_BASIC_MATERIAL_ARRAY = new BaseMaterial[]{null}; static { for (int i = 0; i < materialLookup.length; i++) { materialLookup[i] = new AtomicReference<>(); - materialLookup[i].set(NULL_MATERIAL_ARRAY); + materialLookup[i].set(NULL_BASIC_MATERIAL_ARRAY); } } /** * Sets up the material registry for its first use. May not be called more than once.
This attempts to load the materials.dat file from the 'worlds' directory into memory.
- * + *

* Can throw an {@link IllegalStateException} if the material registry has already been setup. * * @return StringToUniqueIntegerMap of registered materials @@ -66,11 +67,11 @@ public static SyncedStringMap setupRegistry() { if (setup) { throw new IllegalStateException("Can not setup material registry twice!"); } - if (Flow.getPlatform().isServer()) { - setupServer(); - } else { - setupClient(); - } + if (Flow.getPlatform().isServer()) { + setupServer(); + } else { + setupClient(); + } setup = true; return materialRegistry; @@ -79,57 +80,59 @@ public static SyncedStringMap setupRegistry() { private static void setupServer() { File serverItemMap = new File(((Server) Flow.getEngine()).getWorldManager().getWorldFolder(), "materials.dat"); BinaryFileStore store = new BinaryFileStore(serverItemMap); - materialRegistry = SyncedStringMap.create(null, store, 1, Short.MAX_VALUE, Material.class.getName()); + materialRegistry = SyncedStringMap.create(null, store, 1, Short.MAX_VALUE, BaseMaterial.class.getName()); if (serverItemMap.exists()) { store.load(); } } private static void setupClient() { - materialRegistry = SyncedStringMap.create(null, new MemoryStore(), 1, Short.MAX_VALUE, Material.class.getName()); + materialRegistry = SyncedStringMap.create(null, new MemoryStore(), 1, Short.MAX_VALUE, BaseMaterial.class.getName()); } /** - * Registers the material in the material lookup service + * Registers the baseMaterial in the baseMaterial lookup service * - * @param material to register - * @return id of the material registered + * @param baseMaterial to register + * + * @return id of the baseMaterial registered */ - protected static int register(Material material) { - if (material.isSubMaterial()) { - material.getParentMaterial().registerSubMaterial(material); - nameLookup.put(formatName(material.getDisplayName()), material); - return material.getParentMaterial().getId(); + protected static int register(BaseMaterial baseMaterial) { + if (baseMaterial.isSubMaterial()) { + baseMaterial.getParentMaterial().registerSubMaterial(baseMaterial); + nameLookup.put(formatName(baseMaterial.getDisplayName()), baseMaterial); + return baseMaterial.getParentMaterial().getId(); } else { - int id = materialRegistry.register(material.getName()); - Material[] subArray = new Material[] {material}; - if (!materialLookup[id].compareAndSet(NULL_MATERIAL_ARRAY, subArray)) { - throw new IllegalArgumentException(materialLookup[id].get() + " is already mapped to id: " + material.getId() + "!"); + int id = materialRegistry.register(baseMaterial.getName()); + BaseMaterial[] subArray = new BaseMaterial[]{baseMaterial}; + if (!materialLookup[id].compareAndSet(NULL_BASIC_MATERIAL_ARRAY, subArray)) { + throw new IllegalArgumentException(materialLookup[id].get() + " is already mapped to id: " + baseMaterial.getId() + "!"); } - nameLookup.put(formatName(material.getDisplayName()), material); + nameLookup.put(formatName(baseMaterial.getDisplayName()), baseMaterial); return id; } } - protected static AtomicReference getSubMaterialReference(short id) { + protected static AtomicReference getSubMaterialReference(short id) { return materialLookup[id]; } /** - * Registers the material in the material lookup service + * Registers the baseMaterial in the baseMaterial lookup service + * + * @param baseMaterial to register * - * @param material to register - * @return id of the material registered. + * @return id of the baseMaterial registered. */ - protected static int register(Material material, int id) { - materialRegistry.register(material.getName(), id); - Material[] subArray = new Material[] {material}; - if (!materialLookup[id].compareAndSet(NULL_MATERIAL_ARRAY, subArray)) { - throw new IllegalArgumentException(materialLookup[id].get()[0] + " is already mapped to id: " + material.getId() + "!"); + protected static int register(BaseMaterial baseMaterial, int id) { + materialRegistry.register(baseMaterial.getName(), id); + BaseMaterial[] subArray = new BaseMaterial[]{baseMaterial}; + if (!materialLookup[id].compareAndSet(NULL_BASIC_MATERIAL_ARRAY, subArray)) { + throw new IllegalArgumentException(materialLookup[id].get()[0] + " is already mapped to id: " + baseMaterial.getId() + "!"); } - nameLookup.put(formatName(material.getName()), material); + nameLookup.put(formatName(baseMaterial.getName()), baseMaterial); return id; } @@ -137,9 +140,10 @@ protected static int register(Material material, int id) { * Gets the material from the given id * * @param id to get + * * @return material or null if none found */ - public static Material get(short id) { + public static BaseMaterial get(short id) { if (id < 0 || id >= materialLookup.length) { return null; } @@ -149,15 +153,16 @@ public static Material get(short id) { /** * Gets the material from the given id and data * - * @param id to get + * @param id to get * @param data to get + * * @return material or null if none found */ - public static Material get(short id, short data) { + public static BaseMaterial get(short id, short data) { if (id < 0 || id >= materialLookup.length) { return null; } - Material[] parent = materialLookup[id].get(); + BaseMaterial[] parent = materialLookup[id].get(); if (parent[0] == null) { return null; } @@ -170,9 +175,10 @@ public static Material get(short id, short data) { * Gets the material for the given BlockFullState * * @param state the full state of the block - * @return Material of the BlockFullState + * + * @return BaseMaterial of the BlockFullState */ - public static Material get(BlockFullState state) { + public static BaseMaterial get(BlockFullState state) { return get(state.getPacked()); } @@ -180,18 +186,19 @@ public static Material get(BlockFullState state) { * Gets the material for the given packed full state * * @param state the full state of the block - * @return Material of the id + * + * @return BaseMaterial of the id */ - public static BlockMaterial get(int packedState) { + public static BlockBaseMaterial get(int packedState) { short id = BlockFullState.getId(packedState); if (id < 0 || id >= materialLookup.length) { return null; } - Material[] material = materialLookup[id].get(); - if (material[0] == null) { + BaseMaterial[] baseMaterial = materialLookup[id].get(); + if (baseMaterial[0] == null) { return null; } - return (BlockMaterial) material[BlockFullState.getData(packedState) & (material[0].getDataMask())]; + return (BlockBaseMaterial) baseMaterial[BlockFullState.getData(packedState) & (baseMaterial[0].getDataMask())]; } /** @@ -199,30 +206,31 @@ public static BlockMaterial get(int packedState) { * * @return an array of all materials */ - public static Material[] values() { + public static BaseMaterial[] values() { //TODO: This is wrong, need to count # of registered materials - HashSet set = new HashSet<>(1000); + HashSet set = new HashSet<>(1000); for (int i = 0; i < materialLookup.length; i++) { if (materialLookup[i].get() != null) { set.add(materialLookup[i].get()[0]); } } - return set.toArray(new Material[0]); + return set.toArray(new BaseMaterial[0]); } /** * Gets the associated material with its name. Case-insensitive. * * @param name to lookup + * * @return material, or null if none found */ - public static Material get(String name) { + public static BaseMaterial get(String name) { return nameLookup.get(formatName(name)); } /** * Returns a human legible material name from the full material. - * + *

* This will strip any '_' and replace with spaces, strip out extra whitespace, and lowercase the material name. * * @return human legible name of the material. @@ -235,10 +243,11 @@ private static String formatName(String matName) { * Gets the minimum data mask required to account for all sub-materials of the material * * @param m the material + * * @return the minimum data mask */ - public static short getMinimumDatamask(Material m) { - Material root = m; + public static short getMinimumDatamask(BaseMaterial m) { + BaseMaterial root = m; while (root.isSubMaterial()) { root = m.getParentMaterial(); } @@ -246,11 +255,11 @@ public static short getMinimumDatamask(Material m) { if (root.getData() != 0) { throw new IllegalStateException("Root materials must have data set to zero"); } - Material[] subMaterials = root.getSubMaterials(); + BaseMaterial[] subBaseMaterials = root.getSubMaterials(); short minimumMask = 0; - for (Material sm : subMaterials) { + for (BaseMaterial sm : subBaseMaterials) { minimumMask |= sm.getData() & 0xFFFF; } diff --git a/src/main/java/com/flowpowered/api/material/Placeable.java b/src/main/java/com/flowpowered/api/material/Placeable.java index 7807e11..b1b8405 100644 --- a/src/main/java/com/flowpowered/api/material/Placeable.java +++ b/src/main/java/com/flowpowered/api/material/Placeable.java @@ -23,24 +23,25 @@ */ package com.flowpowered.api.material; -import com.flowpowered.events.Cause; - import com.flowpowered.api.geo.cuboid.Block; import com.flowpowered.api.material.block.BlockFace; +import com.flowpowered.events.Cause; import com.flowpowered.math.vector.Vector3f; /** - * An interface defining a {@link Material} that can be placed + * An interface defining a {@link BaseMaterial} that can be placed */ public interface Placeable { + /** * Called when this block is about to be placed (before {@link #onPlacement(Block, short, BlockFace, boolean)}), checking if placement is allowed or not. * - * @param block to place - * @param data block data to use during placement - * @param against face against the block is placed + * @param block to place + * @param data block data to use during placement + * @param against face against the block is placed * @param isClickedBlock whether the block is to be placed at the clicked block - * @param cause the cause of the placement + * @param cause the cause of the placement + * * @return true if placement is allowed */ public boolean canPlace(Block block, short data, BlockFace against, Vector3f clickedPos, boolean isClickedBlock, Cause cause); @@ -49,12 +50,12 @@ public interface Placeable { * Called when this block is placed, handling the actual placement
This method should only change properties that rely on the face it is placed against, or in what way it is placed. All other * logic should be performed in onCreate. * - * @param block to affect - * @param data block data to use during placement - * @param against face against the block is placed - * @param clickedPos relative position the block was clicked to place this block + * @param block to affect + * @param data block data to use during placement + * @param against face against the block is placed + * @param clickedPos relative position the block was clicked to place this block * @param isClickedBlock whether the block is being placed at the clicked block - * @param cause the cause of the placement + * @param cause the cause of the placement */ public void onPlacement(Block block, short data, BlockFace against, Vector3f clickedPos, boolean isClickedBlock, Cause cause); } diff --git a/src/main/java/com/flowpowered/api/material/basic/Air.java b/src/main/java/com/flowpowered/api/material/basic/Air.java index a8c4b1b..7b65f9e 100644 --- a/src/main/java/com/flowpowered/api/material/basic/Air.java +++ b/src/main/java/com/flowpowered/api/material/basic/Air.java @@ -23,16 +23,17 @@ */ package com.flowpowered.api.material.basic; -import com.flowpowered.events.Cause; import com.flowpowered.api.geo.cuboid.Block; +import com.flowpowered.api.material.BlockBaseMaterial; +import com.flowpowered.events.Cause; -import com.flowpowered.api.material.BlockMaterial; +public final class Air extends BlockBaseMaterial { -public final class Air extends BlockMaterial { - @SuppressWarnings ("unchecked") + @SuppressWarnings("unchecked") public Air() { super("Air", (short) 0, null); - this.setTransparent().setInvisible(); + setTransparent().setInvisible(); + setMaterialState(MATERIAL_STATE.GAS); } @Override @@ -44,4 +45,4 @@ public boolean isPlacementObstacle() { public boolean onDestroy(Block block, Cause cause) { return false; } -} \ No newline at end of file +} diff --git a/src/main/java/com/flowpowered/api/material/basic/Solid.java b/src/main/java/com/flowpowered/api/material/basic/Solid.java index b00c8cd..edf9038 100644 --- a/src/main/java/com/flowpowered/api/material/basic/Solid.java +++ b/src/main/java/com/flowpowered/api/material/basic/Solid.java @@ -23,14 +23,16 @@ */ package com.flowpowered.api.material.basic; -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import org.spout.physics.collision.shape.BoxShape; import org.spout.physics.math.Vector3; -public class Solid extends BlockMaterial { +public class Solid extends BlockBaseMaterial { + public Solid(String name) { super((short) 0, name, new BoxShape(new Vector3(1f, 1f, 1f))); setHardness(100); + setMaterialState(MATERIAL_STATE.SOLID); } } diff --git a/src/main/java/com/flowpowered/api/material/block/BlockFullState.java b/src/main/java/com/flowpowered/api/material/block/BlockFullState.java index 0ca0736..d3459f4 100644 --- a/src/main/java/com/flowpowered/api/material/block/BlockFullState.java +++ b/src/main/java/com/flowpowered/api/material/block/BlockFullState.java @@ -23,16 +23,16 @@ */ package com.flowpowered.api.material.block; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.commons.StringUtil; import org.apache.commons.lang3.builder.HashCodeBuilder; -import com.flowpowered.api.material.BlockMaterial; - /** * Represents a {@link Block}'s ID and Data values, but contains no location-specific information. */ public class BlockFullState implements Cloneable { + private final short id; private final short data; @@ -76,8 +76,9 @@ public int getPacked() { /** * Returns an Integer representation of the merged ID and data.
The id will be contained in the upper 16-bits. The data will be contained in the lower 16-bits.
* - * @param id to pack. + * @param id to pack. * @param data to pack. + * * @return integer representation of ID and Data. */ public static int getPacked(short id, short data) { @@ -85,16 +86,18 @@ public static int getPacked(short id, short data) { } /** - * Returns an Integer representation of the ID and Data from a {@link BlockMaterial}.
The id will be contained in the upper 16-bits. The data will be contained in the lower 16-bits.
+ * Returns an Integer representation of the ID and Data from a {@link com.flowpowered.api.material.BlockBaseMaterial}.
The id will be contained in the upper 16-bits. The data will be contained + * in the lower 16-bits.
*/ - public static int getPacked(BlockMaterial m) { + public static int getPacked(BlockBaseMaterial m) { return getPacked(m.getId(), m.getData()); } /** - * Unpacks the ID of a Material or Block from a packed integer.
The integer being passed in must have the ID of the Material or Block contained in the upper 16-bits.
+ * Unpacks the ID of a BaseMaterial or Block from a packed integer.
The integer being passed in must have the ID of the BaseMaterial or Block contained in the upper 16-bits.
* * @param packed integer + * * @return id of the material or block */ public static short getId(int packed) { @@ -102,9 +105,10 @@ public static short getId(int packed) { } /** - * Unpacks the Data of a material or block from a packed integer.
The integer being passed in must have the data of the Material or Block contained in the lower 16-bits.
+ * Unpacks the Data of a material or block from a packed integer.
The integer being passed in must have the data of the BaseMaterial or Block contained in the lower 16-bits.
* * @param packed integer + * * @return data of the material or block. */ public static short getData(int packed) { @@ -112,17 +116,18 @@ public static short getData(int packed) { } /** - * Looks up the BlockMaterial from a packed integer.
If the material does not exist in the {@link BlockMaterialRegistry} then {@link BasicAir} will be returned. If the material does exist, and - * it contains data, the Sub-Material will be returned. + * Looks up the BlockBaseMaterial from a packed integer.
If the material does not exist in the {@link BlockMaterialRegistry} then {@link BasicAir} will be returned. If the material does exist, + * and + * it contains data, the Sub-BaseMaterial will be returned. * * @return the material found. */ - public static BlockMaterial getMaterial(int packed) { + public static BlockBaseMaterial getMaterial(int packed) { short id = getId(packed); short data = getData(packed); - BlockMaterial mat = BlockMaterial.get(id); + BlockBaseMaterial mat = BlockBaseMaterial.get(id); if (mat == null) { - return BlockMaterial.AIR; + return BlockBaseMaterial.AIR; } return mat.getSubMaterial(data); } diff --git a/src/main/java/com/flowpowered/api/material/block/BlockSnapshot.java b/src/main/java/com/flowpowered/api/material/block/BlockSnapshot.java index 73d6fad..462e140 100644 --- a/src/main/java/com/flowpowered/api/material/block/BlockSnapshot.java +++ b/src/main/java/com/flowpowered/api/material/block/BlockSnapshot.java @@ -25,16 +25,16 @@ import com.flowpowered.api.geo.World; import com.flowpowered.api.geo.cuboid.Block; -import com.flowpowered.api.material.BlockMaterial; -import com.flowpowered.api.material.Material; - +import com.flowpowered.api.material.BaseMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.commons.hashing.ShortPairHashed; /** * Represents an immutable snapshot of the state of a block */ public class BlockSnapshot { - private final BlockMaterial material; + + private final BlockBaseMaterial material; private final short data; private final int x, y, z; private final World world; @@ -43,11 +43,11 @@ public BlockSnapshot(Block block) { this(block, block.getMaterial(), block.getBlockData()); } - public BlockSnapshot(Block block, BlockMaterial material, short data) { + public BlockSnapshot(Block block, BlockBaseMaterial material, short data) { this(block.getWorld(), block.getX(), block.getY(), block.getZ(), material, data); } - public BlockSnapshot(World world, int x, int y, int z, BlockMaterial material, short data) { + public BlockSnapshot(World world, int x, int y, int z, BlockBaseMaterial material, short data) { this.material = material; this.data = data; this.x = x; @@ -106,7 +106,7 @@ public Block getBlock() { * * @return the material */ - public BlockMaterial getMaterial() { + public BlockBaseMaterial getMaterial() { return this.material; } @@ -133,16 +133,16 @@ public boolean equals(Object o) { return false; } - public boolean isMaterial(Material... materials) { + public boolean isMaterial(BaseMaterial... baseMaterials) { if (this.material == null) { - for (Material material : materials) { - if (material == null) { + for (BaseMaterial baseMaterial : baseMaterials) { + if (baseMaterial == null) { return true; } } return false; } else { - return this.material.isMaterial(materials); + return this.material.isMaterial(baseMaterials); } } } diff --git a/src/main/java/com/flowpowered/api/util/cuboid/CuboidBlockMaterialBuffer.java b/src/main/java/com/flowpowered/api/util/cuboid/CuboidBlockMaterialBuffer.java index 78769ea..7d892c8 100644 --- a/src/main/java/com/flowpowered/api/util/cuboid/CuboidBlockMaterialBuffer.java +++ b/src/main/java/com/flowpowered/api/util/cuboid/CuboidBlockMaterialBuffer.java @@ -25,10 +25,11 @@ import java.util.Arrays; -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.math.vector.Vector3f; public class CuboidBlockMaterialBuffer extends ImmutableCuboidBlockMaterialBuffer { + private CuboidBlockMaterialBuffer source; private final ImmutableCuboidBlockMaterialBuffer backBuffer; @@ -118,21 +119,21 @@ public void setSource(CuboidBuffer source) { /** * Sets a horizontal layer of blocks to a given material * - * @param y - coordinate of the start of the layer - * @param height of the layer + * @param y - coordinate of the start of the layer + * @param height of the layer * @param material to set to */ - public void setHorizontalLayer(int y, int height, BlockMaterial material) { + public void setHorizontalLayer(int y, int height, BlockBaseMaterial material) { setHorizontalLayer(y, height, material.getId(), material.getData()); } /** * Sets a horizontal layer of blocks to a given material id and data * - * @param y - coordinate of the start of the layer + * @param y - coordinate of the start of the layer * @param height of the layer - * @param id of the material to set to - * @param data to set to + * @param id of the material to set to + * @param data to set to */ public void setHorizontalLayer(int y, int height, short id, short data) { final int startIndex = getIndex(this.baseX, y, this.baseZ); @@ -147,12 +148,12 @@ public void setHorizontalLayer(int y, int height, short id, short data) { /** * Sets a single block material * - * @param x - coordinate of the block - * @param y - coordinate of the block - * @param z - coordinate of the block + * @param x - coordinate of the block + * @param y - coordinate of the block + * @param z - coordinate of the block * @param material to set to */ - public void set(int x, int y, int z, BlockMaterial material) { + public void set(int x, int y, int z, BlockBaseMaterial material) { int index = getIndex(x, y, z); if (index < 0) { throw new IllegalArgumentException("Coordinate (" + x + ", " + y + ", " + z + ") is outside the buffer"); @@ -165,10 +166,10 @@ public void set(int x, int y, int z, BlockMaterial material) { /** * Sets a single block material id and data * - * @param x - coordinate of the block - * @param y - coordinate of the block - * @param z - coordinate of the block - * @param id of the material to set to + * @param x - coordinate of the block + * @param y - coordinate of the block + * @param z - coordinate of the block + * @param id of the material to set to * @param data to set to */ public void set(int x, int y, int z, short id, short data) { @@ -181,7 +182,7 @@ public void set(int x, int y, int z, short id, short data) { this.data[index] = data; } - public void flood(BlockMaterial material) { + public void flood(BlockBaseMaterial material) { for (int i = 0; i < id.length; i++) { this.id[i] = material.getId(); this.data[i] = material.getData(); diff --git a/src/main/java/com/flowpowered/api/util/cuboid/ImmutableCuboidBlockMaterialBuffer.java b/src/main/java/com/flowpowered/api/util/cuboid/ImmutableCuboidBlockMaterialBuffer.java index 8319a73..7c66846 100644 --- a/src/main/java/com/flowpowered/api/util/cuboid/ImmutableCuboidBlockMaterialBuffer.java +++ b/src/main/java/com/flowpowered/api/util/cuboid/ImmutableCuboidBlockMaterialBuffer.java @@ -23,11 +23,12 @@ */ package com.flowpowered.api.util.cuboid; -import com.flowpowered.api.material.BlockMaterial; -import com.flowpowered.math.vector.Vector3f; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.api.util.cuboid.procedure.CuboidBlockMaterialProcedure; +import com.flowpowered.math.vector.Vector3f; public class ImmutableCuboidBlockMaterialBuffer extends CuboidBuffer { + protected final short[] id; protected final short[] data; @@ -66,13 +67,13 @@ public void copyElement(int thisIndex, int sourceIndex, int runLength) { public void setSource(CuboidBuffer source) { } - public BlockMaterial get(int x, int y, int z) { + public BlockBaseMaterial get(int x, int y, int z) { int index = getIndex(x, y, z); if (index < 0) { throw new IllegalArgumentException("Coordinate (" + x + ", " + y + ", " + z + ") is outside the buffer"); } - return BlockMaterial.get(id[index], data[index]); + return BlockBaseMaterial.get(id[index], data[index]); } public short getId(int x, int y, int z) { diff --git a/src/main/java/com/flowpowered/engine/FlowSingleplayer.java b/src/main/java/com/flowpowered/engine/FlowSingleplayer.java index 77a0bbd..db5f0c6 100644 --- a/src/main/java/com/flowpowered/engine/FlowSingleplayer.java +++ b/src/main/java/com/flowpowered/engine/FlowSingleplayer.java @@ -31,80 +31,77 @@ import com.flowpowered.api.Singleplayer; import com.flowpowered.api.entity.Entity; import com.flowpowered.api.entity.Player; +import com.flowpowered.api.generator.FlatWorldGenerator; import com.flowpowered.api.geo.LoadOption; import com.flowpowered.api.geo.World; -import com.flowpowered.api.generator.FlatWorldGenerator; -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.engine.entity.FlowPlayer; import com.flowpowered.engine.geo.world.FlowWorld; import com.flowpowered.engine.render.DeployNatives; import com.flowpowered.engine.render.FlowRenderer; - import com.flowpowered.math.vector.Vector3f; public class FlowSingleplayer extends FlowServer implements Singleplayer { - private final AtomicReference player = new AtomicReference<>(); - private final AtomicReference activeWorld = new AtomicReference<>(); - - // TEST CODE - private Entity testEntity; - public FlowSingleplayer(FlowApplication args) { - super(args); - } + private final AtomicReference player = new AtomicReference<>(); + private final AtomicReference activeWorld = new AtomicReference<>(); + // TEST CODE + private Entity testEntity; - @Override - public void init() { - try { - DeployNatives.deploy(); - } catch (Exception ex) { - Logger.getLogger(FlowSingleplayer.class.getName()).log(Level.SEVERE, null, ex); - return; - } - super.init(); - FlowWorld loadedWorld = getWorldManager().loadWorld("fallback", new FlatWorldGenerator(BlockMaterial.SOLID_BLUE)); - activeWorld.set(loadedWorld); - FlowPlayer player = new FlowPlayer("Flowy"); - this.player.set(player); - players.put(player.getName(), player); - Entity entity = loadedWorld.spawnEntity(Vector3f.ZERO, LoadOption.LOAD_GEN); - this.testEntity = entity; - } + public FlowSingleplayer(FlowApplication args) { + super(args); + } - public Entity getTestEntity() { - return testEntity; - } + @Override + public void init() { + try { + DeployNatives.deploy(); + } catch (Exception ex) { + Logger.getLogger(FlowSingleplayer.class.getName()).log(Level.SEVERE, null, ex); + return; + } + super.init(); + FlowWorld loadedWorld = getWorldManager().loadWorld("fallback", new FlatWorldGenerator(BlockBaseMaterial.SOLID_BLUE)); + activeWorld.set(loadedWorld); + FlowPlayer player = new FlowPlayer("Flowy"); + this.player.set(player); + players.put(player.getName(), player); + Entity entity = loadedWorld.spawnEntity(Vector3f.ZERO, LoadOption.LOAD_GEN); + this.testEntity = entity; + } - @Override - public void start() { - getScheduler().startClientThreads(); - super.start(); - } + public Entity getTestEntity() { + return testEntity; + } - @Override - public boolean stop() { - return super.stop(); - - } + @Override + public void start() { + getScheduler().startClientThreads(); + super.start(); + } - @Override - public Platform getPlatform() { - return Platform.SINGLEPLAYER; - } + @Override + public boolean stop() { + return super.stop(); + } - @Override - public Player getPlayer() { - return player.get(); - } + @Override + public Platform getPlatform() { + return Platform.SINGLEPLAYER; + } - @Override - public World getWorld() { - return activeWorld.get(); - } + @Override + public Player getPlayer() { + return player.get(); + } - @Override - public FlowRenderer getRenderer() { - return getScheduler().getRenderThread().getRenderer(); - } + @Override + public World getWorld() { + return activeWorld.get(); + } + @Override + public FlowRenderer getRenderer() { + return getScheduler().getRenderThread().getRenderer(); + } } diff --git a/src/main/java/com/flowpowered/engine/geo/FlowBlock.java b/src/main/java/com/flowpowered/engine/geo/FlowBlock.java index 5130328..85549ac 100644 --- a/src/main/java/com/flowpowered/engine/geo/FlowBlock.java +++ b/src/main/java/com/flowpowered/engine/geo/FlowBlock.java @@ -23,33 +23,33 @@ */ package com.flowpowered.engine.geo; -import com.flowpowered.engine.geo.chunk.FlowChunk; -import com.flowpowered.engine.geo.world.FlowWorld; -import com.flowpowered.engine.geo.region.FlowRegion; import java.lang.ref.WeakReference; import java.util.Collection; -import com.flowpowered.commons.StringUtil; -import com.flowpowered.commons.datatable.ManagedMap; -import com.flowpowered.events.Cause; - -import org.apache.commons.lang3.builder.HashCodeBuilder; - -import com.flowpowered.api.Platform; import com.flowpowered.api.Flow; +import com.flowpowered.api.Platform; import com.flowpowered.api.component.BlockComponentOwner; import com.flowpowered.api.component.Component; import com.flowpowered.api.geo.LoadOption; import com.flowpowered.api.geo.cuboid.Block; import com.flowpowered.api.geo.cuboid.reference.ChunkReference; import com.flowpowered.api.geo.discrete.Point; -import com.flowpowered.api.material.BlockMaterial; -import com.flowpowered.api.material.Material; +import com.flowpowered.api.material.BaseMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.api.material.block.BlockFace; +import com.flowpowered.commons.StringUtil; +import com.flowpowered.commons.datatable.ManagedMap; +import com.flowpowered.engine.geo.chunk.FlowChunk; +import com.flowpowered.engine.geo.region.FlowRegion; +import com.flowpowered.engine.geo.world.FlowWorld; +import com.flowpowered.events.Cause; import com.flowpowered.math.vector.Vector3f; import com.flowpowered.math.vector.Vector3i; +import org.apache.commons.lang3.builder.HashCodeBuilder; + public class FlowBlock implements Block { + private final int x, y, z; private final WeakReference world; private final ChunkReference chunk; @@ -58,8 +58,8 @@ public FlowBlock(FlowWorld world, int x, int y, int z) { this.x = x; this.y = y; this.z = z; - this.world = new WeakReference<>(world); - this.chunk = new ChunkReference(new Point(getWorld(), this.x, this.y, this.z)); + this.world = new WeakReference<>(world); + this.chunk = new ChunkReference(new Point(getWorld(), this.x, this.y, this.z)); } @Override @@ -69,7 +69,7 @@ public Point getPosition() { @Override public FlowChunk getChunk() { - return (FlowChunk) this.chunk.refresh(LoadOption.LOAD_GEN); + return (FlowChunk) this.chunk.refresh(LoadOption.LOAD_GEN); } @Override @@ -147,7 +147,7 @@ public String toString() { } @Override - public boolean setMaterial(BlockMaterial material, int data, Cause cause) { + public boolean setMaterial(BlockBaseMaterial material, int data, Cause cause) { // TODO once stable, remove this if (Flow.getPlatform() != Platform.SERVER) { throw new UnsupportedOperationException("Temporary lockdown of setMaterial. Server only!"); @@ -156,12 +156,12 @@ public boolean setMaterial(BlockMaterial material, int data, Cause cause) { } @Override - public boolean setMaterial(BlockMaterial material, int data) { + public boolean setMaterial(BlockBaseMaterial material, int data) { return setMaterial(material, data, null); } @Override - public FlowBlock setData(BlockMaterial data) { + public FlowBlock setData(BlockBaseMaterial data) { return this.setData(data.getData()); } @@ -222,23 +222,23 @@ public FlowRegion getRegion() { } @Override - public BlockMaterial getMaterial() { + public BlockBaseMaterial getMaterial() { return this.getChunk().getBlockMaterial(this.x, this.y, this.z); } @Override - public boolean setMaterial(BlockMaterial material) { + public boolean setMaterial(BlockBaseMaterial material) { return this.setMaterial(material, material.getData()); } @Override - public boolean setMaterial(BlockMaterial material, Cause cause) { + public boolean setMaterial(BlockBaseMaterial material, Cause cause) { return this.setMaterial(material, material.getData(), cause); } @Override - public boolean isMaterial(Material... materials) { - return getMaterial().isMaterial(materials); + public boolean isMaterial(BaseMaterial... baseMaterials) { + return getMaterial().isMaterial(baseMaterials); } @Override diff --git a/src/main/java/com/flowpowered/engine/geo/chunk/FlowChunk.java b/src/main/java/com/flowpowered/engine/geo/chunk/FlowChunk.java index 2762e2d..32d2f3c 100644 --- a/src/main/java/com/flowpowered/engine/geo/chunk/FlowChunk.java +++ b/src/main/java/com/flowpowered/engine/geo/chunk/FlowChunk.java @@ -26,195 +26,194 @@ import java.util.List; import java.util.Set; -import gnu.trove.map.hash.TShortObjectHashMap; - -import com.flowpowered.commons.datatable.ManagedHashMap; -import com.flowpowered.commons.hashing.NibbleQuadHashed; -import com.flowpowered.commons.store.block.AtomicBlockStore; -import com.flowpowered.events.Cause; - import com.flowpowered.api.component.BlockComponentOwner; import com.flowpowered.api.entity.Entity; import com.flowpowered.api.entity.Player; import com.flowpowered.api.geo.World; import com.flowpowered.api.geo.cuboid.BlockContainer; import com.flowpowered.api.geo.cuboid.Chunk; -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.api.util.cuboid.CuboidBlockMaterialBuffer; +import com.flowpowered.commons.datatable.ManagedHashMap; +import com.flowpowered.commons.hashing.NibbleQuadHashed; +import com.flowpowered.commons.store.block.AtomicBlockStore; import com.flowpowered.engine.geo.FlowBlock; import com.flowpowered.engine.geo.region.FlowRegion; import com.flowpowered.engine.geo.world.FlowWorld; +import com.flowpowered.events.Cause; import com.flowpowered.math.GenericMath; import com.flowpowered.math.vector.Vector3f; +import gnu.trove.map.hash.TShortObjectHashMap; + public class FlowChunk extends Chunk { - private final FlowRegion region; + private final FlowRegion region; /** * Data map and Datatable associated with it */ protected final ManagedHashMap dataMap; - /** + /** * Not thread safe, synchronize on access */ private final TShortObjectHashMap blockComponents = new TShortObjectHashMap<>(); - private final int generationIndex; + private final int generationIndex; /** * Storage for block ids, data and auxiliary data. For blocks with data = 0 and auxiliary data = null, the block is stored as a short. */ protected final AtomicBlockStore blockStore; - public FlowChunk(FlowRegion region, World world, int x, int y, int z, int generationIndex, AtomicBlockStore blockStore) { - super(world, x << BLOCKS.BITS, y << BLOCKS.BITS, z << BLOCKS.BITS); - this.region = region; - this.dataMap = new ManagedHashMap(); - this.generationIndex = generationIndex; - this.blockStore = blockStore; - } - - @Override - public void unload(boolean save) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void save() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void fillBlockContainer(BlockContainer container) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean refreshObserver(Entity player) { - return true; - } - - @Override - public boolean removeObserver(Entity player) { - return true; - } - - @Override - public FlowRegion getRegion() { - return region; - } - - @Override - public boolean isLoaded() { - return true; - } - - @Override - public boolean populate() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean populate(boolean force) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void populate(boolean sync, boolean observe) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void populate(boolean sync, boolean observe, boolean priority) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isPopulated() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List getEntities() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List getLiveEntities() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getNumObservers() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Set getObservingPlayers() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Set getObservers() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getGenerationIndex() { - return generationIndex; - } - - @Override - public boolean setBlockData(int x, int y, int z, short data, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean setBlockMaterial(int x, int y, int z, BlockMaterial material, short data, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean compareAndSetData(int x, int y, int z, int expect, short data, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public short setBlockDataBits(int x, int y, int z, int bits, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public short setBlockDataBits(int x, int y, int z, int bits, boolean set, Cause source) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public short clearBlockDataBits(int x, int y, int z, int bits, Cause source) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getBlockDataField(int x, int y, int z, int bits) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isBlockDataBitSet(int x, int y, int z, int bits) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int setBlockDataField(int x, int y, int z, int bits, int value, Cause source) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int addBlockDataField(int x, int y, int z, int bits, int value, Cause source) { - throw new UnsupportedOperationException("Not supported yet."); - } + public FlowChunk(FlowRegion region, World world, int x, int y, int z, int generationIndex, AtomicBlockStore blockStore) { + super(world, x << BLOCKS.BITS, y << BLOCKS.BITS, z << BLOCKS.BITS); + this.region = region; + this.dataMap = new ManagedHashMap(); + this.generationIndex = generationIndex; + this.blockStore = blockStore; + } + + @Override + public void unload(boolean save) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void save() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void fillBlockContainer(BlockContainer container) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean refreshObserver(Entity player) { + return true; + } + + @Override + public boolean removeObserver(Entity player) { + return true; + } + + @Override + public FlowRegion getRegion() { + return region; + } + + @Override + public boolean isLoaded() { + return true; + } + + @Override + public boolean populate() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean populate(boolean force) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void populate(boolean sync, boolean observe) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void populate(boolean sync, boolean observe, boolean priority) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isPopulated() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getEntities() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getLiveEntities() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getNumObservers() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Set getObservingPlayers() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Set getObservers() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getGenerationIndex() { + return generationIndex; + } + + @Override + public boolean setBlockData(int x, int y, int z, short data, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean setBlockMaterial(int x, int y, int z, BlockBaseMaterial material, short data, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean compareAndSetData(int x, int y, int z, int expect, short data, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short setBlockDataBits(int x, int y, int z, int bits, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short setBlockDataBits(int x, int y, int z, int bits, boolean set, Cause source) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short clearBlockDataBits(int x, int y, int z, int bits, Cause source) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getBlockDataField(int x, int y, int z, int bits) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isBlockDataBitSet(int x, int y, int z, int bits) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int setBlockDataField(int x, int y, int z, int bits, int value, Cause source) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int addBlockDataField(int x, int y, int z, int bits, int value, Cause source) { + throw new UnsupportedOperationException("Not supported yet."); + } @Override public FlowBlock getBlock(float x, float y, float z) { - return new FlowBlock((FlowWorld) getWorld(), GenericMath.floor(x), GenericMath.floor(y), GenericMath.floor(z)); + return new FlowBlock((FlowWorld) getWorld(), GenericMath.floor(x), GenericMath.floor(y), GenericMath.floor(z)); } @Override @@ -222,65 +221,65 @@ public FlowBlock getBlock(Vector3f position) { return this.getBlock(position.getX(), position.getY(), position.getZ()); } - @Override - public boolean commitCuboid(CuboidBlockMaterialBuffer buffer, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setCuboid(CuboidBlockMaterialBuffer buffer, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setCuboid(int x, int y, int z, CuboidBlockMaterialBuffer buffer, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public CuboidBlockMaterialBuffer getCuboid(boolean backBuffer) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public CuboidBlockMaterialBuffer getCuboid(int bx, int by, int bz, int sx, int sy, int sz) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public CuboidBlockMaterialBuffer getCuboid(int bx, int by, int bz, int sx, int sy, int sz, boolean backBuffer) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void getCuboid(int bx, int by, int bz, CuboidBlockMaterialBuffer buffer) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void getCuboid(CuboidBlockMaterialBuffer buffer) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public BlockMaterial getBlockMaterial(int x, int y, int z) { + @Override + public boolean commitCuboid(CuboidBlockMaterialBuffer buffer, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCuboid(CuboidBlockMaterialBuffer buffer, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCuboid(int x, int y, int z, CuboidBlockMaterialBuffer buffer, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CuboidBlockMaterialBuffer getCuboid(boolean backBuffer) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CuboidBlockMaterialBuffer getCuboid(int bx, int by, int bz, int sx, int sy, int sz) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CuboidBlockMaterialBuffer getCuboid(int bx, int by, int bz, int sx, int sy, int sz, boolean backBuffer) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void getCuboid(int bx, int by, int bz, CuboidBlockMaterialBuffer buffer) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void getCuboid(CuboidBlockMaterialBuffer buffer) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BlockBaseMaterial getBlockMaterial(int x, int y, int z) { int state = blockStore.getFullData(x & BLOCKS.MASK, y & BLOCKS.MASK, z & BLOCKS.MASK); - return BlockMaterial.get(state); - } - - @Override - public int getBlockFullState(int x, int y, int z) { - return blockStore.getFullData(x & BLOCKS.MASK, y & BLOCKS.MASK, z & BLOCKS.MASK); - } - - @Override - public short getBlockData(int x, int y, int z) { - return blockStore.getData(x & BLOCKS.MASK, y & BLOCKS.MASK, z & BLOCKS.MASK); - } - - public AtomicBlockStore getBlockStore() { - return blockStore; - } + return BlockBaseMaterial.get(state); + } + + @Override + public int getBlockFullState(int x, int y, int z) { + return blockStore.getFullData(x & BLOCKS.MASK, y & BLOCKS.MASK, z & BLOCKS.MASK); + } + + @Override + public short getBlockData(int x, int y, int z) { + return blockStore.getData(x & BLOCKS.MASK, y & BLOCKS.MASK, z & BLOCKS.MASK); + } + + public AtomicBlockStore getBlockStore() { + return blockStore; + } public BlockComponentOwner getBlockComponentOwner(int x, int y, int z, boolean create) { synchronized (blockComponents) { diff --git a/src/main/java/com/flowpowered/engine/geo/region/FlowRegion.java b/src/main/java/com/flowpowered/engine/geo/region/FlowRegion.java index 1eb5693..06c6852 100644 --- a/src/main/java/com/flowpowered/engine/geo/region/FlowRegion.java +++ b/src/main/java/com/flowpowered/engine/geo/region/FlowRegion.java @@ -30,11 +30,6 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Level; -import com.flowpowered.commons.bit.ShortBitMask; -import com.flowpowered.commons.bit.ShortBitSet; -import com.flowpowered.events.Cause; -import com.flowpowered.math.vector.Vector3f; - import com.flowpowered.api.Flow; import com.flowpowered.api.entity.Entity; import com.flowpowered.api.entity.Player; @@ -44,11 +39,12 @@ import com.flowpowered.api.geo.cuboid.Region; import com.flowpowered.api.geo.discrete.Transform; import com.flowpowered.api.io.bytearrayarray.BAAWrapper; -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.api.material.block.BlockFace; -import com.flowpowered.api.scheduler.TaskManager; import com.flowpowered.api.scheduler.TickStage; import com.flowpowered.api.util.cuboid.CuboidBlockMaterialBuffer; +import com.flowpowered.commons.bit.ShortBitMask; +import com.flowpowered.commons.bit.ShortBitSet; import com.flowpowered.engine.FlowEngine; import com.flowpowered.engine.entity.EntityManager; import com.flowpowered.engine.entity.FlowEntity; @@ -60,71 +56,74 @@ import com.flowpowered.engine.geo.world.FlowWorld; import com.flowpowered.engine.scheduler.render.RenderThread; import com.flowpowered.engine.util.thread.CompleteAsyncManager; +import com.flowpowered.events.Cause; +import com.flowpowered.math.vector.Vector3f; + import org.spout.physics.body.RigidBody; import org.spout.physics.collision.shape.CollisionShape; public class FlowRegion extends Region implements CompleteAsyncManager { + private final RegionGenerator generator; /** * Reference to the persistent ByteArrayArray that stores chunk data */ private final BAAWrapper chunkStore; - protected final FlowEngine engine; + protected final FlowEngine engine; /** * Holds all of the entities to be simulated */ protected final EntityManager entityManager = new EntityManager(); // TODO: possibly have a SoftReference of unloaded chunks to allow for quicker loading of chunk - /** - * Chunks used for ticking. - */ + /** + * Chunks used for ticking. + */ protected final AtomicReference chunks = new AtomicReference<>(new FlowChunk[CHUNKS.VOLUME]); - /** - * All live chunks. These are not ticked, but can be accessed. - */ + /** + * All live chunks. These are not ticked, but can be accessed. + */ protected final AtomicReference live = new AtomicReference<>(new FlowChunk[CHUNKS.VOLUME]); - private final RegionSnapshot snapshot; - private final RenderThread render; - - public FlowRegion(FlowEngine engine, FlowWorld world, int x, int y, int z, BAAWrapper chunkStore, RenderThread render) { - super(world, x << BLOCKS.BITS, y << BLOCKS.BITS, z << BLOCKS.BITS); - this.engine = engine; - this.generator = new RegionGenerator(this, 4); - this.chunkStore = chunkStore; - this.render = render; - this.snapshot = new RegionSnapshot(world.getSnapshot(), getPosition().toInt()); - - } - - @Override - public void save() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void unload(boolean save) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List getAll() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Entity getEntity(int id) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List getPlayers() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isLoaded() { - throw new UnsupportedOperationException("Not supported yet."); - } + private final RegionSnapshot snapshot; + private final RenderThread render; + + public FlowRegion(FlowEngine engine, FlowWorld world, int x, int y, int z, BAAWrapper chunkStore, RenderThread render) { + super(world, x << BLOCKS.BITS, y << BLOCKS.BITS, z << BLOCKS.BITS); + this.engine = engine; + this.generator = new RegionGenerator(this, 4); + this.chunkStore = chunkStore; + this.render = render; + this.snapshot = new RegionSnapshot(world.getSnapshot(), getPosition().toInt()); + } + + @Override + public void save() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void unload(boolean save) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getAll() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Entity getEntity(int id) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getPlayers() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isLoaded() { + throw new UnsupportedOperationException("Not supported yet."); + } protected void checkChunkLoaded(FlowChunk chunk, LoadOption loadopt) { if (loadopt.loadIfNeeded()) { @@ -134,99 +133,100 @@ protected void checkChunkLoaded(FlowChunk chunk, LoadOption loadopt) { } } - @Override - public FlowChunk getChunk(final int x, final int y, final int z, final LoadOption loadopt) { - // If we're not waiting, then we don't care because it's async anyways - if (loadopt.isWait()) { - if (loadopt.generateIfNeeded()) { - TickStage.checkStage(TickStage.noneOf(TickStage.SNAPSHOT, TickStage.PRESNAPSHOT, TickStage.LIGHTING)); - } else if (loadopt.loadIfNeeded()) { - TickStage.checkStage(TickStage.noneOf(TickStage.SNAPSHOT)); - } - } - - final int localX = x & CHUNKS.MASK; - final int localY = y & CHUNKS.MASK; - final int localZ = z & CHUNKS.MASK; - - final FlowChunk chunk = chunks.get()[getChunkIndex(localX, localY, localZ)]; - if (chunk != null) { - checkChunkLoaded(chunk, loadopt); - return chunk; - } - - if (!loadopt.loadIfNeeded() || !engine.getPlatform().isServer()) { - return null; - } - - if (loadopt.isWait()) { - return loadOrGenChunkImmediately(x, y, z, loadopt); - } - - engine.getScheduler().runCoreAsyncTask(new Runnable() { - @Override - public void run() { - loadOrGenChunkImmediately(x, y, z, loadopt); - } - }); - return null; - } - - // If loadopt.isWait(), this method is run synchronously and so is any further generation - // If !loadopt.isWait(), this method is run by a runnable, because the loading is taxing; any further generation is also run in its own Runnable + @Override + public FlowChunk getChunk(final int x, final int y, final int z, final LoadOption loadopt) { + // If we're not waiting, then we don't care because it's async anyways + if (loadopt.isWait()) { + if (loadopt.generateIfNeeded()) { + TickStage.checkStage(TickStage.noneOf(TickStage.SNAPSHOT, TickStage.PRESNAPSHOT, TickStage.LIGHTING)); + } else if (loadopt.loadIfNeeded()) { + TickStage.checkStage(TickStage.noneOf(TickStage.SNAPSHOT)); + } + } + + final int localX = x & CHUNKS.MASK; + final int localY = y & CHUNKS.MASK; + final int localZ = z & CHUNKS.MASK; + + final FlowChunk chunk = chunks.get()[getChunkIndex(localX, localY, localZ)]; + if (chunk != null) { + checkChunkLoaded(chunk, loadopt); + return chunk; + } + + if (!loadopt.loadIfNeeded() || !engine.getPlatform().isServer()) { + return null; + } + + if (loadopt.isWait()) { + return loadOrGenChunkImmediately(x, y, z, loadopt); + } + + engine.getScheduler().runCoreAsyncTask(new Runnable() { + @Override + public void run() { + loadOrGenChunkImmediately(x, y, z, loadopt); + } + }); + return null; + } + + // If loadopt.isWait(), this method is run synchronously and so is any further generation + // If !loadopt.isWait(), this method is run by a runnable, because the loading is taxing; any further generation is also run in its own Runnable private FlowChunk loadOrGenChunkImmediately(int worldX, int worldY, int worldZ, final LoadOption loadopt) { - final int localX = worldX & CHUNKS.MASK; - final int localY = worldY & CHUNKS.MASK; - final int localZ = worldZ & CHUNKS.MASK; + final int localX = worldX & CHUNKS.MASK; + final int localY = worldY & CHUNKS.MASK; + final int localZ = worldZ & CHUNKS.MASK; FlowChunk newChunk = loadopt.loadIfNeeded() ? loadChunk(localX, localY, localZ) : null; if (newChunk != null || !loadopt.generateIfNeeded()) { - return newChunk; + return newChunk; } - generator.generateChunk(worldX, worldY, worldZ, loadopt.isWait()); - if (!loadopt.isWait()) { - return null; - } - final FlowChunk generatedChunk = live.get()[getChunkIndex(localX, localY, localZ)]; - if (generatedChunk != null) { - checkChunkLoaded(generatedChunk, loadopt); - return generatedChunk; - } - Flow.getLogger().severe("Chunk failed to generate! (" + loadopt + ")"); - Flow.getLogger().info("Region " + this + ", chunk " + worldX + ", " + worldY + ", " + worldZ); - Thread.dumpStack(); - return null; - } - - private FlowChunk loadChunk(int x, int y, int z) { - final InputStream stream = this.getChunkInputStream(x, y, z); - if (stream != null) { - try { - try { - ChunkDataForRegion dataForRegion = new ChunkDataForRegion(); - FlowChunk newChunk = ChunkFiles.loadChunk(this, x, y, z, stream, dataForRegion); - if (newChunk == null) { - Flow.getLogger().severe("Unable to load chunk at location " + (getChunkX() + x) + ", " + (getChunkY() + y) + ", " + (getChunkZ() + z) + " in region " + this + ", regenerating chunks"); - return null; - } - FlowChunk c = setChunk(newChunk, x, y, z, dataForRegion); - checkChunkLoaded(c, LoadOption.LOAD_ONLY); - return c; - } finally { - stream.close(); - } - } catch (IOException e) { - Flow.getLogger().log(Level.WARNING, "IOException when loading chunk!", e); - } - } - return null; - } + generator.generateChunk(worldX, worldY, worldZ, loadopt.isWait()); + if (!loadopt.isWait()) { + return null; + } + final FlowChunk generatedChunk = live.get()[getChunkIndex(localX, localY, localZ)]; + if (generatedChunk != null) { + checkChunkLoaded(generatedChunk, loadopt); + return generatedChunk; + } + Flow.getLogger().severe("Chunk failed to generate! (" + loadopt + ")"); + Flow.getLogger().info("Region " + this + ", chunk " + worldX + ", " + worldY + ", " + worldZ); + Thread.dumpStack(); + return null; + } + + private FlowChunk loadChunk(int x, int y, int z) { + final InputStream stream = this.getChunkInputStream(x, y, z); + if (stream != null) { + try { + try { + ChunkDataForRegion dataForRegion = new ChunkDataForRegion(); + FlowChunk newChunk = ChunkFiles.loadChunk(this, x, y, z, stream, dataForRegion); + if (newChunk == null) { + Flow.getLogger().severe("Unable to load chunk at location " + (getChunkX() + x) + ", " + (getChunkY() + y) + ", " + (getChunkZ() + z) + " in region " + this + ", regenerating chunks"); + return null; + } + FlowChunk c = setChunk(newChunk, x, y, z, dataForRegion); + checkChunkLoaded(c, LoadOption.LOAD_ONLY); + return c; + } finally { + stream.close(); + } + } catch (IOException e) { + Flow.getLogger().log(Level.WARNING, "IOException when loading chunk!", e); + } + } + return null; + } /** * Gets the DataInputStream corresponding to a given Chunk.

The stream is based on a snapshot of the array. * * @param x the chunk + * * @return the DataInputStream */ public InputStream getChunkInputStream(int x, int y, int z) { @@ -247,41 +247,41 @@ public static int getChunkKey(int chunkX, int chunkY, int chunkZ) { } protected void setGeneratedChunks(FlowChunk[][][] newChunks, int baseX, int baseY, int baseZ) { - while(true) { - FlowChunk[] live = this.live.get(); - FlowChunk[] newArray = Arrays.copyOf(live, live.length); - final int width = newChunks.length; - for (int x = 0; x < width; x++) { - for (int z = 0; z < width; z++) { - for (int y = 0; y < width; y++) { - int chunkIndex = getChunkIndex(x + baseX, y + baseY, z + baseZ); - if (live[chunkIndex] != null) { - throw new IllegalStateException("Tried to set a generated chunk, but a chunk already existed!"); - } - newArray[chunkIndex] = newChunks[x][y][z]; - } - } - } - if (this.live.compareAndSet(live, newArray)) { - //newChunk.queueNew(); - break; + while (true) { + FlowChunk[] live = this.live.get(); + FlowChunk[] newArray = Arrays.copyOf(live, live.length); + final int width = newChunks.length; + for (int x = 0; x < width; x++) { + for (int z = 0; z < width; z++) { + for (int y = 0; y < width; y++) { + int chunkIndex = getChunkIndex(x + baseX, y + baseY, z + baseZ); + if (live[chunkIndex] != null) { + throw new IllegalStateException("Tried to set a generated chunk, but a chunk already existed!"); + } + newArray[chunkIndex] = newChunks[x][y][z]; + } + } + } + if (this.live.compareAndSet(live, newArray)) { + //newChunk.queueNew(); + break; } - } + } } protected FlowChunk setChunk(FlowChunk newChunk, int x, int y, int z, ChunkDataForRegion dataForRegion) { - final int chunkIndex = getChunkIndex(x, y, z); - while (true) { - FlowChunk[] live = this.live.get(); - FlowChunk old = live[chunkIndex]; - if (old != null) { - //newChunk.setUnloadedUnchecked(); - return old; - } - FlowChunk[] newArray = Arrays.copyOf(live, live.length); - newArray[chunkIndex] = newChunk; - if (this.live.compareAndSet(live, newArray)) { - if (dataForRegion != null) { + final int chunkIndex = getChunkIndex(x, y, z); + while (true) { + FlowChunk[] live = this.live.get(); + FlowChunk old = live[chunkIndex]; + if (old != null) { + //newChunk.setUnloadedUnchecked(); + return old; + } + FlowChunk[] newArray = Arrays.copyOf(live, live.length); + newArray[chunkIndex] = newChunk; + if (this.live.compareAndSet(live, newArray)) { + if (dataForRegion != null) { for (FlowEntitySnapshot snapshot : dataForRegion.loadedEntities) { FlowEntity entity = EntityManager.createEntity(snapshot.getTransform()); entityManager.addEntity(entity); @@ -291,264 +291,265 @@ protected FlowChunk setChunk(FlowChunk newChunk, int x, int y, int z, ChunkDataF } } - @Override - public Chunk getChunkFromBlock(int x, int y, int z, LoadOption loadopt) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Chunk getChunkFromBlock(Vector3f position, LoadOption loadopt) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void saveChunk(int x, int y, int z) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void unloadChunk(int x, int y, int z, boolean save) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getNumLoadedChunks() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean setBlockData(int x, int y, int z, short data, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean setBlockMaterial(int x, int y, int z, BlockMaterial material, short data, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean compareAndSetData(int x, int y, int z, int expect, short data, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public short setBlockDataBits(int x, int y, int z, int bits, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public short setBlockDataBits(int x, int y, int z, int bits, boolean set, Cause source) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public short clearBlockDataBits(int x, int y, int z, int bits, Cause source) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getBlockDataField(int x, int y, int z, int bits) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isBlockDataBitSet(int x, int y, int z, int bits) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int setBlockDataField(int x, int y, int z, int bits, int value, Cause source) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int addBlockDataField(int x, int y, int z, int bits, int value, Cause source) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Block getBlock(float x, float y, float z) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Block getBlock(Vector3f position) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean commitCuboid(CuboidBlockMaterialBuffer buffer, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setCuboid(CuboidBlockMaterialBuffer buffer, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setCuboid(int x, int y, int z, CuboidBlockMaterialBuffer buffer, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public CuboidBlockMaterialBuffer getCuboid(boolean backBuffer) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public CuboidBlockMaterialBuffer getCuboid(int bx, int by, int bz, int sx, int sy, int sz) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public CuboidBlockMaterialBuffer getCuboid(int bx, int by, int bz, int sx, int sy, int sz, boolean backBuffer) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void getCuboid(int bx, int by, int bz, CuboidBlockMaterialBuffer buffer) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void getCuboid(CuboidBlockMaterialBuffer buffer) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public BlockMaterial getBlockMaterial(int x, int y, int z) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getBlockFullState(int x, int y, int z) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public short getBlockData(int x, int y, int z) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Region getLocalRegion(BlockFace face, LoadOption loadopt) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Region getLocalRegion(int dx, int dy, int dz, LoadOption loadopt) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Chunk getLocalChunk(Chunk c, BlockFace face, LoadOption loadopt) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Chunk getLocalChunk(Chunk c, int ox, int oy, int oz, LoadOption loadopt) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Chunk getLocalChunk(int x, int y, int z, int ox, int oy, int oz, LoadOption loadopt) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Chunk getLocalChunk(int x, int y, int z, LoadOption loadopt) { - throw new UnsupportedOperationException("Not supported yet."); - } - - public EntityManager getEntityManager() { - return entityManager; - } - - @Override - public void finalizeRun() { - entityManager.finalizeRun(); - } - - @Override - public void preSnapshotRun() { - entityManager.preSnapshotRun(); - } - - @Override - public void copySnapshotRun(int sequence) { - entityManager.copyAllSnapshots(); - chunks.set(live.get()); - snapshot.update(this); - } - - @Override - public void startTickRun(int stage, long delta) { - } - - @Override - public void runPhysics(int sequence) { - } - - @Override - public void runDynamicUpdates(long threshold, int sequence) { - } - - @Override - public void runLighting(int sequence) { - } - - @Override - public boolean checkSequence(TickStage stage, int seqence) { - if (stage == TickStage.SNAPSHOT) { - return seqence == -1; - } - return seqence == -1; - } - - @Override - public long getFirstDynamicUpdateTime() { - return 0; - } - - @Override - public Thread getExecutionThread() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setExecutionThread(Thread t) { - } - - private static ShortBitSet ALL_STAGES = new ShortBitSet(Short.MAX_VALUE); - @Override - public ShortBitMask getTickStages() { - return ALL_STAGES; - } - - public void removeBody(RigidBody body) { - throw new UnsupportedOperationException("Not supported yet."); - } - - public RigidBody addBody(Transform live, float mass, CollisionShape shape, boolean ghost, boolean mobile) { - throw new UnsupportedOperationException("Not supported yet."); - } - - protected static int getChunkIndex(int x, int y, int z) { - return (CHUNKS.AREA * x) + (CHUNKS.SIZE * y) + z; - } - - @Override - public FlowWorld getWorld() { - return (FlowWorld) super.getWorld(); - } - - public FlowChunk[] getChunks() { - FlowChunk[] get = chunks.get(); - return Arrays.copyOf(get, get.length); - } - - public RegionSnapshot getSnapshot() { - return snapshot; - } + @Override + public Chunk getChunkFromBlock(int x, int y, int z, LoadOption loadopt) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Chunk getChunkFromBlock(Vector3f position, LoadOption loadopt) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void saveChunk(int x, int y, int z) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void unloadChunk(int x, int y, int z, boolean save) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getNumLoadedChunks() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean setBlockData(int x, int y, int z, short data, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean setBlockMaterial(int x, int y, int z, BlockBaseMaterial material, short data, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean compareAndSetData(int x, int y, int z, int expect, short data, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short setBlockDataBits(int x, int y, int z, int bits, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short setBlockDataBits(int x, int y, int z, int bits, boolean set, Cause source) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short clearBlockDataBits(int x, int y, int z, int bits, Cause source) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getBlockDataField(int x, int y, int z, int bits) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isBlockDataBitSet(int x, int y, int z, int bits) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int setBlockDataField(int x, int y, int z, int bits, int value, Cause source) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int addBlockDataField(int x, int y, int z, int bits, int value, Cause source) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Block getBlock(float x, float y, float z) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Block getBlock(Vector3f position) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean commitCuboid(CuboidBlockMaterialBuffer buffer, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCuboid(CuboidBlockMaterialBuffer buffer, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCuboid(int x, int y, int z, CuboidBlockMaterialBuffer buffer, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CuboidBlockMaterialBuffer getCuboid(boolean backBuffer) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CuboidBlockMaterialBuffer getCuboid(int bx, int by, int bz, int sx, int sy, int sz) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CuboidBlockMaterialBuffer getCuboid(int bx, int by, int bz, int sx, int sy, int sz, boolean backBuffer) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void getCuboid(int bx, int by, int bz, CuboidBlockMaterialBuffer buffer) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void getCuboid(CuboidBlockMaterialBuffer buffer) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BlockBaseMaterial getBlockMaterial(int x, int y, int z) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getBlockFullState(int x, int y, int z) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short getBlockData(int x, int y, int z) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Region getLocalRegion(BlockFace face, LoadOption loadopt) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Region getLocalRegion(int dx, int dy, int dz, LoadOption loadopt) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Chunk getLocalChunk(Chunk c, BlockFace face, LoadOption loadopt) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Chunk getLocalChunk(Chunk c, int ox, int oy, int oz, LoadOption loadopt) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Chunk getLocalChunk(int x, int y, int z, int ox, int oy, int oz, LoadOption loadopt) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Chunk getLocalChunk(int x, int y, int z, LoadOption loadopt) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public EntityManager getEntityManager() { + return entityManager; + } + + @Override + public void finalizeRun() { + entityManager.finalizeRun(); + } + + @Override + public void preSnapshotRun() { + entityManager.preSnapshotRun(); + } + + @Override + public void copySnapshotRun(int sequence) { + entityManager.copyAllSnapshots(); + chunks.set(live.get()); + snapshot.update(this); + } + + @Override + public void startTickRun(int stage, long delta) { + } + + @Override + public void runPhysics(int sequence) { + } + + @Override + public void runDynamicUpdates(long threshold, int sequence) { + } + + @Override + public void runLighting(int sequence) { + } + + @Override + public boolean checkSequence(TickStage stage, int seqence) { + if (stage == TickStage.SNAPSHOT) { + return seqence == -1; + } + return seqence == -1; + } + + @Override + public long getFirstDynamicUpdateTime() { + return 0; + } + + @Override + public Thread getExecutionThread() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setExecutionThread(Thread t) { + } + + private static ShortBitSet ALL_STAGES = new ShortBitSet(Short.MAX_VALUE); + + @Override + public ShortBitMask getTickStages() { + return ALL_STAGES; + } + + public void removeBody(RigidBody body) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public RigidBody addBody(Transform live, float mass, CollisionShape shape, boolean ghost, boolean mobile) { + throw new UnsupportedOperationException("Not supported yet."); + } + + protected static int getChunkIndex(int x, int y, int z) { + return (CHUNKS.AREA * x) + (CHUNKS.SIZE * y) + z; + } + + @Override + public FlowWorld getWorld() { + return (FlowWorld) super.getWorld(); + } + + public FlowChunk[] getChunks() { + FlowChunk[] get = chunks.get(); + return Arrays.copyOf(get, get.length); + } + + public RegionSnapshot getSnapshot() { + return snapshot; + } } diff --git a/src/main/java/com/flowpowered/engine/geo/snapshot/ChunkSnapshot.java b/src/main/java/com/flowpowered/engine/geo/snapshot/ChunkSnapshot.java index 67a879d..0463d2c 100644 --- a/src/main/java/com/flowpowered/engine/geo/snapshot/ChunkSnapshot.java +++ b/src/main/java/com/flowpowered/engine/geo/snapshot/ChunkSnapshot.java @@ -27,182 +27,183 @@ import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import com.flowpowered.commons.store.block.AtomicBlockStore; -import com.flowpowered.math.vector.Vector3i; - import com.flowpowered.api.geo.cuboid.Chunk; import com.flowpowered.api.geo.cuboid.Region; -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.api.material.block.BlockFace; import com.flowpowered.api.material.block.BlockFaces; +import com.flowpowered.commons.store.block.AtomicBlockStore; import com.flowpowered.engine.geo.chunk.FlowChunk; +import com.flowpowered.math.vector.Vector3i; /** * */ public class ChunkSnapshot { - private final short[] blockIDs = new short[Chunk.BLOCKS.VOLUME]; - private final short[] blockData = new short[Chunk.BLOCKS.VOLUME]; - private final WorldSnapshot world; - private final RegionSnapshot region; - private final Vector3i position; - private long updateNumber = 0; - private final ReadWriteLock lock = new ReentrantReadWriteLock(true); - - public ChunkSnapshot(WorldSnapshot world, RegionSnapshot region, Vector3i position) { - this.world = world; - this.region = region; - this.position = position; - } - - public WorldSnapshot getWorld() { - return world; - } - - public RegionSnapshot getRegion() { - return region; - } - - public Vector3i getPosition() { - return position; - } - - public int getX() { - return position.getX(); - } - - public int getY() { - return position.getY(); - } - - public int getZ() { - return position.getZ(); - } - - public ChunkSnapshot getRelativeChunk(Vector3i relative) { - return getRelativeChunk(relative.getX(), relative.getY(), relative.getZ()); - } - - public ChunkSnapshot getRelativeChunk(int x, int y, int z) { - // We check to see if the chunk is in this chunk's region first, to avoid a map lookup for the other region - final int regionX = getRegion().getPosition().getX(); - final int regionY = getRegion().getPosition().getY(); - final int regionZ = getRegion().getPosition().getZ(); - final int otherChunkX = this.getX() + x; - final int otherChunkY = this.getY() + y; - final int otherChunkZ = this.getZ() + z; - final int otherRegionX = otherChunkX / Region.CHUNKS.SIZE; - final int otherRegionY = otherChunkY / Region.CHUNKS.SIZE; - final int otherRegionZ = otherChunkZ / Region.CHUNKS.SIZE; - if (regionX == otherRegionX && regionZ == otherRegionZ && regionY == otherRegionY) { - // Get the chunk from the current region - return getRegion().getChunk(otherChunkX, otherChunkY, otherChunkZ); - } - RegionSnapshot other = getWorld().getRegion(otherRegionX, otherRegionY, otherRegionZ); - return other == null ? null : other.getChunk(otherChunkX, otherChunkY, otherChunkZ); - } - - public BlockMaterial getMaterial(Vector3i position) { - return getMaterial(position.getX(), position.getY(), position.getZ()); - } - - public BlockMaterial getMaterial(int x, int y, int z) { - final Lock lock = this.lock.readLock(); - lock.lock(); - try { - final int index = getBlockIndex(x, y, z); - return BlockMaterial.get(blockIDs[index], blockData[index]); - } finally { - lock.unlock(); - } - } - - public long getUpdateNumber() { - final Lock lock = this.lock.readLock(); - lock.lock(); - try { - return updateNumber; - } finally { - lock.unlock(); - } - } - - /** - * Updates the snapshot to the current chunk passed to the constructor. The chunk passed must be a the same location and world than the snapshot. Returns whether or not the snapshot state has - * changed. Clears the chunk block store dirty arrays. - * - * @param current The current chunk to update from - * @return Whether or not the snapshot state has changed - */ - public boolean update(FlowChunk current) { - if (!current.getPosition().toInt().equals(position) || !current.getWorld().getUID().equals(world.getID())) { - throw new IllegalArgumentException("Cannot accept a chunk from another position or world"); - } - final Lock lock = this.lock.writeLock(); - lock.lock(); - try { - // TODO: update only the dirty blocks, unless the dirty arrays are overflown - final AtomicBlockStore blocks = current.getBlockStore(); - if (blocks.isDirty()) { - blocks.getBlockIdArray(blockIDs); - blocks.getDataArray(blockData); - blocks.resetDirtyArrays(); - updateNumber++; - //touchNeighbors(); - return true; - } - return false; - } finally { - lock.unlock(); - } - } - - private void touch() { - final Lock lock = this.lock.writeLock(); - lock.lock(); - try { - updateNumber++; - } finally { - lock.unlock(); - } - } - - private void touchNeighbors() { - for (BlockFace face : BlockFaces.NESWBT) { - ChunkSnapshot rel = getRelativeChunk(face.getOffset()); - if (rel != null) { - rel.touch(); - } - } - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof ChunkSnapshot)) { - return false; - } - final ChunkSnapshot that = (ChunkSnapshot) o; - if (!position.equals(that.position)) { - return false; - } - return world.equals(that.world); - } - - @Override - public int hashCode() { - int result = world.hashCode(); - result = 31 * result + position.hashCode(); - return result; - } - - private static int getBlockIndex(Vector3i position) { - return getBlockIndex(position.getX(), position.getY(), position.getZ()); - } - - private static int getBlockIndex(int x, int y, int z) { - return (y & Chunk.BLOCKS.MASK) << Chunk.BLOCKS.DOUBLE_BITS | (z & Chunk.BLOCKS.MASK) << Chunk.BLOCKS.BITS | x & Chunk.BLOCKS.MASK; - } + + private final short[] blockIDs = new short[Chunk.BLOCKS.VOLUME]; + private final short[] blockData = new short[Chunk.BLOCKS.VOLUME]; + private final WorldSnapshot world; + private final RegionSnapshot region; + private final Vector3i position; + private long updateNumber = 0; + private final ReadWriteLock lock = new ReentrantReadWriteLock(true); + + public ChunkSnapshot(WorldSnapshot world, RegionSnapshot region, Vector3i position) { + this.world = world; + this.region = region; + this.position = position; + } + + public WorldSnapshot getWorld() { + return world; + } + + public RegionSnapshot getRegion() { + return region; + } + + public Vector3i getPosition() { + return position; + } + + public int getX() { + return position.getX(); + } + + public int getY() { + return position.getY(); + } + + public int getZ() { + return position.getZ(); + } + + public ChunkSnapshot getRelativeChunk(Vector3i relative) { + return getRelativeChunk(relative.getX(), relative.getY(), relative.getZ()); + } + + public ChunkSnapshot getRelativeChunk(int x, int y, int z) { + // We check to see if the chunk is in this chunk's region first, to avoid a map lookup for the other region + final int regionX = getRegion().getPosition().getX(); + final int regionY = getRegion().getPosition().getY(); + final int regionZ = getRegion().getPosition().getZ(); + final int otherChunkX = this.getX() + x; + final int otherChunkY = this.getY() + y; + final int otherChunkZ = this.getZ() + z; + final int otherRegionX = otherChunkX / Region.CHUNKS.SIZE; + final int otherRegionY = otherChunkY / Region.CHUNKS.SIZE; + final int otherRegionZ = otherChunkZ / Region.CHUNKS.SIZE; + if (regionX == otherRegionX && regionZ == otherRegionZ && regionY == otherRegionY) { + // Get the chunk from the current region + return getRegion().getChunk(otherChunkX, otherChunkY, otherChunkZ); + } + RegionSnapshot other = getWorld().getRegion(otherRegionX, otherRegionY, otherRegionZ); + return other == null ? null : other.getChunk(otherChunkX, otherChunkY, otherChunkZ); + } + + public BlockBaseMaterial getMaterial(Vector3i position) { + return getMaterial(position.getX(), position.getY(), position.getZ()); + } + + public BlockBaseMaterial getMaterial(int x, int y, int z) { + final Lock lock = this.lock.readLock(); + lock.lock(); + try { + final int index = getBlockIndex(x, y, z); + return BlockBaseMaterial.get(blockIDs[index], blockData[index]); + } finally { + lock.unlock(); + } + } + + public long getUpdateNumber() { + final Lock lock = this.lock.readLock(); + lock.lock(); + try { + return updateNumber; + } finally { + lock.unlock(); + } + } + + /** + * Updates the snapshot to the current chunk passed to the constructor. The chunk passed must be a the same location and world than the snapshot. Returns whether or not the snapshot state has + * changed. Clears the chunk block store dirty arrays. + * + * @param current The current chunk to update from + * + * @return Whether or not the snapshot state has changed + */ + public boolean update(FlowChunk current) { + if (!current.getPosition().toInt().equals(position) || !current.getWorld().getUID().equals(world.getID())) { + throw new IllegalArgumentException("Cannot accept a chunk from another position or world"); + } + final Lock lock = this.lock.writeLock(); + lock.lock(); + try { + // TODO: update only the dirty blocks, unless the dirty arrays are overflown + final AtomicBlockStore blocks = current.getBlockStore(); + if (blocks.isDirty()) { + blocks.getBlockIdArray(blockIDs); + blocks.getDataArray(blockData); + blocks.resetDirtyArrays(); + updateNumber++; + //touchNeighbors(); + return true; + } + return false; + } finally { + lock.unlock(); + } + } + + private void touch() { + final Lock lock = this.lock.writeLock(); + lock.lock(); + try { + updateNumber++; + } finally { + lock.unlock(); + } + } + + private void touchNeighbors() { + for (BlockFace face : BlockFaces.NESWBT) { + ChunkSnapshot rel = getRelativeChunk(face.getOffset()); + if (rel != null) { + rel.touch(); + } + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ChunkSnapshot)) { + return false; + } + final ChunkSnapshot that = (ChunkSnapshot) o; + if (!position.equals(that.position)) { + return false; + } + return world.equals(that.world); + } + + @Override + public int hashCode() { + int result = world.hashCode(); + result = 31 * result + position.hashCode(); + return result; + } + + private static int getBlockIndex(Vector3i position) { + return getBlockIndex(position.getX(), position.getY(), position.getZ()); + } + + private static int getBlockIndex(int x, int y, int z) { + return (y & Chunk.BLOCKS.MASK) << Chunk.BLOCKS.DOUBLE_BITS | (z & Chunk.BLOCKS.MASK) << Chunk.BLOCKS.BITS | x & Chunk.BLOCKS.MASK; + } } diff --git a/src/main/java/com/flowpowered/engine/geo/snapshot/ChunkSnapshotGroup.java b/src/main/java/com/flowpowered/engine/geo/snapshot/ChunkSnapshotGroup.java index 28e0395..b283699 100644 --- a/src/main/java/com/flowpowered/engine/geo/snapshot/ChunkSnapshotGroup.java +++ b/src/main/java/com/flowpowered/engine/geo/snapshot/ChunkSnapshotGroup.java @@ -24,72 +24,75 @@ package com.flowpowered.engine.geo.snapshot; import com.flowpowered.api.geo.cuboid.Chunk; -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.math.vector.Vector3i; /** * A chunk and it's immediate neighbours (BTNESW), used for meshing the chunk including it's edge blocks with proper occlusion. */ public class ChunkSnapshotGroup { - private final ChunkSnapshot middle; - private final ChunkSnapshot top; - private final ChunkSnapshot bottom; - private final ChunkSnapshot north; - private final ChunkSnapshot east; - private final ChunkSnapshot south; - private final ChunkSnapshot west; - /** - * Constructs a new snapshot group from the middle chunk snapshot and the world snapshot. The world snapshot from the chunk will be used to source the neighbouring chunks (if they exist). - * - * @param middle The middle chunk - */ - public ChunkSnapshotGroup(ChunkSnapshot middle) { - this.middle = middle; - this.top = middle.getRelativeChunk(Vector3i.UP); - this.bottom = middle.getRelativeChunk(Vector3i.UP.mul(-1)); - this.north = middle.getRelativeChunk(Vector3i.RIGHT.mul(-1)); - this.south = middle.getRelativeChunk(Vector3i.RIGHT); - this.east = middle.getRelativeChunk(Vector3i.FORWARD.mul(-1)); - this.west = middle.getRelativeChunk(Vector3i.FORWARD); - } + private final ChunkSnapshot middle; + private final ChunkSnapshot top; + private final ChunkSnapshot bottom; + private final ChunkSnapshot north; + private final ChunkSnapshot east; + private final ChunkSnapshot south; + private final ChunkSnapshot west; - /** - * Returns the material at the position, looking at the directly neighbouring chunks if the position is outside the chunk. - * - * @param position The position to lookup the material at - * @return The material or null if missing - */ - public BlockMaterial getMaterial(Vector3i position) { - return getMaterial(position.getX(), position.getY(), position.getZ()); - } + /** + * Constructs a new snapshot group from the middle chunk snapshot and the world snapshot. The world snapshot from the chunk will be used to source the neighbouring chunks (if they exist). + * + * @param middle The middle chunk + */ + public ChunkSnapshotGroup(ChunkSnapshot middle) { + this.middle = middle; + this.top = middle.getRelativeChunk(Vector3i.UP); + this.bottom = middle.getRelativeChunk(Vector3i.UP.mul(-1)); + this.north = middle.getRelativeChunk(Vector3i.RIGHT.mul(-1)); + this.south = middle.getRelativeChunk(Vector3i.RIGHT); + this.east = middle.getRelativeChunk(Vector3i.FORWARD.mul(-1)); + this.west = middle.getRelativeChunk(Vector3i.FORWARD); + } - /** - * Returns the material at the position, looking at the directly neighbouring chunks if the position is outside the chunk. - * - * @param x The x coordinate of the position - * @param y The y coordinate of the position - * @param z The z coordinate of the position - * @return The material or null if missing - */ - public BlockMaterial getMaterial(int x, int y, int z) { - if (x < 0) { - return north != null ? north.getMaterial(x, y, z) : null; - } else if (x >= Chunk.BLOCKS.SIZE) { - return south != null ? south.getMaterial(x, y, z) : null; - } else if (y < 0) { - return bottom != null ? bottom.getMaterial(x, y, z) : null; - } else if (y >= Chunk.BLOCKS.SIZE) { - return top != null ? top.getMaterial(x, y, z) : null; - } else if (z < 0) { - return east != null ? east.getMaterial(x, y, z) : null; - } else if (z >= Chunk.BLOCKS.SIZE) { - return west != null ? west.getMaterial(x, y, z) : null; - } - return middle.getMaterial(x, y, z); - } + /** + * Returns the material at the position, looking at the directly neighbouring chunks if the position is outside the chunk. + * + * @param position The position to lookup the material at + * + * @return The material or null if missing + */ + public BlockBaseMaterial getMaterial(Vector3i position) { + return getMaterial(position.getX(), position.getY(), position.getZ()); + } - public ChunkSnapshot getMiddle() { - return middle; - } + /** + * Returns the material at the position, looking at the directly neighbouring chunks if the position is outside the chunk. + * + * @param x The x coordinate of the position + * @param y The y coordinate of the position + * @param z The z coordinate of the position + * + * @return The material or null if missing + */ + public BlockBaseMaterial getMaterial(int x, int y, int z) { + if (x < 0) { + return north != null ? north.getMaterial(x, y, z) : null; + } else if (x >= Chunk.BLOCKS.SIZE) { + return south != null ? south.getMaterial(x, y, z) : null; + } else if (y < 0) { + return bottom != null ? bottom.getMaterial(x, y, z) : null; + } else if (y >= Chunk.BLOCKS.SIZE) { + return top != null ? top.getMaterial(x, y, z) : null; + } else if (z < 0) { + return east != null ? east.getMaterial(x, y, z) : null; + } else if (z >= Chunk.BLOCKS.SIZE) { + return west != null ? west.getMaterial(x, y, z) : null; + } + return middle.getMaterial(x, y, z); + } + + public ChunkSnapshot getMiddle() { + return middle; + } } diff --git a/src/main/java/com/flowpowered/engine/geo/world/FlowWorld.java b/src/main/java/com/flowpowered/engine/geo/world/FlowWorld.java index 6e683d7..c8e3a03 100644 --- a/src/main/java/com/flowpowered/engine/geo/world/FlowWorld.java +++ b/src/main/java/com/flowpowered/engine/geo/world/FlowWorld.java @@ -23,15 +23,10 @@ */ package com.flowpowered.engine.geo.world; -import com.flowpowered.engine.geo.region.FlowRegion; import java.util.Collection; import java.util.List; import java.util.UUID; -import com.flowpowered.commons.bit.ShortBitMask; -import com.flowpowered.commons.bit.ShortBitSet; -import com.flowpowered.events.Cause; - import com.flowpowered.api.component.BaseComponentOwner; import com.flowpowered.api.component.Component; import com.flowpowered.api.entity.Entity; @@ -43,345 +38,346 @@ import com.flowpowered.api.geo.cuboid.Region; import com.flowpowered.api.geo.discrete.Point; import com.flowpowered.api.geo.discrete.Transform; -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.api.scheduler.TaskManager; import com.flowpowered.api.scheduler.TickStage; import com.flowpowered.api.util.cuboid.CuboidBlockMaterialBuffer; +import com.flowpowered.commons.bit.ShortBitMask; import com.flowpowered.engine.FlowEngine; import com.flowpowered.engine.entity.EntityManager; import com.flowpowered.engine.entity.FlowEntity; -import com.flowpowered.engine.geo.region.RegionSource; import com.flowpowered.engine.geo.FlowBlock; import com.flowpowered.engine.geo.chunk.FlowChunk; +import com.flowpowered.engine.geo.region.FlowRegion; +import com.flowpowered.engine.geo.region.RegionSource; import com.flowpowered.engine.geo.snapshot.WorldSnapshot; import com.flowpowered.engine.util.thread.CopySnapshotManager; -import com.flowpowered.engine.util.thread.FinalizeManager; import com.flowpowered.engine.util.thread.StartTickManager; import com.flowpowered.engine.util.thread.snapshotable.SnapshotManager; import com.flowpowered.engine.util.thread.snapshotable.SnapshotableLong; +import com.flowpowered.events.Cause; import com.flowpowered.math.GenericMath; import com.flowpowered.math.imaginary.Quaternionf; import com.flowpowered.math.vector.Vector3f; public class FlowWorld extends BaseComponentOwner implements World, StartTickManager, CopySnapshotManager { - // TEST CODE - /** - * Number of milliseconds in a day. - */ - public static final long MILLIS_IN_DAY = 1000 * 60 * 60 * 24; - /** - * The duration of a day in the game, in real life, in milliseconds. - */ - public static final long GAME_DAY_IRL = 1000 * 60; - private final FlowEngine engine; - private final String name; - private final UUID uid; - private final SnapshotManager snapshotManager; - private final SnapshotableLong age; - private final RegionSource regionSource; - private final WorldSnapshot snapshot; - - public FlowWorld(FlowEngine engine, String name, UUID uid, long age) { - this.engine = engine; - this.name = name; - this.uid = uid; - this.snapshotManager = new SnapshotManager(); - this.age = new SnapshotableLong(snapshotManager, age); - this.regionSource = new RegionSource(engine, (FlowServerWorld) this); - this.snapshot = new WorldSnapshot(this); - } - - public FlowWorld(FlowEngine engine, String name) { - this(engine, name, UUID.randomUUID(), 0); - } - - - @Override - public String getName() { - return name; - } - - @Override - public long getAge() { - return age.get(); - } - - @Override - public UUID getUID() { - return uid; - } - - @Override - public Entity getEntity(UUID uid) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Entity spawnEntity(Vector3f point, LoadOption option, EntityPrefab prefab) { - return spawnEntity(point, option, prefab.getComponents().toArray(new Class[0])); - } - - @Override - public Entity spawnEntity(Vector3f point, LoadOption option, Class... classes) { - FlowRegion region = (FlowRegion) getRegionFromBlock(point, option); - if (region == null) { - return null; - } - - FlowEntity entity = EntityManager.createEntity(new Transform(new Point(point, this), Quaternionf.fromAxesAnglesDeg(0, 0, 0), Vector3f.ONE)); + // TEST CODE + /** + * Number of milliseconds in a day. + */ + public static final long MILLIS_IN_DAY = 1000 * 60 * 60 * 24; + /** + * The duration of a day in the game, in real life, in milliseconds. + */ + public static final long GAME_DAY_IRL = 1000 * 60; + private final FlowEngine engine; + private final String name; + private final UUID uid; + private final SnapshotManager snapshotManager; + private final SnapshotableLong age; + private final RegionSource regionSource; + private final WorldSnapshot snapshot; + + public FlowWorld(FlowEngine engine, String name, UUID uid, long age) { + this.engine = engine; + this.name = name; + this.uid = uid; + this.snapshotManager = new SnapshotManager(); + this.age = new SnapshotableLong(snapshotManager, age); + this.regionSource = new RegionSource(engine, (FlowServerWorld) this); + this.snapshot = new WorldSnapshot(this); + } + + public FlowWorld(FlowEngine engine, String name) { + this(engine, name, UUID.randomUUID(), 0); + } + + @Override + public String getName() { + return name; + } + + @Override + public long getAge() { + return age.get(); + } + + @Override + public UUID getUID() { + return uid; + } + + @Override + public Entity getEntity(UUID uid) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Entity spawnEntity(Vector3f point, LoadOption option, EntityPrefab prefab) { + return spawnEntity(point, option, prefab.getComponents().toArray(new Class[0])); + } + + @Override + public Entity spawnEntity(Vector3f point, LoadOption option, Class... classes) { + FlowRegion region = (FlowRegion) getRegionFromBlock(point, option); + if (region == null) { + return null; + } + + FlowEntity entity = EntityManager.createEntity(new Transform(new Point(point, this), Quaternionf.fromAxesAnglesDeg(0, 0, 0), Vector3f.ONE)); region.getEntityManager().addEntity(entity); - return entity; - } + return entity; + } - @Override - public Entity[] spawnEntities(Vector3f[] points, LoadOption option, Class... classes) { - Entity[] entities = new Entity[points.length]; + @Override + public Entity[] spawnEntities(Vector3f[] points, LoadOption option, Class... classes) { + Entity[] entities = new Entity[points.length]; for (int i = 0; i < points.length; i++) { entities[i] = spawnEntity(points[i], option, classes); } return entities; - } - - @Override - public FlowEngine getEngine() { - return engine; - } - - @Override - public List getAll() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Entity getEntity(int id) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public TaskManager getTaskManager() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List getNearbyEntities(Point position, Entity ignore, int range) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List getNearbyEntities(Point position, int range) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List getNearbyEntities(Entity entity, int range) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Entity getNearestEntity(Point position, Entity ignore, int range) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Entity getNearestEntity(Point position, int range) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Entity getNearestEntity(Entity entity, int range) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List getNearbyPlayers(Point position, Player ignore, int range) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List getNearbyPlayers(Point position, int range) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List getNearbyPlayers(Entity entity, int range) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Player getNearestPlayer(Point position, Player ignore, int range) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Player getNearestPlayer(Point position, int range) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Player getNearestPlayer(Entity entity, int range) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setCuboid(CuboidBlockMaterialBuffer buffer, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setCuboid(int x, int y, int z, CuboidBlockMaterialBuffer buffer, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public CuboidBlockMaterialBuffer getCuboid(int bx, int by, int bz, int sx, int sy, int sz) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void getCuboid(int bx, int by, int bz, CuboidBlockMaterialBuffer buffer) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void getCuboid(CuboidBlockMaterialBuffer buffer) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List getPlayers() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Collection getRegions() { - return regionSource.getRegions(); - } - - public Collection getFlowRegions() { - return (Collection) getRegions(); - } - - @Override - public FlowRegion getRegion(int x, int y, int z, LoadOption loadopt) { - return regionSource.getRegion(x, y, z, loadopt); - } - - @Override - public FlowRegion getRegionFromChunk(int x, int y, int z, LoadOption loadopt) { - return getRegion(x >> Region.CHUNKS.BITS, y >> Region.CHUNKS.BITS, z >> Region.CHUNKS.BITS, loadopt); - } - - @Override - public FlowRegion getRegionFromBlock(int x, int y, int z, LoadOption loadopt) { - return getRegion(x >> Region.BLOCKS.BITS, y >> Region.BLOCKS.BITS, z >> Region.BLOCKS.BITS, loadopt); - } - - @Override - public FlowRegion getRegionFromBlock(Vector3f position, LoadOption loadopt) { - return getRegionFromBlock(position.getFloorX(), position.getFloorY(), position.getFloorZ(), loadopt); - } - - @Override - public boolean containsChunk(int x, int y, int z) { - return true; - } - - @Override - public FlowChunk getChunk(int x, int y, int z, LoadOption loadopt) { - FlowRegion region = getRegionFromChunk(x, y, z, loadopt); - if (region == null) { - return null; - } - return region.getChunk(x, y, z, loadopt); - } - - @Override - public Chunk getChunkFromBlock(int x, int y, int z, LoadOption loadopt) { - Region region = getRegionFromBlock(x, y, z, loadopt); - if (region == null) { - return null; - } - return region.getChunkFromBlock(x, y, z, loadopt); - } - - @Override - public Chunk getChunkFromBlock(Vector3f position, LoadOption loadopt) { - Region region = getRegionFromBlock(position, loadopt); - if (region == null) { - return null; - } - return region.getChunkFromBlock(position, loadopt); - } - - @Override - public void saveChunk(int x, int y, int z) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void unloadChunk(int x, int y, int z, boolean save) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getNumLoadedChunks() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean setBlockData(int x, int y, int z, short data, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean setBlockMaterial(int x, int y, int z, BlockMaterial material, short data, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean compareAndSetData(int x, int y, int z, int expect, short data, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public short setBlockDataBits(int x, int y, int z, int bits, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public short setBlockDataBits(int x, int y, int z, int bits, boolean set, Cause source) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public short clearBlockDataBits(int x, int y, int z, int bits, Cause source) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getBlockDataField(int x, int y, int z, int bits) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isBlockDataBitSet(int x, int y, int z, int bits) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int setBlockDataField(int x, int y, int z, int bits, int value, Cause source) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int addBlockDataField(int x, int y, int z, int bits, int value, Cause source) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean containsBlock(int x, int y, int z) { - return true; - } + } + + @Override + public FlowEngine getEngine() { + return engine; + } + + @Override + public List getAll() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Entity getEntity(int id) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public TaskManager getTaskManager() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getNearbyEntities(Point position, Entity ignore, int range) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getNearbyEntities(Point position, int range) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getNearbyEntities(Entity entity, int range) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Entity getNearestEntity(Point position, Entity ignore, int range) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Entity getNearestEntity(Point position, int range) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Entity getNearestEntity(Entity entity, int range) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getNearbyPlayers(Point position, Player ignore, int range) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getNearbyPlayers(Point position, int range) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getNearbyPlayers(Entity entity, int range) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Player getNearestPlayer(Point position, Player ignore, int range) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Player getNearestPlayer(Point position, int range) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Player getNearestPlayer(Entity entity, int range) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCuboid(CuboidBlockMaterialBuffer buffer, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCuboid(int x, int y, int z, CuboidBlockMaterialBuffer buffer, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CuboidBlockMaterialBuffer getCuboid(int bx, int by, int bz, int sx, int sy, int sz) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void getCuboid(int bx, int by, int bz, CuboidBlockMaterialBuffer buffer) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void getCuboid(CuboidBlockMaterialBuffer buffer) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getPlayers() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Collection getRegions() { + return regionSource.getRegions(); + } + + public Collection getFlowRegions() { + return (Collection) getRegions(); + } + + @Override + public FlowRegion getRegion(int x, int y, int z, LoadOption loadopt) { + return regionSource.getRegion(x, y, z, loadopt); + } + + @Override + public FlowRegion getRegionFromChunk(int x, int y, int z, LoadOption loadopt) { + return getRegion(x >> Region.CHUNKS.BITS, y >> Region.CHUNKS.BITS, z >> Region.CHUNKS.BITS, loadopt); + } + + @Override + public FlowRegion getRegionFromBlock(int x, int y, int z, LoadOption loadopt) { + return getRegion(x >> Region.BLOCKS.BITS, y >> Region.BLOCKS.BITS, z >> Region.BLOCKS.BITS, loadopt); + } + + @Override + public FlowRegion getRegionFromBlock(Vector3f position, LoadOption loadopt) { + return getRegionFromBlock(position.getFloorX(), position.getFloorY(), position.getFloorZ(), loadopt); + } + + @Override + public boolean containsChunk(int x, int y, int z) { + return true; + } + + @Override + public FlowChunk getChunk(int x, int y, int z, LoadOption loadopt) { + FlowRegion region = getRegionFromChunk(x, y, z, loadopt); + if (region == null) { + return null; + } + return region.getChunk(x, y, z, loadopt); + } + + @Override + public Chunk getChunkFromBlock(int x, int y, int z, LoadOption loadopt) { + Region region = getRegionFromBlock(x, y, z, loadopt); + if (region == null) { + return null; + } + return region.getChunkFromBlock(x, y, z, loadopt); + } + + @Override + public Chunk getChunkFromBlock(Vector3f position, LoadOption loadopt) { + Region region = getRegionFromBlock(position, loadopt); + if (region == null) { + return null; + } + return region.getChunkFromBlock(position, loadopt); + } + + @Override + public void saveChunk(int x, int y, int z) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void unloadChunk(int x, int y, int z, boolean save) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getNumLoadedChunks() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean setBlockData(int x, int y, int z, short data, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean setBlockMaterial(int x, int y, int z, BlockBaseMaterial material, short data, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean compareAndSetData(int x, int y, int z, int expect, short data, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short setBlockDataBits(int x, int y, int z, int bits, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short setBlockDataBits(int x, int y, int z, int bits, boolean set, Cause source) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short clearBlockDataBits(int x, int y, int z, int bits, Cause source) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getBlockDataField(int x, int y, int z, int bits) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isBlockDataBitSet(int x, int y, int z, int bits) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int setBlockDataField(int x, int y, int z, int bits, int value, Cause source) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int addBlockDataField(int x, int y, int z, int bits, int value, Cause source) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean containsBlock(int x, int y, int z) { + return true; + } @Override public FlowBlock getBlock(float x, float y, float z) { @@ -393,73 +389,74 @@ public FlowBlock getBlock(Vector3f position) { return this.getBlock(position.getX(), position.getY(), position.getZ()); } - @Override - public boolean commitCuboid(CuboidBlockMaterialBuffer buffer, Cause cause) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public CuboidBlockMaterialBuffer getCuboid(boolean backBuffer) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public CuboidBlockMaterialBuffer getCuboid(int bx, int by, int bz, int sx, int sy, int sz, boolean backBuffer) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public BlockMaterial getBlockMaterial(int x, int y, int z) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getBlockFullState(int x, int y, int z) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public short getBlockData(int x, int y, int z) { - throw new UnsupportedOperationException("Not supported yet."); - } - - public WorldSnapshot getSnapshot() { - return snapshot; - } - - @Override - public void startTickRun(int stage, long delta) { - if (stage == 0) { - age.set((long) (age.get() + (delta / 1000000d * (MILLIS_IN_DAY / GAME_DAY_IRL)))); - } - } - - @Override - public void copySnapshotRun(int sequence) { - // TODO: modified status - snapshot.update(this); - } - - @Override - public boolean checkSequence(TickStage stage, int sequence) { - if (stage == TickStage.SNAPSHOT) { - return sequence == 0; - } - return sequence == -1; - } - - @Override - public Thread getExecutionThread() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setExecutionThread(Thread t) { - } - - private static ShortBitMask STAGES = TickStage.allOf(TickStage.STAGE1, TickStage.SNAPSHOT); - @Override - public ShortBitMask getTickStages() { - return STAGES; - } + @Override + public boolean commitCuboid(CuboidBlockMaterialBuffer buffer, Cause cause) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CuboidBlockMaterialBuffer getCuboid(boolean backBuffer) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CuboidBlockMaterialBuffer getCuboid(int bx, int by, int bz, int sx, int sy, int sz, boolean backBuffer) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BlockBaseMaterial getBlockMaterial(int x, int y, int z) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getBlockFullState(int x, int y, int z) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public short getBlockData(int x, int y, int z) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public WorldSnapshot getSnapshot() { + return snapshot; + } + + @Override + public void startTickRun(int stage, long delta) { + if (stage == 0) { + age.set((long) (age.get() + (delta / 1000000d * (MILLIS_IN_DAY / GAME_DAY_IRL)))); + } + } + + @Override + public void copySnapshotRun(int sequence) { + // TODO: modified status + snapshot.update(this); + } + + @Override + public boolean checkSequence(TickStage stage, int sequence) { + if (stage == TickStage.SNAPSHOT) { + return sequence == 0; + } + return sequence == -1; + } + + @Override + public Thread getExecutionThread() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setExecutionThread(Thread t) { + } + + private static ShortBitMask STAGES = TickStage.allOf(TickStage.STAGE1, TickStage.SNAPSHOT); + + @Override + public ShortBitMask getTickStages() { + return STAGES; + } } diff --git a/src/main/java/com/flowpowered/engine/registry/Attribute.java b/src/main/java/com/flowpowered/engine/registry/Attribute.java new file mode 100644 index 0000000..8e01365 --- /dev/null +++ b/src/main/java/com/flowpowered/engine/registry/Attribute.java @@ -0,0 +1,35 @@ +package com.flowpowered.engine.registry; + +/** + * Parametrized identifiers base class + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + * @see A generic and yet type-safe DTO - part 2 + */ +public class Attribute { + + private String name; + + public Attribute(String name) { + if (name == null) { + throw new IllegalArgumentException(); + } + this.name = name; + } + + public static Attribute getInstance( + String name) { + return new Attribute(name); + } + + @Override + public String toString() { + return name; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof Attribute && name.toLowerCase().equals(obj.toString().toLowerCase()); + } +} diff --git a/src/main/java/com/flowpowered/engine/registry/AttributeGroup.java b/src/main/java/com/flowpowered/engine/registry/AttributeGroup.java new file mode 100644 index 0000000..5679e60 --- /dev/null +++ b/src/main/java/com/flowpowered/engine/registry/AttributeGroup.java @@ -0,0 +1,12 @@ +package com.flowpowered.engine.registry; + +/** + * Marker Interface + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + * @see A generic and yet type-safe DTO - part 2 + */ +public interface AttributeGroup { + +} diff --git a/src/main/java/com/flowpowered/engine/registry/BlockAttributes.java b/src/main/java/com/flowpowered/engine/registry/BlockAttributes.java new file mode 100644 index 0000000..9f3e9c7 --- /dev/null +++ b/src/main/java/com/flowpowered/engine/registry/BlockAttributes.java @@ -0,0 +1,19 @@ +package com.flowpowered.engine.registry; + +import java.util.LinkedList; + +import com.flowpowered.api.material.BlockBaseMaterial; + +/** + * Please change this + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + */ +public interface BlockAttributes extends AttributeGroup { + + public static final Attribute NAME = Attribute.getInstance("NAME"); + public static final Attribute ID = Attribute.getInstance("ID"); + public static final Attribute> CUSTOM_MATERIAL = Attribute.getInstance("CUSTOM_MATERIAL"); + public static final Attribute BASE_MATERIAL = Attribute.getInstance("BASE_MATERIAL"); +} diff --git a/src/main/java/com/flowpowered/engine/registry/BlockMaterial.java b/src/main/java/com/flowpowered/engine/registry/BlockMaterial.java new file mode 100644 index 0000000..938ea6a --- /dev/null +++ b/src/main/java/com/flowpowered/engine/registry/BlockMaterial.java @@ -0,0 +1,99 @@ +package com.flowpowered.engine.registry; + +import java.util.LinkedList; + +import com.flowpowered.api.material.BlockBaseMaterial; + +/** + * BlockMaterial which contains the default game based {@link BlockBaseMaterial} and any other custom {@link BlockBaseMaterial} + * TODO: add logging for FINE + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + */ +public class BlockMaterial extends GenericRegistryObject { + + BlockMaterial(final Class attributeGroup) { + super(BlockAttributes.class); + } + + static BlockMaterial createBlockMaterial(BlockBaseMaterial blockBaseMaterial) { + return createBlockMaterial(blockBaseMaterial, null); + } + + static BlockMaterial createBlockMaterial(BlockBaseMaterial blockBaseMaterial, BlockBaseMaterial customBlockBaseMaterial) { + if (blockBaseMaterial == null) { + if (customBlockBaseMaterial == null) { + throw new IllegalArgumentException("Both materials can't be null!"); + } else { + blockBaseMaterial = customBlockBaseMaterial; + } + } else { + if (customBlockBaseMaterial == null) { + customBlockBaseMaterial = blockBaseMaterial; + } + } + BlockMaterial blockMaterial = new BlockMaterial(BlockAttributes.class); + LinkedList customBlockBaseMaterialList = new LinkedList<>(); + customBlockBaseMaterialList.add(customBlockBaseMaterial); + blockMaterial.set(BlockAttributes.ID, -1); + blockMaterial.set(BlockAttributes.CUSTOM_MATERIAL, customBlockBaseMaterialList); + blockMaterial.set(BlockAttributes.BASE_MATERIAL, blockBaseMaterial); + blockMaterial.set(BlockAttributes.NAME, blockBaseMaterial.getName()); + return blockMaterial; + } + + public BlockBaseMaterial getBlockBaseMaterial() { + return (BlockBaseMaterial) this.get(BlockAttributes.BASE_MATERIAL); + } + + public BlockBaseMaterial getCustomBlockBaseMaterial() { + return ((LinkedList) this.get(BlockAttributes.CUSTOM_MATERIAL)).getLast(); + } + + public LinkedList getCustomBlockBaseMaterials() { + return (LinkedList) this.get(BlockAttributes.CUSTOM_MATERIAL); + } + + public boolean addCustomBlockBaseMaterial(BlockBaseMaterial blockBaseMaterial) { + LinkedList customBlockBaseMaterialList = this.getCustomBlockBaseMaterials(); + Boolean success = customBlockBaseMaterialList.add(blockBaseMaterial); + if (success) { + this.set(BlockAttributes.CUSTOM_MATERIAL, customBlockBaseMaterialList); + } + return success; + } + + public boolean removeCustomBlockBaseMaterial(BlockBaseMaterial blockBaseMaterial) { + Boolean success = false; + if (blockBaseMaterial != this.getBlockBaseMaterial()) { + LinkedList customBlockBaseMaterialList = this.getCustomBlockBaseMaterials(); + success = customBlockBaseMaterialList.remove(blockBaseMaterial); + if (success) { + this.set(BlockAttributes.CUSTOM_MATERIAL, customBlockBaseMaterialList); + } + } + return success; + } + + public boolean revertToLastCustomBlockBaseMaterial() { + LinkedList customBlockBaseMaterialList = this.getCustomBlockBaseMaterials(); + Boolean success = (customBlockBaseMaterialList.removeLast() != null); + if (success) { + this.set(BlockAttributes.CUSTOM_MATERIAL, customBlockBaseMaterialList); + } + return success; + } + + Integer getID() { + return (Integer) this.get(BlockAttributes.ID); + } + + void setID(Integer id) { + this.set(BlockAttributes.ID, id); + } + + public String getName() { + return (String) this.get(BlockAttributes.NAME); + } +} diff --git a/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java b/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java new file mode 100644 index 0000000..df9eebb --- /dev/null +++ b/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java @@ -0,0 +1,147 @@ +package com.flowpowered.engine.registry; + +import java.util.HashMap; +import java.util.Map; + +import com.flowpowered.api.Flow; +import com.flowpowered.api.material.BlockBaseMaterial; + +/** + * Registry Class which handles everything concerning BlockMaterial interaction. + * TODO: add world support + * TODO: create abstract base class to support Item and Entity Registry + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + */ +public class BlockMaterialRegistry { + + /** + * Class of the instancing game. + * This is required to make sure that only objects from the instancing game can be used as fallback objects. + */ + private Class gameClass; + private String gameClassPath; + private Map idNameMap = new HashMap<>(500); + private Map nameIdMap = new HashMap<>(500); + private Map idRegistryMap = new HashMap<>(500); + private Integer numberOfMaterials = 0; + private boolean initialized = false; + + public BlockMaterialRegistry(TempGame game) { + gameClass = game.getClass(); + gameClassPath = gameClass.getPackage().getName(); + } + + public BlockMaterial addBlockMaterial(BlockBaseMaterial blockBaseMaterial) { + return addBlockMaterial(blockBaseMaterial, blockBaseMaterial); + } + + public BlockMaterial addBlockMaterial(BlockBaseMaterial blockBaseMaterial, BlockBaseMaterial customBlockBaseMaterial) { + if (!blockBaseMaterial.getClass().getName().contains(gameClassPath)) { + throw new IllegalArgumentException("BlockBaseMaterial must be from classes of the Game!"); + } + String blockMaterialName = blockBaseMaterial.getName(); + BlockMaterial blockMaterial; + if (nameIdMap.containsKey(blockMaterialName)) { + Integer id = nameIdMap.get(blockMaterialName); + if (idRegistryMap.containsKey(id)) { + blockMaterial = ((BlockMaterial) idRegistryMap.get(id)); + Flow.log("BlockMaterial with the Name " + blockMaterialName + " already exists!"); + Flow.fine("Returning original BlockMaterial"); + if (blockMaterial.getCustomBlockBaseMaterial().equals(customBlockBaseMaterial) || (customBlockBaseMaterial.getClass().getName().contains(gameClassPath))) { + Flow.fine("without changes"); + } else { + blockMaterial.addCustomBlockBaseMaterial(customBlockBaseMaterial); + } + } else { + blockMaterial = addBlockMaterialToRegistry(id, blockBaseMaterial, customBlockBaseMaterial); + } + } else { + numberOfMaterials++; + blockMaterial = addBlockMaterialToRegistry(numberOfMaterials, blockBaseMaterial, customBlockBaseMaterial); + } + return blockMaterial; + } + + public boolean addCustomBlockBaseMaterial(String blockMaterialName, BlockBaseMaterial customBlockBaseMaterial) { + checkIfBlockMaterialNameExists(blockMaterialName); + return addCustomBlockBaseMaterial(nameIdMap.get(blockMaterialName), customBlockBaseMaterial); + } + + public boolean addCustomBlockBaseMaterial(Integer id, BlockBaseMaterial customBlockBaseMaterial) { + checkIfBlockMaterialIdExists(id); + BlockMaterial blockMaterial = (BlockMaterial) idRegistryMap.get(id); + return blockMaterial.addCustomBlockBaseMaterial(customBlockBaseMaterial); + } + + public boolean removeCustomBlockBaseMaterial(String blockMaterialName, BlockBaseMaterial customBlockBaseMaterial) { + checkIfBlockMaterialNameExists(blockMaterialName); + return removeCustomBlockBaseMaterial(nameIdMap.get(blockMaterialName), customBlockBaseMaterial); + } + + private void checkIfBlockMaterialNameExists(final String blockMaterialName) { + if (!nameIdMap.containsKey(blockMaterialName)) { + throw new IllegalArgumentException("The BlockMaterial with the name " + blockMaterialName + " doesn't exist!"); + } + } + + public boolean removeCustomBlockBaseMaterial(Integer id, BlockBaseMaterial customBlockBaseMaterial) { + checkIfBlockMaterialIdExists(id); + BlockMaterial blockMaterial = (BlockMaterial) idRegistryMap.get(id); + return blockMaterial.removeCustomBlockBaseMaterial(customBlockBaseMaterial); + } + + private void checkIfBlockMaterialIdExists(final Integer id) { + if (!idRegistryMap.containsKey(id)) { + throw new IllegalArgumentException("The BlockMaterial with the ID " + id + " doesn't exist!"); + } + } + + public boolean revertToLastCustomBlockBaseMaterial(String blockMaterialName) { + checkIfBlockMaterialNameExists(blockMaterialName); + return revertToLastCustomBlockBaseMaterial(nameIdMap.get(blockMaterialName)); + } + + public BlockMaterial getBlockMaterialByName(String blockMaterialName) { + checkIfBlockMaterialNameExists(blockMaterialName); + Integer id = nameIdMap.get(blockMaterialName); + return getBlockMaterialByID(id); + } + + public BlockMaterial getBlockMaterialByID(Integer id) { + checkIfBlockMaterialIdExists(id); + return (BlockMaterial) idRegistryMap.get(id); + } + + public boolean revertToLastCustomBlockBaseMaterial(Integer id) { + checkIfBlockMaterialIdExists(id); + BlockMaterial blockMaterial = (BlockMaterial) idRegistryMap.get(id); + return blockMaterial.revertToLastCustomBlockBaseMaterial(); + } + + private BlockMaterial addBlockMaterialToRegistry(Integer id, BlockBaseMaterial blockBaseMaterial, BlockBaseMaterial customBlockBaseMaterial) { + String blockMaterialName = blockBaseMaterial.getName(); + idNameMap.put(id, blockMaterialName); + nameIdMap.put(blockMaterialName, id); + BlockMaterial blockMaterial = BlockMaterial.createBlockMaterial(blockBaseMaterial, customBlockBaseMaterial); + idRegistryMap.put(id, blockMaterial); + blockMaterial.setID(id); + return blockMaterial; + } + + private boolean initializeRegistry() { + // TODO: add reading of initial registry if saved file found + return false; + } + + public boolean loadRegistry() { + // TODO: add loading of registry from file + return false; + } + + public boolean saveRegistry() { + // TODO: add saving of registry to file + return false; + } +} diff --git a/src/main/java/com/flowpowered/engine/registry/EntityAttributes.java b/src/main/java/com/flowpowered/engine/registry/EntityAttributes.java new file mode 100644 index 0000000..f845c47 --- /dev/null +++ b/src/main/java/com/flowpowered/engine/registry/EntityAttributes.java @@ -0,0 +1,13 @@ +package com.flowpowered.engine.registry; + +/** + * Please change this + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + */ +public interface EntityAttributes extends AttributeGroup { + + public static final Attribute NAME = Attribute.getInstance("NAME"); + public static final Attribute ENTITY_TYPE = Attribute.getInstance("ENTITY_TYPE"); +} diff --git a/src/main/java/com/flowpowered/engine/registry/GenericRegistryObject.java b/src/main/java/com/flowpowered/engine/registry/GenericRegistryObject.java new file mode 100644 index 0000000..c35e18b --- /dev/null +++ b/src/main/java/com/flowpowered/engine/registry/GenericRegistryObject.java @@ -0,0 +1,74 @@ +package com.flowpowered.engine.registry; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +/** + * Type-safe generic registry object + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + * @see A generic and yet type-safe DTO - part 2 + */ +public class GenericRegistryObject { + + private Class attributeGroup; + private Map, Object> attributes = new LinkedHashMap, Object>(); + private String name; + + GenericRegistryObject(Class attributeGroup) { + this.attributeGroup = attributeGroup; + } + + public static GenericRegistryObject getInstance( + Class clazz) { + return new GenericRegistryObject(clazz); + } + + public GenericRegistryObject set(Attribute identifier, T value) { + attributes.put(identifier, value); + return this; + } + + public T get(Attribute identifier) { + @SuppressWarnings("unchecked") + T theValue = (T) attributes.get(identifier); + return theValue; + } + + public T remove(Attribute identifier) { + @SuppressWarnings("unchecked") + T theValue = (T) attributes.remove(identifier); + return theValue; + } + + public void clear() { + attributes.clear(); + } + + public int size() { + return attributes.size(); + } + + public Set> getAttributes() { + return attributes.keySet(); + } + + public boolean contains(Attribute identifier) { + return attributes.containsKey(identifier); + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + @Override + public String toString() { + return attributeGroup.getSimpleName() + " [" + attributes + "]"; + } +} diff --git a/src/main/java/com/flowpowered/engine/registry/MaterialMapper.java b/src/main/java/com/flowpowered/engine/registry/MaterialMapper.java new file mode 100644 index 0000000..d15eaa0 --- /dev/null +++ b/src/main/java/com/flowpowered/engine/registry/MaterialMapper.java @@ -0,0 +1,44 @@ +package com.flowpowered.engine.registry; + +import com.flowpowered.api.material.BaseMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; + +/** + * This is the connection between the engine and the original baseMaterial. + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + */ +public class MaterialMapper { + + private int id; + private BlockBaseMaterial baseMaterial; + private BlockBaseMaterial fallbackBaseMaterial; + + protected MaterialMapper(int id, BaseMaterial baseMaterial, BaseMaterial fallbackBaseMaterial) { + this.id = id; + if (baseMaterial == null) { + if (fallbackBaseMaterial == null) { + throw new IllegalArgumentException("Both materials can't be null!"); + } else { + baseMaterial = fallbackBaseMaterial; + } + } else { + if (fallbackBaseMaterial == null) { + fallbackBaseMaterial = baseMaterial; + } + } + } + + public int getId() { + return id; + } + + public BaseMaterial getBaseMaterial() { + return baseMaterial; + } + + public BaseMaterial getFallbackBaseMaterial() { + return fallbackBaseMaterial; + } +} diff --git a/src/main/java/com/flowpowered/engine/registry/TempEntityType.java b/src/main/java/com/flowpowered/engine/registry/TempEntityType.java new file mode 100644 index 0000000..d926078 --- /dev/null +++ b/src/main/java/com/flowpowered/engine/registry/TempEntityType.java @@ -0,0 +1,23 @@ +package com.flowpowered.engine.registry; + +/** + * Temporary Object as placeholder to show working of new Entity Setup + *

+ * The Entity Type will be used to combine all necessary information like + * behaviour, texture, model etc into one object + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + */ +public class TempEntityType { + + private String name; + + public TempEntityType(String name) { + this.name = name.toUpperCase(); + } + + public String toString() { + return name; + } +} diff --git a/src/main/java/com/flowpowered/engine/registry/TempGame.java b/src/main/java/com/flowpowered/engine/registry/TempGame.java new file mode 100644 index 0000000..faf75bb --- /dev/null +++ b/src/main/java/com/flowpowered/engine/registry/TempGame.java @@ -0,0 +1,11 @@ +package com.flowpowered.engine.registry; + +/** + * Temporary Game Object + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + */ +public class TempGame { + +} diff --git a/src/main/java/com/flowpowered/engine/render/mesher/StandardChunkMesher.java b/src/main/java/com/flowpowered/engine/render/mesher/StandardChunkMesher.java index 26d5866..4ac3123 100644 --- a/src/main/java/com/flowpowered/engine/render/mesher/StandardChunkMesher.java +++ b/src/main/java/com/flowpowered/engine/render/mesher/StandardChunkMesher.java @@ -23,133 +23,134 @@ */ package com.flowpowered.engine.render.mesher; -import gnu.trove.list.TFloatList; -import gnu.trove.list.TIntList; import com.flowpowered.api.geo.cuboid.Chunk; - -import com.flowpowered.api.material.BlockMaterial; +import com.flowpowered.api.material.BlockBaseMaterial; import com.flowpowered.api.material.block.BlockFace; import com.flowpowered.api.material.block.BlockFaces; -import com.flowpowered.api.model.mesher.ChunkMesher; import com.flowpowered.api.model.mesh.Mesh; import com.flowpowered.api.model.mesh.Mesh.MeshAttribute; +import com.flowpowered.api.model.mesher.ChunkMesher; import com.flowpowered.engine.geo.snapshot.ChunkSnapshotGroup; +import gnu.trove.list.TFloatList; +import gnu.trove.list.TIntList; + /** * The standard chunk mesher. Voxels are meshed as blocks. Occludes any block not visible, including the edge blocks. Can mesh a chunk with 3n^2(n+2) block access operations, n being the size of the * chunk. */ public class StandardChunkMesher implements ChunkMesher { - @Override - public Mesh mesh(ChunkSnapshotGroup chunk) { - // TODO: add textures - final Mesh mesh = new Mesh(MeshAttribute.POSITIONS, MeshAttribute.NORMALS); - final TFloatList positions = mesh.getAttribute(MeshAttribute.POSITIONS); - final TIntList indices = mesh.getIndices(); - int index = 0; - // Mesh the faces on the x axis - for (int zz = 0; zz < Chunk.BLOCKS.SIZE; zz++) { - for (int yy = 0; yy < Chunk.BLOCKS.SIZE; yy++) { - BlockMaterial backMaterial = chunk.getMaterial(-1, yy, zz); - backMaterial = backMaterial == null ? BlockMaterial.AIR : backMaterial; - for (int xx = 0; xx < Chunk.BLOCKS.SIZE + 1; xx++) { - BlockMaterial frontMaterial = chunk.getMaterial(xx, yy, zz); - frontMaterial = frontMaterial == null ? BlockMaterial.AIR : frontMaterial; - final BlockFace face = getFace(backMaterial, frontMaterial, BlockFaces.NS); - if (face == BlockFace.NORTH) { - add(indices, index + 3, index + 2, index + 1, index + 2, index, index + 1); - } else if (face == BlockFace.SOUTH) { - add(indices, index + 3, index + 1, index + 2, index + 2, index + 1, index); - } else { - backMaterial = frontMaterial; - continue; - } - add(positions, xx, yy + 1, zz + 1); - add(positions, xx, yy + 1, zz); - add(positions, xx, yy, zz + 1); - add(positions, xx, yy, zz); - index += 4; - backMaterial = frontMaterial; - } - } - } - // Mesh the faces on the y axis - for (int xx = 0; xx < Chunk.BLOCKS.SIZE; xx++) { - for (int zz = 0; zz < Chunk.BLOCKS.SIZE; zz++) { - BlockMaterial backMaterial = chunk.getMaterial(xx, -1, zz); - backMaterial = backMaterial == null ? BlockMaterial.AIR : backMaterial; - for (int yy = 0; yy < Chunk.BLOCKS.SIZE + 1; yy++) { - BlockMaterial frontMaterial = chunk.getMaterial(xx, yy, zz); - frontMaterial = frontMaterial == null ? BlockMaterial.AIR : frontMaterial; - final BlockFace face = getFace(backMaterial, frontMaterial, BlockFaces.BT); - if (face == BlockFace.BOTTOM) { - add(indices, index + 3, index + 2, index + 1, index + 2, index, index + 1); - } else if (face == BlockFace.TOP) { - add(indices, index + 3, index + 1, index + 2, index + 2, index + 1, index); - } else { - backMaterial = frontMaterial; - continue; - } - add(positions, xx, yy, zz); - add(positions, xx + 1, yy, zz); - add(positions, xx, yy, zz + 1); - add(positions, xx + 1, yy, zz + 1); - index += 4; - backMaterial = frontMaterial; - } - } - } - // Mesh the faces on the z axis - for (int xx = 0; xx < Chunk.BLOCKS.SIZE; xx++) { - for (int yy = 0; yy < Chunk.BLOCKS.SIZE; yy++) { - BlockMaterial backMaterial = chunk.getMaterial(xx, yy, -1); - backMaterial = backMaterial == null ? BlockMaterial.AIR : backMaterial; - for (int zz = 0; zz < Chunk.BLOCKS.SIZE + 1; zz++) { - BlockMaterial frontMaterial = chunk.getMaterial(xx, yy, zz); - frontMaterial = frontMaterial == null ? BlockMaterial.AIR : frontMaterial; - final BlockFace face = getFace(backMaterial, frontMaterial, BlockFaces.EW); - if (face == BlockFace.EAST) { - add(indices, index + 3, index + 2, index + 1, index + 2, index, index + 1); - } else if (face == BlockFace.WEST) { - add(indices, index + 3, index + 1, index + 2, index + 2, index + 1, index); - } else { - backMaterial = frontMaterial; - continue; - } - add(positions, xx, yy + 1, zz); - add(positions, xx + 1, yy + 1, zz); - add(positions, xx, yy, zz); - add(positions, xx + 1, yy, zz); - index += 4; - backMaterial = frontMaterial; - } - } - } - return mesh; - } - private BlockFace getFace(BlockMaterial back, BlockMaterial front, BlockFaces axis) { - if (!back.isInvisible() && !front.occludes(axis.get(0), back)) { - return axis.get(1); - } - if (!front.isInvisible() && !back.occludes(axis.get(1), front)) { - return axis.get(0); - } - return null; - } + @Override + public Mesh mesh(ChunkSnapshotGroup chunk) { + // TODO: add textures + final Mesh mesh = new Mesh(MeshAttribute.POSITIONS, MeshAttribute.NORMALS); + final TFloatList positions = mesh.getAttribute(MeshAttribute.POSITIONS); + final TIntList indices = mesh.getIndices(); + int index = 0; + // Mesh the faces on the x axis + for (int zz = 0; zz < Chunk.BLOCKS.SIZE; zz++) { + for (int yy = 0; yy < Chunk.BLOCKS.SIZE; yy++) { + BlockBaseMaterial backMaterial = chunk.getMaterial(-1, yy, zz); + backMaterial = backMaterial == null ? BlockBaseMaterial.AIR : backMaterial; + for (int xx = 0; xx < Chunk.BLOCKS.SIZE + 1; xx++) { + BlockBaseMaterial frontMaterial = chunk.getMaterial(xx, yy, zz); + frontMaterial = frontMaterial == null ? BlockBaseMaterial.AIR : frontMaterial; + final BlockFace face = getFace(backMaterial, frontMaterial, BlockFaces.NS); + if (face == BlockFace.NORTH) { + add(indices, index + 3, index + 2, index + 1, index + 2, index, index + 1); + } else if (face == BlockFace.SOUTH) { + add(indices, index + 3, index + 1, index + 2, index + 2, index + 1, index); + } else { + backMaterial = frontMaterial; + continue; + } + add(positions, xx, yy + 1, zz + 1); + add(positions, xx, yy + 1, zz); + add(positions, xx, yy, zz + 1); + add(positions, xx, yy, zz); + index += 4; + backMaterial = frontMaterial; + } + } + } + // Mesh the faces on the y axis + for (int xx = 0; xx < Chunk.BLOCKS.SIZE; xx++) { + for (int zz = 0; zz < Chunk.BLOCKS.SIZE; zz++) { + BlockBaseMaterial backMaterial = chunk.getMaterial(xx, -1, zz); + backMaterial = backMaterial == null ? BlockBaseMaterial.AIR : backMaterial; + for (int yy = 0; yy < Chunk.BLOCKS.SIZE + 1; yy++) { + BlockBaseMaterial frontMaterial = chunk.getMaterial(xx, yy, zz); + frontMaterial = frontMaterial == null ? BlockBaseMaterial.AIR : frontMaterial; + final BlockFace face = getFace(backMaterial, frontMaterial, BlockFaces.BT); + if (face == BlockFace.BOTTOM) { + add(indices, index + 3, index + 2, index + 1, index + 2, index, index + 1); + } else if (face == BlockFace.TOP) { + add(indices, index + 3, index + 1, index + 2, index + 2, index + 1, index); + } else { + backMaterial = frontMaterial; + continue; + } + add(positions, xx, yy, zz); + add(positions, xx + 1, yy, zz); + add(positions, xx, yy, zz + 1); + add(positions, xx + 1, yy, zz + 1); + index += 4; + backMaterial = frontMaterial; + } + } + } + // Mesh the faces on the z axis + for (int xx = 0; xx < Chunk.BLOCKS.SIZE; xx++) { + for (int yy = 0; yy < Chunk.BLOCKS.SIZE; yy++) { + BlockBaseMaterial backMaterial = chunk.getMaterial(xx, yy, -1); + backMaterial = backMaterial == null ? BlockBaseMaterial.AIR : backMaterial; + for (int zz = 0; zz < Chunk.BLOCKS.SIZE + 1; zz++) { + BlockBaseMaterial frontMaterial = chunk.getMaterial(xx, yy, zz); + frontMaterial = frontMaterial == null ? BlockBaseMaterial.AIR : frontMaterial; + final BlockFace face = getFace(backMaterial, frontMaterial, BlockFaces.EW); + if (face == BlockFace.EAST) { + add(indices, index + 3, index + 2, index + 1, index + 2, index, index + 1); + } else if (face == BlockFace.WEST) { + add(indices, index + 3, index + 1, index + 2, index + 2, index + 1, index); + } else { + backMaterial = frontMaterial; + continue; + } + add(positions, xx, yy + 1, zz); + add(positions, xx + 1, yy + 1, zz); + add(positions, xx, yy, zz); + add(positions, xx + 1, yy, zz); + index += 4; + backMaterial = frontMaterial; + } + } + } + return mesh; + } + + private BlockFace getFace(BlockBaseMaterial back, BlockBaseMaterial front, BlockFaces axis) { + if (!back.isInvisible() && !front.occludes(axis.get(0), back)) { + return axis.get(1); + } + if (!front.isInvisible() && !back.occludes(axis.get(1), front)) { + return axis.get(0); + } + return null; + } - private static void add(TFloatList list, float x, float y, float z) { - list.add(x); - list.add(y); - list.add(z); - } + private static void add(TFloatList list, float x, float y, float z) { + list.add(x); + list.add(y); + list.add(z); + } - private static void add(TIntList list, int i0, int i1, int i2, int i3, int i4, int i5) { - list.add(i0); - list.add(i1); - list.add(i2); - list.add(i3); - list.add(i4); - list.add(i5); - } + private static void add(TIntList list, int i0, int i1, int i2, int i3, int i4, int i5) { + list.add(i0); + list.add(i1); + list.add(i2); + list.add(i3); + list.add(i4); + list.add(i5); + } } From b117b73010b6f2d9a6cd3ff1740bdbb73e10d798 Mon Sep 17 00:00:00 2001 From: Don Redhorse Date: Wed, 21 May 2014 15:19:47 +0200 Subject: [PATCH 3/7] adding temp plugin classes --- .../api/material/block/TempClientPlugin.java | 35 ++ .../api/material/block/TempPlugin.java | 118 ++++++ .../block/TempPluginDescriptionFile.java | 392 ++++++++++++++++++ .../api/material/block/TempServerPlugin.java | 35 ++ .../registry/BlockMaterialRegistry.java | 11 +- .../engine/registry/MaterialMapper.java | 44 -- .../flowpowered/engine/registry/TempGame.java | 11 - 7 files changed, 587 insertions(+), 59 deletions(-) create mode 100644 src/main/java/com/flowpowered/api/material/block/TempClientPlugin.java create mode 100644 src/main/java/com/flowpowered/api/material/block/TempPlugin.java create mode 100644 src/main/java/com/flowpowered/api/material/block/TempPluginDescriptionFile.java create mode 100644 src/main/java/com/flowpowered/api/material/block/TempServerPlugin.java delete mode 100644 src/main/java/com/flowpowered/engine/registry/MaterialMapper.java delete mode 100644 src/main/java/com/flowpowered/engine/registry/TempGame.java diff --git a/src/main/java/com/flowpowered/api/material/block/TempClientPlugin.java b/src/main/java/com/flowpowered/api/material/block/TempClientPlugin.java new file mode 100644 index 0000000..332e5e0 --- /dev/null +++ b/src/main/java/com/flowpowered/api/material/block/TempClientPlugin.java @@ -0,0 +1,35 @@ +package com.flowpowered.api.material.block; + +/** + * Please change this + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + */ +public interface TempClientPlugin extends TempPlugin { + + /** + * Called when the plugin is enabled + */ + public void onClientEnable(); + + /** + * Called when the plugins is disabled + */ + public void onClientDisable(); + + /** + * Called when the client is reloaded + */ + public void onClientReload(); + + /** + * Called when the plugin is initially loaded + */ + public void onClientLoad(); + + /** + * Called when the client is unloaded + */ + public void onClientUnload(); +} diff --git a/src/main/java/com/flowpowered/api/material/block/TempPlugin.java b/src/main/java/com/flowpowered/api/material/block/TempPlugin.java new file mode 100644 index 0000000..e8ee371 --- /dev/null +++ b/src/main/java/com/flowpowered/api/material/block/TempPlugin.java @@ -0,0 +1,118 @@ +package com.flowpowered.api.material.block; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import com.flowpowered.api.Engine; +import com.flowpowered.api.generator.WorldGenerator; +import com.flowpowered.commons.Named; + +import net.java.games.util.plugins.PluginLoader; +import org.slf4j.Logger; + +/** + * Please change this + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + */ +public interface TempPlugin extends Named { + + /** + * Returns true if the plugins is enabled + * + * @return enabled + */ + public boolean isEnabled(); + + /** + * Changes the enabled state of the plugin This should only be called by the + * plugin's loader + * + * @param enabled + */ + public void setEnabled(boolean enabled); + + /** + * Returns the plugin's loader + * + * @return loader + */ + public PluginLoader getPluginLoader(); + + /** + * Returns the plugin's logger + * + * @return logger + */ + public Logger getLogger(); + + /** + * Returns the plugin's description + * @return description + */ + // public PluginDescriptionFile getDescription(); + + /** + * Returns the engine object + * + * @return engine + */ + public Engine getEngine(); + + /** + * Gets the suitable generator for the world and generator name. + * + * @param world name to generate + * @param generator name + * + * @return world generator + */ + public WorldGenerator getWorldGenerator(String world, String generator); + + /** + * Returns the plugin's data folder + * + * @return + */ + public File getDataFolder(); + + /** + * Returns a File that is the plugin's jar file. + * + * @return + */ + public File getFile(); + + /** + * Returns a resource from the plugin's archive + * + * @param path The path of the resource to get + * + * @return The resource's input stream, or null if none could be found or the implementation does not support this method + */ + public InputStream getResource(String path); + + /** + * Extracts a resource returned by {@link #getResource(String)} to the given path + * + * @param path The path to get the resource at + * @param destination The destination file + * + * @throws IOException When the resource could not be found or the copying failed + */ + public void extractResource(String path, File destination) throws IOException; + + /** + * Allows plugins to load external libraries into the JVM + * + * @param file that is the library + */ + public void loadLibrary(File file); + + /** + * @return the plugins dictionary + */ + // public PluginDictionary getDictionary(); +} diff --git a/src/main/java/com/flowpowered/api/material/block/TempPluginDescriptionFile.java b/src/main/java/com/flowpowered/api/material/block/TempPluginDescriptionFile.java new file mode 100644 index 0000000..7531dfe --- /dev/null +++ b/src/main/java/com/flowpowered/api/material/block/TempPluginDescriptionFile.java @@ -0,0 +1,392 @@ +package com.flowpowered.api.material.block; + +import java.io.InputStream; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import com.flowpowered.api.Platform; + +import org.spout.cereal.config.ConfigurationException; +import org.spout.cereal.config.ConfigurationNode; +import org.spout.cereal.config.ConfigurationNodeSource; +import org.spout.cereal.config.serialization.Serialization; +import org.spout.cereal.config.yaml.YamlConfiguration; + +/** + * Please change this + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + */ +public class TempPluginDescriptionFile { + + public static final List RESTRICTED_NAMES = Collections.unmodifiableList(Arrays.asList( + "org.spout", + "org.getspout", + "org.spoutcraft", + "in.spout")); + private final HashMap data = new HashMap(); + private String name; + private String version; + private String description; + private List authors = new ArrayList(); + private String website; + private boolean reload; + private Platform platform; + //private LoadOrder load; + private String main; + private List depends; + private List softdepends; + private String fullname; + private Locale codedLocale = Locale.ENGLISH; + + public TempPluginDescriptionFile(String name, String version, String main, Platform platform) { + this.name = name; + this.version = version; + this.main = main; + this.platform = platform; + fullname = name + " v" + version; + } + + public TempPluginDescriptionFile(InputStream stream) //throws InvalidDescriptionFileException { + { + YamlConfiguration yaml = new YamlConfiguration(stream); + try { + yaml.load(); + } catch (ConfigurationException e) { + //throw new InvalidDescriptionFileException(e); + } + load(yaml); + } + + public TempPluginDescriptionFile(Reader reader) //throws InvalidDescriptionFileException { + { + YamlConfiguration yaml = new YamlConfiguration(reader); + try { + yaml.load(); + } catch (ConfigurationException e) { + //throw new InvalidDescriptionFileException(e); + } + load(yaml); + } + + public TempPluginDescriptionFile(String raw) //throws InvalidDescriptionFileException { + { + YamlConfiguration yaml = new YamlConfiguration(raw); + try { + yaml.load(); + } catch (ConfigurationException e) { + //throw new InvalidDescriptionFileException(e); + } + load(yaml); + } + + @SuppressWarnings("unchecked") + private void load(Map map) //throws InvalidDescriptionFileException { + { + name = getEntry("name", String.class, map); + if (!name.matches("^[A-Za-z0-9 _.-]+$")) { + //throw new InvalidDescriptionFileException("The field 'name' in properties.yml contains invalid characters."); + } + if (name.toLowerCase().contains("spout")) { + //throw new InvalidDescriptionFileException("The plugin '" + name + "' has Spout in the name. This is not allowed."); + } + + main = getEntry("main", String.class, map); + if (!isOfficialPlugin(main)) { + for (String namespace : RESTRICTED_NAMES) { + if (main.startsWith(namespace)) { + //throw new InvalidDescriptionFileException("The use of the namespace '" + namespace + "' is not permitted."); + } + } + } + + version = getEntry("version", String.class, map); + platform = getEntry("platform", Platform.class, map); + fullname = name + " v" + version; + + if (map.containsKey("author")) { + authors.add(getEntry("author", String.class, map)); + } + + if (map.containsKey("authors")) { + authors.addAll(getEntry("authors", List.class, map)); + } + + if (map.containsKey("depends")) { + depends = getEntry("depends", List.class, map); + } + + if (map.containsKey("softdepends")) { + softdepends = getEntry("softdepends", List.class, map); + } + + if (map.containsKey("description")) { + description = getEntry("description", String.class, map); + } + + if (map.containsKey("load")) { + //load = getEntry("load", LoadOrder.class, map); + } + + if (map.containsKey("reload")) { + reload = getEntry("reload", Boolean.class, map); + } + + if (map.containsKey("website")) { + website = getEntry("website", String.class, map); + } + + if (map.containsKey("codedlocale")) { + Locale[] locales = Locale.getAvailableLocales(); + for (Locale l : locales) { + if (l.getLanguage().equals((new Locale((String) map.get("codedlocale"))).getLanguage())) { + codedLocale = l; + } + } + } + if (map.containsKey("data")) { + Map data = getEntry("data", Map.class, map); + for (Map.Entry entry : data.entrySet()) { + String key = entry.getKey().toString(); + String value = entry.getValue().toString(); + this.data.put(key, value); + } + } + } + + private void load(YamlConfiguration yaml) //throws InvalidDescriptionFileException { + { + name = getEntry("name", String.class, yaml); + if (!name.matches("^[A-Za-z0-9 _.-]+$")) { + //throw new InvalidDescriptionFileException("The field 'name' in properties.yml contains invalid characters."); + } + if (name.toLowerCase().contains("spout")) { + //throw new InvalidDescriptionFileException("The plugin '" + name + "' has Spout in the name. This is not allowed."); + } + + main = getEntry("main", String.class, yaml); + if (!isOfficialPlugin(main)) { + for (String namespace : RESTRICTED_NAMES) { + if (main.startsWith(namespace)) { + //throw new InvalidDescriptionFileException("The use of the namespace '" + namespace + "' is not permitted."); + } + } + } + + version = getEntry("version", String.class, yaml); + platform = getEntry("platform", Platform.class, yaml); + fullname = name + " v" + version; + + if (yaml.hasChild("author")) { + authors.add(getEntry("author", String.class, yaml)); + } + + if (yaml.hasChild("authors")) { + authors.addAll(getEntry("authors", List.class, yaml)); + } + + if (yaml.hasChild("depends")) { + depends = getEntry("depends", List.class, yaml); + } + + if (yaml.hasChild("softdepends")) { + softdepends = getEntry("softdepends", List.class, yaml); + } + + if (yaml.hasChild("description")) { + description = getEntry("description", String.class, yaml); + } + + if (yaml.hasChild("load")) { + //load = getEntry("load", LoadOrder.class, yaml); + } + + if (yaml.hasChild("reload")) { + reload = getEntry("reload", Boolean.class, yaml); + } + + if (yaml.hasChild("website")) { + website = getEntry("website", String.class, yaml); + } + + if (yaml.hasChild("codedlocale")) { + Locale[] locales = Locale.getAvailableLocales(); + for (Locale l : locales) { + if (l.getLanguage().equals((new Locale(yaml.getChild("codedlocale").getString())).getLanguage())) { + codedLocale = l; + } + } + } + if (yaml.hasChild("data")) { + Map data = yaml.getChild("data").getChildren(); + for (Map.Entry entry : data.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue().getString(); + this.data.put(key, value); + } + } + } + + @SuppressWarnings("unchecked") + private T getEntry(Object key, Class type, Map values) //throws InvalidDescriptionFileException { + { + Object value = values.get(key); + if (value == null) { + //throw new InvalidDescriptionFileException("The field '" + key + "' is not present in the properties.yml!"); + } + + return (T) Serialization.deserialize(type, value); + } + + private T getEntry(String key, Class type, ConfigurationNodeSource src) //throws InvalidDescriptionFileException { + { + T value = src.getChild(key).getTypedValue(type); + if (value == null) { + //throw new InvalidDescriptionFileException("The field '" + key + "' is not present in the properties.yml!"); + } + return value; + } + + /** + * Returns true if the plugin is an Official Spout Plugin + * + * @param namespace The plugin's main class namespace + * + * @return true if an official plugin + */ + private boolean isOfficialPlugin(String namespace) { + return (namespace.equalsIgnoreCase("org.spout.vanilla.plugin.VanillaPlugin") + || namespace.equalsIgnoreCase("org.spout.bridge.VanillaBridgePlugin") + || namespace.equalsIgnoreCase("org.spout.infobjects.InfObjectsPlugin") + || namespace.startsWith("org.spout.droplet")); + } + + /** + * Returns the plugin's name + * + * @return name + */ + public String getName() { + return name; + } + + /** + * Returns the plugin's version + * + * @return version + */ + public String getVersion() { + return version; + } + + /** + * Returns the plugin's description + * + * @return description + */ + public String getDescription() { + return description; + } + + /** + * Returns the plugin's authors + * + * @return authors + */ + public List getAuthors() { + return authors; + } + + /** + * Returns the plugin's website + * + * @return website + */ + public String getWebsite() { + return website; + } + + /** + * Returns false if the plugin wants to be exempt from a reload + * + * @return reload + */ + public boolean allowsReload() { + return reload; + } + + /** + * Returns the plugin's platform + * + * @return platform + */ + public Platform getPlatform() { + return platform; + } + + /** + * Returns the plugin's load order + * @return load + */ + //public LoadOrder getLoad() { + // return load; + //} + + /** + * Returns the path the plugins main class + * + * @return main + */ + public String getMain() { + return main; + } + + /** + * Returns the plugin's dependencies + * + * @return depends + */ + public List getDepends() { + return depends; + } + + /** + * Returns the plugin's soft dependencies + * + * @return softdepends + */ + public List getSoftDepends() { + return softdepends; + } + + /** + * Returns the plugin's fullname The fullname is formatted as follows: + * [name] v[version] + * + * @return The full name of the plugin + */ + public String getFullName() { + return fullname; + } + + /** + * Returns the locale the strings in the plugin are coded in. + * Will be read from the plugins properties.yml from the field "codedlocale" + * + * @return the locale the plugin is coded in + */ + public Locale getCodedLocale() { + return codedLocale; + } + + public String getData(String key) { + return data.get(key); + } +} diff --git a/src/main/java/com/flowpowered/api/material/block/TempServerPlugin.java b/src/main/java/com/flowpowered/api/material/block/TempServerPlugin.java new file mode 100644 index 0000000..ca63165 --- /dev/null +++ b/src/main/java/com/flowpowered/api/material/block/TempServerPlugin.java @@ -0,0 +1,35 @@ +package com.flowpowered.api.material.block; + +/** + * Please change this + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + */ +public interface TempServerPlugin extends TempPlugin { + + /** + * Called when the plugin is enabled + */ + public void onServerEnable(); + + /** + * Called when the plugins is disabled + */ + public void onServerDisable(); + + /** + * Called when the server is reloaded + */ + public void onServerReload(); + + /** + * Called when the plugin is initially loaded + */ + public void onServerLoad(); + + /** + * Called when the server is unloaded + */ + public void onServerUnload(); +} diff --git a/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java b/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java index df9eebb..3a6e1fa 100644 --- a/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java +++ b/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java @@ -4,6 +4,7 @@ import java.util.Map; import com.flowpowered.api.Flow; +import com.flowpowered.api.geo.World; import com.flowpowered.api.material.BlockBaseMaterial; /** @@ -17,10 +18,11 @@ public class BlockMaterialRegistry { /** - * Class of the instancing game. + * Class of the instancing Plugin. * This is required to make sure that only objects from the instancing game can be used as fallback objects. */ - private Class gameClass; + private Class gameClass; + private World world; private String gameClassPath; private Map idNameMap = new HashMap<>(500); private Map nameIdMap = new HashMap<>(500); @@ -28,9 +30,10 @@ public class BlockMaterialRegistry { private Integer numberOfMaterials = 0; private boolean initialized = false; - public BlockMaterialRegistry(TempGame game) { + public BlockMaterialRegistry(TempGame game, World world) { gameClass = game.getClass(); gameClassPath = gameClass.getPackage().getName(); + this.world = world; } public BlockMaterial addBlockMaterial(BlockBaseMaterial blockBaseMaterial) { @@ -39,7 +42,7 @@ public BlockMaterial addBlockMaterial(BlockBaseMaterial blockBaseMaterial) { public BlockMaterial addBlockMaterial(BlockBaseMaterial blockBaseMaterial, BlockBaseMaterial customBlockBaseMaterial) { if (!blockBaseMaterial.getClass().getName().contains(gameClassPath)) { - throw new IllegalArgumentException("BlockBaseMaterial must be from classes of the Game!"); + throw new IllegalArgumentException("BlockBaseMaterial must be from classes of the registering plugin: " + gameClass.getName() + " !"); } String blockMaterialName = blockBaseMaterial.getName(); BlockMaterial blockMaterial; diff --git a/src/main/java/com/flowpowered/engine/registry/MaterialMapper.java b/src/main/java/com/flowpowered/engine/registry/MaterialMapper.java deleted file mode 100644 index d15eaa0..0000000 --- a/src/main/java/com/flowpowered/engine/registry/MaterialMapper.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.flowpowered.engine.registry; - -import com.flowpowered.api.material.BaseMaterial; -import com.flowpowered.api.material.BlockBaseMaterial; - -/** - * This is the connection between the engine and the original baseMaterial. - * - * @author $Author: dredhorse$ - * @version $FullVersion$* - */ -public class MaterialMapper { - - private int id; - private BlockBaseMaterial baseMaterial; - private BlockBaseMaterial fallbackBaseMaterial; - - protected MaterialMapper(int id, BaseMaterial baseMaterial, BaseMaterial fallbackBaseMaterial) { - this.id = id; - if (baseMaterial == null) { - if (fallbackBaseMaterial == null) { - throw new IllegalArgumentException("Both materials can't be null!"); - } else { - baseMaterial = fallbackBaseMaterial; - } - } else { - if (fallbackBaseMaterial == null) { - fallbackBaseMaterial = baseMaterial; - } - } - } - - public int getId() { - return id; - } - - public BaseMaterial getBaseMaterial() { - return baseMaterial; - } - - public BaseMaterial getFallbackBaseMaterial() { - return fallbackBaseMaterial; - } -} diff --git a/src/main/java/com/flowpowered/engine/registry/TempGame.java b/src/main/java/com/flowpowered/engine/registry/TempGame.java deleted file mode 100644 index faf75bb..0000000 --- a/src/main/java/com/flowpowered/engine/registry/TempGame.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.flowpowered.engine.registry; - -/** - * Temporary Game Object - * - * @author $Author: dredhorse$ - * @version $FullVersion$* - */ -public class TempGame { - -} From 4580fa7de2d678331d4629eb9bbef14e7e8b2913 Mon Sep 17 00:00:00 2001 From: Don Redhorse Date: Thu, 5 Jun 2014 15:21:01 +0200 Subject: [PATCH 4/7] changed BlockMaterial to correctly support generics --- .../api/material/block/TempPlugin.java | 16 +++++++++ .../engine/registry/BlockMaterial.java | 33 +++++++++++-------- .../registry/BlockMaterialRegistry.java | 21 ++++++------ 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/flowpowered/api/material/block/TempPlugin.java b/src/main/java/com/flowpowered/api/material/block/TempPlugin.java index e8ee371..c11b14f 100644 --- a/src/main/java/com/flowpowered/api/material/block/TempPlugin.java +++ b/src/main/java/com/flowpowered/api/material/block/TempPlugin.java @@ -7,6 +7,7 @@ import com.flowpowered.api.Engine; import com.flowpowered.api.generator.WorldGenerator; import com.flowpowered.commons.Named; +import com.flowpowered.engine.registry.BlockMaterialRegistry; import net.java.games.util.plugins.PluginLoader; import org.slf4j.Logger; @@ -115,4 +116,19 @@ public interface TempPlugin extends Named { * @return the plugins dictionary */ // public PluginDictionary getDictionary(); + + /** + * @return the plugins BlockMaterialRegistry + */ + public BlockMaterialRegistry getBlockMaterialRegistry(); + + /** + * @return the plugins ItemMaterialRegistry + */ + //public ItemMaterialRegistry getItemMaterialRegistry(); + + /** + * @return the plugins EntitiyMaterialRegistry + */ + //public EntityMaterialRegistry getEntityMaterialRegistry(); } diff --git a/src/main/java/com/flowpowered/engine/registry/BlockMaterial.java b/src/main/java/com/flowpowered/engine/registry/BlockMaterial.java index 938ea6a..82c8598 100644 --- a/src/main/java/com/flowpowered/engine/registry/BlockMaterial.java +++ b/src/main/java/com/flowpowered/engine/registry/BlockMaterial.java @@ -4,6 +4,11 @@ import com.flowpowered.api.material.BlockBaseMaterial; +import static com.flowpowered.engine.registry.BlockAttributes.BASE_MATERIAL; +import static com.flowpowered.engine.registry.BlockAttributes.CUSTOM_MATERIAL; +import static com.flowpowered.engine.registry.BlockAttributes.ID; +import static com.flowpowered.engine.registry.BlockAttributes.NAME; + /** * BlockMaterial which contains the default game based {@link BlockBaseMaterial} and any other custom {@link BlockBaseMaterial} * TODO: add logging for FINE @@ -11,7 +16,7 @@ * @author $Author: dredhorse$ * @version $FullVersion$* */ -public class BlockMaterial extends GenericRegistryObject { +public class BlockMaterial extends GenericRegistryObject { BlockMaterial(final Class attributeGroup) { super(BlockAttributes.class); @@ -36,30 +41,30 @@ static BlockMaterial createBlockMaterial(BlockBaseMaterial blockBaseMaterial, Bl BlockMaterial blockMaterial = new BlockMaterial(BlockAttributes.class); LinkedList customBlockBaseMaterialList = new LinkedList<>(); customBlockBaseMaterialList.add(customBlockBaseMaterial); - blockMaterial.set(BlockAttributes.ID, -1); - blockMaterial.set(BlockAttributes.CUSTOM_MATERIAL, customBlockBaseMaterialList); - blockMaterial.set(BlockAttributes.BASE_MATERIAL, blockBaseMaterial); - blockMaterial.set(BlockAttributes.NAME, blockBaseMaterial.getName()); + blockMaterial.set(ID, -1); + blockMaterial.set(CUSTOM_MATERIAL, customBlockBaseMaterialList); + blockMaterial.set(BASE_MATERIAL, blockBaseMaterial); + blockMaterial.set(NAME, blockBaseMaterial.getName()); return blockMaterial; } public BlockBaseMaterial getBlockBaseMaterial() { - return (BlockBaseMaterial) this.get(BlockAttributes.BASE_MATERIAL); + return this.get(BASE_MATERIAL); } public BlockBaseMaterial getCustomBlockBaseMaterial() { - return ((LinkedList) this.get(BlockAttributes.CUSTOM_MATERIAL)).getLast(); + return this.get(CUSTOM_MATERIAL).getLast(); } public LinkedList getCustomBlockBaseMaterials() { - return (LinkedList) this.get(BlockAttributes.CUSTOM_MATERIAL); + return this.get(CUSTOM_MATERIAL); } public boolean addCustomBlockBaseMaterial(BlockBaseMaterial blockBaseMaterial) { LinkedList customBlockBaseMaterialList = this.getCustomBlockBaseMaterials(); Boolean success = customBlockBaseMaterialList.add(blockBaseMaterial); if (success) { - this.set(BlockAttributes.CUSTOM_MATERIAL, customBlockBaseMaterialList); + this.set(CUSTOM_MATERIAL, customBlockBaseMaterialList); } return success; } @@ -70,7 +75,7 @@ public boolean removeCustomBlockBaseMaterial(BlockBaseMaterial blockBaseMaterial LinkedList customBlockBaseMaterialList = this.getCustomBlockBaseMaterials(); success = customBlockBaseMaterialList.remove(blockBaseMaterial); if (success) { - this.set(BlockAttributes.CUSTOM_MATERIAL, customBlockBaseMaterialList); + this.set(CUSTOM_MATERIAL, customBlockBaseMaterialList); } } return success; @@ -80,20 +85,20 @@ public boolean revertToLastCustomBlockBaseMaterial() { LinkedList customBlockBaseMaterialList = this.getCustomBlockBaseMaterials(); Boolean success = (customBlockBaseMaterialList.removeLast() != null); if (success) { - this.set(BlockAttributes.CUSTOM_MATERIAL, customBlockBaseMaterialList); + this.set(CUSTOM_MATERIAL, customBlockBaseMaterialList); } return success; } Integer getID() { - return (Integer) this.get(BlockAttributes.ID); + return this.get(ID); } void setID(Integer id) { - this.set(BlockAttributes.ID, id); + this.set(ID, id); } public String getName() { - return (String) this.get(BlockAttributes.NAME); + return this.get(NAME); } } diff --git a/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java b/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java index 3a6e1fa..fd782a1 100644 --- a/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java +++ b/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java @@ -4,12 +4,11 @@ import java.util.Map; import com.flowpowered.api.Flow; -import com.flowpowered.api.geo.World; import com.flowpowered.api.material.BlockBaseMaterial; +import com.flowpowered.api.material.block.TempPlugin; /** * Registry Class which handles everything concerning BlockMaterial interaction. - * TODO: add world support * TODO: create abstract base class to support Item and Entity Registry * * @author $Author: dredhorse$ @@ -22,18 +21,18 @@ public class BlockMaterialRegistry { * This is required to make sure that only objects from the instancing game can be used as fallback objects. */ private Class gameClass; - private World world; + private TempPlugin plugin; private String gameClassPath; private Map idNameMap = new HashMap<>(500); private Map nameIdMap = new HashMap<>(500); - private Map idRegistryMap = new HashMap<>(500); + private Map idRegistryMap = new HashMap<>(500); private Integer numberOfMaterials = 0; private boolean initialized = false; - public BlockMaterialRegistry(TempGame game, World world) { + public BlockMaterialRegistry(TempPlugin game) { gameClass = game.getClass(); gameClassPath = gameClass.getPackage().getName(); - this.world = world; + this.plugin = game; } public BlockMaterial addBlockMaterial(BlockBaseMaterial blockBaseMaterial) { @@ -49,7 +48,7 @@ public BlockMaterial addBlockMaterial(BlockBaseMaterial blockBaseMaterial, Block if (nameIdMap.containsKey(blockMaterialName)) { Integer id = nameIdMap.get(blockMaterialName); if (idRegistryMap.containsKey(id)) { - blockMaterial = ((BlockMaterial) idRegistryMap.get(id)); + blockMaterial = idRegistryMap.get(id); Flow.log("BlockMaterial with the Name " + blockMaterialName + " already exists!"); Flow.fine("Returning original BlockMaterial"); if (blockMaterial.getCustomBlockBaseMaterial().equals(customBlockBaseMaterial) || (customBlockBaseMaterial.getClass().getName().contains(gameClassPath))) { @@ -74,7 +73,7 @@ public boolean addCustomBlockBaseMaterial(String blockMaterialName, BlockBaseMat public boolean addCustomBlockBaseMaterial(Integer id, BlockBaseMaterial customBlockBaseMaterial) { checkIfBlockMaterialIdExists(id); - BlockMaterial blockMaterial = (BlockMaterial) idRegistryMap.get(id); + BlockMaterial blockMaterial = idRegistryMap.get(id); return blockMaterial.addCustomBlockBaseMaterial(customBlockBaseMaterial); } @@ -91,7 +90,7 @@ private void checkIfBlockMaterialNameExists(final String blockMaterialName) { public boolean removeCustomBlockBaseMaterial(Integer id, BlockBaseMaterial customBlockBaseMaterial) { checkIfBlockMaterialIdExists(id); - BlockMaterial blockMaterial = (BlockMaterial) idRegistryMap.get(id); + BlockMaterial blockMaterial = idRegistryMap.get(id); return blockMaterial.removeCustomBlockBaseMaterial(customBlockBaseMaterial); } @@ -114,12 +113,12 @@ public BlockMaterial getBlockMaterialByName(String blockMaterialName) { public BlockMaterial getBlockMaterialByID(Integer id) { checkIfBlockMaterialIdExists(id); - return (BlockMaterial) idRegistryMap.get(id); + return idRegistryMap.get(id); } public boolean revertToLastCustomBlockBaseMaterial(Integer id) { checkIfBlockMaterialIdExists(id); - BlockMaterial blockMaterial = (BlockMaterial) idRegistryMap.get(id); + BlockMaterial blockMaterial = idRegistryMap.get(id); return blockMaterial.revertToLastCustomBlockBaseMaterial(); } From 1571e4b7ffe3cc46bff19dcb3ea04d61ef68206c Mon Sep 17 00:00:00 2001 From: Don Redhorse Date: Tue, 17 Jun 2014 19:58:44 +0200 Subject: [PATCH 5/7] added RegistryNotInitializedException --- .../registry/BlockMaterialRegistry.java | 24 ++++++++++ .../RegistryNotInitializedException.java | 44 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 src/main/java/com/flowpowered/engine/registry/RegistryNotInitializedException.java diff --git a/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java b/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java index fd782a1..2d98a8c 100644 --- a/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java +++ b/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java @@ -40,6 +40,7 @@ public BlockMaterial addBlockMaterial(BlockBaseMaterial blockBaseMaterial) { } public BlockMaterial addBlockMaterial(BlockBaseMaterial blockBaseMaterial, BlockBaseMaterial customBlockBaseMaterial) { + checkIfRegistryIsInitialized(); if (!blockBaseMaterial.getClass().getName().contains(gameClassPath)) { throw new IllegalArgumentException("BlockBaseMaterial must be from classes of the registering plugin: " + gameClass.getName() + " !"); } @@ -66,18 +67,29 @@ public BlockMaterial addBlockMaterial(BlockBaseMaterial blockBaseMaterial, Block return blockMaterial; } + private void checkIfRegistryIsInitialized() { + if (!initialized) { + if (!initializeRegistry()) { + throw new RegistryNotInitializedException("BlockRegistry"); + } + } + } + public boolean addCustomBlockBaseMaterial(String blockMaterialName, BlockBaseMaterial customBlockBaseMaterial) { + checkIfRegistryIsInitialized(); checkIfBlockMaterialNameExists(blockMaterialName); return addCustomBlockBaseMaterial(nameIdMap.get(blockMaterialName), customBlockBaseMaterial); } public boolean addCustomBlockBaseMaterial(Integer id, BlockBaseMaterial customBlockBaseMaterial) { + checkIfRegistryIsInitialized(); checkIfBlockMaterialIdExists(id); BlockMaterial blockMaterial = idRegistryMap.get(id); return blockMaterial.addCustomBlockBaseMaterial(customBlockBaseMaterial); } public boolean removeCustomBlockBaseMaterial(String blockMaterialName, BlockBaseMaterial customBlockBaseMaterial) { + checkIfRegistryIsInitialized(); checkIfBlockMaterialNameExists(blockMaterialName); return removeCustomBlockBaseMaterial(nameIdMap.get(blockMaterialName), customBlockBaseMaterial); } @@ -89,6 +101,7 @@ private void checkIfBlockMaterialNameExists(final String blockMaterialName) { } public boolean removeCustomBlockBaseMaterial(Integer id, BlockBaseMaterial customBlockBaseMaterial) { + checkIfRegistryIsInitialized(); checkIfBlockMaterialIdExists(id); BlockMaterial blockMaterial = idRegistryMap.get(id); return blockMaterial.removeCustomBlockBaseMaterial(customBlockBaseMaterial); @@ -101,28 +114,33 @@ private void checkIfBlockMaterialIdExists(final Integer id) { } public boolean revertToLastCustomBlockBaseMaterial(String blockMaterialName) { + checkIfRegistryIsInitialized(); checkIfBlockMaterialNameExists(blockMaterialName); return revertToLastCustomBlockBaseMaterial(nameIdMap.get(blockMaterialName)); } public BlockMaterial getBlockMaterialByName(String blockMaterialName) { + checkIfRegistryIsInitialized(); checkIfBlockMaterialNameExists(blockMaterialName); Integer id = nameIdMap.get(blockMaterialName); return getBlockMaterialByID(id); } public BlockMaterial getBlockMaterialByID(Integer id) { + checkIfRegistryIsInitialized(); checkIfBlockMaterialIdExists(id); return idRegistryMap.get(id); } public boolean revertToLastCustomBlockBaseMaterial(Integer id) { + checkIfRegistryIsInitialized(); checkIfBlockMaterialIdExists(id); BlockMaterial blockMaterial = idRegistryMap.get(id); return blockMaterial.revertToLastCustomBlockBaseMaterial(); } private BlockMaterial addBlockMaterialToRegistry(Integer id, BlockBaseMaterial blockBaseMaterial, BlockBaseMaterial customBlockBaseMaterial) { + checkIfRegistryIsInitialized(); String blockMaterialName = blockBaseMaterial.getName(); idNameMap.put(id, blockMaterialName); nameIdMap.put(blockMaterialName, id); @@ -133,16 +151,22 @@ private BlockMaterial addBlockMaterialToRegistry(Integer id, BlockBaseMaterial b } private boolean initializeRegistry() { + if (initialized) { + Flow.severe("This blockregistry is already initialized, doing nothing!"); + return true; + } // TODO: add reading of initial registry if saved file found return false; } public boolean loadRegistry() { + checkIfRegistryIsInitialized(); // TODO: add loading of registry from file return false; } public boolean saveRegistry() { + checkIfRegistryIsInitialized(); // TODO: add saving of registry to file return false; } diff --git a/src/main/java/com/flowpowered/engine/registry/RegistryNotInitializedException.java b/src/main/java/com/flowpowered/engine/registry/RegistryNotInitializedException.java new file mode 100644 index 0000000..85fcb79 --- /dev/null +++ b/src/main/java/com/flowpowered/engine/registry/RegistryNotInitializedException.java @@ -0,0 +1,44 @@ +package com.flowpowered.engine.registry; + +import com.flowpowered.api.Flow; + +/** + * RunTimeException which is thrown when the Registry is not initialized yet. + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + */ +public class RegistryNotInitializedException extends RuntimeException { + + private Exception exception; + + public RegistryNotInitializedException(final String registryName) { + super("The " + registryName + " has not been initialized!"); + exception = null; + Flow.severe("The " + registryName + " is not initialized yet!"); + Flow.severe("This is a major error and you should notify the developer!"); + } + + public RegistryNotInitializedException() { + super("The registry has not been initialized!"); + exception = null; + Flow.severe("This registry is not initialized yet!"); + Flow.severe("This is a major error and you should notify the developer!"); + } + + public RegistryNotInitializedException(final String registryName, Exception ex) { + super("The " + registryName + " has not been initialized!", ex); + exception = ex; + Flow.severe("The " + registryName + " is not initialized yet!"); + Flow.severe("The following Exception was thrown:", exception); + Flow.getLogger().severe("This is a major error and you should notify the developer!"); + } + + public String getMessage() { + return "The registry has not been initialized!, please contact the developer as this is a major error!"; + } + + public Exception getException() { + return exception; + } +} From b43e1b7518b370b06a8881ae036fa08a8f495138 Mon Sep 17 00:00:00 2001 From: Don Redhorse Date: Wed, 18 Jun 2014 18:47:30 +0200 Subject: [PATCH 6/7] refactored to support yamlregistry object. --- .../registry/BlockMaterialRegistry.java | 49 ++++++----- .../engine/registry/RegistryIOException.java | 45 ++++++++++ .../RegistryNotInitializedException.java | 2 +- .../engine/registry/YamlRegistry.java | 82 +++++++++++++++++++ 4 files changed, 158 insertions(+), 20 deletions(-) create mode 100644 src/main/java/com/flowpowered/engine/registry/RegistryIOException.java create mode 100644 src/main/java/com/flowpowered/engine/registry/YamlRegistry.java diff --git a/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java b/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java index 2d98a8c..3780990 100644 --- a/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java +++ b/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java @@ -23,8 +23,8 @@ public class BlockMaterialRegistry { private Class gameClass; private TempPlugin plugin; private String gameClassPath; - private Map idNameMap = new HashMap<>(500); - private Map nameIdMap = new HashMap<>(500); + String blockRegistryFileName = plugin.getDataFolder() + "blockregistry"; + private YamlRegistry yamlRegistry = new YamlRegistry(500); private Map idRegistryMap = new HashMap<>(500); private Integer numberOfMaterials = 0; private boolean initialized = false; @@ -46,8 +46,8 @@ public BlockMaterial addBlockMaterial(BlockBaseMaterial blockBaseMaterial, Block } String blockMaterialName = blockBaseMaterial.getName(); BlockMaterial blockMaterial; - if (nameIdMap.containsKey(blockMaterialName)) { - Integer id = nameIdMap.get(blockMaterialName); + if (yamlRegistry.containsKeyName(blockMaterialName)) { + Integer id = yamlRegistry.getIdByName(blockMaterialName); if (idRegistryMap.containsKey(id)) { blockMaterial = idRegistryMap.get(id); Flow.log("BlockMaterial with the Name " + blockMaterialName + " already exists!"); @@ -78,7 +78,7 @@ private void checkIfRegistryIsInitialized() { public boolean addCustomBlockBaseMaterial(String blockMaterialName, BlockBaseMaterial customBlockBaseMaterial) { checkIfRegistryIsInitialized(); checkIfBlockMaterialNameExists(blockMaterialName); - return addCustomBlockBaseMaterial(nameIdMap.get(blockMaterialName), customBlockBaseMaterial); + return addCustomBlockBaseMaterial(yamlRegistry.getIdByName(blockMaterialName), customBlockBaseMaterial); } public boolean addCustomBlockBaseMaterial(Integer id, BlockBaseMaterial customBlockBaseMaterial) { @@ -91,11 +91,11 @@ public boolean addCustomBlockBaseMaterial(Integer id, BlockBaseMaterial customBl public boolean removeCustomBlockBaseMaterial(String blockMaterialName, BlockBaseMaterial customBlockBaseMaterial) { checkIfRegistryIsInitialized(); checkIfBlockMaterialNameExists(blockMaterialName); - return removeCustomBlockBaseMaterial(nameIdMap.get(blockMaterialName), customBlockBaseMaterial); + return removeCustomBlockBaseMaterial(yamlRegistry.getIdByName(blockMaterialName), customBlockBaseMaterial); } private void checkIfBlockMaterialNameExists(final String blockMaterialName) { - if (!nameIdMap.containsKey(blockMaterialName)) { + if (!yamlRegistry.containsKeyName(blockMaterialName)) { throw new IllegalArgumentException("The BlockMaterial with the name " + blockMaterialName + " doesn't exist!"); } } @@ -116,13 +116,13 @@ private void checkIfBlockMaterialIdExists(final Integer id) { public boolean revertToLastCustomBlockBaseMaterial(String blockMaterialName) { checkIfRegistryIsInitialized(); checkIfBlockMaterialNameExists(blockMaterialName); - return revertToLastCustomBlockBaseMaterial(nameIdMap.get(blockMaterialName)); + return revertToLastCustomBlockBaseMaterial(yamlRegistry.getIdByName(blockMaterialName)); } public BlockMaterial getBlockMaterialByName(String blockMaterialName) { checkIfRegistryIsInitialized(); checkIfBlockMaterialNameExists(blockMaterialName); - Integer id = nameIdMap.get(blockMaterialName); + Integer id = yamlRegistry.getIdByName(blockMaterialName); return getBlockMaterialByID(id); } @@ -142,8 +142,7 @@ public boolean revertToLastCustomBlockBaseMaterial(Integer id) { private BlockMaterial addBlockMaterialToRegistry(Integer id, BlockBaseMaterial blockBaseMaterial, BlockBaseMaterial customBlockBaseMaterial) { checkIfRegistryIsInitialized(); String blockMaterialName = blockBaseMaterial.getName(); - idNameMap.put(id, blockMaterialName); - nameIdMap.put(blockMaterialName, id); + yamlRegistry.addIdName(id, blockMaterialName); BlockMaterial blockMaterial = BlockMaterial.createBlockMaterial(blockBaseMaterial, customBlockBaseMaterial); idRegistryMap.put(id, blockMaterial); blockMaterial.setID(id); @@ -152,22 +151,34 @@ private BlockMaterial addBlockMaterialToRegistry(Integer id, BlockBaseMaterial b private boolean initializeRegistry() { if (initialized) { - Flow.severe("This blockregistry is already initialized, doing nothing!"); + Flow.fine("This BlockRegistry is already initialized, doing nothing!"); return true; } - // TODO: add reading of initial registry if saved file found - return false; + if (Flow.getPlatform().isServer()) { + if (yamlRegistry.checkIfRegistryStorageExists(blockRegistryFileName)) { + if (!loadRegistry()) { + throw new RegistryIOException("BlockRegistry", "loaded"); + } + } + } + initialized = true; + return initialized; } public boolean loadRegistry() { - checkIfRegistryIsInitialized(); - // TODO: add loading of registry from file - return false; + if (Flow.getPlatform().isClient()) { + Flow.debug("Won't be loading registry on client platform!"); + return true; + } + return yamlRegistry.load(blockRegistryFileName); } public boolean saveRegistry() { + if (Flow.getPlatform().isClient()) { + Flow.debug("Won't be saving registry on client platform!"); + return true; + } checkIfRegistryIsInitialized(); - // TODO: add saving of registry to file - return false; + return yamlRegistry.save(blockRegistryFileName); } } diff --git a/src/main/java/com/flowpowered/engine/registry/RegistryIOException.java b/src/main/java/com/flowpowered/engine/registry/RegistryIOException.java new file mode 100644 index 0000000..eccd779 --- /dev/null +++ b/src/main/java/com/flowpowered/engine/registry/RegistryIOException.java @@ -0,0 +1,45 @@ +package com.flowpowered.engine.registry; + +import com.flowpowered.api.Flow; + +/** + * RunTimeException which is thrown when the Registry can not be loaded or saved. + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + */ +public class RegistryIOException extends RuntimeException { + + private Exception exception; + + public RegistryIOException(final String registryName, final String ioKind) { + super("The " + registryName + " can not be " + ioKind + "!"); + exception = null; + Flow.severe("The " + registryName + " can not be " + ioKind + "!"); + Flow.severe("This is a major error and you should check your filesystem!"); + Flow.severe("NOTE: Without fixing this worlds can not be " + ioKind + " correctly !"); + } + + public RegistryIOException() { + super("The registry has some IO errors!"); + exception = null; + Flow.severe("This is a major error and you should check your filesystem!"); + Flow.severe("NOTE: Without fixing this worlds can not be correctly handled!"); + } + + public RegistryIOException(final String registryName, final String ioKind, Exception ex) { + super("The " + registryName + " can not be " + ioKind + "!", ex); + exception = ex; + Flow.severe("The " + registryName + " can not be " + ioKind + "!"); + Flow.severe("This is a major error and you should check your filesystem!"); + Flow.severe("NOTE: Without fixing this worlds can not be " + ioKind + " correctly !"); + } + + public String getMessage() { + return "The registry has some IO errors!, please check your file system as this is a major error!"; + } + + public Exception getException() { + return exception; + } +} diff --git a/src/main/java/com/flowpowered/engine/registry/RegistryNotInitializedException.java b/src/main/java/com/flowpowered/engine/registry/RegistryNotInitializedException.java index 85fcb79..8ef56fb 100644 --- a/src/main/java/com/flowpowered/engine/registry/RegistryNotInitializedException.java +++ b/src/main/java/com/flowpowered/engine/registry/RegistryNotInitializedException.java @@ -31,7 +31,7 @@ public RegistryNotInitializedException(final String registryName, Exception ex) exception = ex; Flow.severe("The " + registryName + " is not initialized yet!"); Flow.severe("The following Exception was thrown:", exception); - Flow.getLogger().severe("This is a major error and you should notify the developer!"); + Flow.severe("This is a major error and you should notify the developer!"); } public String getMessage() { diff --git a/src/main/java/com/flowpowered/engine/registry/YamlRegistry.java b/src/main/java/com/flowpowered/engine/registry/YamlRegistry.java new file mode 100644 index 0000000..bc2e783 --- /dev/null +++ b/src/main/java/com/flowpowered/engine/registry/YamlRegistry.java @@ -0,0 +1,82 @@ +package com.flowpowered.engine.registry; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +/** + * Registry object which is using the yaml standard to save data. + * Todo make abstract to support other ways of saving / loading + * + * @author $Author: dredhorse$ + * @version $FullVersion$* + */ +public class YamlRegistry { + + private Map idNameMap; + private Map nameIdMap; + + public YamlRegistry() { + this(500); + } + + public YamlRegistry(Integer number) { + idNameMap = new HashMap<>(number); + nameIdMap = new HashMap<>(number); + } + + public String addIdName(Integer id, String name) { + nameIdMap.put(name, id); + return idNameMap.put(id, name); + } + + public Integer addNameId(String name, Integer id) { + idNameMap.put(id, name); + return nameIdMap.put(name, id); + } + + public Integer getIdByName(String name) { + return nameIdMap.get(name); + } + + public String getNameById(Integer id) { + return idNameMap.get(id); + } + + public String removeId(Integer id) { + String name = idNameMap.get(id); + nameIdMap.remove(name); + return idNameMap.remove(id); + } + + public Integer removeName(String name) { + Integer id = nameIdMap.get(name); + idNameMap.remove(id); + return nameIdMap.remove(name); + } + + public boolean containsKeyId(Integer id) { + return idNameMap.containsKey(id); + } + + public boolean containsKeyName(String name) { + return nameIdMap.containsKey(name); + } + + public boolean save(String file) { + // Todo implement yaml save + + return false; + } + + public boolean load(String file) { + // Todo implement yaml load + + return false; + } + + public boolean checkIfRegistryStorageExists(String file) { + return new File(file + ".yml").exists(); + } +} + From 26f0699cbff64bf284ad313d4ba8d913b978f8af Mon Sep 17 00:00:00 2001 From: Don Redhorse Date: Sun, 29 Jun 2014 12:28:02 +0200 Subject: [PATCH 7/7] refactored to support yamlregistry object. --- .../engine/registry/Attribute.java | 2 +- .../engine/registry/BlockAttributes.java | 8 ++-- .../registry/BlockMaterialRegistry.java | 38 ++++++++++++++----- .../engine/registry/EntityAttributes.java | 4 +- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/flowpowered/engine/registry/Attribute.java b/src/main/java/com/flowpowered/engine/registry/Attribute.java index 8e01365..1a95b66 100644 --- a/src/main/java/com/flowpowered/engine/registry/Attribute.java +++ b/src/main/java/com/flowpowered/engine/registry/Attribute.java @@ -18,7 +18,7 @@ public Attribute(String name) { this.name = name; } - public static Attribute getInstance( + public static Attribute get( String name) { return new Attribute(name); } diff --git a/src/main/java/com/flowpowered/engine/registry/BlockAttributes.java b/src/main/java/com/flowpowered/engine/registry/BlockAttributes.java index 9f3e9c7..3954a00 100644 --- a/src/main/java/com/flowpowered/engine/registry/BlockAttributes.java +++ b/src/main/java/com/flowpowered/engine/registry/BlockAttributes.java @@ -12,8 +12,8 @@ */ public interface BlockAttributes extends AttributeGroup { - public static final Attribute NAME = Attribute.getInstance("NAME"); - public static final Attribute ID = Attribute.getInstance("ID"); - public static final Attribute> CUSTOM_MATERIAL = Attribute.getInstance("CUSTOM_MATERIAL"); - public static final Attribute BASE_MATERIAL = Attribute.getInstance("BASE_MATERIAL"); + public static final Attribute NAME = Attribute.get("NAME"); + public static final Attribute ID = Attribute.get("ID"); + public static final Attribute> CUSTOM_MATERIAL = Attribute.get("CUSTOM_MATERIAL"); + public static final Attribute BASE_MATERIAL = Attribute.get("BASE_MATERIAL"); } diff --git a/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java b/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java index 3780990..88a06d4 100644 --- a/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java +++ b/src/main/java/com/flowpowered/engine/registry/BlockMaterialRegistry.java @@ -23,7 +23,7 @@ public class BlockMaterialRegistry { private Class gameClass; private TempPlugin plugin; private String gameClassPath; - String blockRegistryFileName = plugin.getDataFolder() + "blockregistry"; + String blockRegistryFileName; private YamlRegistry yamlRegistry = new YamlRegistry(500); private Map idRegistryMap = new HashMap<>(500); private Integer numberOfMaterials = 0; @@ -33,6 +33,21 @@ public BlockMaterialRegistry(TempPlugin game) { gameClass = game.getClass(); gameClassPath = gameClass.getPackage().getName(); this.plugin = game; + blockRegistryFileName = plugin.getDataFolder() + "blockregistry"; + } + + public BlockMaterialRegistry(TempPlugin game, String blockRegistryFileName) { + gameClass = game.getClass(); + gameClassPath = gameClass.getPackage().getName(); + this.plugin = game; + blockRegistryFileName = plugin.getDataFolder() + blockRegistryFileName; + } + + public BlockMaterialRegistry(TempPlugin game, String pathToBlockRegistry, String blockRegistryFileName) { + gameClass = game.getClass(); + gameClassPath = gameClass.getPackage().getName(); + this.plugin = game; + blockRegistryFileName = pathToBlockRegistry + blockRegistryFileName; } public BlockMaterial addBlockMaterial(BlockBaseMaterial blockBaseMaterial) { @@ -61,8 +76,8 @@ public BlockMaterial addBlockMaterial(BlockBaseMaterial blockBaseMaterial, Block blockMaterial = addBlockMaterialToRegistry(id, blockBaseMaterial, customBlockBaseMaterial); } } else { - numberOfMaterials++; blockMaterial = addBlockMaterialToRegistry(numberOfMaterials, blockBaseMaterial, customBlockBaseMaterial); + numberOfMaterials++; } return blockMaterial; } @@ -166,19 +181,24 @@ private boolean initializeRegistry() { } public boolean loadRegistry() { - if (Flow.getPlatform().isClient()) { + Boolean loaded = true; + if (Flow.getPlatform().isServer()) { + loaded = yamlRegistry.load(blockRegistryFileName); + } else { Flow.debug("Won't be loading registry on client platform!"); - return true; } - return yamlRegistry.load(blockRegistryFileName); + return loaded; } public boolean saveRegistry() { - if (Flow.getPlatform().isClient()) { + Boolean saved = true; + if (Flow.getPlatform().isServer()) { + checkIfRegistryIsInitialized(); + saved = yamlRegistry.save(blockRegistryFileName); + } else { Flow.debug("Won't be saving registry on client platform!"); - return true; } - checkIfRegistryIsInitialized(); - return yamlRegistry.save(blockRegistryFileName); + + return saved; } } diff --git a/src/main/java/com/flowpowered/engine/registry/EntityAttributes.java b/src/main/java/com/flowpowered/engine/registry/EntityAttributes.java index f845c47..6e1ec9a 100644 --- a/src/main/java/com/flowpowered/engine/registry/EntityAttributes.java +++ b/src/main/java/com/flowpowered/engine/registry/EntityAttributes.java @@ -8,6 +8,6 @@ */ public interface EntityAttributes extends AttributeGroup { - public static final Attribute NAME = Attribute.getInstance("NAME"); - public static final Attribute ENTITY_TYPE = Attribute.getInstance("ENTITY_TYPE"); + public static final Attribute NAME = Attribute.get("NAME"); + public static final Attribute ENTITY_TYPE = Attribute.get("ENTITY_TYPE"); }