Refactored Namespaced stuff
- Namespaced now takes full ID in constructor - Changed the rest of source accordingly - Moved everything related to Namespaced into .util.namespaced package - Errors are now reported with IllegalIdException instead of IAE - Error checking is optimized - NamespacedUtil exposes more of its requirements - Added StringUtil.splitAt - Added ArrayUtil.isSorted
This commit is contained in:
parent
b51b3a4d80
commit
5d7cfdb3bc
@ -66,6 +66,18 @@ public class ArrayUtil {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static boolean isSorted(byte[] array, boolean ascending) {
|
||||
for (int i = 0; i < array.length - 1; ++i) {
|
||||
if (array[i] == array[i + 1]) continue;
|
||||
|
||||
if ((array[i] < array[i + 1]) != ascending) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int firstIndexOf(short[] array, short element) {
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
if (array[i] == element) {
|
||||
@ -107,6 +119,18 @@ public class ArrayUtil {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static boolean isSorted(short[] array, boolean ascending) {
|
||||
for (int i = 0; i < array.length - 1; ++i) {
|
||||
if (array[i] == array[i + 1]) continue;
|
||||
|
||||
if ((array[i] < array[i + 1]) != ascending) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int firstIndexOf(int[] array, int element) {
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
if (array[i] == element) {
|
||||
@ -148,6 +172,18 @@ public class ArrayUtil {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static boolean isSorted(int[] array, boolean ascending) {
|
||||
for (int i = 0; i < array.length - 1; ++i) {
|
||||
if (array[i] == array[i + 1]) continue;
|
||||
|
||||
if ((array[i] < array[i + 1]) != ascending) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int firstIndexOf(long[] array, long element) {
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
if (array[i] == element) {
|
||||
@ -189,6 +225,18 @@ public class ArrayUtil {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static boolean isSorted(long[] array, boolean ascending) {
|
||||
for (int i = 0; i < array.length - 1; ++i) {
|
||||
if (array[i] == array[i + 1]) continue;
|
||||
|
||||
if ((array[i] < array[i + 1]) != ascending) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int firstIndexOf(float[] array, float element) {
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
if (array[i] == element) {
|
||||
@ -230,6 +278,18 @@ public class ArrayUtil {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static boolean isSorted(float[] array, boolean ascending) {
|
||||
for (int i = 0; i < array.length - 1; ++i) {
|
||||
if (array[i] == array[i + 1]) continue;
|
||||
|
||||
if ((array[i] < array[i + 1]) != ascending) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int firstIndexOf(double[] array, double element) {
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
if (array[i] == element) {
|
||||
@ -271,6 +331,18 @@ public class ArrayUtil {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static boolean isSorted(double[] array, boolean ascending) {
|
||||
for (int i = 0; i < array.length - 1; ++i) {
|
||||
if (array[i] == array[i + 1]) continue;
|
||||
|
||||
if ((array[i] < array[i + 1]) != ascending) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int firstIndexOf(boolean[] array, boolean element) {
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
if (array[i] == element) {
|
||||
@ -340,6 +412,18 @@ public class ArrayUtil {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static boolean isSorted(char[] array, boolean ascending) {
|
||||
for (int i = 0; i < array.length - 1; ++i) {
|
||||
if (array[i] == array[i + 1]) continue;
|
||||
|
||||
if ((array[i] < array[i + 1]) != ascending) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int firstIndexOf(Object[] array, Object element) {
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
if (array[i] == element) {
|
||||
@ -422,6 +506,20 @@ public class ArrayUtil {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static <T extends Comparable<T>> boolean isSorted(T[] array, boolean ascending) {
|
||||
for (int i = 0; i < array.length - 1; ++i) {
|
||||
if (array[i] == array[i + 1]) continue;
|
||||
|
||||
int order = array[i].compareTo(array[i + 1]);
|
||||
|
||||
if ((order < 0) != ascending) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static long sum(byte[] array, int start, int length) {
|
||||
long s = 0;
|
||||
length += start;
|
||||
|
@ -29,6 +29,8 @@ import java.util.Iterator;
|
||||
import java.util.Objects;
|
||||
import java.util.function.IntFunction;
|
||||
|
||||
import ru.windcorp.jputil.ArrayUtil;
|
||||
|
||||
public class StringUtil {
|
||||
|
||||
private StringUtil() {}
|
||||
@ -369,6 +371,106 @@ public class StringUtil {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits {@code src} at index {@code at} discarding the character at that index.
|
||||
* <p>
|
||||
* Indices {@code 0} and {@code src.length() - 1} produce {@code str} excluding
|
||||
* the specified character and {@code ""}.
|
||||
* <p>
|
||||
* @param src the String to split
|
||||
* @param at index to split at
|
||||
* @throws IllegalArgumentException if the index is out of bounds for {@code src}
|
||||
* @return an array containing the substrings, in order of encounter in {@code src}.
|
||||
* Its length is always 2.
|
||||
*/
|
||||
public static String[] splitAt(String src, int at) {
|
||||
Objects.requireNonNull(src, "src");
|
||||
|
||||
if (at < 0) {
|
||||
throw new StringIndexOutOfBoundsException(at);
|
||||
} else if (at >= src.length()) {
|
||||
throw new StringIndexOutOfBoundsException(at);
|
||||
}
|
||||
|
||||
if (at == 0) {
|
||||
return new String[] {"", src.substring(1)};
|
||||
} else if (at == src.length()) {
|
||||
return new String[] {src.substring(0, src.length() - 1), ""};
|
||||
}
|
||||
|
||||
return new String[] {
|
||||
src.substring(0, at),
|
||||
src.substring(at + 1)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits {@code src} at indices {@code at} discarding characters at those indices.
|
||||
* <p>
|
||||
* Indices {@code 0} and {@code src.length() - 1} produce extra zero-length outputs.
|
||||
* Duplicate indices produce extra zero-length outputs.
|
||||
* <p>
|
||||
* Examples:
|
||||
* <pre>
|
||||
* splitAt("a.b.c", new int[] {1, 3}) -> {"a", "b", "c"}
|
||||
* splitAt("a..b", new int[] {1, 2}) -> {"a", "", "b"}
|
||||
* splitAt(".b.", new int[] {0, 2}) -> {"", "b", ""}
|
||||
* splitAt("a.b", new int[] {1, 1, 1}) -> {"a", "", "", "b"}
|
||||
* </pre>
|
||||
* @param src the String to split
|
||||
* @param at indices to split at, in any order
|
||||
* @throws IllegalArgumentException if some index is out of bounds for {@code src}
|
||||
* @return an array containing the substrings, in order of encounter in {@code src}.
|
||||
* Its length is always {@code at.length + 1}.
|
||||
*/
|
||||
public static String[] splitAt(String src, int... at) {
|
||||
Objects.requireNonNull(src, "src");
|
||||
Objects.requireNonNull(at, "at");
|
||||
|
||||
if (at.length == 0) return new String[] {src};
|
||||
if (at.length == 1) return splitAt(src, at[0]);
|
||||
|
||||
int[] indices; // Always sorted
|
||||
|
||||
if (ArrayUtil.isSorted(at, true)) {
|
||||
indices = at;
|
||||
} else {
|
||||
indices = at.clone();
|
||||
Arrays.sort(indices);
|
||||
}
|
||||
|
||||
if (indices[0] < 0) {
|
||||
throw new StringIndexOutOfBoundsException(indices[0]);
|
||||
} else if (indices[indices.length - 1] >= src.length()) {
|
||||
throw new StringIndexOutOfBoundsException(indices[indices.length - 1]);
|
||||
}
|
||||
|
||||
String[] result = new String[at.length + 1];
|
||||
|
||||
int start = 0;
|
||||
int resultIndex = 0;
|
||||
for (int index : indices) {
|
||||
int end = index;
|
||||
|
||||
String substring;
|
||||
|
||||
if (end <= start) {
|
||||
// Duplicate or successive index
|
||||
substring = "";
|
||||
} else {
|
||||
substring = src.substring(start, end);
|
||||
}
|
||||
|
||||
result[resultIndex] = substring;
|
||||
resultIndex++;
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
result[resultIndex] = src.substring(start);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static IllegalArgumentException illegalArrayLength(int length) {
|
||||
return new IllegalArgumentException("arrayLength must be non-negative (" + length + ")");
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
package ru.windcorp.progressia.client.comms.controls;
|
||||
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
|
||||
public abstract class ControlTrigger extends Namespaced {
|
||||
|
||||
public ControlTrigger(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public ControlTrigger(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ import ru.windcorp.progressia.common.comms.controls.PacketControl;
|
||||
|
||||
public abstract class ControlTriggerInputBased extends ControlTrigger {
|
||||
|
||||
public ControlTriggerInputBased(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public ControlTriggerInputBased(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public abstract PacketControl onInputEvent(InputEvent event);
|
||||
|
@ -6,6 +6,7 @@ import ru.windcorp.progressia.client.graphics.input.InputEvent;
|
||||
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
||||
import ru.windcorp.progressia.common.comms.controls.ControlDataRegistry;
|
||||
import ru.windcorp.progressia.common.comms.controls.PacketControl;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedUtil;
|
||||
|
||||
public class ControlTriggerOnKeyPress extends ControlTriggerInputBased {
|
||||
|
||||
@ -13,13 +14,13 @@ public class ControlTriggerOnKeyPress extends ControlTriggerInputBased {
|
||||
private final PacketControl packet;
|
||||
|
||||
public ControlTriggerOnKeyPress(
|
||||
String namespace, String name,
|
||||
String id,
|
||||
Predicate<KeyEvent> predicate
|
||||
) {
|
||||
super(namespace, name);
|
||||
super(id);
|
||||
this.predicate = predicate;
|
||||
this.packet = new PacketControl(
|
||||
getNamespace(), "ControlKeyPress" + getName(),
|
||||
NamespacedUtil.getId(getNamespace(), "ControlKeyPress" + getName()),
|
||||
ControlDataRegistry.getInstance().get(getId())
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package ru.windcorp.progressia.client.comms.controls;
|
||||
|
||||
import ru.windcorp.progressia.common.util.NamespacedRegistry;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedRegistry;
|
||||
|
||||
public class ControlTriggerRegistry extends NamespacedRegistry<ControlTrigger> {
|
||||
|
||||
|
@ -18,13 +18,13 @@
|
||||
package ru.windcorp.progressia.client.world.block;
|
||||
|
||||
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
import ru.windcorp.progressia.client.graphics.model.Renderable;
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
|
||||
public abstract class BlockRender extends Namespaced {
|
||||
|
||||
public BlockRender(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public BlockRender(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public void render(ShapeRenderHelper renderer) {
|
||||
|
@ -22,8 +22,8 @@ import ru.windcorp.progressia.client.graphics.model.Renderable;
|
||||
|
||||
public class BlockRenderNone extends BlockRender {
|
||||
|
||||
public BlockRenderNone(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public BlockRenderNone(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -23,25 +23,22 @@ import ru.windcorp.progressia.common.world.block.BlockFace;
|
||||
public class BlockRenderOpaqueCube extends BlockRenderTexturedCube {
|
||||
|
||||
public BlockRenderOpaqueCube(
|
||||
String namespace, String name,
|
||||
String id,
|
||||
Texture topTexture, Texture bottomTexture,
|
||||
Texture northTexture, Texture southTexture,
|
||||
Texture eastTexture, Texture westTexture
|
||||
) {
|
||||
super(
|
||||
namespace, name,
|
||||
id,
|
||||
topTexture, bottomTexture,
|
||||
northTexture, southTexture,
|
||||
eastTexture, westTexture
|
||||
);
|
||||
}
|
||||
|
||||
public BlockRenderOpaqueCube(
|
||||
String namespace, String name,
|
||||
Texture texture
|
||||
) {
|
||||
public BlockRenderOpaqueCube(String id, Texture texture) {
|
||||
this(
|
||||
namespace, name,
|
||||
id,
|
||||
texture, texture,
|
||||
texture, texture,
|
||||
texture, texture
|
||||
|
@ -22,7 +22,7 @@ import ru.windcorp.progressia.client.graphics.texture.Atlases.AtlasGroup;
|
||||
import ru.windcorp.progressia.client.graphics.texture.SimpleTexture;
|
||||
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||
import ru.windcorp.progressia.common.resource.ResourceManager;
|
||||
import ru.windcorp.progressia.common.util.NamespacedRegistry;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedRegistry;
|
||||
|
||||
public class BlockRenderRegistry extends NamespacedRegistry<BlockRender> {
|
||||
|
||||
|
@ -36,12 +36,12 @@ implements OpaqueCube {
|
||||
private final Map<BlockFace, Texture> textures = new HashMap<>();
|
||||
|
||||
public BlockRenderTexturedCube(
|
||||
String namespace, String name,
|
||||
String id,
|
||||
Texture topTexture, Texture bottomTexture,
|
||||
Texture northTexture, Texture southTexture,
|
||||
Texture eastTexture, Texture westTexture
|
||||
) {
|
||||
super(namespace, name);
|
||||
super(id);
|
||||
|
||||
textures.put(TOP, topTexture);
|
||||
textures.put(BOTTOM, bottomTexture);
|
||||
|
@ -23,25 +23,22 @@ import ru.windcorp.progressia.common.world.block.BlockFace;
|
||||
public class BlockRenderTransparentCube extends BlockRenderTexturedCube {
|
||||
|
||||
public BlockRenderTransparentCube(
|
||||
String namespace, String name,
|
||||
String id,
|
||||
Texture topTexture, Texture bottomTexture,
|
||||
Texture northTexture, Texture southTexture,
|
||||
Texture eastTexture, Texture westTexture
|
||||
) {
|
||||
super(
|
||||
namespace, name,
|
||||
id,
|
||||
topTexture, bottomTexture,
|
||||
northTexture, southTexture,
|
||||
eastTexture, westTexture
|
||||
);
|
||||
}
|
||||
|
||||
public BlockRenderTransparentCube(
|
||||
String namespace, String name,
|
||||
Texture texture
|
||||
) {
|
||||
public BlockRenderTransparentCube(String id, Texture texture) {
|
||||
this(
|
||||
namespace, name,
|
||||
id,
|
||||
texture, texture,
|
||||
texture, texture,
|
||||
texture, texture
|
||||
|
@ -19,21 +19,21 @@ package ru.windcorp.progressia.client.world.cro;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
|
||||
public abstract class ChunkRenderOptimizerSupplier extends Namespaced {
|
||||
|
||||
public ChunkRenderOptimizerSupplier(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public ChunkRenderOptimizerSupplier(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public abstract ChunkRenderOptimizer createOptimizer();
|
||||
|
||||
public static ChunkRenderOptimizerSupplier of(
|
||||
String namespace, String name,
|
||||
String id,
|
||||
Supplier<ChunkRenderOptimizer> supplier
|
||||
) {
|
||||
return new ChunkRenderOptimizerSupplier(namespace, name) {
|
||||
return new ChunkRenderOptimizerSupplier(id) {
|
||||
@Override
|
||||
public ChunkRenderOptimizer createOptimizer() {
|
||||
return supplier.get();
|
||||
|
@ -30,7 +30,7 @@ public class ChunkRenderOptimizers {
|
||||
|
||||
static {
|
||||
register(ChunkRenderOptimizerSupplier.of(
|
||||
"Default", "OpaqueCube",
|
||||
"Default:OpaqueCube",
|
||||
ChunkRenderOptimizerCube::new
|
||||
));
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
package ru.windcorp.progressia.client.world.entity;
|
||||
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||
|
||||
public abstract class EntityRender extends Namespaced {
|
||||
|
||||
public EntityRender(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public EntityRender(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public abstract EntityRenderable createRenderable(EntityData entity);
|
||||
|
@ -6,7 +6,7 @@ import ru.windcorp.progressia.client.graphics.texture.TextureLoader;
|
||||
import ru.windcorp.progressia.client.graphics.texture.TexturePrimitive;
|
||||
import ru.windcorp.progressia.client.graphics.texture.TextureSettings;
|
||||
import ru.windcorp.progressia.common.resource.ResourceManager;
|
||||
import ru.windcorp.progressia.common.util.NamespacedRegistry;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedRegistry;
|
||||
|
||||
public class EntityRenderRegistry extends NamespacedRegistry<EntityRender> {
|
||||
|
||||
|
@ -3,13 +3,13 @@ package ru.windcorp.progressia.client.world.tile;
|
||||
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
|
||||
import ru.windcorp.progressia.client.graphics.model.Renderable;
|
||||
import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizer;
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
import ru.windcorp.progressia.common.world.block.BlockFace;
|
||||
|
||||
public class TileRender extends Namespaced {
|
||||
|
||||
public TileRender(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public TileRender(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public void render(ShapeRenderHelper renderer, BlockFace face) {
|
||||
|
@ -18,10 +18,10 @@ public class TileRenderGrass extends TileRender implements OpaqueTile {
|
||||
private final Texture sideTexture;
|
||||
|
||||
public TileRenderGrass(
|
||||
String namespace, String name,
|
||||
String id,
|
||||
Texture top, Texture side
|
||||
) {
|
||||
super(namespace, name);
|
||||
super(id);
|
||||
this.topTexture = top;
|
||||
this.sideTexture = side;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import ru.windcorp.progressia.client.graphics.texture.Atlases.AtlasGroup;
|
||||
import ru.windcorp.progressia.client.graphics.texture.SimpleTexture;
|
||||
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||
import ru.windcorp.progressia.common.resource.ResourceManager;
|
||||
import ru.windcorp.progressia.common.util.NamespacedRegistry;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedRegistry;
|
||||
|
||||
public class TileRenderRegistry extends NamespacedRegistry<TileRender> {
|
||||
|
||||
|
@ -16,8 +16,8 @@ public class TileRenderSimple extends TileRender implements OpaqueTile {
|
||||
|
||||
private final Texture texture;
|
||||
|
||||
public TileRenderSimple(String namespace, String name, Texture texture) {
|
||||
super(namespace, name);
|
||||
public TileRenderSimple(String id, Texture texture) {
|
||||
super(id);
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
package ru.windcorp.progressia.common.comms.controls;
|
||||
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
|
||||
public class ControlData extends Namespaced {
|
||||
|
||||
public ControlData(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public ControlData(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package ru.windcorp.progressia.common.comms.controls;
|
||||
|
||||
import ru.windcorp.progressia.common.util.NamespacedRegistry;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedRegistry;
|
||||
|
||||
public class ControlDataRegistry extends NamespacedRegistry<ControlData> {
|
||||
|
||||
|
@ -6,8 +6,8 @@ public class PacketControl extends Packet {
|
||||
|
||||
private final ControlData control;
|
||||
|
||||
public PacketControl(String namespace, String name, ControlData control) {
|
||||
super(namespace, name);
|
||||
public PacketControl(String id, ControlData control) {
|
||||
super(id);
|
||||
this.control = control;
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
package ru.windcorp.progressia.common.comms.packets;
|
||||
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
|
||||
public class Packet extends Namespaced {
|
||||
|
||||
public Packet(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public Packet(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,11 @@ public class PacketSetLocalPlayer extends Packet {
|
||||
private long localPlayerEntityId;
|
||||
|
||||
public PacketSetLocalPlayer(long entityId) {
|
||||
super("Core", "SetLocalPlayer");
|
||||
this("Core:SetLocalPlayer", entityId);
|
||||
}
|
||||
|
||||
protected PacketSetLocalPlayer(String id, long entityId) {
|
||||
super(id);
|
||||
this.localPlayerEntityId = entityId;
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,8 @@ import ru.windcorp.progressia.common.world.WorldData;
|
||||
|
||||
public abstract class PacketWorldChange extends Packet {
|
||||
|
||||
public PacketWorldChange(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public PacketWorldChange(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public abstract void apply(WorldData world);
|
||||
|
@ -43,10 +43,8 @@ extends AbstractStatefulObjectLayout {
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateFieldBuilder getBuilder(String namespace, String name) {
|
||||
return new InspectingStateFieldBuilder(
|
||||
namespace, name
|
||||
);
|
||||
public StateFieldBuilder getBuilder(String id) {
|
||||
return new InspectingStateFieldBuilder(id);
|
||||
}
|
||||
|
||||
private class InspectingStateFieldBuilder implements StateFieldBuilder {
|
||||
@ -56,7 +54,7 @@ extends AbstractStatefulObjectLayout {
|
||||
@Override
|
||||
public IntStateField build() {
|
||||
return registerField(new IntStateField(
|
||||
namespace, name,
|
||||
id,
|
||||
isLocal,
|
||||
fieldIndexCounters.getIntsThenIncrement()
|
||||
));
|
||||
@ -64,16 +62,12 @@ extends AbstractStatefulObjectLayout {
|
||||
|
||||
}
|
||||
|
||||
private final String namespace;
|
||||
private final String name;
|
||||
private final String id;
|
||||
|
||||
private boolean isLocal = true;
|
||||
|
||||
public InspectingStateFieldBuilder(
|
||||
String namespace, String name
|
||||
) {
|
||||
this.namespace = namespace;
|
||||
this.name = name;
|
||||
public InspectingStateFieldBuilder(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -7,11 +7,11 @@ import java.io.IOException;
|
||||
public class IntStateField extends StateField {
|
||||
|
||||
public IntStateField(
|
||||
String namespace, String name,
|
||||
String id,
|
||||
boolean isLocal,
|
||||
int index
|
||||
) {
|
||||
super(namespace, name, isLocal, index);
|
||||
super(id, isLocal, index);
|
||||
}
|
||||
|
||||
public int get(StatefulObject object) {
|
||||
|
@ -35,7 +35,7 @@ extends AbstractStatefulObjectLayout {
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateFieldBuilder getBuilder(String namespace, String name) {
|
||||
public StateFieldBuilder getBuilder(String id) {
|
||||
return new RetrieverStateFieldBuilder();
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
|
||||
public abstract class StateField extends Namespaced {
|
||||
|
||||
@ -12,11 +12,11 @@ public abstract class StateField extends Namespaced {
|
||||
private final int index;
|
||||
|
||||
public StateField(
|
||||
String namespace, String name,
|
||||
String id,
|
||||
boolean isLocal,
|
||||
int index
|
||||
) {
|
||||
super(namespace, name);
|
||||
super(id);
|
||||
this.isLocal = isLocal;
|
||||
this.index = index;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
|
||||
/**
|
||||
* An abstract class describing objects that have trackable state,
|
||||
@ -44,10 +44,9 @@ public abstract class StatefulObject extends Namespaced {
|
||||
|
||||
public StatefulObject(
|
||||
StatefulObjectRegistry<?> type,
|
||||
String namespace,
|
||||
String name
|
||||
String id
|
||||
) {
|
||||
super(namespace, name);
|
||||
super(id);
|
||||
this.layout = type.getLayout(getId());
|
||||
this.storage = getLayout().createStorage();
|
||||
}
|
||||
@ -96,8 +95,8 @@ public abstract class StatefulObject extends Namespaced {
|
||||
*
|
||||
* @return a configured builder
|
||||
*/
|
||||
protected StateFieldBuilder field(String namespace, String name) {
|
||||
StateFieldBuilder builder = getLayout().getBuilder(namespace, name);
|
||||
protected StateFieldBuilder field(String id) {
|
||||
StateFieldBuilder builder = getLayout().getBuilder(id);
|
||||
|
||||
builder.setOrdinal(fieldOrdinal);
|
||||
fieldOrdinal++;
|
||||
|
@ -43,6 +43,6 @@ public abstract class StatefulObjectLayout {
|
||||
public abstract int computeHashCode(StatefulObject object);
|
||||
public abstract boolean areEqual(StatefulObject a, StatefulObject b);
|
||||
|
||||
public abstract StateFieldBuilder getBuilder(String namespace, String name);
|
||||
public abstract StateFieldBuilder getBuilder(String id);
|
||||
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.NamespacedRegistry;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedRegistry;
|
||||
|
||||
/**
|
||||
* Registry-like object for identification of various {@link StatefulObject}
|
||||
@ -30,8 +30,8 @@ public class StatefulObjectRegistry<T extends StatefulObject> {
|
||||
|
||||
private final AtomicBoolean isRegistered = new AtomicBoolean(false);
|
||||
|
||||
public Type(String namespace, String name, Factory<T> factory) {
|
||||
super(namespace, name);
|
||||
public Type(String id, Factory<T> factory) {
|
||||
super(id);
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@ -91,8 +91,8 @@ public class StatefulObjectRegistry<T extends StatefulObject> {
|
||||
return registry.get(id).build();
|
||||
}
|
||||
|
||||
public void register(String namespace, String name, Factory<T> factory) {
|
||||
registry.register(new Type<>(namespace, name, factory));
|
||||
public void register(String id, Factory<T> factory) {
|
||||
registry.register(new Type<>(id, factory));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,46 +0,0 @@
|
||||
package ru.windcorp.progressia.common.util;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class NamespacedUtil {
|
||||
|
||||
public static final char SEPARATOR = ':';
|
||||
public static final int MAX_PART_LENGTH = 127;
|
||||
public static final int MAX_TOTAL_LENGTH = MAX_PART_LENGTH * 2 + 1;
|
||||
|
||||
private static final String PART_REGEX = "^[A-Z][a-zA-Z0-9]{2,}$";
|
||||
|
||||
private static final Predicate<String> PART_CHECKER =
|
||||
Pattern.compile(PART_REGEX).asPredicate();
|
||||
|
||||
public static String getId(String namespace, String name) {
|
||||
checkPart(namespace, "Namespace");
|
||||
checkPart(name, "Name");
|
||||
|
||||
return namespace + SEPARATOR + name;
|
||||
}
|
||||
|
||||
private static void checkPart(String data, String name) {
|
||||
Objects.requireNonNull(data, name);
|
||||
|
||||
if (data.length() > MAX_PART_LENGTH) {
|
||||
throw new IllegalArgumentException(
|
||||
name + " \"" + data + "\" is too long. "
|
||||
+ "Expected at most " + MAX_PART_LENGTH
|
||||
+ " characters"
|
||||
);
|
||||
}
|
||||
|
||||
if (!PART_CHECKER.test(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
name + " \"" + data + "\" is invalid. "
|
||||
+ "Allowed is: " + PART_REGEX
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private NamespacedUtil() {}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package ru.windcorp.progressia.common.util.namespaces;
|
||||
|
||||
public class IllegalIdException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -1572240191058305981L;
|
||||
|
||||
public IllegalIdException() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected IllegalIdException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
public IllegalIdException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public IllegalIdException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public IllegalIdException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
@ -15,50 +15,27 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
package ru.windcorp.progressia.common.util;
|
||||
package ru.windcorp.progressia.common.util.namespaces;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
public abstract class Namespaced {
|
||||
|
||||
public abstract class Namespaced extends Named {
|
||||
|
||||
private static final char SEPARATOR = ':';
|
||||
|
||||
private static final String PART_REGEX = "^[A-Z][a-zA-Z0-9]{2,}$";
|
||||
|
||||
private static final Predicate<String> PART_CHECKER =
|
||||
Pattern.compile(PART_REGEX).asPredicate();
|
||||
|
||||
private final String namespace;
|
||||
private final String id;
|
||||
|
||||
public Namespaced(String namespace, String name) {
|
||||
super(name);
|
||||
this.namespace = Objects.requireNonNull(namespace, "namespace");
|
||||
this.id = namespace + SEPARATOR + name;
|
||||
|
||||
if (!PART_CHECKER.test(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Name \"" + name + "\" is invalid. "
|
||||
+ "Allowed is: " + PART_REGEX
|
||||
);
|
||||
public Namespaced(String id) {
|
||||
NamespacedUtil.checkId(id);
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
if (!PART_CHECKER.test(namespace)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Namespace \"" + namespace + "\" is invalid. "
|
||||
+ "Allowed is: " + PART_REGEX
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
public final String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
return NamespacedUtil.getNamespace(getId());
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return NamespacedUtil.getName(getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -75,15 +52,10 @@ public abstract class Namespaced extends Named {
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Namespaced other = (Namespaced) obj;
|
||||
if (id == null) {
|
||||
if (other.id != null)
|
||||
return false;
|
||||
} else if (!id.equals(other.id))
|
||||
if (!id.equals(other.id))
|
||||
return false;
|
||||
return true;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package ru.windcorp.progressia.common.util;
|
||||
package ru.windcorp.progressia.common.util.namespaces;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
@ -0,0 +1,106 @@
|
||||
package ru.windcorp.progressia.common.util.namespaces;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import ru.windcorp.jputil.chars.StringUtil;
|
||||
|
||||
public class NamespacedUtil {
|
||||
|
||||
public static final char SEPARATOR = ':';
|
||||
|
||||
public static final int MAX_ID_LENGTH = 255;
|
||||
private static final int MAX_PART_LENGTH = (MAX_ID_LENGTH - 1) / 2;
|
||||
|
||||
public static final int MAX_NAMESPACE_LENGTH = MAX_PART_LENGTH;
|
||||
public static final int MAX_NAME_LENGTH = MAX_PART_LENGTH;
|
||||
|
||||
private static final int MIN_PART_LENGTH = 3;
|
||||
|
||||
public static final int MIN_NAMESPACE_LENGTH = MIN_PART_LENGTH;
|
||||
public static final int MIN_NAME_LENGTH = MIN_PART_LENGTH;
|
||||
|
||||
/*
|
||||
* This is the definition of the accepted pattern, but the value of
|
||||
* these constants is not actually consulted in the check* methods.
|
||||
*/
|
||||
private static final String PART_CORE_REGEX = "[A-Z][a-zA-Z0-9]{2," + (MAX_PART_LENGTH - 1) + "}";
|
||||
private static final String PART_REGEX = "^" + PART_CORE_REGEX + "$";
|
||||
|
||||
public static final String NAMESPACE_REGEX = PART_REGEX;
|
||||
public static final String NAME_REGEX = PART_REGEX;
|
||||
public static final String ID_REGEX = "^" + PART_CORE_REGEX + ":" + PART_CORE_REGEX + "$";
|
||||
|
||||
public static String getName(String id) {
|
||||
checkId(id);
|
||||
return id.substring(id.indexOf(':') + 1);
|
||||
}
|
||||
|
||||
public static String getNamespace(String id) {
|
||||
checkId(id);
|
||||
return id.substring(0, id.indexOf(':'));
|
||||
}
|
||||
|
||||
public static String getId(String namespace, String name) {
|
||||
checkPart(namespace, 0, namespace.length(), "Namespace");
|
||||
checkPart(name, 0, name.length(), "Name");
|
||||
|
||||
return namespace + SEPARATOR + name;
|
||||
}
|
||||
|
||||
public static void checkId(String id) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
|
||||
int firstSeparator = id.indexOf(SEPARATOR);
|
||||
|
||||
boolean areSeparatorsInvalid = (firstSeparator < 0) || (id.indexOf(SEPARATOR, firstSeparator + 1) >= 0);
|
||||
|
||||
if (areSeparatorsInvalid) {
|
||||
int separators = StringUtil.count(id, SEPARATOR);
|
||||
throw new IllegalIdException(
|
||||
"ID \"" + id + "\" is invalid. "
|
||||
+ (separators == 0 ? "No " : "Too many (" + separators + ") ")
|
||||
+ "separators '" + SEPARATOR + "' found, exactly one required"
|
||||
);
|
||||
}
|
||||
|
||||
checkPart(id, 0, firstSeparator, "namespace");
|
||||
checkPart(id, firstSeparator + 1, id.length() - firstSeparator - 1, "name");
|
||||
}
|
||||
|
||||
private static void checkPart(String data, int offset, int length, String nameForErrors) {
|
||||
Objects.requireNonNull(data, nameForErrors);
|
||||
|
||||
if (length > MAX_PART_LENGTH) {
|
||||
throw new IllegalIdException(
|
||||
nameForErrors + " \"" + data.substring(offset, offset + length) + "\" is too long. "
|
||||
+ "Expected at most " + MAX_PART_LENGTH
|
||||
+ " characters"
|
||||
);
|
||||
} else if (length < MIN_PART_LENGTH) {
|
||||
throw new IllegalIdException(
|
||||
nameForErrors + " \"" + data.substring(offset, offset + length) + "\" is too short. "
|
||||
+ "Expected at lest " + MIN_PART_LENGTH
|
||||
+ " characters"
|
||||
);
|
||||
}
|
||||
|
||||
// Don't actually use *_REGEX for speed
|
||||
|
||||
for (int i = 0; i < length; ++i) {
|
||||
char c = data.charAt(i + offset);
|
||||
if (!(
|
||||
( c >= 'A' && c <= 'Z') ||
|
||||
(i != 0 && c >= 'a' && c <= 'z') ||
|
||||
(i != 0 && c >= '0' && c <= '9')
|
||||
)) {
|
||||
throw new IllegalIdException(
|
||||
nameForErrors + " \"" + data.substring(offset, offset + length) + "\" is invalid. "
|
||||
+ "Allowed is: " + PART_REGEX
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private NamespacedUtil() {}
|
||||
|
||||
}
|
@ -19,12 +19,12 @@ package ru.windcorp.progressia.common.world.block;
|
||||
|
||||
import ru.windcorp.progressia.common.collision.AABB;
|
||||
import ru.windcorp.progressia.common.collision.CollisionModel;
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
|
||||
public class BlockData extends Namespaced {
|
||||
|
||||
public BlockData(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public BlockData(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public CollisionModel getCollisionModel() {
|
||||
|
@ -17,7 +17,7 @@
|
||||
*******************************************************************************/
|
||||
package ru.windcorp.progressia.common.world.block;
|
||||
|
||||
import ru.windcorp.progressia.common.util.NamespacedRegistry;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedRegistry;
|
||||
|
||||
public class BlockDataRegistry extends NamespacedRegistry<BlockData> {
|
||||
|
||||
|
@ -20,8 +20,8 @@ public class EntityData extends StatefulObject implements Collideable {
|
||||
|
||||
private double age = 0;
|
||||
|
||||
public EntityData(String namespace, String name) {
|
||||
super(EntityDataRegistry.getInstance(), namespace, name);
|
||||
public EntityData(String id) {
|
||||
super(EntityDataRegistry.getInstance(), id);
|
||||
}
|
||||
|
||||
public Vec3 getPosition() {
|
||||
|
@ -10,8 +10,8 @@ public class EntityDataRegistry extends StatefulObjectRegistry<EntityData> {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public void register(String namespace, String name) {
|
||||
super.register(namespace, name, () -> new EntityData(namespace, name));
|
||||
public void register(String id) {
|
||||
super.register(id, () -> new EntityData(id));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,11 @@ public class PacketEntityChange extends PacketWorldChange {
|
||||
private final DataBuffer buffer = new DataBuffer();
|
||||
|
||||
public PacketEntityChange() {
|
||||
super("Core", "EntityChange");
|
||||
super("Core:EntityChange");
|
||||
}
|
||||
|
||||
protected PacketEntityChange(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public long getEntityId() {
|
||||
|
@ -17,12 +17,12 @@
|
||||
*******************************************************************************/
|
||||
package ru.windcorp.progressia.common.world.tile;
|
||||
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
|
||||
public class TileData extends Namespaced {
|
||||
|
||||
public TileData(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public TileData(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
*******************************************************************************/
|
||||
package ru.windcorp.progressia.common.world.tile;
|
||||
|
||||
import ru.windcorp.progressia.common.util.NamespacedRegistry;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedRegistry;
|
||||
|
||||
public class TileDataRegistry extends NamespacedRegistry<TileData> {
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
package ru.windcorp.progressia.server.comms.controls;
|
||||
|
||||
import ru.windcorp.progressia.common.comms.controls.PacketControl;
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
import ru.windcorp.progressia.server.comms.Client;
|
||||
|
||||
public abstract class ControlLogic extends Namespaced {
|
||||
|
||||
public ControlLogic(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public ControlLogic(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public abstract void apply(
|
||||
|
@ -1,6 +1,6 @@
|
||||
package ru.windcorp.progressia.server.comms.controls;
|
||||
|
||||
import ru.windcorp.progressia.common.util.NamespacedRegistry;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedRegistry;
|
||||
|
||||
public class ControlLogicRegistry extends NamespacedRegistry<ControlLogic> {
|
||||
|
||||
|
@ -35,7 +35,11 @@ public class ImplementedChangeTracker implements Changer {
|
||||
private BlockData block;
|
||||
|
||||
public SetBlock() {
|
||||
super("Core", "SetBlock");
|
||||
this("Core:SetBlock");
|
||||
}
|
||||
|
||||
protected SetBlock(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public void initialize(Vec3i position, BlockData block) {
|
||||
@ -76,7 +80,11 @@ public class ImplementedChangeTracker implements Changer {
|
||||
private boolean shouldAdd;
|
||||
|
||||
public AddOrRemoveTile() {
|
||||
super("Core", "AddOrRemoveTile");
|
||||
this("Core:AddOrRemoveTile");
|
||||
}
|
||||
|
||||
protected AddOrRemoveTile(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public void initialize(
|
||||
|
@ -1,11 +1,11 @@
|
||||
package ru.windcorp.progressia.server.world.block;
|
||||
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
|
||||
public class BlockLogic extends Namespaced {
|
||||
|
||||
public BlockLogic(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public BlockLogic(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package ru.windcorp.progressia.server.world.block;
|
||||
|
||||
import ru.windcorp.progressia.common.util.NamespacedRegistry;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedRegistry;
|
||||
|
||||
public class BlockLogicRegistry extends NamespacedRegistry<BlockLogic> {
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
package ru.windcorp.progressia.server.world.entity;
|
||||
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||
import ru.windcorp.progressia.server.world.Changer;
|
||||
import ru.windcorp.progressia.server.world.TickContext;
|
||||
|
||||
public class EntityLogic extends Namespaced {
|
||||
|
||||
public EntityLogic(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public EntityLogic(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public void tick(EntityData entity, TickContext context, Changer changer) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package ru.windcorp.progressia.server.world.entity;
|
||||
|
||||
import ru.windcorp.progressia.common.util.NamespacedRegistry;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedRegistry;
|
||||
|
||||
public class EntityLogicRegistry extends NamespacedRegistry<EntityLogic> {
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
package ru.windcorp.progressia.server.world.tile;
|
||||
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
import ru.windcorp.progressia.common.world.block.BlockFace;
|
||||
|
||||
public class TileLogic extends Namespaced {
|
||||
|
||||
public TileLogic(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public TileLogic(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public boolean canOccupyFace(TileTickContext context) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package ru.windcorp.progressia.server.world.tile;
|
||||
|
||||
import ru.windcorp.progressia.common.util.NamespacedRegistry;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedRegistry;
|
||||
|
||||
public class TileLogicRegistry extends NamespacedRegistry<TileLogic> {
|
||||
|
||||
|
@ -42,65 +42,65 @@ public class TestContent {
|
||||
}
|
||||
|
||||
private static void registerBlocks() {
|
||||
register(new BlockData("Test", "Air") {
|
||||
register(new BlockData("Test:Air") {
|
||||
@Override
|
||||
public CollisionModel getCollisionModel() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
register(new BlockRenderNone("Test", "Air"));
|
||||
register(new BlockLogic("Test", "Air"));
|
||||
register(new BlockRenderNone("Test:Air"));
|
||||
register(new BlockLogic("Test:Air"));
|
||||
|
||||
register(new BlockData("Test", "Dirt"));
|
||||
register(new BlockRenderOpaqueCube("Test", "Dirt", getBlockTexture("dirt")));
|
||||
register(new BlockLogic("Test", "Dirt"));
|
||||
register(new BlockData("Test:Dirt"));
|
||||
register(new BlockRenderOpaqueCube("Test:Dirt", getBlockTexture("dirt")));
|
||||
register(new BlockLogic("Test:Dirt"));
|
||||
|
||||
register(new BlockData("Test", "Stone"));
|
||||
register(new BlockRenderOpaqueCube("Test", "Stone", getBlockTexture("stone")));
|
||||
register(new BlockLogic("Test", "Stone"));
|
||||
register(new BlockData("Test:Stone"));
|
||||
register(new BlockRenderOpaqueCube("Test:Stone", getBlockTexture("stone")));
|
||||
register(new BlockLogic("Test:Stone"));
|
||||
|
||||
register(new BlockData("Test", "Compass"));
|
||||
register(new BlockRenderOpaqueCube("Test", "Compass", getBlockTexture("compass")));
|
||||
register(new BlockLogic("Test", "Compass"));
|
||||
register(new BlockData("Test:Compass"));
|
||||
register(new BlockRenderOpaqueCube("Test:Compass", getBlockTexture("compass")));
|
||||
register(new BlockLogic("Test:Compass"));
|
||||
|
||||
register(new BlockData("Test", "Glass"));
|
||||
register(new BlockRenderTransparentCube("Test", "Glass", getBlockTexture("glass_clear")));
|
||||
register(new BlockLogic("Test", "Glass"));
|
||||
register(new BlockData("Test:Glass"));
|
||||
register(new BlockRenderTransparentCube("Test:Glass", getBlockTexture("glass_clear")));
|
||||
register(new BlockLogic("Test:Glass"));
|
||||
}
|
||||
|
||||
private static void registerTiles() {
|
||||
register(new TileData("Test", "Grass"));
|
||||
register(new TileRenderGrass("Test", "Grass", getTileTexture("grass_top"), getTileTexture("grass_side")));
|
||||
register(new TileLogic("Test", "Grass"));
|
||||
register(new TileData("Test:Grass"));
|
||||
register(new TileRenderGrass("Test:Grass", getTileTexture("grass_top"), getTileTexture("grass_side")));
|
||||
register(new TileLogic("Test:Grass"));
|
||||
|
||||
register(new TileData("Test", "Stones"));
|
||||
register(new TileRenderSimple("Test", "Stones", getTileTexture("stones")));
|
||||
register(new TileLogic("Test", "Stones"));
|
||||
register(new TileData("Test:Stones"));
|
||||
register(new TileRenderSimple("Test:Stones", getTileTexture("stones")));
|
||||
register(new TileLogic("Test:Stones"));
|
||||
|
||||
register(new TileData("Test", "YellowFlowers"));
|
||||
register(new TileRenderSimple("Test", "YellowFlowers", getTileTexture("yellow_flowers")));
|
||||
register(new TileLogic("Test", "YellowFlowers"));
|
||||
register(new TileData("Test:YellowFlowers"));
|
||||
register(new TileRenderSimple("Test:YellowFlowers", getTileTexture("yellow_flowers")));
|
||||
register(new TileLogic("Test:YellowFlowers"));
|
||||
|
||||
register(new TileData("Test", "Sand"));
|
||||
register(new TileRenderSimple("Test", "Sand", getTileTexture("sand")));
|
||||
register(new TileLogic("Test", "Sand"));
|
||||
register(new TileData("Test:Sand"));
|
||||
register(new TileRenderSimple("Test:Sand", getTileTexture("sand")));
|
||||
register(new TileLogic("Test:Sand"));
|
||||
}
|
||||
|
||||
private static void registerEntities() {
|
||||
float scale = 1.8f / 8;
|
||||
registerEntityData("Test", "Player", e -> e.setCollisionModel(new AABB(0, 0, 4*scale, 0.75f, 0.75f, 1.8f)));
|
||||
register(new TestEntityRenderHuman());
|
||||
register(new EntityLogic("Test", "Player"));
|
||||
registerEntityData("Test:Player", e -> e.setCollisionModel(new AABB(0, 0, 4*scale, 0.75f, 0.75f, 1.8f)));
|
||||
register(new TestEntityRenderHuman("Test:Player"));
|
||||
register(new EntityLogic("Test:Player"));
|
||||
|
||||
register("Test", "Statie", TestEntityDataStatie::new);
|
||||
register(new TestEntityRenderStatie());
|
||||
register(new TestEntityLogicStatie());
|
||||
register("Test:Statie", TestEntityDataStatie::new);
|
||||
register(new TestEntityRenderStatie("Test:Statie"));
|
||||
register(new TestEntityLogicStatie("Test:Statie"));
|
||||
}
|
||||
|
||||
private static void regsiterControls() {
|
||||
ControlDataRegistry.getInstance().register(new ControlData("Test", "Switch000"));
|
||||
ControlTriggerRegistry.getInstance().register(new ControlTriggerOnKeyPress("Test", "Switch000", new KeyMatcher(GLFW.GLFW_KEY_H, new int[0], 0)::matches));
|
||||
ControlLogicRegistry.getInstance().register(new ControlLogic("Test", "Switch000") {
|
||||
ControlDataRegistry.getInstance().register(new ControlData("Test:Switch000"));
|
||||
ControlTriggerRegistry.getInstance().register(new ControlTriggerOnKeyPress("Test:Switch000", new KeyMatcher(GLFW.GLFW_KEY_H, new int[0], 0)::matches));
|
||||
ControlLogicRegistry.getInstance().register(new ControlLogic("Test:Switch000") {
|
||||
@Override
|
||||
public void apply(Server server, PacketControl packet, Client client) {
|
||||
Vec3i z000 = new Vec3i(0, 0, 0);
|
||||
@ -117,26 +117,6 @@ public class TestContent {
|
||||
server.getAdHocChanger().setBlock(z000, block);
|
||||
}
|
||||
});
|
||||
|
||||
// ControlDataRegistry.getInstance().register(new ControlData("Test", "BreakBlock"));
|
||||
// ControlTriggerRegistry.getInstance().register(new ControlTriggerOnKeyPress("Test", "BreakBlock", new KeyMatcher(GLFW.GLFW_KEY_ENTER, new int[0], 0)::matches));
|
||||
// ControlLogicRegistry.getInstance().register(new ControlLogic("Test", "BreakBlock") {
|
||||
// @Override
|
||||
// public void apply(Server server, PacketControl packet, Client client) {
|
||||
// Vec3i z000 = new Vec3i(0, 0, 0);
|
||||
//
|
||||
// ChunkData data = server.getWorld().getChunk(z000).getData();
|
||||
//
|
||||
// BlockData block;
|
||||
// if (data.getBlock(z000).getId().equals("Test:Stone")) {
|
||||
// block = BlockDataRegistry.getInstance().get("Test:Glass");
|
||||
// } else {
|
||||
// block = BlockDataRegistry.getInstance().get("Test:Stone");
|
||||
// }
|
||||
//
|
||||
// server.getAdHocChanger().setBlock(z000, block);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
private static void register(BlockData x) {
|
||||
@ -148,20 +128,20 @@ public class TestContent {
|
||||
}
|
||||
|
||||
private static void register(
|
||||
String namespace, String name,
|
||||
String id,
|
||||
Factory<EntityData> factory
|
||||
) {
|
||||
EntityDataRegistry.getInstance().register(namespace, name, factory);
|
||||
EntityDataRegistry.getInstance().register(id, factory);
|
||||
}
|
||||
|
||||
private static void registerEntityData(
|
||||
String namespace, String name,
|
||||
String id,
|
||||
Consumer<EntityData> transform
|
||||
) {
|
||||
EntityDataRegistry.getInstance().register(namespace, name, new Factory<EntityData>() {
|
||||
EntityDataRegistry.getInstance().register(id, new Factory<EntityData>() {
|
||||
@Override
|
||||
public EntityData build() {
|
||||
EntityData entity = new EntityData(namespace, name);
|
||||
EntityData entity = new EntityData(id);
|
||||
transform.accept(entity);
|
||||
return entity;
|
||||
}
|
||||
|
@ -7,10 +7,14 @@ import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||
public class TestEntityDataStatie extends EntityData {
|
||||
|
||||
private final IntStateField size =
|
||||
field("Test", "Size").setShared().ofInt().build();
|
||||
field("Test:Size").setShared().ofInt().build();
|
||||
|
||||
public TestEntityDataStatie() {
|
||||
super("Test", "Statie");
|
||||
this("Test:Statie");
|
||||
}
|
||||
|
||||
protected TestEntityDataStatie(String id) {
|
||||
super(id);
|
||||
setCollisionModel(new AABB(0, 0, 0, 1, 1, 1));
|
||||
setSizeNow(16);
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ import ru.windcorp.progressia.server.world.entity.EntityLogic;
|
||||
|
||||
public class TestEntityLogicStatie extends EntityLogic {
|
||||
|
||||
public TestEntityLogicStatie() {
|
||||
super("Test", "Statie");
|
||||
public TestEntityLogicStatie(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -9,6 +9,7 @@ import ru.windcorp.progressia.client.graphics.model.Renderable;
|
||||
import ru.windcorp.progressia.client.graphics.model.Shapes.PppBuilder;
|
||||
import ru.windcorp.progressia.client.graphics.model.StaticModel;
|
||||
import ru.windcorp.progressia.client.graphics.texture.ComplexTexture;
|
||||
import ru.windcorp.progressia.client.graphics.texture.TexturePrimitive;
|
||||
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
|
||||
import ru.windcorp.progressia.client.world.entity.HumanoidModel;
|
||||
import ru.windcorp.progressia.client.world.entity.EntityRender;
|
||||
@ -30,11 +31,15 @@ public class TestEntityRenderHuman extends EntityRender {
|
||||
private final Renderable leftLeg;
|
||||
private final Renderable rightLeg;
|
||||
|
||||
public TestEntityRenderHuman() {
|
||||
super("Test", "Player");
|
||||
private final TexturePrimitive skin;
|
||||
|
||||
public TestEntityRenderHuman(String id) {
|
||||
super(id);
|
||||
|
||||
this.skin = fetchSkin();
|
||||
|
||||
ComplexTexture texture = new ComplexTexture(
|
||||
EntityRenderRegistry.getEntityTexture("pyotr"),
|
||||
this.skin,
|
||||
16, 16
|
||||
);
|
||||
|
||||
@ -47,6 +52,14 @@ public class TestEntityRenderHuman extends EntityRender {
|
||||
this.rightLeg = createLimb(texture, 0, 8, 0, 4, false, false);
|
||||
}
|
||||
|
||||
protected TexturePrimitive fetchSkin() {
|
||||
return EntityRenderRegistry.getEntityTexture("pyotr");
|
||||
}
|
||||
|
||||
public TexturePrimitive getSkin() {
|
||||
return skin;
|
||||
}
|
||||
|
||||
private Renderable createBody(ComplexTexture texture) {
|
||||
return createLayeredCuboid(
|
||||
texture,
|
||||
|
@ -32,8 +32,8 @@ public class TestEntityRenderJavapony extends EntityRender {
|
||||
private final Renderable rightForeLeg;
|
||||
private final Renderable rightHindLeg;
|
||||
|
||||
public TestEntityRenderJavapony() {
|
||||
super("Test", "Javapony");
|
||||
public TestEntityRenderJavapony(String id) {
|
||||
super(id);
|
||||
|
||||
ComplexTexture texture = new ComplexTexture(
|
||||
EntityRenderRegistry.getEntityTexture("javapony"),
|
||||
|
@ -19,8 +19,8 @@ public class TestEntityRenderStatie extends EntityRender {
|
||||
.setColorMultiplier(1, 1, 0)
|
||||
.create();
|
||||
|
||||
public TestEntityRenderStatie() {
|
||||
super("Test", "Statie");
|
||||
public TestEntityRenderStatie(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,70 @@
|
||||
package ru.windcorp.jputil.chars.stringUtil;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ru.windcorp.jputil.chars.StringUtil;
|
||||
|
||||
public class SplitAtTest {
|
||||
|
||||
@Test
|
||||
public void testExamplesFromDocs() {
|
||||
test("a.b.c", new int[] {1, 3}, new String[] {"a", "b", "c"});
|
||||
test("a..b", new int[] {1, 2}, new String[] {"a", "", "b"});
|
||||
test(".b.", new int[] {0, 2}, new String[] {"", "b", ""});
|
||||
test("a.b", new int[] {1, 1, 1}, new String[] {"a", "", "", "b"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexPermutations() {
|
||||
Random random = new Random(0);
|
||||
|
||||
int stringLength = 1000;
|
||||
char[] chars = new char[stringLength];
|
||||
|
||||
for (int i = 0; i < stringLength; ++i) {
|
||||
chars[i] = (char) ('a' + random.nextInt('z' - 'a'));
|
||||
}
|
||||
|
||||
String src = new String(chars);
|
||||
|
||||
int[] indices = new int[100];
|
||||
|
||||
for (int i = 0; i < indices.length; ++i) {
|
||||
indices[i] = random.nextInt(stringLength);
|
||||
}
|
||||
|
||||
String[] expected = StringUtil.splitAt(src, indices);
|
||||
|
||||
for (int i = 0; i < 10000; ++i) {
|
||||
shuffleArray(indices, random);
|
||||
|
||||
int[] copy = indices.clone();
|
||||
test(src, indices, expected);
|
||||
assertArrayEquals(indices, copy); // Make sure indices array hasn't changed
|
||||
}
|
||||
}
|
||||
|
||||
// Shamelessly copied from
|
||||
// https://stackoverflow.com/a/1520212/4463352
|
||||
// Thanks, https://stackoverflow.com/users/15459/philho!
|
||||
|
||||
// Implementing Fisher–Yates shuffle
|
||||
private static void shuffleArray(int[] ar, Random random) {
|
||||
for (int i = ar.length - 1; i > 0; i--) {
|
||||
int index = random.nextInt(i + 1);
|
||||
// Simple swap
|
||||
int a = ar[index];
|
||||
ar[index] = ar[i];
|
||||
ar[i] = a;
|
||||
}
|
||||
}
|
||||
|
||||
private void test(String string, int[] at, String[] expecteds) {
|
||||
assertArrayEquals(expecteds, StringUtil.splitAt(string, at));
|
||||
}
|
||||
|
||||
}
|
@ -29,38 +29,40 @@ import java.util.Random;
|
||||
import org.junit.Test;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
import ru.windcorp.progressia.common.util.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.IllegalIdException;
|
||||
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedUtil;
|
||||
|
||||
public class NamespacedTest {
|
||||
|
||||
class TestNamespaced extends Namespaced {
|
||||
|
||||
public TestNamespaced(String namespace, String name) {
|
||||
super(namespace, name);
|
||||
public TestNamespaced(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void shouldReject(String a, String b) {
|
||||
try {
|
||||
new TestNamespaced(a, b);
|
||||
} catch (IllegalArgumentException | NullPointerException e) {
|
||||
new TestNamespaced(NamespacedUtil.getId(a, b));
|
||||
} catch (IllegalIdException | NullPointerException e) {
|
||||
try {
|
||||
new TestNamespaced(b, a);
|
||||
} catch (IllegalArgumentException | NullPointerException e1) {
|
||||
new TestNamespaced(NamespacedUtil.getId(b, a));
|
||||
} catch (IllegalIdException | NullPointerException e1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new AssertionFailedError("Expected NPE or IAE for: \"" + a + "\":\"" + b + "\"");
|
||||
throw new AssertionFailedError("Expected NPE or IllegalIdException for: \"" + a + "\":\"" + b + "\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAllow() {
|
||||
new TestNamespaced("Something", "Usual");
|
||||
new TestNamespaced("Vry", "Sml");
|
||||
new TestNamespaced("ALL", "CAPS");
|
||||
new TestNamespaced("WithDigits12345", "MoreDigits67890");
|
||||
new TestNamespaced("Something:Usual");
|
||||
new TestNamespaced("Vry:Sml");
|
||||
new TestNamespaced("ALL:CAPS");
|
||||
new TestNamespaced("WithDigits12345:MoreDigits67890");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -80,17 +82,17 @@ public class NamespacedTest {
|
||||
shouldReject("XS", "Normal");
|
||||
shouldReject("", "Normal");
|
||||
shouldReject("Contains:separators", "Normal");
|
||||
shouldReject("СодержитРусский", "Normal");
|
||||
shouldReject("СодержитНеАльфанум", "Normal");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectGarbage() {
|
||||
Random random = new Random(0);
|
||||
|
||||
byte[] bytes = new byte[1024];
|
||||
byte[] bytes = new byte[NamespacedUtil.MAX_NAME_LENGTH];
|
||||
for (int attempt = 0; attempt < 10000; ++attempt) {
|
||||
random.nextBytes(bytes);
|
||||
bytes[0] = 'a'; // Make sure it is invalid
|
||||
bytes[bytes.length - 1] = '!'; // Make sure it is invalid
|
||||
shouldReject(new String(bytes), "ContainsUtterGarbage");
|
||||
}
|
||||
}
|
||||
@ -108,8 +110,8 @@ public class NamespacedTest {
|
||||
String namespace = getRandomValidString(random);
|
||||
String name = getRandomValidString(random);
|
||||
|
||||
TestNamespaced a = new TestNamespaced(namespace, name);
|
||||
TestNamespaced b = new TestNamespaced(namespace, name);
|
||||
TestNamespaced a = new TestNamespaced(NamespacedUtil.getId(namespace, name));
|
||||
TestNamespaced b = new TestNamespaced(NamespacedUtil.getId(namespace, name));
|
||||
|
||||
contains.add(a);
|
||||
hashSet.add(b);
|
||||
@ -119,7 +121,7 @@ public class NamespacedTest {
|
||||
String namespace = getRandomValidString(random);
|
||||
String name = getRandomValidString(random);
|
||||
|
||||
TestNamespaced c = new TestNamespaced(namespace, name);
|
||||
TestNamespaced c = new TestNamespaced(NamespacedUtil.getId(namespace, name));
|
||||
|
||||
doesNotContain.add(c);
|
||||
}
|
||||
@ -128,7 +130,7 @@ public class NamespacedTest {
|
||||
Iterator<TestNamespaced> it = doesNotContain.iterator();
|
||||
while (it.hasNext()) {
|
||||
TestNamespaced next = it.next();
|
||||
if (next.getName().equals(x.getName()) && next.getNamespace().equals(x.getNamespace())) {
|
||||
if (next.getId().equals(x.getId())) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
@ -144,7 +146,7 @@ public class NamespacedTest {
|
||||
}
|
||||
|
||||
String getRandomValidString(Random random) {
|
||||
char[] chars = new char[random.nextInt(100) + 3];
|
||||
char[] chars = new char[random.nextInt(NamespacedUtil.MAX_NAME_LENGTH - 3) + 3];
|
||||
|
||||
for (int i = 0; i < chars.length; ++i) {
|
||||
switch (random.nextInt(3)) {
|
||||
|
Reference in New Issue
Block a user