From 70493f68dcb74b36eb6fd8cc024a4f96691c6122 Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Sun, 23 Oct 2016 12:32:12 -0200 Subject: [PATCH 01/10] Remove BlockProperties --- .../v18/wrapper/block/backward/BWBlock.java | 14 +- .../v18/wrapper/block/forward/FWBlock.java | 28 ++- .../wrapper/block/forward/FWBlockSound.java | 58 +++++ .../block/forward/MCBlockProperties.java | 116 --------- .../wrapper/block/forward/ProxyMaterial.java | 34 +++ src/main/java/nova/core/block/Block.java | 6 +- .../core/block/component/BlockProperties.java | 142 ----------- .../core/block/component/BlockProperty.java | 231 ++++++++++++++++++ src/main/java/nova/core/item/ItemBlock.java | 6 +- 9 files changed, 358 insertions(+), 277 deletions(-) create mode 100644 minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java delete mode 100644 minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/MCBlockProperties.java create mode 100644 minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/ProxyMaterial.java delete mode 100644 src/main/java/nova/core/block/component/BlockProperties.java create mode 100644 src/main/java/nova/core/block/component/BlockProperty.java diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/backward/BWBlock.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/backward/BWBlock.java index b5180821d..a7d70ff25 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/backward/BWBlock.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/backward/BWBlock.java @@ -31,7 +31,7 @@ import net.minecraft.util.BlockPos; import net.minecraft.world.IBlockAccess; import nova.core.block.Block; -import nova.core.block.component.BlockProperties; +import nova.core.block.component.BlockProperty; import nova.core.block.component.LightEmitter; import nova.core.component.misc.Collider; import nova.core.component.transform.BlockTransform; @@ -39,6 +39,7 @@ import nova.core.retention.Data; import nova.core.retention.Storable; import nova.core.retention.Store; +import nova.core.sound.Sound; import nova.core.util.shape.Cuboid; import nova.core.world.World; import nova.core.wrapper.mc.forge.v18.wrapper.block.world.BWWorld; @@ -66,11 +67,12 @@ public BWBlock(net.minecraft.block.Block block, World world, Vector3D pos) { transform.setWorld(world); transform.setPosition(pos); - BlockProperties blockMaterial = components.add(new BlockProperties()); - blockMaterial.setLightTransmission(!mcBlock.getMaterial().blocksLight()); - blockMaterial.setBlockSound(BlockProperties.BlockSoundTrigger.PLACE, mcBlock.stepSound.getPlaceSound()); - blockMaterial.setBlockSound(BlockProperties.BlockSoundTrigger.BREAK, mcBlock.stepSound.getBreakSound()); - blockMaterial.setBlockSound(BlockProperties.BlockSoundTrigger.WALK, mcBlock.stepSound.getStepSound()); + components.add(new BlockProperty.Opacity().setLightTransmission(!mcBlock.getMaterial().blocksLight())); + + BlockProperty.BlockSound blockSound = components.add(new BlockProperty.BlockSound()); + blockSound.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.PLACE, new Sound("", mcBlock.stepSound.getPlaceSound())); + blockSound.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.BREAK, new Sound("", mcBlock.stepSound.getBreakSound())); + blockSound.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.WALK, new Sound("", mcBlock.stepSound.getStepSound())); components.add(new LightEmitter()).setEmittedLevel(() -> mcBlock.getLightValue(getMcBlockAccess(), new BlockPos(x(), y(), z())) / 15.0F); components.add(new Collider(this)) diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java index 593f7a376..36d9eb71a 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java @@ -20,6 +20,7 @@ package nova.core.wrapper.mc.forge.v18.wrapper.block.forward; +import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; @@ -37,11 +38,12 @@ import nova.core.block.Block; import nova.core.block.BlockFactory; import nova.core.block.Stateful; -import nova.core.block.component.BlockProperties; +import nova.core.block.component.BlockProperty; import nova.core.block.component.LightEmitter; import nova.core.component.Updater; import nova.core.component.misc.Collider; import nova.core.retention.Storable; +import nova.core.sound.Sound; import nova.core.util.Direction; import nova.core.util.shape.Cuboid; import nova.core.wrapper.mc.forge.v18.util.WrapperEvent; @@ -72,18 +74,28 @@ public class FWBlock extends net.minecraft.block.Block { public BlockPos lastExtendedStatePos; private Map harvestedBlocks = new HashMap<>(); + private static Material getMcMaterial(BlockFactory factory) { + Block dummy = factory.build(); + if (dummy.components.has(BlockProperty.Opacity.class)) { + // TODO allow color selection + return new ProxyMaterial(MapColor.grayColor, dummy.components.get(BlockProperty.Opacity.class)); + } else { + return Material.piston; + } + } + public FWBlock(BlockFactory factory) { //TODO: Hack build() method - super(factory.build().components.has(BlockProperties.class) ? new MCBlockProperties(factory.build().components.get(BlockProperties.class)).toMcMaterial() : Material.piston); + super(getMcMaterial(factory)); this.factory = factory; this.dummy = factory.build(); - if (this.getMaterial() instanceof MCBlockProperties.ProxyMaterial) { - this.stepSound = ((MCBlockProperties.ProxyMaterial) this.getMaterial()).getSoundType(); + if (dummy.components.has(BlockProperty.BlockSound.class)) { + this.stepSound = new FWBlockSound(dummy.components.get(BlockProperty.BlockSound.class)); } else { - BlockProperties properties = dummy.components.add(new BlockProperties()); - properties.setBlockSound(BlockProperties.BlockSoundTrigger.BREAK, soundTypeStone.getBreakSound()); - properties.setBlockSound(BlockProperties.BlockSoundTrigger.PLACE, soundTypeStone.getPlaceSound()); - properties.setBlockSound(BlockProperties.BlockSoundTrigger.WALK, soundTypeStone.getStepSound()); + BlockProperty.BlockSound properties = dummy.components.add(new BlockProperty.BlockSound()); + properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.BREAK, new Sound("", soundTypeStone.getBreakSound())); + properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.PLACE, new Sound("", soundTypeStone.getPlaceSound())); + properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.WALK, new Sound("", soundTypeStone.getStepSound())); this.stepSound = soundTypeStone; } this.blockClass = dummy.getClass(); diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java new file mode 100644 index 000000000..f7f1326ab --- /dev/null +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java @@ -0,0 +1,58 @@ +package nova.core.wrapper.mc.forge.v18.wrapper.block.forward; + +import net.minecraft.block.Block; +import nova.core.block.component.BlockProperty.BlockSound; +import nova.core.sound.Sound; + +/** + * @author winsock, soniex2 + */ +public class FWBlockSound extends Block.SoundType { + private final BlockSound blockSound; + + /** + * Construct a new FWBlockSound + * @param blockSound The BlockSound to use. + */ + public FWBlockSound(BlockSound blockSound) { + super("", 1f, 1f); + this.blockSound = blockSound; + } + + @Override + public String getBreakSound() { + if (blockSound.blockSoundSoundMap.containsKey(BlockSound.BlockSoundTrigger.BREAK)) { + Sound sound = blockSound.blockSoundSoundMap.get(BlockSound.BlockSoundTrigger.BREAK); + if (sound.domain.isEmpty() && !sound.name.contains(".")) { + return "dig." + sound.name; + } + return sound.getID(); + } + return super.getBreakSound(); + } + + @Override + public String getStepSound() { + if (blockSound.blockSoundSoundMap.containsKey(BlockSound.BlockSoundTrigger.WALK)) { + Sound sound = blockSound.blockSoundSoundMap.get(BlockSound.BlockSoundTrigger.WALK); + if (sound.domain.isEmpty() && !sound.name.contains(".")) { + return "step." + sound.name; + } + return sound.getID(); + } + return super.getStepSound(); + } + + @Override + public String getPlaceSound() { + if (blockSound.blockSoundSoundMap.containsKey(BlockSound.BlockSoundTrigger.WALK)) { + Sound sound = blockSound.blockSoundSoundMap.get(BlockSound.BlockSoundTrigger.WALK); + if (sound.domain.isEmpty()) { + return sound.name; + } + return sound.getID(); + } + // By default MC uses the block break sound for block placement + return this.getBreakSound(); + } +} diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/MCBlockProperties.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/MCBlockProperties.java deleted file mode 100644 index 45dcacf47..000000000 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/MCBlockProperties.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2015 NOVA, All rights reserved. - * This library is free software, licensed under GNU Lesser General Public License version 3 - * - * This file is part of NOVA. - * - * NOVA is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * NOVA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NOVA. If not, see . - */ - -package nova.core.wrapper.mc.forge.v18.wrapper.block.forward; - -import net.minecraft.block.Block; -import net.minecraft.block.material.MapColor; -import net.minecraft.block.material.Material; -import nova.core.block.component.BlockProperties; -import nova.core.sound.Sound; - -/** - * Created by winsock on 7/2/15. - */ -public class MCBlockProperties extends BlockProperties { - private Material mcMaterial = null; - - public MCBlockProperties() { - } - - public MCBlockProperties(BlockProperties copy) { - this.blockSoundSoundMap = copy.blockSoundSoundMap; - this.customDefinedSounds = copy.customDefinedSounds; - this.allowsLightThrough = copy.allowsLightThrough; - } - - public Material toMcMaterial() { - if (mcMaterial == null) { - // TODO: We most likely should offer a way to set the color. - mcMaterial = new ProxyMaterial(MapColor.grayColor); - } - return mcMaterial; - } - - public class ProxyMaterial extends Material { - private final FWBlockSound sound = new FWBlockSound(); - - public ProxyMaterial(MapColor color) { - super(color); - } - - @Override - public boolean blocksLight() { - return !MCBlockProperties.this.allowsLightThrough; - } - - @Override - public boolean isOpaque() { - return !MCBlockProperties.this.allowsLightThrough; - } - - public Block.SoundType getSoundType() { - return sound; - } - - private class FWBlockSound extends Block.SoundType { - public FWBlockSound() { - super("", 1f, 1f); - } - - @Override - public String getBreakSound() { - if (MCBlockProperties.this.blockSoundSoundMap.containsKey(BlockSoundTrigger.BREAK)) { - Sound sound = MCBlockProperties.this.blockSoundSoundMap.get(BlockSoundTrigger.BREAK); - if (sound.domain.isEmpty() && !sound.name.contains(".")) { - return "dig." + sound.name; - } - return sound.getID(); - } - return super.getBreakSound(); - } - - @Override - public String getStepSound() { - if (MCBlockProperties.this.blockSoundSoundMap.containsKey(BlockSoundTrigger.WALK)) { - Sound sound = MCBlockProperties.this.blockSoundSoundMap.get(BlockSoundTrigger.WALK); - if (sound.domain.isEmpty() && !sound.name.contains(".")) { - return "step." + sound.name; - } - return sound.getID(); - } - return super.getStepSound(); - } - - @Override - public String getPlaceSound() { - if (MCBlockProperties.this.blockSoundSoundMap.containsKey(BlockSoundTrigger.WALK)) { - Sound sound = MCBlockProperties.this.blockSoundSoundMap.get(BlockSoundTrigger.WALK); - if (sound.domain.isEmpty()) { - return sound.name; - } - return sound.getID(); - } - // By default MC uses the block break sound for block placement - return this.getBreakSound(); - } - } - } -} diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/ProxyMaterial.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/ProxyMaterial.java new file mode 100644 index 000000000..a5b6cfc4b --- /dev/null +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/ProxyMaterial.java @@ -0,0 +1,34 @@ +package nova.core.wrapper.mc.forge.v18.wrapper.block.forward; + +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import nova.core.block.component.BlockProperty; +import nova.core.block.component.BlockProperty.Opacity; + +/** + * @author soniex2 + */ +public class ProxyMaterial extends Material { + private final Opacity opacity; + + /** + * Construct a new proxy material. + * @param color The map color. + * @param opacity The Opacity to use. + */ + public ProxyMaterial(MapColor color, Opacity opacity) { + super(color); + this.opacity = opacity; + } + + @Override + public boolean blocksLight() { + return opacity.allowsLightThrough; + } + + @Override + public boolean isOpaque() { + return opacity.allowsLightThrough; + } + +} diff --git a/src/main/java/nova/core/block/Block.java b/src/main/java/nova/core/block/Block.java index fa298f9d7..7b7f4fb6a 100644 --- a/src/main/java/nova/core/block/Block.java +++ b/src/main/java/nova/core/block/Block.java @@ -20,6 +20,7 @@ package nova.core.block; +import nova.core.block.component.BlockProperty; import nova.core.component.ComponentProvider; import nova.core.component.misc.FactoryProvider; import nova.core.component.transform.BlockTransform; @@ -104,7 +105,7 @@ public final int z() { * @return The breaking difficulty. */ public double getHardness() { - return 1; + return components.getOp(BlockProperty.Hardness.class).orElseGet(BlockProperty.Hardness::new).getHardness(); } /** @@ -113,7 +114,7 @@ public double getHardness() { * @return The resistance. */ public double getResistance() { - return 1; + return components.getOp(BlockProperty.Resistance.class).orElseGet(BlockProperty.Resistance::new).getResistance(); } /** @@ -127,6 +128,7 @@ public boolean canReplace() { /** * Called when an ItemBlock tries to place a block in this position whether to displace the place position or not. * If the ItemBlock does not displace the position, it will replace this block. + * TODO move out into BlockProperty * @return True if by right clicking on this block, the placement of the new block should be displaced. */ public boolean shouldDisplacePlacement() { diff --git a/src/main/java/nova/core/block/component/BlockProperties.java b/src/main/java/nova/core/block/component/BlockProperties.java deleted file mode 100644 index 9e7ff1d4a..000000000 --- a/src/main/java/nova/core/block/component/BlockProperties.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2015 NOVA, All rights reserved. - * This library is free software, licensed under GNU Lesser General Public License version 3 - * - * This file is part of NOVA. - * - * NOVA is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * NOVA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NOVA. If not, see . - */ - -package nova.core.block.component; - -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import nova.core.component.Component; -import nova.core.sound.Sound; - -import java.util.Optional; - -/** - * This optional component is for properties that alter a blocks function - * These properties are intended to effect all blocks of one type. - * TODO: Make a component for blocks that have instance properties. E.G. In Minecraft NBT data - * - Note(winsock): I think instance block data storage is an agnostic voxel game feature that goes beyond just 'dumb' blocks - * Created by winsock on 7/2/15. - */ -public class BlockProperties extends Component { - - public BiMap blockSoundSoundMap = HashBiMap.create(); - public Optional> customDefinedSounds; - /** - * This boolean determines if the block should allow light through itself or not. - */ - public boolean allowsLightThrough = false; - - /** - * Sets a sound to play on a specified trigger. Note to set a @see{BlockSoundTrigger.CUSTOM_TRIGGER} use @see{BlockProperties.setCustomBlockSound(String,Sound)} - * - * @param trigger The trigger to set the sound for - * @param sound The sound to play on the triggering of the trigger - * @return This instance for chaining if desired. - */ - public BlockProperties setBlockSound(BlockSoundTrigger trigger, Sound sound) { - if (trigger == BlockSoundTrigger.CUSTOM_TRIGGER) { - return this; - } - blockSoundSoundMap.put(trigger, sound); - return this; - } - - public BlockProperties setBlockSound(BlockSoundTrigger trigger, String soundResourceString) { - return setBlockSound(trigger, new Sound("", soundResourceString)); - } - - /** - * Sets a sound to an id of choice - * - * @param id The custom id for the sound - * @param sound The sound to associate with the id - * @return This instance for chaining if desired. - */ - public BlockProperties setCustomBlockSound(String id, Sound sound) { - if (!customDefinedSounds.isPresent()) { - customDefinedSounds = Optional.of(HashBiMap.create()); - } - customDefinedSounds.get().put(id, sound); - return this; - } - - /** - * Get the sound associated with a trigger - * - * @param trigger The trigger to get the sound for - * @return The sound object associated with the trigger - */ - public Sound getSound(BlockSoundTrigger trigger) { - if (trigger == BlockSoundTrigger.CUSTOM_TRIGGER) { - return null; - } - if (blockSoundSoundMap.containsKey(trigger)) { - return blockSoundSoundMap.get(trigger); - } - return null; - } - - /** - * Get the sound associated with a custom Id - * - * @param customId The custom id of the sound - * @return The sound object associated with the custom Id - */ - public Sound getCustomSound(String customId) { - if (!customDefinedSounds.isPresent()) { - return null; - } - if (customDefinedSounds.get().containsKey(customId)) { - return customDefinedSounds.get().get(customId); - } - return null; - } - - /** - * Sets that the block should allow light through - * - * @return This instance for chaining if desired. - */ - public BlockProperties setTransparent() { - allowsLightThrough = true; - return this; - } - - /** - * Sets if light should be transmitted through this block - * - * @param allowLightThrough Boolean flag if light should be allowed through - * @return This instance for chaining if desired. - */ - public BlockProperties setLightTransmission(boolean allowLightThrough) { - this.allowsLightThrough = allowLightThrough; - return this; - } - - /** - * Triggers for sounds to play on the location of a block - */ - public enum BlockSoundTrigger { - BREAK, - PLACE, - WALK, - CUSTOM_TRIGGER - } -} diff --git a/src/main/java/nova/core/block/component/BlockProperty.java b/src/main/java/nova/core/block/component/BlockProperty.java new file mode 100644 index 000000000..c8ffcb8ff --- /dev/null +++ b/src/main/java/nova/core/block/component/BlockProperty.java @@ -0,0 +1,231 @@ +package nova.core.block.component; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import nova.core.component.Component; +import nova.core.sound.Sound; + +import java.util.Optional; + +/** + * Block properties. + * + * @author soniex2 + */ +public interface BlockProperty { + /** + * The breaking difficulty of a block, or how long it takes to break a block. + * Tools and armour may make the block break faster or slower than this. + *

+ * The standard, regular block hardness is 1. {@code Double.POSITIVE_INFINITY} is unbreakable. + *

+ */ + public static class Hardness extends Component implements BlockProperty { + private double hardness = 1.0; + + /** + * Sets the breaking difficulty. + * + * @param hardness The breaking difficulty. + * @return This instance for chaining if desired. + */ + public Hardness setHardness(double hardness) { + this.hardness = hardness; + return this; + } + + /** + * Gets the breaking difficulty. + * + * @return The breaking difficulty. + */ + public double getHardness() { + return hardness; + } + } + + /** + * The blast resistance of a block. + *

+ * The standard, regular block resistance is 1. {@link Double#POSITIVE_INFINITY} is unexplodable. + *

+ */ + public static class Resistance extends Component implements BlockProperty { + private double resistance = 1.0; + + /** + * Sets the blast resistance + * + * @param resistance The blast resistance. + * @return This instance for chaining if desired. + */ + public Resistance setResistance(double resistance) { + this.resistance = resistance; + return this; + } + + /** + * Gets the blast resistance. + * + * @return The blast resistance. + */ + public double getResistance() { + return resistance; + } + } + + /** + * The block sounds associated with a block. + * + * @author winsock + */ + public static class BlockSound extends Component implements BlockProperty { + public BiMap blockSoundSoundMap = HashBiMap.create(); + public Optional> customDefinedSounds; + + /** + * Sets a sound to play on a specified trigger. Note to set a {@link BlockSoundTrigger#CUSTOM_TRIGGER} use {@link BlockSound#setCustomBlockSound(String,Sound)} + * + * @param trigger The trigger to set the sound for + * @param sound The sound to play on the triggering of the trigger + * @return This instance for chaining if desired. + */ + public BlockSound setBlockSound(BlockSoundTrigger trigger, Sound sound) { + if (trigger == BlockSoundTrigger.CUSTOM_TRIGGER) { + return this; + } + blockSoundSoundMap.put(trigger, sound); + return this; + } + + /** + * Sets a sound to an id of choice + * + * @param id The custom id for the sound + * @param sound The sound to associate with the id + * @return This instance for chaining if desired. + */ + public BlockSound setCustomBlockSound(String id, Sound sound) { + if (!customDefinedSounds.isPresent()) { + customDefinedSounds = Optional.of(HashBiMap.create()); + } + customDefinedSounds.get().put(id, sound); + return this; + } + + /** + * Get the sound associated with a trigger + * + * @param trigger The trigger to get the sound for + * @return The sound object associated with the trigger + */ + public Sound getSound(BlockSoundTrigger trigger) { + if (trigger == BlockSoundTrigger.CUSTOM_TRIGGER) { + return null; + } + if (blockSoundSoundMap.containsKey(trigger)) { + return blockSoundSoundMap.get(trigger); + } + return null; + } + + /** + * Get the sound associated with a custom Id + * + * @param customId The custom id of the sound + * @return The sound object associated with the custom Id + */ + public Sound getCustomSound(String customId) { + if (!customDefinedSounds.isPresent()) { + return null; + } + if (customDefinedSounds.get().containsKey(customId)) { + return customDefinedSounds.get().get(customId); + } + return null; + } + + /** + * Triggers for sounds to play on the location of a block + */ + public enum BlockSoundTrigger { + BREAK, + PLACE, + WALK, + CUSTOM_TRIGGER + } + + } + + /** + * The opacity associated with a block. + * + * @author winsock + */ + public static class Opacity extends Component implements BlockProperty { + // TODO maybe consider a double for opacity? Where 0 is 100% transparent and 1 is 100% opaque? + + /** + * This boolean determines if the block should allow light through itself or not. + */ + public boolean allowsLightThrough = false; + + /** + * Sets that the block should allow light through + * + * @return This instance for chaining if desired. + */ + public Opacity setTransparent() { + allowsLightThrough = true; + return this; + } + + /** + * Sets if light should be transmitted through this block + * + * @param allowLightThrough Boolean flag if light should be allowed through + * @return This instance for chaining if desired. + */ + public Opacity setLightTransmission(boolean allowLightThrough) { + this.allowsLightThrough = allowLightThrough; + return this; + } + } + + // TODO +// /** +// * Indicates whether the block is replaceable. +// */ +// public static final class Replaceable extends Component implements BlockProperty { +// /** +// * Singleton for Replaceable. +// */ +// private static Replaceable theInstance = null; +// +// /** +// * Gets the singleton for Replaceable. +// * +// * @return The singleton for Replaceable. +// */ +// public static Replaceable instance() { +// if (theInstance == null) { +// theInstance = new Replaceable(); +// } +// +// return theInstance; +// } +// +// private Replaceable() { +// } +// +// @Override +// public boolean equals(Object o) { +// return this == o || o instanceof Replaceable; +// } +// +// @Override +// public int hashCode() { +// return Replaceable.class.hashCode(); +// } +// } +} diff --git a/src/main/java/nova/core/item/ItemBlock.java b/src/main/java/nova/core/item/ItemBlock.java index 62e9e013d..f30af52f5 100644 --- a/src/main/java/nova/core/item/ItemBlock.java +++ b/src/main/java/nova/core/item/ItemBlock.java @@ -20,7 +20,7 @@ import nova.core.block.Block; import nova.core.block.BlockFactory; -import nova.core.block.component.BlockProperties; +import nova.core.block.component.BlockProperty; import nova.core.entity.Entity; import nova.core.util.Direction; import nova.core.world.World; @@ -67,8 +67,8 @@ protected boolean onPostPlace(Entity entity, World world, Vector3D placePos, Dir if (opBlock.isPresent() && opBlock.get().sameType(blockFactory)) { //TODO: What if the block is NOT placed by a player? opBlock.get().events.publish(new Block.PlaceEvent(entity, side, hit, this)); - if (opBlock.get().components.has(BlockProperties.class)) { - world.playSoundAtPosition(placePos, opBlock.get().components.get(BlockProperties.class).getSound(BlockProperties.BlockSoundTrigger.PLACE)); + if (opBlock.get().components.has(BlockProperty.BlockSound.class)) { + world.playSoundAtPosition(placePos, opBlock.get().components.get(BlockProperty.BlockSound.class).getSound(BlockProperty.BlockSound.BlockSoundTrigger.PLACE)); } } From 5e56559d932bca50a691d69bf6e7b545825dfaac Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Wed, 26 Oct 2016 22:06:35 -0200 Subject: [PATCH 02/10] String -> Identifier. WIP. --- .../v17/recipes/MinecraftItemIngredient.java | 2 +- .../mc/forge/v17/recipes/RecipeConverter.java | 2 +- .../v17/wrapper/block/BlockConverter.java | 2 +- .../v17/wrapper/block/forward/FWBlock.java | 4 +- .../v17/wrapper/block/world/BWWorld.java | 8 ++- .../v17/wrapper/entity/backward/BWEntity.java | 6 +- .../v17/wrapper/entity/forward/FWEntity.java | 4 +- .../mc/forge/v17/wrapper/item/BWItem.java | 2 +- .../mc/forge/v17/wrapper/item/FWItem.java | 2 +- .../forge/v17/wrapper/item/ItemConverter.java | 4 +- .../v18/recipes/MinecraftItemIngredient.java | 2 +- .../mc/forge/v18/recipes/RecipeConverter.java | 2 +- .../v18/wrapper/block/BlockConverter.java | 2 +- .../v18/wrapper/block/forward/FWBlock.java | 4 +- .../wrapper/block/forward/FWBlockSound.java | 6 +- .../v18/wrapper/block/world/BWWorld.java | 8 ++- .../v18/wrapper/entity/backward/BWEntity.java | 6 +- .../v18/wrapper/entity/forward/FWEntity.java | 4 +- .../mc/forge/v18/wrapper/item/BWItem.java | 2 +- .../mc/forge/v18/wrapper/item/FWItem.java | 2 +- .../forge/v18/wrapper/item/ItemConverter.java | 4 +- src/main/java/nova/core/block/Block.java | 5 +- .../java/nova/core/component/Category.java | 8 ++- .../java/nova/core/component/Component.java | 8 ++- .../java/nova/core/component/fluid/Fluid.java | 10 ++-- .../nova/core/component/misc/Damageable.java | 8 ++- src/main/java/nova/core/entity/Entity.java | 10 ++-- src/main/java/nova/core/item/Item.java | 5 +- src/main/java/nova/core/item/ItemFactory.java | 2 +- src/main/java/nova/core/item/ItemManager.java | 4 +- src/main/java/nova/core/network/Packet.java | 55 +++++++++++++++++-- .../crafting/CraftingRecipeManager.java | 4 +- .../recipes/crafting/OreItemIngredient.java | 3 +- src/main/java/nova/core/render/Asset.java | 8 ++- .../java/nova/core/render/RenderManager.java | 8 +-- .../nova/core/render/texture/Texture.java | 8 ++- src/main/java/nova/core/retention/Data.java | 36 ++++++++++-- .../java/nova/core/retention/Storable.java | 6 +- src/main/java/nova/core/sound/Sound.java | 2 +- .../nova/core/util/id/AbstractIdentifier.java | 46 ++++++++++++++++ .../nova/core/util/id/ClassIdentifier.java | 32 +++++++++++ .../nova/core/util/{ => id}/Identifiable.java | 4 +- .../java/nova/core/util/id/Identifier.java | 19 +++++++ .../nova/core/util/id/StringIdentifier.java | 18 ++++++ .../nova/core/util/id/UUIDIdentifier.java | 29 ++++++++++ .../util/{ => id}/UniqueIdentifiable.java | 6 +- .../java/nova/core/util/registry/Factory.java | 9 ++- .../core/util/registry/FactoryManager.java | 2 +- .../nova/core/util/registry/Registry.java | 6 +- src/main/java/nova/core/world/World.java | 2 +- .../java/nova/core/util/MockIdentifiable.java | 10 +++- .../java/nova/core/util/RegistryTest.java | 6 +- src/test/java/nova/testutils/FakeWorld.java | 6 +- 53 files changed, 359 insertions(+), 104 deletions(-) create mode 100644 src/main/java/nova/core/util/id/AbstractIdentifier.java create mode 100644 src/main/java/nova/core/util/id/ClassIdentifier.java rename src/main/java/nova/core/util/{ => id}/Identifiable.java (96%) create mode 100644 src/main/java/nova/core/util/id/Identifier.java create mode 100644 src/main/java/nova/core/util/id/StringIdentifier.java create mode 100644 src/main/java/nova/core/util/id/UUIDIdentifier.java rename src/main/java/nova/core/util/{ => id}/UniqueIdentifiable.java (87%) diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java index 97582befa..ddf1fbe86 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java @@ -29,6 +29,6 @@ */ public class MinecraftItemIngredient extends SpecificItemIngredient { public MinecraftItemIngredient(net.minecraft.item.ItemStack itemStack) { - super(((Item) Game.natives().toNova(itemStack)).getID()); + super(((Item) Game.natives().toNova(itemStack)).getID().asString()); // TODO? } } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java index 298f3d266..f02af76db 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java @@ -84,7 +84,7 @@ private static ItemIngredient getIngredient(Object ingredient) { if (ingredient == null) { return null; } else if (ingredient instanceof ItemStack) { - return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID()); + return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID().asString()); // TODO? } else if (ingredient instanceof String) { return new OreItemIngredient((String) ingredient); } else if (ingredient instanceof List) { diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java index 58b2c817a..9e7c845cc 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java @@ -136,7 +136,7 @@ private void registerNovaBlock(BlockFactory blockFactory) { FWBlock blockWrapper = new FWBlock(blockFactory); blockFactoryMap.put(blockFactory, blockWrapper); NovaMinecraft.proxy.registerBlock(blockWrapper); - GameRegistry.registerBlock(blockWrapper, FWItemBlock.class, blockFactory.getID()); + GameRegistry.registerBlock(blockWrapper, FWItemBlock.class, blockFactory.getID().asString()); // TODO? if (blockWrapper.dummy.components.has(Category.class) && FMLCommonHandler.instance().getSide().isClient()) { //Add into creative tab diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java index 123d2e4f9..b4710f806 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java @@ -91,7 +91,7 @@ public FWBlock(BlockFactory factory) { this.factory = factory; this.dummy = factory.build(); this.blockClass = dummy.getClass(); - this.setBlockName(dummy.getID()); + this.setBlockName(dummy.getID().asString()); // TODO? // Recalculate super constructor things after loading the block properly this.opaque = isOpaqueCube(); @@ -169,7 +169,7 @@ public boolean hasTileEntity(int metadata) { @Override public TileEntity createTileEntity(World world, int metadata) { - return FWTileLoader.loadTile(dummy.getID()); + return FWTileLoader.loadTile(dummy.getID().asString()); // TODO? } @Override diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/world/BWWorld.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/world/BWWorld.java index 28f892222..858f4bc37 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/world/BWWorld.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/world/BWWorld.java @@ -29,6 +29,8 @@ import nova.core.entity.EntityFactory; import nova.core.item.Item; import nova.core.sound.Sound; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import nova.core.util.shape.Cuboid; import nova.core.world.World; import nova.core.wrapper.mc.forge.v17.launcher.NovaMinecraft; @@ -144,12 +146,12 @@ public Optional getEntity(String uniqueID) { } @Override - public String getID() { - return world().provider.getDimensionName(); + public Identifier getID() { + return new StringIdentifier(world().provider.getDimensionName()); } @Override public void playSoundAtPosition(Vector3D position, Sound sound) { - world().playSound(position.getX(), position.getY(), position.getZ(), sound.getID(), sound.pitch, sound.volume, false); + world().playSound(position.getX(), position.getY(), position.getZ(), sound.getID().asString(), sound.pitch, sound.volume, false); } } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/backward/BWEntity.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/backward/BWEntity.java index bc58ff023..83dda3ee3 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/backward/BWEntity.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/backward/BWEntity.java @@ -28,6 +28,8 @@ import nova.core.entity.Entity; import nova.core.entity.component.Living; import nova.core.entity.component.Player; +import nova.core.util.id.Identifier; +import nova.core.util.id.UUIDIdentifier; import nova.core.wrapper.mc.forge.v17.wrapper.entity.forward.MCEntityTransform; import nova.core.wrapper.mc.forge.v17.wrapper.inventory.BWInventory; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; @@ -88,8 +90,8 @@ public String getUsername() { } @Override - public String getID() { - return entity.getGameProfile().getId().toString(); + public Identifier getID() { + return new UUIDIdentifier(entity.getGameProfile().getId()); } @Override diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java index 02a7bb50e..9e4a91a4b 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java @@ -75,13 +75,13 @@ protected void writeEntityToNBT(NBTTagCompound nbt) { ((Storable) wrapped).save(data); DataWrapper.instance().toNative(nbt, data); } - nbt.setString("novaID", wrapped.getID()); + nbt.setString("novaID", wrapped.getID().asString()); // TODO? } @Override public void writeSpawnData(ByteBuf buffer) { //Write the ID of the entity to client - String id = wrapped.getID(); + String id = wrapped.getID().asString(); // TODO? char[] chars = id.toCharArray(); buffer.writeInt(chars.length); diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java index 9bb8b6925..08fd8ebae 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java @@ -97,6 +97,6 @@ public net.minecraft.item.ItemStack makeItemStack(int stackSize) { @Override public String toString() { - return getID(); + return getID().asString(); // TODO? } } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java index 7c4e8c8ec..ebc78662b 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java @@ -38,7 +38,7 @@ public class FWItem extends net.minecraft.item.Item implements ItemWrapperMethod public FWItem(ItemFactory item) { this.itemFactory = item; - setUnlocalizedName(item.getID()); + setUnlocalizedName(item.getID().asString()); // TODO? setMaxStackSize(item.build().getMaxCount()); } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java index 969162193..17b988425 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java @@ -106,7 +106,7 @@ public ItemStack toNative(Item item) { if (item instanceof BWItem) { return ((BWItem) item).makeItemStack(item.count()); } else { - ItemFactory itemFactory = Game.items().get(item.getID()).get(); + ItemFactory itemFactory = Game.items().get(item.getID().asString()).get(); // TODO? FWNBTTagCompound tag = new FWNBTTagCompound(item); MinecraftItemMapping mapping = get(itemFactory); @@ -202,7 +202,7 @@ private void registerNOVAItem(ItemFactory itemFactory) { // Don't register ItemBlocks twice if (!(dummy instanceof ItemBlock)) { NovaMinecraft.proxy.registerItem((FWItem) itemWrapper); - GameRegistry.registerItem(itemWrapper, itemFactory.getID()); + GameRegistry.registerItem(itemWrapper, itemFactory.getID().asString()); // TODO? if (dummy.components.has(Category.class) && FMLCommonHandler.instance().getSide().isClient()) { //Add into creative tab diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java index 72116bf5e..40701caf8 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java @@ -29,6 +29,6 @@ */ public class MinecraftItemIngredient extends SpecificItemIngredient { public MinecraftItemIngredient(net.minecraft.item.ItemStack itemStack) { - super(((Item) Game.natives().toNova(itemStack)).getID()); + super(((Item) Game.natives().toNova(itemStack)).getID().asString()); // TODO? } } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java index cd616f714..8547f577c 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java @@ -84,7 +84,7 @@ private static ItemIngredient getIngredient(Object ingredient) { if (ingredient == null) { return null; } else if (ingredient instanceof ItemStack) { - return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID()); + return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID().asString()); // TODO? } else if (ingredient instanceof String) { return new OreItemIngredient((String) ingredient); } else if (ingredient instanceof List) { diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java index 17514f534..680d891bb 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java @@ -136,7 +136,7 @@ public boolean canReplace() { private void registerNovaBlock(BlockFactory blockFactory) { FWBlock blockWrapper = new FWBlock(blockFactory); blockFactoryMap.put(blockFactory, blockWrapper); - GameRegistry.registerBlock(blockWrapper, FWItemBlock.class, blockFactory.getID()); + GameRegistry.registerBlock(blockWrapper, FWItemBlock.class, blockFactory.getID().asString()); NovaMinecraft.proxy.postRegisterBlock(blockWrapper); if (blockWrapper.dummy.components.has(Category.class) && FMLCommonHandler.instance().getSide().isClient()) { diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java index 36d9eb71a..8a3a4c6f6 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java @@ -99,7 +99,7 @@ public FWBlock(BlockFactory factory) { this.stepSound = soundTypeStone; } this.blockClass = dummy.getClass(); - this.setUnlocalizedName(dummy.getID()); + this.setUnlocalizedName(dummy.getID().asString()); // TODO? // Recalculate super constructor things after loading the block properly this.fullBlock = isOpaqueCube(); @@ -179,7 +179,7 @@ public boolean hasTileEntity(IBlockState state) { @Override public TileEntity createTileEntity(World world, IBlockState state) { - FWTile fwTile = FWTileLoader.loadTile(dummy.getID()); + FWTile fwTile = FWTileLoader.loadTile(dummy.getID().asString()); // TODO? if (lastExtendedStatePos != null) { fwTile.block.components.getOrAdd(new MCBlockTransform(dummy, Game.natives().toNova(world), new Vector3D(lastExtendedStatePos.getX(), lastExtendedStatePos.getY(), lastExtendedStatePos.getZ()))); lastExtendedStatePos = null; diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java index f7f1326ab..b62c264db 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java @@ -26,7 +26,7 @@ public String getBreakSound() { if (sound.domain.isEmpty() && !sound.name.contains(".")) { return "dig." + sound.name; } - return sound.getID(); + return sound.getID().asString(); // TODO? } return super.getBreakSound(); } @@ -38,7 +38,7 @@ public String getStepSound() { if (sound.domain.isEmpty() && !sound.name.contains(".")) { return "step." + sound.name; } - return sound.getID(); + return sound.getID().asString(); // TODO? } return super.getStepSound(); } @@ -50,7 +50,7 @@ public String getPlaceSound() { if (sound.domain.isEmpty()) { return sound.name; } - return sound.getID(); + return sound.getID().asString(); // TODO? } // By default MC uses the block break sound for block placement return this.getBreakSound(); diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/world/BWWorld.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/world/BWWorld.java index d53baf619..36eea8f77 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/world/BWWorld.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/world/BWWorld.java @@ -31,6 +31,8 @@ import nova.core.entity.EntityFactory; import nova.core.item.Item; import nova.core.sound.Sound; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import nova.core.util.shape.Cuboid; import nova.core.world.World; import nova.core.wrapper.mc.forge.v18.launcher.NovaMinecraft; @@ -153,12 +155,12 @@ public Optional getEntity(String uniqueID) { } @Override - public String getID() { - return world().provider.getDimensionName(); + public Identifier getID() { + return new StringIdentifier(world().provider.getDimensionName()); } @Override public void playSoundAtPosition(Vector3D position, Sound sound) { - world().playSoundEffect(position.getX(), position.getY(), position.getZ(), sound.getID(), sound.volume, sound.pitch); + world().playSoundEffect(position.getX(), position.getY(), position.getZ(), sound.getID().asString(), sound.volume, sound.pitch); } } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/backward/BWEntity.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/backward/BWEntity.java index eb68b58ff..acb33bc20 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/backward/BWEntity.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/backward/BWEntity.java @@ -28,6 +28,8 @@ import nova.core.entity.Entity; import nova.core.entity.component.Living; import nova.core.entity.component.Player; +import nova.core.util.id.Identifier; +import nova.core.util.id.UUIDIdentifier; import nova.core.wrapper.mc.forge.v18.wrapper.entity.forward.MCEntityTransform; import nova.core.wrapper.mc.forge.v18.wrapper.inventory.BWInventory; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; @@ -88,8 +90,8 @@ public String getUsername() { } @Override - public String getID() { - return entity.getGameProfile().getId().toString(); + public Identifier getID() { + return new UUIDIdentifier(entity.getGameProfile().getId()); } @Override diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java index d01763dc2..72ae58935 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java @@ -75,13 +75,13 @@ protected void writeEntityToNBT(NBTTagCompound nbt) { ((Storable) wrapped).save(data); DataWrapper.instance().toNative(nbt, data); } - nbt.setString("novaID", wrapped.getID()); + nbt.setString("novaID", wrapped.getID().asString()); // TODO? } @Override public void writeSpawnData(ByteBuf buffer) { //Write the ID of the entity to client - String id = wrapped.getID(); + String id = wrapped.getID().asString(); // TODO? char[] chars = id.toCharArray(); buffer.writeInt(chars.length); diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java index 7476b9d26..490c5b996 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java @@ -66,6 +66,6 @@ public ItemStack makeItemStack(int stackSize) { @Override public String toString() { - return getID(); + return getID().asString(); // TODO? } } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java index 6ce3b84a4..61b7b9adc 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java @@ -38,7 +38,7 @@ public class FWItem extends net.minecraft.item.Item implements ItemWrapperMethod public FWItem(ItemFactory item) { this.itemFactory = item; - setUnlocalizedName(item.getID()); + setUnlocalizedName(item.getID().asString()); // TODO? setMaxStackSize(item.build().getMaxCount()); } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java index 793bb2fd1..2b5c54df3 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java @@ -107,7 +107,7 @@ public ItemStack toNative(Item item) { if (item instanceof BWItem) { return ((BWItem) item).makeItemStack(item.count()); } else { - ItemFactory itemFactory = Game.items().get(item.getID()).get(); + ItemFactory itemFactory = Game.items().get(item.getID().asString()).get();// TODO? FWNBTTagCompound tag = new FWNBTTagCompound(item); MinecraftItemMapping mapping = get(itemFactory); @@ -204,7 +204,7 @@ private void registerNOVAItem(ItemFactory itemFactory) { // Don't register ItemBlocks twice if (!(dummy instanceof ItemBlock)) { NovaMinecraft.proxy.registerItem((FWItem) itemWrapper); - GameRegistry.registerItem(itemWrapper, itemFactory.getID()); + GameRegistry.registerItem(itemWrapper, itemFactory.getID().asString()); if (dummy.components.has(Category.class) && FMLCommonHandler.instance().getSide().isClient()) { //Add into creative tab diff --git a/src/main/java/nova/core/block/Block.java b/src/main/java/nova/core/block/Block.java index 7b7f4fb6a..1e0e04bf4 100644 --- a/src/main/java/nova/core/block/Block.java +++ b/src/main/java/nova/core/block/Block.java @@ -30,7 +30,8 @@ import nova.core.item.Item; import nova.core.item.ItemFactory; import nova.core.util.Direction; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; import nova.core.world.World; import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; @@ -59,7 +60,7 @@ public final BlockFactory getFactory() { } @Override - public final String getID() { + public final Identifier getID() { return getFactory().getID(); } diff --git a/src/main/java/nova/core/component/Category.java b/src/main/java/nova/core/component/Category.java index 95c8002d4..f8cd3a0df 100644 --- a/src/main/java/nova/core/component/Category.java +++ b/src/main/java/nova/core/component/Category.java @@ -21,7 +21,9 @@ package nova.core.component; import nova.core.item.Item; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import java.util.Optional; @@ -46,7 +48,7 @@ public Category(String name) { } @Override - public String getID() { - return name; + public Identifier getID() { + return new StringIdentifier(name); } } diff --git a/src/main/java/nova/core/component/Component.java b/src/main/java/nova/core/component/Component.java index df2ecd0d4..a0a854b6a 100644 --- a/src/main/java/nova/core/component/Component.java +++ b/src/main/java/nova/core/component/Component.java @@ -21,7 +21,9 @@ package nova.core.component; import nova.core.component.exception.ComponentException; -import nova.core.util.Identifiable; +import nova.core.util.id.ClassIdentifier; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; /** * Base interface for all Components. @@ -51,7 +53,7 @@ public void onProviderChange() { } @Override - public String getID() { - return getClass().getSimpleName(); + public Identifier getID() { + return new ClassIdentifier(getClass()); } } diff --git a/src/main/java/nova/core/component/fluid/Fluid.java b/src/main/java/nova/core/component/fluid/Fluid.java index 809e968ca..675c36a57 100644 --- a/src/main/java/nova/core/component/fluid/Fluid.java +++ b/src/main/java/nova/core/component/fluid/Fluid.java @@ -24,7 +24,9 @@ import nova.core.retention.Data; import nova.core.retention.Storable; import nova.core.retention.Store; -import nova.core.util.Identifiable; +import nova.core.util.id.AbstractIdentifier; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; import nova.internal.core.Game; import java.util.Optional; @@ -126,7 +128,7 @@ public boolean sameType(Fluid stack) { } @Override - public final String getID() { + public final Identifier getID() { return factory.getID(); } @@ -138,12 +140,12 @@ public int hashCode() { @Override public void save(Data data) { Storable.super.save(data); - data.put("id", factory.getID()); + data.put("id", factory.getID().asString()); // TODO? } @Override public void load(Data data) { Storable.super.load(data); - factory = Game.fluids().get(data.get("id")).get(); + factory = Game.fluids().get(data.get("id")).get(); // FIXME } } diff --git a/src/main/java/nova/core/component/misc/Damageable.java b/src/main/java/nova/core/component/misc/Damageable.java index 5f4c63c7d..e5e6c9771 100644 --- a/src/main/java/nova/core/component/misc/Damageable.java +++ b/src/main/java/nova/core/component/misc/Damageable.java @@ -21,7 +21,9 @@ package nova.core.component.misc; import nova.core.component.Component; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; /** * Applied to objects that can take damage. @@ -46,8 +48,8 @@ public DamageType(String name) { } @Override - public String getID() { - return name; + public Identifier getID() { + return new StringIdentifier(name); } } } diff --git a/src/main/java/nova/core/entity/Entity.java b/src/main/java/nova/core/entity/Entity.java index c0943e100..e8edd4958 100644 --- a/src/main/java/nova/core/entity/Entity.java +++ b/src/main/java/nova/core/entity/Entity.java @@ -24,8 +24,10 @@ import nova.core.component.ComponentProvider; import nova.core.component.misc.FactoryProvider; import nova.core.component.transform.EntityTransform; -import nova.core.util.Identifiable; -import nova.core.util.UniqueIdentifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.UniqueIdentifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.UUIDIdentifier; import nova.core.world.World; import org.apache.commons.math3.geometry.euclidean.threed.Rotation; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; @@ -96,12 +98,12 @@ public final EntityFactory getFactory() { } @Override - public final String getID() { + public final Identifier getID() { return getFactory().getID(); } @Override - public String getUniqueID() { + public UUIDIdentifier getUniqueID() { return components.get(UniqueIdentifiable.class).getUniqueID(); } } diff --git a/src/main/java/nova/core/item/Item.java b/src/main/java/nova/core/item/Item.java index 61f6c86e1..255314bc7 100644 --- a/src/main/java/nova/core/item/Item.java +++ b/src/main/java/nova/core/item/Item.java @@ -27,7 +27,8 @@ import nova.core.render.Color; import nova.core.retention.Storable; import nova.core.util.Direction; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import java.util.List; @@ -50,7 +51,7 @@ public final ItemFactory getFactory() { } @Override - public final String getID() { + public final Identifier getID() { return getFactory().getID(); } diff --git a/src/main/java/nova/core/item/ItemFactory.java b/src/main/java/nova/core/item/ItemFactory.java index a31f83599..976b927ac 100644 --- a/src/main/java/nova/core/item/ItemFactory.java +++ b/src/main/java/nova/core/item/ItemFactory.java @@ -24,7 +24,7 @@ import nova.core.retention.Data; import nova.core.retention.Storable; import nova.core.util.registry.Factory; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; import java.util.function.Function; import java.util.function.Supplier; diff --git a/src/main/java/nova/core/item/ItemManager.java b/src/main/java/nova/core/item/ItemManager.java index d31b79dcb..a95d91e6c 100644 --- a/src/main/java/nova/core/item/ItemManager.java +++ b/src/main/java/nova/core/item/ItemManager.java @@ -58,11 +58,11 @@ public ItemFactory register(ItemFactory factory) { } public ItemFactory getItemFromBlock(BlockFactory block) { - return registry.get(block.getID()).get(); + return registry.get(block.getID().asString()).get(); // TODO } public Optional getBlockFromItem(Item item) { - return blockManager.get().get(item.getID()); + return blockManager.get().get(item.getID().asString()); // TODO } @Override diff --git a/src/main/java/nova/core/network/Packet.java b/src/main/java/nova/core/network/Packet.java index 2ad0c0484..258c5c60f 100644 --- a/src/main/java/nova/core/network/Packet.java +++ b/src/main/java/nova/core/network/Packet.java @@ -26,16 +26,12 @@ import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.stream.IntStream; /** * A packet of data that is writable or readable. + * * @author Calclavia */ public interface Packet { @@ -47,6 +43,7 @@ public interface Packet { /** * Sets the ID of this packet, allowing it to be sent accordingly. + * * @return The packet itself. */ Packet setID(int id); @@ -58,6 +55,7 @@ public interface Packet { /** * Writes an arbitrary object, automatically finding the relevant class. + * * @param data Object to write * @return This packet */ @@ -82,6 +80,8 @@ default Packet write(Object data) { writeString((String) data); } else if (data instanceof Enum) { writeEnum((Enum) data); + } else if (data instanceof Class) { + writeClass((Class) data); } else if (data instanceof Optional) { writeOptional((Optional) data); } else if (data instanceof Data) { @@ -101,6 +101,8 @@ default Packet write(Object data) { } else if (data instanceof Vector2D) { writeDouble(((Vector2D) data).getX()); writeDouble(((Vector2D) data).getY()); + } else if (data instanceof UUID) { + writeString(data.toString()); } else { throw new IllegalArgumentException("Packet attempt to write an invalid object: " + data); } @@ -115,6 +117,7 @@ default Packet write(Object data) { /** * Sets the specified boolean at the current {@code writerIndex} * and increases the {@code writerIndex} by {@code 1} in this buffer. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 1} @@ -125,6 +128,7 @@ default Packet write(Object data) { * Sets the specified byte at the current {@code writerIndex} * and increases the {@code writerIndex} by {@code 1} in this buffer. * The 24 high-order bits of the specified value are ignored. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 1} @@ -135,6 +139,7 @@ default Packet write(Object data) { * Sets the specified 16-bit short integer at the current * {@code writerIndex} and increases the {@code writerIndex} by {@code 2} * in this buffer. The 16 high-order bits of the specified value are ignored. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 2} @@ -144,6 +149,7 @@ default Packet write(Object data) { /** * Sets the specified 32-bit integer at the current {@code writerIndex} * and increases the {@code writerIndex} by {@code 4} in this buffer. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 4} @@ -154,6 +160,7 @@ default Packet write(Object data) { * Sets the specified 64-bit long integer at the current * {@code writerIndex} and increases the {@code writerIndex} by {@code 8} * in this buffer. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 8} @@ -164,6 +171,7 @@ default Packet write(Object data) { * Sets the specified 2-byte UTF-16 character at the current * {@code writerIndex} and increases the {@code writerIndex} by {@code 2} * in this buffer. The 16 high-order bits of the specified value are ignored. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 2} @@ -174,6 +182,7 @@ default Packet write(Object data) { * Sets the specified 32-bit floating point number at the current * {@code writerIndex} and increases the {@code writerIndex} by {@code 4} * in this buffer. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 4} @@ -184,6 +193,7 @@ default Packet write(Object data) { * Sets the specified 64-bit floating point number at the current * {@code writerIndex} and increases the {@code writerIndex} by {@code 8} * in this buffer. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 8} @@ -199,6 +209,11 @@ default Packet writeEnum(Enum data) { return this; } + default Packet writeClass(Class data) { + writeString(data.getName()); + return this; + } + default int getType(Class compare) { return IntStream .range(0, Data.dataTypes.length) @@ -258,6 +273,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a boolean at the current {@code readerIndex} and increases * the {@code readerIndex} by {@code 1} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 1} */ @@ -266,6 +282,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a byte at the current {@code readerIndex} and increases * the {@code readerIndex} by {@code 1} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 1} */ @@ -274,6 +291,7 @@ default Packet writeOptional(Optional optional) { /** * Gets an unsigned byte at the current {@code readerIndex} and increases * the {@code readerIndex} by {@code 1} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 1} */ @@ -282,6 +300,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a 16-bit short integer at the current {@code readerIndex} * and increases the {@code readerIndex} by {@code 2} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 2} */ @@ -290,6 +309,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a 32-bit integer at the current {@code readerIndex} * and increases the {@code readerIndex} by {@code 4} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 4} */ @@ -298,6 +318,7 @@ default Packet writeOptional(Optional optional) { /** * Gets an unsigned 32-bit integer at the current {@code readerIndex} * and increases the {@code readerIndex} by {@code 4} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 4} */ @@ -306,6 +327,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a 64-bit integer at the current {@code readerIndex} * and increases the {@code readerIndex} by {@code 8} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 8} */ @@ -314,6 +336,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a 2-byte UTF-16 character at the current {@code readerIndex} * and increases the {@code readerIndex} by {@code 2} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 2} */ @@ -322,6 +345,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a 32-bit floating point number at the current {@code readerIndex} * and increases the {@code readerIndex} by {@code 4} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 4} */ @@ -330,6 +354,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a 64-bit floating point number at the current {@code readerIndex} * and increases the {@code readerIndex} by {@code 8} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 8} */ @@ -426,6 +451,20 @@ default Vector3D readVector3D() { return new Vector3D(readDouble(), readDouble(), readDouble()); } + default Class readClass() { + try { + String classClassName = readString(); + Class classClass = (Class) Class.forName(classClassName); + return classClass; + } catch (Exception e) { + throw new NetworkException("Failed to read enum.", e); + } + } + + default UUID readUUID() { + return UUID.fromString(readString()); + } + default T read(Class clazz) { if (clazz == Boolean.class || clazz == boolean.class) { return (T) Boolean.valueOf(readBoolean()); @@ -459,6 +498,10 @@ else if (Syncable.class.isAssignableFrom(clazz)) { return (T) readVector3D(); } else if (Vector2D.class.isAssignableFrom(clazz)) { return (T) readVector2D(); + } else if (Class.class.isAssignableFrom(clazz)) { + return (T) readClass(); + } else if (UUID.class.isAssignableFrom(clazz)) { + return (T) readUUID(); } else if (List.class.isAssignableFrom(clazz)) { return (T) readList(); } else if (Set.class.isAssignableFrom(clazz)) { diff --git a/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java b/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java index 6648c79ce..4587cbc5d 100644 --- a/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java +++ b/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java @@ -24,6 +24,7 @@ import nova.core.recipes.RecipeAddedEvent; import nova.core.recipes.RecipeManager; import nova.core.recipes.RecipeRemovedEvent; +import nova.core.util.id.Identifier; import java.util.ArrayList; import java.util.Collection; @@ -37,6 +38,7 @@ * @author Stan Hebben */ public class CraftingRecipeManager { + // TODO switch this to using Identifiers private final RecipeManager recipeManager; private final List dynamicRecipes; private final Multimap staticRecipes; @@ -86,7 +88,7 @@ public Optional getRecipe(CraftingGrid grid) { return Optional.empty(); } - String firstItemId = firstItem.get().getID(); + String firstItemId = firstItem.get().getID().asString(); // TODO (this is BAD) if (!staticRecipes.containsKey(firstItemId)) { return Optional.empty(); } diff --git a/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java b/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java index 6a4661d8e..52d3a473c 100644 --- a/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java +++ b/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java @@ -21,6 +21,7 @@ package nova.core.recipes.crafting; import nova.core.item.Item; +import nova.core.util.id.Identifier; import nova.internal.core.Game; import java.util.ArrayList; @@ -46,7 +47,7 @@ public String getName() { @Override public Optional> getPossibleItemIds() { - return Optional.of(Game.itemDictionary().get(name).stream().map(Item::getID).collect(Collectors.toList())); + return Optional.of(Game.itemDictionary().get(name).stream().map(Item::getID).map(Identifier::asString).collect(Collectors.toList())); // TODO? } @Override diff --git a/src/main/java/nova/core/render/Asset.java b/src/main/java/nova/core/render/Asset.java index b5f9b96ec..5aafccaa4 100644 --- a/src/main/java/nova/core/render/Asset.java +++ b/src/main/java/nova/core/render/Asset.java @@ -20,7 +20,9 @@ package nova.core.render; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; /** * @author Calclavia @@ -48,7 +50,7 @@ public boolean equals(Object obj) { } @Override - public final String getID() { - return domain + ":" + name; + public final Identifier getID() { + return new StringIdentifier(domain + ":" + name); } } diff --git a/src/main/java/nova/core/render/RenderManager.java b/src/main/java/nova/core/render/RenderManager.java index c25f6b8eb..4098a8c87 100644 --- a/src/main/java/nova/core/render/RenderManager.java +++ b/src/main/java/nova/core/render/RenderManager.java @@ -43,7 +43,7 @@ public abstract class RenderManager extends Manager { public final Registry modelProviders = new Registry<>(); public ItemTexture registerTexture(ItemTexture texture) { - Optional itemTexture = itemTextures.get(texture.getID()); + Optional itemTexture = itemTextures.get(texture.getID().asString()); // TODO? if (itemTexture.isPresent()) { Game.logger().error("Attempt to register the same texture twice: " + texture); return itemTexture.get(); @@ -53,7 +53,7 @@ public ItemTexture registerTexture(ItemTexture texture) { } public BlockTexture registerTexture(BlockTexture texture) { - Optional blockTexture = blockTextures.get(texture.getID()); + Optional blockTexture = blockTextures.get(texture.getID().asString()); // TODO? if (blockTexture.isPresent()) { Game.logger().error("Attempt to register the same texture twice: " + texture); return blockTexture.get(); @@ -63,7 +63,7 @@ public BlockTexture registerTexture(BlockTexture texture) { } public EntityTexture registerTexture(EntityTexture texture) { - Optional entityTexture = entityTextures.get(texture.getID()); + Optional entityTexture = entityTextures.get(texture.getID().asString()); // TODO? if (entityTexture.isPresent()) { Game.logger().error("Attempt to register the same texture twice: " + texture); return entityTexture.get(); @@ -73,7 +73,7 @@ public EntityTexture registerTexture(EntityTexture texture) { } public ModelProvider registerModel(ModelProvider modelProvider) { - Optional modelProviderCheck = modelProviders.get(modelProvider.getID()); + Optional modelProviderCheck = modelProviders.get(modelProvider.getID().asString()); // TODO? if (modelProviderCheck.isPresent()) { Game.logger().error("Attempt to register the same model twice: " + modelProvider); return modelProviderCheck.get(); diff --git a/src/main/java/nova/core/render/texture/Texture.java b/src/main/java/nova/core/render/texture/Texture.java index ee7596cfa..4c62b3c32 100644 --- a/src/main/java/nova/core/render/texture/Texture.java +++ b/src/main/java/nova/core/render/texture/Texture.java @@ -18,7 +18,9 @@ * along with NOVA. If not, see . */package nova.core.render.texture; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import nova.core.util.math.Vector2DUtil; import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; @@ -60,8 +62,8 @@ public String toString() { } @Override - public final String getID() { - return getResource(); + public final Identifier getID() { + return new StringIdentifier(getResource()); } @Override diff --git a/src/main/java/nova/core/retention/Data.java b/src/main/java/nova/core/retention/Data.java index 71d689c74..f3e2cea52 100755 --- a/src/main/java/nova/core/retention/Data.java +++ b/src/main/java/nova/core/retention/Data.java @@ -23,10 +23,7 @@ import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** * The data class is capable of storing named data. @@ -66,7 +63,9 @@ public class Data extends HashMap { Data.class, Collection.class, Vector3D.class, - Vector2D.class }; + Vector2D.class, + Class.class, + UUID.class }; public String className; @@ -108,6 +107,10 @@ public static Object unserialize(Data data) { return new Vector3D(data.get("x"), data.get("y"), data.get("z")); } else if (clazz == Vector2D.class) { return new Vector2D(data.get("x"), (double) data.get("y")); + } else if (clazz == UUID.class) { + return UUID.fromString(data.get("uuid")); + } else if (clazz == Class.class) { + return Class.forName(data.get("name")); } else { return unserialize(clazz, data); } @@ -165,6 +168,14 @@ public Object put(String key, Object value) { vectorData.put("x", ((Vector2D) value).getX()); vectorData.put("y", ((Vector2D) value).getY()); value = vectorData; + } else if (value instanceof UUID) { + Data uuidData = new Data(UUID.class); + uuidData.put("uuid", value.toString()); + value = uuidData; + } else if (value instanceof Class) { + Data classData = new Data(Class.class); + classData.put("name", ((Class) value).getName()); + value = classData; } else if (value instanceof Storable) { value = serialize((Storable) value); } @@ -214,4 +225,19 @@ public T getStorable(String key) { } } + public Class getClass(String key) { + Data classData = get(key); + try { + @SuppressWarnings("unchecked") + Class classClass = (Class) Class.forName(classData.className); + return classClass; + } catch (Exception e) { + throw new DataException(e); + } + } + + public UUID getUUID(String key) { + Data data = get(key); + return UUID.fromString(data.get("uuid")); + } } diff --git a/src/main/java/nova/core/retention/Storable.java b/src/main/java/nova/core/retention/Storable.java index 84fcfbed7..2e1fdb586 100644 --- a/src/main/java/nova/core/retention/Storable.java +++ b/src/main/java/nova/core/retention/Storable.java @@ -61,11 +61,11 @@ default void load(Data data) { if (data.containsKey(name)) { try { field.setAccessible(true); - Class type = field.getType(); + Class type = field.getType(); // FIXME Object fieldValue = field.get(this); Object value = data.get(name); - if (Storable.class.isAssignableFrom(type) || value instanceof Data) { - if (fieldValue instanceof Storable && value instanceof Data) { + if (Storable.class.isAssignableFrom(type) || value instanceof Data) { // FIXME should test things based on `data` + if (fieldValue instanceof Storable && value instanceof Data) { // this one is fine tho //We already have an instance. Don't need to create the object. ((Storable) fieldValue).load((Data) value); } else { diff --git a/src/main/java/nova/core/sound/Sound.java b/src/main/java/nova/core/sound/Sound.java index 127bc23d3..6dc35697d 100644 --- a/src/main/java/nova/core/sound/Sound.java +++ b/src/main/java/nova/core/sound/Sound.java @@ -21,7 +21,7 @@ package nova.core.sound; import nova.core.render.Asset; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; /** * An object representing a sound. (including the modification to pitch and volume, etc...) diff --git a/src/main/java/nova/core/util/id/AbstractIdentifier.java b/src/main/java/nova/core/util/id/AbstractIdentifier.java new file mode 100644 index 000000000..651b5438d --- /dev/null +++ b/src/main/java/nova/core/util/id/AbstractIdentifier.java @@ -0,0 +1,46 @@ +package nova.core.util.id; + +import nova.core.retention.Data; +import nova.core.retention.Storable; +import nova.core.retention.Store; + +/** + * Basic implementation of Identifier. + * + * @author soniex2 + */ +public abstract class AbstractIdentifier implements Identifier { + /** + * The ID. + */ + protected final T id; + + /** + * Constructs a new AbstractIdentifier. + * + * @param id The ID. + */ + public AbstractIdentifier(T id) { + this.id = id; + } + + @Override + public String asString() { + return id.toString(); + } + + @Override + public String toString() { + return id.toString(); + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + @Override + public boolean equals(Object o) { + return this == o || (o != null && getClass() == o.getClass() && id.equals(((AbstractIdentifier) o).id)); + } +} diff --git a/src/main/java/nova/core/util/id/ClassIdentifier.java b/src/main/java/nova/core/util/id/ClassIdentifier.java new file mode 100644 index 000000000..8fbc7466c --- /dev/null +++ b/src/main/java/nova/core/util/id/ClassIdentifier.java @@ -0,0 +1,32 @@ +package nova.core.util.id; + +/** + * A Class Identifier. + * + * @author soniex2 + */ +public final class ClassIdentifier extends AbstractIdentifier> implements Identifier { + + /** + * Constructs a new ClassIdentifier. + * + * @param id The Class. + */ + public ClassIdentifier(Class id) { + super(id); + } + + @Override + public String asString() { + return id.getSimpleName(); + } + + /** + * Returns this Identifier's Class. + * + * @return The Class. + */ + public Class asClass() { + return id; + } +} diff --git a/src/main/java/nova/core/util/Identifiable.java b/src/main/java/nova/core/util/id/Identifiable.java similarity index 96% rename from src/main/java/nova/core/util/Identifiable.java rename to src/main/java/nova/core/util/id/Identifiable.java index e98159e43..3ff8c86ff 100644 --- a/src/main/java/nova/core/util/Identifiable.java +++ b/src/main/java/nova/core/util/id/Identifiable.java @@ -18,7 +18,7 @@ * along with NOVA. If not, see . */ -package nova.core.util; +package nova.core.util.id; /** * A generic interface signifying that this object is identifiable @@ -30,7 +30,7 @@ public interface Identifiable { * * @return the ID */ - String getID(); + Identifier getID(); /** * Compares the ID of the Identifialbes diff --git a/src/main/java/nova/core/util/id/Identifier.java b/src/main/java/nova/core/util/id/Identifier.java new file mode 100644 index 000000000..7453cef99 --- /dev/null +++ b/src/main/java/nova/core/util/id/Identifier.java @@ -0,0 +1,19 @@ +package nova.core.util.id; + +/** + * The interface for all identifiers. + *

+ * Implementations should override {@link Object#equals(Object)}, {@link Object#hashCode()} and {@link Object#toString()}. + *

+ * + * @author soniex2 + */ +public interface Identifier { + /** + * Converts this Identifier into a String. + * The output from this method may be different than {@link Object#toString()}. + * + * @return A string representation of this Identifier. + */ + String asString(); +} diff --git a/src/main/java/nova/core/util/id/StringIdentifier.java b/src/main/java/nova/core/util/id/StringIdentifier.java new file mode 100644 index 000000000..f52b45030 --- /dev/null +++ b/src/main/java/nova/core/util/id/StringIdentifier.java @@ -0,0 +1,18 @@ +package nova.core.util.id; + +/** + * A String Identifier. + * + * @author soniex2 + */ +public final class StringIdentifier extends AbstractIdentifier implements Identifier { + + /** + * Constructs a new StringIdentifier. + * + * @param id The String. + */ + public StringIdentifier(String id) { + super(id); + } +} diff --git a/src/main/java/nova/core/util/id/UUIDIdentifier.java b/src/main/java/nova/core/util/id/UUIDIdentifier.java new file mode 100644 index 000000000..754c214fd --- /dev/null +++ b/src/main/java/nova/core/util/id/UUIDIdentifier.java @@ -0,0 +1,29 @@ +package nova.core.util.id; + +import java.util.UUID; + +/** + * An UUID Identifier. + * + * @author soniex2 + */ +public final class UUIDIdentifier extends AbstractIdentifier implements Identifier { + + /** + * Constructs a new UUIDIdentifier. + * + * @param id The UUID. + */ + public UUIDIdentifier(UUID id) { + super(id); + } + + /** + * Returns this Identifier's UUID. + * + * @return The UUID. + */ + public UUID asUUID() { + return id; + } +} diff --git a/src/main/java/nova/core/util/UniqueIdentifiable.java b/src/main/java/nova/core/util/id/UniqueIdentifiable.java similarity index 87% rename from src/main/java/nova/core/util/UniqueIdentifiable.java rename to src/main/java/nova/core/util/id/UniqueIdentifiable.java index a795892d1..ae37ad60f 100644 --- a/src/main/java/nova/core/util/UniqueIdentifiable.java +++ b/src/main/java/nova/core/util/id/UniqueIdentifiable.java @@ -18,7 +18,9 @@ * along with NOVA. If not, see . */ -package nova.core.util; +package nova.core.util.id; + +import nova.core.util.id.UUIDIdentifier; /** * A generic interface signifying that this object is uniquely identifiable @@ -30,5 +32,5 @@ public interface UniqueIdentifiable { * * @return the ID */ - String getUniqueID(); + UUIDIdentifier getUniqueID(); // TODO maybe this should return a simple Identifier } diff --git a/src/main/java/nova/core/util/registry/Factory.java b/src/main/java/nova/core/util/registry/Factory.java index 7ce169d1e..2034a3168 100644 --- a/src/main/java/nova/core/util/registry/Factory.java +++ b/src/main/java/nova/core/util/registry/Factory.java @@ -20,7 +20,10 @@ package nova.core.util.registry; -import nova.core.util.Identifiable; +import nova.core.component.ComponentProvider; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import java.util.function.Function; import java.util.function.Supplier; @@ -78,7 +81,7 @@ public T build() { return processor.apply(constructor.get()); } - public String getID() { - return id; + public Identifier getID() { + return new StringIdentifier(id); } } diff --git a/src/main/java/nova/core/util/registry/FactoryManager.java b/src/main/java/nova/core/util/registry/FactoryManager.java index 20a38d558..8c2281833 100644 --- a/src/main/java/nova/core/util/registry/FactoryManager.java +++ b/src/main/java/nova/core/util/registry/FactoryManager.java @@ -20,7 +20,7 @@ package nova.core.util.registry; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; import java.util.Optional; import java.util.function.Supplier; diff --git a/src/main/java/nova/core/util/registry/Registry.java b/src/main/java/nova/core/util/registry/Registry.java index bf25553d9..24e724416 100644 --- a/src/main/java/nova/core/util/registry/Registry.java +++ b/src/main/java/nova/core/util/registry/Registry.java @@ -19,7 +19,8 @@ */package nova.core.util.registry; import com.google.common.collect.HashBiMap; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; import java.util.Iterator; import java.util.Optional; @@ -32,6 +33,7 @@ * @param The object type */ public class Registry implements Iterable { + // TODO maybe index by Identifier? Could be nice when the game uses int IDs (e.g. very old versions of minecraft). private final HashBiMap objects = HashBiMap.create(); public Registry() { @@ -45,7 +47,7 @@ public Registry() { * @return Given object */ public T register(T object) { - objects.put(object.getID(), object); + objects.put(object.getID().asString(), object); return object; } diff --git a/src/main/java/nova/core/world/World.java b/src/main/java/nova/core/world/World.java index d89565221..22832ac35 100644 --- a/src/main/java/nova/core/world/World.java +++ b/src/main/java/nova/core/world/World.java @@ -24,7 +24,7 @@ import nova.core.entity.EntityFactory; import nova.core.item.Item; import nova.core.sound.Sound; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; import nova.core.util.shape.Cuboid; import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; diff --git a/src/test/java/nova/core/util/MockIdentifiable.java b/src/test/java/nova/core/util/MockIdentifiable.java index a69500bc8..33569e31c 100644 --- a/src/test/java/nova/core/util/MockIdentifiable.java +++ b/src/test/java/nova/core/util/MockIdentifiable.java @@ -20,6 +20,10 @@ package nova.core.util; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; + public class MockIdentifiable implements Identifiable { String ID; @@ -28,12 +32,12 @@ public MockIdentifiable(String ID) { } @Override - public String getID() { - return ID; + public Identifier getID() { + return new StringIdentifier(ID); } @Override public String toString() { - return getID(); + return getID().asString(); } } diff --git a/src/test/java/nova/core/util/RegistryTest.java b/src/test/java/nova/core/util/RegistryTest.java index 79afd10d8..9e80a9313 100644 --- a/src/test/java/nova/core/util/RegistryTest.java +++ b/src/test/java/nova/core/util/RegistryTest.java @@ -20,6 +20,8 @@ package nova.core.util; +import nova.core.util.id.Identifiable; +import nova.core.util.id.StringIdentifier; import nova.core.util.registry.Registry; import org.junit.Test; @@ -41,8 +43,8 @@ public void testRegistry() throws Exception { assertThat(registry.contains("ID1")).isTrue(); assertThat(registry.contains("ID2")).isTrue(); - assertThat(registry.get("ID1").get().getID()).isEqualTo("ID1"); - assertThat(registry.get("ID2").get().getID()).isEqualTo("ID2"); + assertThat(registry.get("ID1").get().getID()).isEqualTo(new StringIdentifier("ID1")); + assertThat(registry.get("ID2").get().getID()).isEqualTo(new StringIdentifier("ID2")); assertThat(registry.get("ID1").get()).isEqualTo(id1); assertThat(registry.get("ID2").get()).isEqualTo(id2); diff --git a/src/test/java/nova/testutils/FakeWorld.java b/src/test/java/nova/testutils/FakeWorld.java index c4443bdb5..522e878ab 100644 --- a/src/test/java/nova/testutils/FakeWorld.java +++ b/src/test/java/nova/testutils/FakeWorld.java @@ -28,6 +28,8 @@ import nova.core.entity.EntityFactory; import nova.core.item.Item; import nova.core.sound.Sound; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import nova.core.util.shape.Cuboid; import nova.core.world.World; import nova.internal.core.Game; @@ -131,7 +133,7 @@ public void playSoundAtPosition(Vector3D position, Sound sound) { } @Override - public String getID() { - return "fakeWorld"; + public Identifier getID() { + return new StringIdentifier("fakeWorld"); } } From 04e3ae22b9c56fa94feaaa3ab424ba51d06c5093 Mon Sep 17 00:00:00 2001 From: ExE Boss Date: Sat, 7 Jan 2017 23:06:01 +0100 Subject: [PATCH 03/10] Work on Identifiers --- .../nova/core/util/id/AbstractIdentifier.java | 20 ++++++---- .../nova/core/util/id/ClassIdentifier.java | 9 ++++- .../java/nova/core/util/id/Identifiable.java | 4 +- .../java/nova/core/util/id/Identifier.java | 1 + .../util/id/NamespacedStringIdentifier.java | 39 +++++++++++++++++++ .../nova/core/util/id/StringIdentifier.java | 9 ++++- .../nova/core/util/id/UUIDIdentifier.java | 8 +++- .../nova/core/util/id/UniqueIdentifiable.java | 17 +++++++- 8 files changed, 92 insertions(+), 15 deletions(-) create mode 100644 src/main/java/nova/core/util/id/NamespacedStringIdentifier.java diff --git a/src/main/java/nova/core/util/id/AbstractIdentifier.java b/src/main/java/nova/core/util/id/AbstractIdentifier.java index 651b5438d..b625d49fd 100644 --- a/src/main/java/nova/core/util/id/AbstractIdentifier.java +++ b/src/main/java/nova/core/util/id/AbstractIdentifier.java @@ -1,8 +1,7 @@ package nova.core.util.id; -import nova.core.retention.Data; -import nova.core.retention.Storable; -import nova.core.retention.Store; +import java.util.Objects; +import java.util.function.Function; /** * Basic implementation of Identifier. @@ -26,21 +25,26 @@ public AbstractIdentifier(T id) { @Override public String asString() { - return id.toString(); + return Objects.toString(id); } @Override public String toString() { - return id.toString(); + return Objects.toString(id); } @Override public int hashCode() { - return id.hashCode(); + return Objects.hashCode(id); } @Override - public boolean equals(Object o) { - return this == o || (o != null && getClass() == o.getClass() && id.equals(((AbstractIdentifier) o).id)); + public abstract boolean equals(Object other); + + protected static final boolean equalsImpl(Identifier _this, Object other, Class superclass, Function getter) { + if (_this == other) return true; + if (_this == null || other == null) return false; + if (!_this.getClass().isAssignableFrom(superclass) || !other.getClass().isAssignableFrom(superclass)) return false; + return Objects.equals(getter.apply((T)_this), getter.apply((T)other)); } } diff --git a/src/main/java/nova/core/util/id/ClassIdentifier.java b/src/main/java/nova/core/util/id/ClassIdentifier.java index 8fbc7466c..5ef75d809 100644 --- a/src/main/java/nova/core/util/id/ClassIdentifier.java +++ b/src/main/java/nova/core/util/id/ClassIdentifier.java @@ -1,11 +1,13 @@ package nova.core.util.id; +import java.util.Objects; + /** * A Class Identifier. * * @author soniex2 */ -public final class ClassIdentifier extends AbstractIdentifier> implements Identifier { +public class ClassIdentifier extends AbstractIdentifier> implements Identifier { /** * Constructs a new ClassIdentifier. @@ -29,4 +31,9 @@ public String asString() { public Class asClass() { return id; } + + @Override + public boolean equals(Object other) { + return equalsImpl(this, other, ClassIdentifier.class, id -> id.asClass()); + } } diff --git a/src/main/java/nova/core/util/id/Identifiable.java b/src/main/java/nova/core/util/id/Identifiable.java index 3ff8c86ff..6c24b1928 100644 --- a/src/main/java/nova/core/util/id/Identifiable.java +++ b/src/main/java/nova/core/util/id/Identifiable.java @@ -22,9 +22,10 @@ /** * A generic interface signifying that this object is identifiable - * by an ID + * by an ID. */ public interface Identifiable { + /** * Get the ID to identify this object by * @@ -38,7 +39,6 @@ public interface Identifiable { * @param other Identifiable to compare to * @return If the Identifiables are the same type */ - default boolean sameType(Identifiable other) { return getID().equals(other.getID()); } diff --git a/src/main/java/nova/core/util/id/Identifier.java b/src/main/java/nova/core/util/id/Identifier.java index 7453cef99..c71666c9e 100644 --- a/src/main/java/nova/core/util/id/Identifier.java +++ b/src/main/java/nova/core/util/id/Identifier.java @@ -9,6 +9,7 @@ * @author soniex2 */ public interface Identifier { + /** * Converts this Identifier into a String. * The output from this method may be different than {@link Object#toString()}. diff --git a/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java b/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java new file mode 100644 index 000000000..d5246fb27 --- /dev/null +++ b/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java @@ -0,0 +1,39 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package nova.core.util.id; + +/** + * A Namespaced String Identifier. + * + * @author ExE Boss + */ +public class NamespacedStringIdentifier extends StringIdentifier { + + protected final String domain; + + public NamespacedStringIdentifier(String id) { + super(id.substring(id.indexOf(':') + 1)); + this.domain = (id.contains(":") ? id.substring(0, id.indexOf(':')) : "nova"); + } + + public NamespacedStringIdentifier(String domain, String id) { + super(id); + this.domain = domain; + } + + public String getDomain() { + return domain; + } + + public String getId() { + return id; + } + + @Override + public String asString() { + return domain + ':' + id; + } +} diff --git a/src/main/java/nova/core/util/id/StringIdentifier.java b/src/main/java/nova/core/util/id/StringIdentifier.java index f52b45030..424d6780e 100644 --- a/src/main/java/nova/core/util/id/StringIdentifier.java +++ b/src/main/java/nova/core/util/id/StringIdentifier.java @@ -1,11 +1,13 @@ package nova.core.util.id; +import java.util.Objects; + /** * A String Identifier. * * @author soniex2 */ -public final class StringIdentifier extends AbstractIdentifier implements Identifier { +public class StringIdentifier extends AbstractIdentifier implements Identifier { /** * Constructs a new StringIdentifier. @@ -15,4 +17,9 @@ public final class StringIdentifier extends AbstractIdentifier implement public StringIdentifier(String id) { super(id); } + + @Override + public boolean equals(Object other) { + return equalsImpl(this, other, StringIdentifier.class, id -> id.asString()); + } } diff --git a/src/main/java/nova/core/util/id/UUIDIdentifier.java b/src/main/java/nova/core/util/id/UUIDIdentifier.java index 754c214fd..8ce727f92 100644 --- a/src/main/java/nova/core/util/id/UUIDIdentifier.java +++ b/src/main/java/nova/core/util/id/UUIDIdentifier.java @@ -1,5 +1,6 @@ package nova.core.util.id; +import java.util.Objects; import java.util.UUID; /** @@ -7,7 +8,7 @@ * * @author soniex2 */ -public final class UUIDIdentifier extends AbstractIdentifier implements Identifier { +public class UUIDIdentifier extends AbstractIdentifier implements Identifier { /** * Constructs a new UUIDIdentifier. @@ -26,4 +27,9 @@ public UUIDIdentifier(UUID id) { public UUID asUUID() { return id; } + + @Override + public boolean equals(Object other) { + return equalsImpl(this, other, UUIDIdentifier.class, id -> id.asUUID()); + } } diff --git a/src/main/java/nova/core/util/id/UniqueIdentifiable.java b/src/main/java/nova/core/util/id/UniqueIdentifiable.java index ae37ad60f..f8e939dd3 100644 --- a/src/main/java/nova/core/util/id/UniqueIdentifiable.java +++ b/src/main/java/nova/core/util/id/UniqueIdentifiable.java @@ -24,13 +24,26 @@ /** * A generic interface signifying that this object is uniquely identifiable - * by an ID + * by an ID. */ -public interface UniqueIdentifiable { +public interface UniqueIdentifiable extends Identifiable { + + /** + * {@inheritDoc} + * + * @return the ID. The default implementation returns the same result as {@link #getUniqueID()}. + * @see #getUniqueID() + */ + @Override + default Identifier getID() { + return getUniqueID(); + } + /** * Get the unique ID to identify this object. * * @return the ID + * @see #getID() */ UUIDIdentifier getUniqueID(); // TODO maybe this should return a simple Identifier } From f773b011ea864b57a2fd9027bc70787128296abd Mon Sep 17 00:00:00 2001 From: ExE Boss Date: Sat, 7 Jan 2017 23:37:32 +0100 Subject: [PATCH 04/10] Change all instances of String id to Identifier in core TODO: Fix wrappers --- .../java/nova/core/block/BlockFactory.java | 9 +++--- .../java/nova/core/block/BlockManager.java | 6 ++-- .../core/component/fluid/FluidFactory.java | 7 +++-- .../core/component/fluid/FluidManager.java | 8 +++-- .../java/nova/core/entity/EntityFactory.java | 7 +++-- .../java/nova/core/entity/EntityManager.java | 3 +- src/main/java/nova/core/item/ItemFactory.java | 7 +++-- src/main/java/nova/core/item/ItemManager.java | 11 +++---- .../core/recipes/crafting/CraftingRecipe.java | 3 +- .../crafting/CraftingRecipeManager.java | 12 ++++---- .../core/recipes/crafting/ItemIngredient.java | 8 +++-- .../recipes/crafting/OreItemIngredient.java | 10 ++++--- .../crafting/ShapedCraftingRecipe.java | 11 +++---- .../crafting/SpecificItemIngredient.java | 30 +++++++------------ .../java/nova/core/render/RenderManager.java | 8 ++--- .../java/nova/core/util/id/Identifier.java | 2 +- .../java/nova/core/util/registry/Factory.java | 10 +++---- .../core/util/registry/FactoryManager.java | 19 ++++++++++-- .../nova/core/util/registry/Registry.java | 12 ++++---- .../java/nova/core/world/WorldFactory.java | 7 +++-- .../java/nova/core/world/WorldManager.java | 3 +- .../java/nova/core/util/MockIdentifiable.java | 6 ++-- .../java/nova/core/util/RayTraceTest.java | 5 ++-- .../java/nova/core/util/RegistryTest.java | 18 +++++------ .../wrappertests/NovaLauncherTestFactory.java | 3 +- 25 files changed, 124 insertions(+), 101 deletions(-) diff --git a/src/main/java/nova/core/block/BlockFactory.java b/src/main/java/nova/core/block/BlockFactory.java index 29e947504..8a8111964 100644 --- a/src/main/java/nova/core/block/BlockFactory.java +++ b/src/main/java/nova/core/block/BlockFactory.java @@ -24,6 +24,7 @@ import nova.core.event.BlockEvent; import nova.core.event.bus.EventListener; import nova.core.item.ItemBlock; +import nova.core.util.id.Identifier; import nova.core.util.registry.Factory; import nova.internal.core.Game; @@ -35,11 +36,11 @@ * @author Calclavia */ public class BlockFactory extends Factory { - public BlockFactory(String id, Supplier constructor, Function processor) { + public BlockFactory(Identifier id, Supplier constructor, Function processor) { super(id, constructor, processor); } - public BlockFactory(String id, Supplier constructor) { + public BlockFactory(Identifier id, Supplier constructor) { this(id, constructor, evt -> { Game.items().register(id, () -> new ItemBlock(evt.blockFactory)); }); @@ -51,7 +52,7 @@ public BlockFactory(String id, Supplier constructor) { * @param constructor The constructor function * @param postCreate Function for registering item blocks */ - public BlockFactory(String id, Supplier constructor, EventListener postCreate) { + public BlockFactory(Identifier id, Supplier constructor, EventListener postCreate) { super(id, constructor); postCreate(postCreate); } @@ -61,7 +62,7 @@ protected void postCreate(EventListener postCreate) { } @Override - protected BlockFactory selfConstructor(String id, Supplier constructor, Function processor) { + protected BlockFactory selfConstructor(Identifier id, Supplier constructor, Function processor) { return new BlockFactory(id, constructor, processor); } diff --git a/src/main/java/nova/core/block/BlockManager.java b/src/main/java/nova/core/block/BlockManager.java index 41a28f90f..b5f27151f 100644 --- a/src/main/java/nova/core/block/BlockManager.java +++ b/src/main/java/nova/core/block/BlockManager.java @@ -21,6 +21,8 @@ package nova.core.block; import nova.core.event.BlockEvent; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import nova.core.util.registry.FactoryManager; import nova.core.util.registry.Registry; import nova.internal.core.Game; @@ -38,7 +40,7 @@ private BlockManager(Registry registry) { * @return The air block factory */ public BlockFactory getAirBlock() { - return get("air").get(); + return get(new StringIdentifier("air")).get(); } /** @@ -47,7 +49,7 @@ public BlockFactory getAirBlock() { * @return Dummy block */ @Override - public BlockFactory register(String id, Supplier constructor) { + public BlockFactory register(Identifier id, Supplier constructor) { return register(new BlockFactory(id, constructor)); } diff --git a/src/main/java/nova/core/component/fluid/FluidFactory.java b/src/main/java/nova/core/component/fluid/FluidFactory.java index 4b5af7ced..b6353d764 100644 --- a/src/main/java/nova/core/component/fluid/FluidFactory.java +++ b/src/main/java/nova/core/component/fluid/FluidFactory.java @@ -20,6 +20,7 @@ package nova.core.component.fluid; +import nova.core.util.id.Identifier; import nova.core.util.registry.Factory; import java.util.function.Function; @@ -30,11 +31,11 @@ */ public class FluidFactory extends Factory { - public FluidFactory(String id, Supplier constructor, Function processor) { + public FluidFactory(Identifier id, Supplier constructor, Function processor) { super(id, constructor, processor); } - public FluidFactory(String id, Supplier constructor) { + public FluidFactory(Identifier id, Supplier constructor) { super(id, constructor); } @@ -46,7 +47,7 @@ public Fluid build() { } @Override - protected FluidFactory selfConstructor(String id, Supplier constructor, Function processor) { + protected FluidFactory selfConstructor(Identifier id, Supplier constructor, Function processor) { return new FluidFactory(id, constructor, processor); } } diff --git a/src/main/java/nova/core/component/fluid/FluidManager.java b/src/main/java/nova/core/component/fluid/FluidManager.java index f5a1b2d73..1759a5ff6 100644 --- a/src/main/java/nova/core/component/fluid/FluidManager.java +++ b/src/main/java/nova/core/component/fluid/FluidManager.java @@ -20,6 +20,8 @@ package nova.core.component.fluid; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import nova.core.util.registry.FactoryManager; import nova.core.util.registry.Registry; @@ -32,12 +34,12 @@ public class FluidManager extends FactoryManager fluidRegistry) { super(fluidRegistry); //TODO: Too Minecraft specific. Implementation should be hidden. - this.water = register("water", Fluid::new); - this.lava = register("lava", Fluid::new); + this.water = register(new StringIdentifier("water"), Fluid::new); + this.lava = register(new StringIdentifier("lava"), Fluid::new); } @Override - public FluidFactory register(String id, Supplier constructor) { + public FluidFactory register(Identifier id, Supplier constructor) { return register(new FluidFactory(id, constructor)); } diff --git a/src/main/java/nova/core/entity/EntityFactory.java b/src/main/java/nova/core/entity/EntityFactory.java index 7a1712b7e..c7c352189 100644 --- a/src/main/java/nova/core/entity/EntityFactory.java +++ b/src/main/java/nova/core/entity/EntityFactory.java @@ -21,6 +21,7 @@ package nova.core.entity; import nova.core.component.misc.FactoryProvider; +import nova.core.util.id.Identifier; import nova.core.util.registry.Factory; import java.util.function.Function; @@ -31,16 +32,16 @@ * @author Calclavia */ public class EntityFactory extends Factory { - public EntityFactory(String id, Supplier constructor, Function processor) { + public EntityFactory(Identifier id, Supplier constructor, Function processor) { super(id, constructor, processor); } - public EntityFactory(String id, Supplier constructor) { + public EntityFactory(Identifier id, Supplier constructor) { super(id, constructor); } @Override - protected EntityFactory selfConstructor(String id, Supplier constructor, Function processor) { + protected EntityFactory selfConstructor(Identifier id, Supplier constructor, Function processor) { return new EntityFactory(id, constructor, processor); } diff --git a/src/main/java/nova/core/entity/EntityManager.java b/src/main/java/nova/core/entity/EntityManager.java index c49ec3731..91cc06ecb 100644 --- a/src/main/java/nova/core/entity/EntityManager.java +++ b/src/main/java/nova/core/entity/EntityManager.java @@ -20,6 +20,7 @@ package nova.core.entity; +import nova.core.util.id.Identifier; import nova.core.util.registry.FactoryManager; import nova.core.util.registry.Registry; import nova.internal.core.Game; @@ -38,7 +39,7 @@ private EntityManager(Registry registry) { * @return The entity factory */ @Override - public EntityFactory register(String id, Supplier constructor) { + public EntityFactory register(Identifier id, Supplier constructor) { return register(new EntityFactory(id, constructor)); } diff --git a/src/main/java/nova/core/item/ItemFactory.java b/src/main/java/nova/core/item/ItemFactory.java index 976b927ac..91bf50553 100644 --- a/src/main/java/nova/core/item/ItemFactory.java +++ b/src/main/java/nova/core/item/ItemFactory.java @@ -25,6 +25,7 @@ import nova.core.retention.Storable; import nova.core.util.registry.Factory; import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; import java.util.function.Function; import java.util.function.Supplier; @@ -33,11 +34,11 @@ * @author Calclavia */ public class ItemFactory extends Factory implements Identifiable { - public ItemFactory(String id, Supplier constructor, Function processor) { + public ItemFactory(Identifier id, Supplier constructor, Function processor) { super(id, constructor, processor); } - public ItemFactory(String id, Supplier constructor) { + public ItemFactory(Identifier id, Supplier constructor) { super(id, constructor); } @@ -74,7 +75,7 @@ public Data save(Item item) { } @Override - protected ItemFactory selfConstructor(String id, Supplier constructor, Function processor) { + protected ItemFactory selfConstructor(Identifier id, Supplier constructor, Function processor) { return new ItemFactory(id, constructor, processor); } } diff --git a/src/main/java/nova/core/item/ItemManager.java b/src/main/java/nova/core/item/ItemManager.java index a95d91e6c..d425f124e 100644 --- a/src/main/java/nova/core/item/ItemManager.java +++ b/src/main/java/nova/core/item/ItemManager.java @@ -24,6 +24,7 @@ import nova.core.block.BlockManager; import nova.core.event.bus.CancelableEvent; import nova.core.item.event.ItemIDNotFoundEvent; +import nova.core.util.id.Identifier; import nova.core.util.registry.FactoryManager; import nova.core.util.registry.Registry; import nova.internal.core.Game; @@ -46,7 +47,7 @@ private ItemManager(Registry itemRegistry, Supplier b * @return Dummy item */ @Override - public ItemFactory register(String id, Supplier constructor) { + public ItemFactory register(Identifier id, Supplier constructor) { return register(new ItemFactory(id, constructor)); } @@ -58,17 +59,17 @@ public ItemFactory register(ItemFactory factory) { } public ItemFactory getItemFromBlock(BlockFactory block) { - return registry.get(block.getID().asString()).get(); // TODO + return registry.get(block.getID()).get(); } public Optional getBlockFromItem(Item item) { - return blockManager.get().get(item.getID().asString()); // TODO + return blockManager.get().get(item.getID()); } @Override - public Optional get(String name) { + public Optional get(Identifier name) { if (!registry.contains(name)) { - ItemIDNotFoundEvent event = new ItemIDNotFoundEvent(name); + ItemIDNotFoundEvent event = new ItemIDNotFoundEvent(name.asString()); Game.events().publish(event); if (event.getRemappedFactory() != null) { diff --git a/src/main/java/nova/core/recipes/crafting/CraftingRecipe.java b/src/main/java/nova/core/recipes/crafting/CraftingRecipe.java index 5703176f4..d0f72233f 100755 --- a/src/main/java/nova/core/recipes/crafting/CraftingRecipe.java +++ b/src/main/java/nova/core/recipes/crafting/CraftingRecipe.java @@ -22,6 +22,7 @@ import nova.core.item.Item; import nova.core.recipes.Recipe; +import nova.core.util.id.Identifier; import java.util.Collection; import java.util.Optional; @@ -73,7 +74,7 @@ public interface CraftingRecipe extends Recipe { * * @return The items */ - default Optional> getPossibleItemsInFirstSlot() { + default Optional> getPossibleItemsInFirstSlot() { return Optional.empty(); } } diff --git a/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java b/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java index 4587cbc5d..925d35bff 100644 --- a/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java +++ b/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java @@ -41,7 +41,7 @@ public class CraftingRecipeManager { // TODO switch this to using Identifiers private final RecipeManager recipeManager; private final List dynamicRecipes; - private final Multimap staticRecipes; + private final Multimap staticRecipes; public CraftingRecipeManager(RecipeManager recipeManager) { this.recipeManager = recipeManager; @@ -88,7 +88,7 @@ public Optional getRecipe(CraftingGrid grid) { return Optional.empty(); } - String firstItemId = firstItem.get().getID().asString(); // TODO (this is BAD) + Identifier firstItemId = firstItem.get().getID(); if (!staticRecipes.containsKey(firstItemId)) { return Optional.empty(); } @@ -107,9 +107,9 @@ public Optional getRecipe(CraftingGrid grid) { // ####################### private void onCraftingRecipeAdded(RecipeAddedEvent e) { - Optional> possibleFirstItemIds = e.getRecipe().getPossibleItemsInFirstSlot(); + Optional> possibleFirstItemIds = e.getRecipe().getPossibleItemsInFirstSlot(); if (possibleFirstItemIds.isPresent()) { - for (String itemId : possibleFirstItemIds.get()) { + for (Identifier itemId : possibleFirstItemIds.get()) { staticRecipes.put(itemId, e.getRecipe()); } } else { @@ -118,9 +118,9 @@ private void onCraftingRecipeAdded(RecipeAddedEvent void onCraftingRecipeRemoved(RecipeRemovedEvent e) { - Optional> possibleFirstItemIds = e.getRecipe().getPossibleItemsInFirstSlot(); + Optional> possibleFirstItemIds = e.getRecipe().getPossibleItemsInFirstSlot(); if (possibleFirstItemIds.isPresent()) { - for (String itemId : possibleFirstItemIds.get()) { + for (Identifier itemId : possibleFirstItemIds.get()) { staticRecipes.remove(itemId, e.getRecipe()); } } else { diff --git a/src/main/java/nova/core/recipes/crafting/ItemIngredient.java b/src/main/java/nova/core/recipes/crafting/ItemIngredient.java index 5aa41d22e..90c8cbb58 100755 --- a/src/main/java/nova/core/recipes/crafting/ItemIngredient.java +++ b/src/main/java/nova/core/recipes/crafting/ItemIngredient.java @@ -21,6 +21,8 @@ package nova.core.recipes.crafting; import nova.core.item.Item; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; import java.util.Collection; import java.util.Optional; @@ -31,14 +33,14 @@ * * @author Stan Hebben */ -public interface ItemIngredient { +public interface ItemIngredient extends Identifiable { /** * Retrieves an ingredient to represent a specific item. * * @param itemId item ID * @return ingredient */ - static ItemIngredient forItem(String itemId) { + static ItemIngredient forItem(Identifier itemId) { return new SpecificItemIngredient(itemId); } @@ -58,7 +60,7 @@ static ItemIngredient forDictionary(String id) { * * @return possible items */ - Optional> getPossibleItemIds(); + Optional> getPossibleItemIDs(); /** * Returns a list of example items. This list could be used to render diff --git a/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java b/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java index 52d3a473c..2bf56d8fa 100644 --- a/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java +++ b/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java @@ -22,6 +22,7 @@ import nova.core.item.Item; import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import nova.internal.core.Game; import java.util.ArrayList; @@ -41,13 +42,14 @@ public OreItemIngredient(String name) { this.name = name; } - public String getName() { - return name; + @Override + public StringIdentifier getID() { + return new StringIdentifier(name); } @Override - public Optional> getPossibleItemIds() { - return Optional.of(Game.itemDictionary().get(name).stream().map(Item::getID).map(Identifier::asString).collect(Collectors.toList())); // TODO? + public Optional> getPossibleItemIDs() { + return Optional.of(Game.itemDictionary().get(name).stream().map(Item::getID).collect(Collectors.toList())); } @Override diff --git a/src/main/java/nova/core/recipes/crafting/ShapedCraftingRecipe.java b/src/main/java/nova/core/recipes/crafting/ShapedCraftingRecipe.java index dfd095fc8..4bdfb0e3a 100755 --- a/src/main/java/nova/core/recipes/crafting/ShapedCraftingRecipe.java +++ b/src/main/java/nova/core/recipes/crafting/ShapedCraftingRecipe.java @@ -21,6 +21,7 @@ package nova.core.recipes.crafting; import nova.core.item.Item; +import nova.core.util.id.Identifier; import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; import java.util.Collection; @@ -270,24 +271,24 @@ public void consumeItems(CraftingGrid craftingGrid) { } @Override - public Optional> getPossibleItemsInFirstSlot() { + public Optional> getPossibleItemsInFirstSlot() { if (isMirrored()) { - Optional> optionsForFirstItem = ingredients[0].getPossibleItemIds(); + Optional> optionsForFirstItem = ingredients[0].getPossibleItemIDs(); if (!optionsForFirstItem.isPresent()) { return Optional.empty(); } - Optional> optionsForSecondItem = ingredients[lastIngredientIndexOnFirstLine].getPossibleItemIds(); + Optional> optionsForSecondItem = ingredients[lastIngredientIndexOnFirstLine].getPossibleItemIDs(); if (!optionsForSecondItem.isPresent()) { return Optional.empty(); } - Set result = new HashSet<>(); + Set result = new HashSet<>(); result.addAll(optionsForFirstItem.get()); result.addAll(optionsForSecondItem.get()); return Optional.of(result); } else { - return ingredients[0].getPossibleItemIds(); + return ingredients[0].getPossibleItemIDs(); } } diff --git a/src/main/java/nova/core/recipes/crafting/SpecificItemIngredient.java b/src/main/java/nova/core/recipes/crafting/SpecificItemIngredient.java index d3b2330ca..2a2c0cf69 100644 --- a/src/main/java/nova/core/recipes/crafting/SpecificItemIngredient.java +++ b/src/main/java/nova/core/recipes/crafting/SpecificItemIngredient.java @@ -21,6 +21,7 @@ import nova.core.item.Item; import nova.core.item.ItemFactory; import nova.core.util.exception.RegistrationException; +import nova.core.util.id.Identifier; import nova.internal.core.Game; import java.util.Collection; @@ -32,18 +33,19 @@ * @author Stan Hebben */ public class SpecificItemIngredient implements ItemIngredient { - private final String itemId; + private final Identifier itemId; - public SpecificItemIngredient(String itemId) { + public SpecificItemIngredient(Identifier itemId) { this.itemId = itemId; } - public String getItemId() { + @Override + public Identifier getID() { return itemId; } @Override - public Optional> getPossibleItemIds() { + public Optional> getPossibleItemIDs() { return Optional.of(Collections.singleton(itemId)); } @@ -74,21 +76,9 @@ public Item consumeOnCrafting(Item original, CraftingGrid craftingGrid) { @Override public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o == null || getClass() != o.getClass()) { - return false; - } - - SpecificItemIngredient that = (SpecificItemIngredient) o; - - if (!itemId.equals(that.itemId)) { - return false; - } - - return true; + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + return itemId.equals(((SpecificItemIngredient) o).itemId); } @Override @@ -96,7 +86,7 @@ public int hashCode() { return itemId.hashCode(); } - private Item getItem(String itemId) { + private Item getItem(Identifier itemId) { Optional itemFactory = Game.items().get(itemId); if (itemFactory.isPresent()) { diff --git a/src/main/java/nova/core/render/RenderManager.java b/src/main/java/nova/core/render/RenderManager.java index 4098a8c87..c25f6b8eb 100644 --- a/src/main/java/nova/core/render/RenderManager.java +++ b/src/main/java/nova/core/render/RenderManager.java @@ -43,7 +43,7 @@ public abstract class RenderManager extends Manager { public final Registry modelProviders = new Registry<>(); public ItemTexture registerTexture(ItemTexture texture) { - Optional itemTexture = itemTextures.get(texture.getID().asString()); // TODO? + Optional itemTexture = itemTextures.get(texture.getID()); if (itemTexture.isPresent()) { Game.logger().error("Attempt to register the same texture twice: " + texture); return itemTexture.get(); @@ -53,7 +53,7 @@ public ItemTexture registerTexture(ItemTexture texture) { } public BlockTexture registerTexture(BlockTexture texture) { - Optional blockTexture = blockTextures.get(texture.getID().asString()); // TODO? + Optional blockTexture = blockTextures.get(texture.getID()); if (blockTexture.isPresent()) { Game.logger().error("Attempt to register the same texture twice: " + texture); return blockTexture.get(); @@ -63,7 +63,7 @@ public BlockTexture registerTexture(BlockTexture texture) { } public EntityTexture registerTexture(EntityTexture texture) { - Optional entityTexture = entityTextures.get(texture.getID().asString()); // TODO? + Optional entityTexture = entityTextures.get(texture.getID()); if (entityTexture.isPresent()) { Game.logger().error("Attempt to register the same texture twice: " + texture); return entityTexture.get(); @@ -73,7 +73,7 @@ public EntityTexture registerTexture(EntityTexture texture) { } public ModelProvider registerModel(ModelProvider modelProvider) { - Optional modelProviderCheck = modelProviders.get(modelProvider.getID().asString()); // TODO? + Optional modelProviderCheck = modelProviders.get(modelProvider.getID()); if (modelProviderCheck.isPresent()) { Game.logger().error("Attempt to register the same model twice: " + modelProvider); return modelProviderCheck.get(); diff --git a/src/main/java/nova/core/util/id/Identifier.java b/src/main/java/nova/core/util/id/Identifier.java index c71666c9e..2e6fc0ff1 100644 --- a/src/main/java/nova/core/util/id/Identifier.java +++ b/src/main/java/nova/core/util/id/Identifier.java @@ -1,7 +1,7 @@ package nova.core.util.id; /** - * The interface for all identifiers. + * The interface for all identifiers. An Identifier must be immutable. *

* Implementations should override {@link Object#equals(Object)}, {@link Object#hashCode()} and {@link Object#toString()}. *

diff --git a/src/main/java/nova/core/util/registry/Factory.java b/src/main/java/nova/core/util/registry/Factory.java index 2034a3168..b4f9aadf7 100644 --- a/src/main/java/nova/core/util/registry/Factory.java +++ b/src/main/java/nova/core/util/registry/Factory.java @@ -36,7 +36,7 @@ */ public abstract class Factory, T extends Identifiable> implements Identifiable { //The ID of the factory - protected final String id; + protected final Identifier id; //The constructor function protected final Supplier constructor; @@ -53,13 +53,13 @@ public abstract class Factory, T extends Identifiable> i * @param constructor The construction function * @param processor The processor function */ - public Factory(String id, Supplier constructor, Function processor) { + public Factory(Identifier id, Supplier constructor, Function processor) { this.id = id; this.constructor = constructor; this.processor = processor; } - public Factory(String id, Supplier constructor) { + public Factory(Identifier id, Supplier constructor) { this(id, constructor, obj -> obj); } @@ -72,7 +72,7 @@ public S process(Function processor) { return selfConstructor(id, constructor, this.processor.compose(processor)); } - protected abstract S selfConstructor(String id, Supplier constructor, Function processor); + protected abstract S selfConstructor(Identifier id, Supplier constructor, Function processor); /** * @return A new instance of T based on the construction method @@ -82,6 +82,6 @@ public T build() { } public Identifier getID() { - return new StringIdentifier(id); + return id; } } diff --git a/src/main/java/nova/core/util/registry/FactoryManager.java b/src/main/java/nova/core/util/registry/FactoryManager.java index 8c2281833..549b4e752 100644 --- a/src/main/java/nova/core/util/registry/FactoryManager.java +++ b/src/main/java/nova/core/util/registry/FactoryManager.java @@ -21,6 +21,8 @@ package nova.core.util.registry; import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import java.util.Optional; import java.util.function.Supplier; @@ -40,11 +42,22 @@ public FactoryManager(Registry registry) { /** * Register a new object construction factory. * - * Note that you make use: register(BlockStone::new), passing a method reference. + * Note that you can use: register(id, BlockStone::new), passing a method reference. * @param constructor Instance supplier {@link Supplier} * @return The factory */ - public abstract F register(String id, Supplier constructor); + public F register(String id, Supplier constructor) { + return this.register(new StringIdentifier(id), constructor); + } + + /** + * Register a new object construction factory. + * + * Note that you can use: register(id, BlockStone::new), passing a method reference. + * @param constructor Instance supplier {@link Supplier} + * @return The factory + */ + public abstract F register(Identifier id, Supplier constructor); /** * Register a new object construction factory. @@ -61,7 +74,7 @@ public F register(F factory) { * @param name Registered name * @return The object */ - public Optional get(String name) { + public Optional get(Identifier name) { return registry.get(name); } } diff --git a/src/main/java/nova/core/util/registry/Registry.java b/src/main/java/nova/core/util/registry/Registry.java index 24e724416..52e20237d 100644 --- a/src/main/java/nova/core/util/registry/Registry.java +++ b/src/main/java/nova/core/util/registry/Registry.java @@ -33,8 +33,7 @@ * @param The object type */ public class Registry implements Iterable { - // TODO maybe index by Identifier? Could be nice when the game uses int IDs (e.g. very old versions of minecraft). - private final HashBiMap objects = HashBiMap.create(); + private final HashBiMap objects = HashBiMap.create(); public Registry() { @@ -47,7 +46,7 @@ public Registry() { * @return Given object */ public T register(T object) { - objects.put(object.getID().asString(), object); + objects.put(object.getID(), object); return object; } @@ -57,7 +56,7 @@ public T register(T object) { * @param ID the id to find. * @return true if the registry contains the object with the given ID. */ - public boolean contains(String ID) { + public boolean contains(Identifier ID) { return objects.containsKey(ID); } @@ -67,7 +66,7 @@ public boolean contains(String ID) { * @param ID the id to find. * @return the object found or empty Optional if not found. */ - public Optional get(String ID) { + public Optional get(Identifier ID) { return Optional.ofNullable(objects.get(ID)); } @@ -77,7 +76,7 @@ public Optional get(String ID) { * @param object the object to find. * @return the name of the object or empty Optional if not found. */ - public Optional getName(T object) { + public Optional getName(T object) { return Optional.ofNullable(objects.inverse().get(object)); } @@ -89,6 +88,7 @@ public Iterator iterator() { return objects.values().iterator(); } + @Override public Spliterator spliterator() { return objects.values().spliterator(); } diff --git a/src/main/java/nova/core/world/WorldFactory.java b/src/main/java/nova/core/world/WorldFactory.java index cf53aaf80..2ede5b5fe 100644 --- a/src/main/java/nova/core/world/WorldFactory.java +++ b/src/main/java/nova/core/world/WorldFactory.java @@ -20,6 +20,7 @@ package nova.core.world; +import nova.core.util.id.Identifier; import nova.core.util.registry.Factory; import java.util.function.Function; @@ -30,16 +31,16 @@ * @author Calclavia */ public class WorldFactory extends Factory { - public WorldFactory(String id, Supplier constructor, Function processor) { + public WorldFactory(Identifier id, Supplier constructor, Function processor) { super(id, constructor, processor); } - public WorldFactory(String id, Supplier constructor) { + public WorldFactory(Identifier id, Supplier constructor) { super(id, constructor); } @Override - protected WorldFactory selfConstructor(String id, Supplier constructor, Function processor) { + protected WorldFactory selfConstructor(Identifier id, Supplier constructor, Function processor) { return new WorldFactory(id, constructor, processor); } } diff --git a/src/main/java/nova/core/world/WorldManager.java b/src/main/java/nova/core/world/WorldManager.java index 1f2c4bd82..c038e49a9 100644 --- a/src/main/java/nova/core/world/WorldManager.java +++ b/src/main/java/nova/core/world/WorldManager.java @@ -22,6 +22,7 @@ import nova.core.event.WorldEvent; import nova.core.event.bus.GlobalEvents; +import nova.core.util.id.Identifier; import nova.core.util.registry.FactoryManager; import nova.core.util.registry.Registry; import nova.internal.core.Game; @@ -48,7 +49,7 @@ public WorldManager(Registry registry, GlobalEvents events) { } @Override - public WorldFactory register(String id, Supplier constructor) { + public WorldFactory register(Identifier id, Supplier constructor) { return register(new WorldFactory(id, constructor)); } diff --git a/src/test/java/nova/core/util/MockIdentifiable.java b/src/test/java/nova/core/util/MockIdentifiable.java index 33569e31c..10cd6b413 100644 --- a/src/test/java/nova/core/util/MockIdentifiable.java +++ b/src/test/java/nova/core/util/MockIdentifiable.java @@ -25,15 +25,15 @@ import nova.core.util.id.StringIdentifier; public class MockIdentifiable implements Identifiable { - String ID; + Identifier ID; - public MockIdentifiable(String ID) { + public MockIdentifiable(Identifier ID) { this.ID = ID; } @Override public Identifier getID() { - return new StringIdentifier(ID); + return ID; } @Override diff --git a/src/test/java/nova/core/util/RayTraceTest.java b/src/test/java/nova/core/util/RayTraceTest.java index 0815f904b..34d24771b 100755 --- a/src/test/java/nova/core/util/RayTraceTest.java +++ b/src/test/java/nova/core/util/RayTraceTest.java @@ -27,6 +27,7 @@ import nova.core.entity.EntityFactory; import nova.core.loader.Loadable; import nova.core.loader.Mod; +import nova.core.util.id.StringIdentifier; import nova.core.util.math.RotationUtil; import nova.internal.core.Game; import nova.internal.core.launch.NovaLauncher; @@ -145,7 +146,7 @@ public static class RayTraceMod implements Loadable { @Override public void preInit() { solid = Game.blocks().register( - "solid", + new StringIdentifier("solid"), () -> { Block solid = new Block(); solid.components.add(new Collider(solid)); @@ -153,7 +154,7 @@ public void preInit() { } ); - testEntity = Game.entities().register("test", Entity::new); + testEntity = Game.entities().register(new StringIdentifier("test"), Entity::new); } } } diff --git a/src/test/java/nova/core/util/RegistryTest.java b/src/test/java/nova/core/util/RegistryTest.java index 9e80a9313..56e067857 100644 --- a/src/test/java/nova/core/util/RegistryTest.java +++ b/src/test/java/nova/core/util/RegistryTest.java @@ -34,24 +34,24 @@ public void testRegistry() throws Exception { Registry registry = new Registry<>(); - Identifiable id1 = new MockIdentifiable("ID1"); - Identifiable id2 = new MockIdentifiable("ID2"); + Identifiable id1 = new MockIdentifiable(new StringIdentifier("ID1")); + Identifiable id2 = new MockIdentifiable(new StringIdentifier("ID2")); registry.register(id1); registry.register(id2); - assertThat(registry.contains("ID1")).isTrue(); - assertThat(registry.contains("ID2")).isTrue(); + assertThat(registry.contains(new StringIdentifier("ID1"))).isTrue(); + assertThat(registry.contains(new StringIdentifier("ID2"))).isTrue(); - assertThat(registry.get("ID1").get().getID()).isEqualTo(new StringIdentifier("ID1")); - assertThat(registry.get("ID2").get().getID()).isEqualTo(new StringIdentifier("ID2")); + assertThat(registry.get(new StringIdentifier("ID1")).get().getID()).isEqualTo(new StringIdentifier("ID1")); + assertThat(registry.get(new StringIdentifier("ID2")).get().getID()).isEqualTo(new StringIdentifier("ID2")); - assertThat(registry.get("ID1").get()).isEqualTo(id1); - assertThat(registry.get("ID2").get()).isEqualTo(id2); + assertThat(registry.get(new StringIdentifier("ID1")).get()).isEqualTo(id1); + assertThat(registry.get(new StringIdentifier("ID2")).get()).isEqualTo(id2); assertThat(registry.iterator()).containsOnly(id1, id2); - assertThat(registry.get("None").isPresent()).isFalse(); + assertThat(registry.get(new StringIdentifier("None")).isPresent()).isFalse(); } } diff --git a/src/test/java/nova/wrappertests/NovaLauncherTestFactory.java b/src/test/java/nova/wrappertests/NovaLauncherTestFactory.java index 131897439..2b509a753 100644 --- a/src/test/java/nova/wrappertests/NovaLauncherTestFactory.java +++ b/src/test/java/nova/wrappertests/NovaLauncherTestFactory.java @@ -22,6 +22,7 @@ import nova.core.block.Block; import nova.core.block.BlockFactory; +import nova.core.util.id.StringIdentifier; import nova.internal.core.Game; import nova.internal.core.bootstrap.DependencyInjectionEntryPoint; import nova.internal.core.launch.NovaLauncher; @@ -82,7 +83,7 @@ public NovaLauncher createLauncher() { /** * Register fake air block */ - Game.blocks().register(new BlockFactory("air", Block::new, evt -> {})); + Game.blocks().register(new BlockFactory(new StringIdentifier("air"), Block::new, evt -> {})); launcher.generateDependencies(); launcher.load(); From 3954e02608d641fa93c896d4ae4f78e6cc7247e1 Mon Sep 17 00:00:00 2001 From: ExE Boss Date: Sun, 8 Jan 2017 02:52:01 +0100 Subject: [PATCH 05/10] Write tests + Fix Identifier.equals + Create EnumIdentifier --- .../core/recipes/crafting/ItemIngredient.java | 23 ++++++++ .../nova/core/util/id/AbstractIdentifier.java | 2 +- .../nova/core/util/id/ClassIdentifier.java | 2 +- .../nova/core/util/id/EnumIdentifier.java | 28 +++++++++ .../java/nova/core/util/id/Identifier.java | 7 +-- .../util/id/NamespacedStringIdentifier.java | 11 ++-- .../nova/core/util/id/StringIdentifier.java | 2 +- .../nova/core/util/id/UUIDIdentifier.java | 2 +- src/test/java/nova/core/util/EnumExample.java | 21 +++++++ .../java/nova/core/util/EnumSelectorTest.java | 11 ---- .../nova/core/util/id/IdentifierTest.java | 58 +++++++++++++++++++ 11 files changed, 144 insertions(+), 23 deletions(-) create mode 100644 src/main/java/nova/core/util/id/EnumIdentifier.java create mode 100644 src/test/java/nova/core/util/EnumExample.java create mode 100644 src/test/java/nova/core/util/id/IdentifierTest.java diff --git a/src/main/java/nova/core/recipes/crafting/ItemIngredient.java b/src/main/java/nova/core/recipes/crafting/ItemIngredient.java index 90c8cbb58..fbacb0097 100755 --- a/src/main/java/nova/core/recipes/crafting/ItemIngredient.java +++ b/src/main/java/nova/core/recipes/crafting/ItemIngredient.java @@ -20,7 +20,9 @@ package nova.core.recipes.crafting; +import nova.core.block.BlockFactory; import nova.core.item.Item; +import nova.core.item.ItemFactory; import nova.core.util.id.Identifiable; import nova.core.util.id.Identifier; @@ -34,6 +36,27 @@ * @author Stan Hebben */ public interface ItemIngredient extends Identifiable { + + /** + * Retrieves an ingredient to represent a specific item. + * + * @param item The item + * @return ingredient + */ + static ItemIngredient forBlock(BlockFactory block) { + return new SpecificItemIngredient(block.getID()); + } + + /** + * Retrieves an ingredient to represent a specific item. + * + * @param item The item + * @return ingredient + */ + static ItemIngredient forItem(ItemFactory item) { + return new SpecificItemIngredient(item.getID()); + } + /** * Retrieves an ingredient to represent a specific item. * diff --git a/src/main/java/nova/core/util/id/AbstractIdentifier.java b/src/main/java/nova/core/util/id/AbstractIdentifier.java index b625d49fd..d5e3111fc 100644 --- a/src/main/java/nova/core/util/id/AbstractIdentifier.java +++ b/src/main/java/nova/core/util/id/AbstractIdentifier.java @@ -44,7 +44,7 @@ public int hashCode() { protected static final boolean equalsImpl(Identifier _this, Object other, Class superclass, Function getter) { if (_this == other) return true; if (_this == null || other == null) return false; - if (!_this.getClass().isAssignableFrom(superclass) || !other.getClass().isAssignableFrom(superclass)) return false; + if (!superclass.isAssignableFrom(_this.getClass()) || !superclass.isAssignableFrom(other.getClass())) return false; return Objects.equals(getter.apply((T)_this), getter.apply((T)other)); } } diff --git a/src/main/java/nova/core/util/id/ClassIdentifier.java b/src/main/java/nova/core/util/id/ClassIdentifier.java index 5ef75d809..c17731a1d 100644 --- a/src/main/java/nova/core/util/id/ClassIdentifier.java +++ b/src/main/java/nova/core/util/id/ClassIdentifier.java @@ -34,6 +34,6 @@ public Class asClass() { @Override public boolean equals(Object other) { - return equalsImpl(this, other, ClassIdentifier.class, id -> id.asClass()); + return equalsImpl(this, other, ClassIdentifier.class, ClassIdentifier::asClass); } } diff --git a/src/main/java/nova/core/util/id/EnumIdentifier.java b/src/main/java/nova/core/util/id/EnumIdentifier.java new file mode 100644 index 000000000..0d2ce7f1d --- /dev/null +++ b/src/main/java/nova/core/util/id/EnumIdentifier.java @@ -0,0 +1,28 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package nova.core.util.id; + +import java.util.Objects; + +/** + * + * @author ExE Boss + */ +public class EnumIdentifier> extends AbstractIdentifier { + + public EnumIdentifier(E id) { + super(id); + } + + public E asEnum() { + return id; + } + + @Override + public boolean equals(Object other) { + return equalsImpl(this, other, EnumIdentifier.class, EnumIdentifier::asEnum); + } +} diff --git a/src/main/java/nova/core/util/id/Identifier.java b/src/main/java/nova/core/util/id/Identifier.java index 2e6fc0ff1..f959ade9f 100644 --- a/src/main/java/nova/core/util/id/Identifier.java +++ b/src/main/java/nova/core/util/id/Identifier.java @@ -1,12 +1,11 @@ package nova.core.util.id; /** - * The interface for all identifiers. An Identifier must be immutable. - *

+ * The interface for all identifiers. The Identifier must be immutable. + *

* Implementations should override {@link Object#equals(Object)}, {@link Object#hashCode()} and {@link Object#toString()}. - *

* - * @author soniex2 + * @author SoniEx2, ExE Boss */ public interface Identifier { diff --git a/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java b/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java index d5246fb27..8862de900 100644 --- a/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java +++ b/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java @@ -14,9 +14,12 @@ public class NamespacedStringIdentifier extends StringIdentifier { protected final String domain; - public NamespacedStringIdentifier(String id) { - super(id.substring(id.indexOf(':') + 1)); - this.domain = (id.contains(":") ? id.substring(0, id.indexOf(':')) : "nova"); + public NamespacedStringIdentifier(final String id) { + super(id == null ? null : id.substring(id.indexOf(':') + 1)); + if (id != null) + this.domain = (id.contains(":") ? id.substring(0, id.indexOf(':')) : null); + else + this.domain = null; } public NamespacedStringIdentifier(String domain, String id) { @@ -34,6 +37,6 @@ public String getId() { @Override public String asString() { - return domain + ':' + id; + return (domain == null ? id : (domain + ':' + id)); } } diff --git a/src/main/java/nova/core/util/id/StringIdentifier.java b/src/main/java/nova/core/util/id/StringIdentifier.java index 424d6780e..74ea3c223 100644 --- a/src/main/java/nova/core/util/id/StringIdentifier.java +++ b/src/main/java/nova/core/util/id/StringIdentifier.java @@ -20,6 +20,6 @@ public StringIdentifier(String id) { @Override public boolean equals(Object other) { - return equalsImpl(this, other, StringIdentifier.class, id -> id.asString()); + return equalsImpl(this, other, StringIdentifier.class, Identifier::asString); } } diff --git a/src/main/java/nova/core/util/id/UUIDIdentifier.java b/src/main/java/nova/core/util/id/UUIDIdentifier.java index 8ce727f92..6c7431711 100644 --- a/src/main/java/nova/core/util/id/UUIDIdentifier.java +++ b/src/main/java/nova/core/util/id/UUIDIdentifier.java @@ -30,6 +30,6 @@ public UUID asUUID() { @Override public boolean equals(Object other) { - return equalsImpl(this, other, UUIDIdentifier.class, id -> id.asUUID()); + return equalsImpl(this, other, UUIDIdentifier.class, UUIDIdentifier::asUUID); } } diff --git a/src/test/java/nova/core/util/EnumExample.java b/src/test/java/nova/core/util/EnumExample.java new file mode 100644 index 000000000..899c3367c --- /dev/null +++ b/src/test/java/nova/core/util/EnumExample.java @@ -0,0 +1,21 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package nova.core.util; + +/** + * @author ExE Boss + */ +public enum EnumExample { + EXAMPLE_8, + EXAMPLE_16, + EXAMPLE_24, + EXAMPLE_32, + EXAMPLE_48, + EXAMPLE_64, + + EXAMPLE_42; +} diff --git a/src/test/java/nova/core/util/EnumSelectorTest.java b/src/test/java/nova/core/util/EnumSelectorTest.java index 6434770df..372c0b1d3 100644 --- a/src/test/java/nova/core/util/EnumSelectorTest.java +++ b/src/test/java/nova/core/util/EnumSelectorTest.java @@ -336,15 +336,4 @@ public void testCannotAllowBlocking() { } assertThat(result).isNotNull(); } - - public static enum EnumExample { - EXAMPLE_8, - EXAMPLE_16, - EXAMPLE_24, - EXAMPLE_32, - EXAMPLE_48, - EXAMPLE_64, - - EXAMPLE_42; - } } diff --git a/src/test/java/nova/core/util/id/IdentifierTest.java b/src/test/java/nova/core/util/id/IdentifierTest.java new file mode 100644 index 000000000..9842ab3dd --- /dev/null +++ b/src/test/java/nova/core/util/id/IdentifierTest.java @@ -0,0 +1,58 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package nova.core.util.id; + +import nova.core.util.EnumExample; +import org.junit.Test; + +import java.util.UUID; + +import static nova.testutils.NovaAssertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * + * @author ExE Boss + */ +public class IdentifierTest { + + @Test + public void stringEquals() { + StringIdentifier str = new StringIdentifier("not_namespaced"); + StringIdentifier namespaced1 = new StringIdentifier("nova:namespaced"); + NamespacedStringIdentifier namespaced2 = new NamespacedStringIdentifier("nova", "namespaced"); + + assertThat(str.asString()).isEqualTo("not_namespaced"); + assertThat(namespaced1).isEqualTo(namespaced2); + } + + @Test + public void classEquals() { + ClassIdentifier clazz = new ClassIdentifier(IdentifierTest.class); + + assertThat(clazz.asClass()).isEqualTo(IdentifierTest.class); + assertThat(clazz.asString()).isEqualTo(IdentifierTest.class.getSimpleName()); + assertThat(clazz).isEqualTo(new ClassIdentifier(IdentifierTest.class)); + } + + @Test + public void uuidEquals() { + UUIDIdentifier uuid = new UUIDIdentifier(new UUID(0, 0)); + + assertThat(uuid.asUUID()).isEqualTo(new UUID(0, 0)); + assertThat(uuid.asString()).isEqualTo(new UUID(0, 0).toString()); + assertThat(uuid).isEqualTo(new UUIDIdentifier(new UUID(0, 0))); + } + + @Test + public void enumEquals() { + EnumIdentifier enumIdentifier = new EnumIdentifier<>(EnumExample.EXAMPLE_42); + + assertThat(enumIdentifier.asEnum()).isEqualTo(EnumExample.EXAMPLE_42); + assertThat(enumIdentifier.asString()).isEqualTo(EnumExample.EXAMPLE_42.toString()); + assertThat(enumIdentifier).isEqualTo(new EnumIdentifier<>(EnumExample.EXAMPLE_42)); + } +} From 9e3d76acd6fa8cdc28b542cc0f0bbb4a5257e325 Mon Sep 17 00:00:00 2001 From: ExE Boss Date: Sun, 8 Jan 2017 03:04:36 +0100 Subject: [PATCH 06/10] Make it possible to store Identifiers in Data + Write tests --- src/main/java/nova/core/retention/Data.java | 18 ++++ .../nova/core/util/id/ClassIdentifier.java | 29 +++++++ .../nova/core/util/id/EnumIdentifier.java | 29 +++++++ .../nova/core/util/id/IdentifierLoader.java | 40 +++++++++ .../nova/core/util/id/IdentifierRegistry.java | 83 +++++++++++++++++++ .../util/id/NamespacedStringIdentifier.java | 2 + .../nova/core/util/id/NoSuchIDException.java | 34 ++++++++ .../nova/core/util/id/StringIdentifier.java | 24 ++++++ .../nova/core/util/id/UUIDIdentifier.java | 24 ++++++ .../nova/core/util/registry/Registry.java | 4 + .../nova/core/retention/StorableTest.java | 31 +++++++ .../core/util/id/IdentifierRegistryTest.java | 56 +++++++++++++ .../nova/core/util/id/IdentifierTest.java | 2 - 13 files changed, 374 insertions(+), 2 deletions(-) create mode 100644 src/main/java/nova/core/util/id/IdentifierLoader.java create mode 100644 src/main/java/nova/core/util/id/IdentifierRegistry.java create mode 100644 src/main/java/nova/core/util/id/NoSuchIDException.java create mode 100644 src/test/java/nova/core/util/id/IdentifierRegistryTest.java diff --git a/src/main/java/nova/core/retention/Data.java b/src/main/java/nova/core/retention/Data.java index f3e2cea52..7ca2e9a46 100755 --- a/src/main/java/nova/core/retention/Data.java +++ b/src/main/java/nova/core/retention/Data.java @@ -20,10 +20,13 @@ package nova.core.retention; +import nova.core.util.id.Identifier; +import nova.core.util.id.IdentifierRegistry; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; import java.util.*; +import java.util.function.Consumer; /** * The data class is capable of storing named data. @@ -58,6 +61,7 @@ public class Data extends HashMap { Double.class, String.class, //Special data types that all convert into Data. + Identifier.class, Enum.class, Storable.class, Data.class, @@ -176,6 +180,10 @@ public Object put(String key, Object value) { Data classData = new Data(Class.class); classData.put("name", ((Class) value).getName()); value = classData; + } else if (value instanceof Identifier) { + Data identifierData = new Data(Identifier.class); + IdentifierRegistry.instance().save(identifierData, (Identifier) value); + value = identifierData; } else if (value instanceof Storable) { value = serialize((Storable) value); } @@ -212,6 +220,16 @@ public Vector2D getVector2D(String key) { return new Vector2D(data.get("x"), (double) data.get("y")); } + @SuppressWarnings("unchecked") + public T getIdentifier(String key) { + Data storableData = get(key); + try { + return (T) IdentifierRegistry.instance().load(storableData); + } catch (Exception e) { + throw new DataException(e); + } + } + public T getStorable(String key) { Data storableData = get(key); try { diff --git a/src/main/java/nova/core/util/id/ClassIdentifier.java b/src/main/java/nova/core/util/id/ClassIdentifier.java index c17731a1d..a082b7a21 100644 --- a/src/main/java/nova/core/util/id/ClassIdentifier.java +++ b/src/main/java/nova/core/util/id/ClassIdentifier.java @@ -1,5 +1,8 @@ package nova.core.util.id; +import nova.core.retention.Data; +import nova.core.retention.DataException; + import java.util.Objects; /** @@ -36,4 +39,30 @@ public Class asClass() { public boolean equals(Object other) { return equalsImpl(this, other, ClassIdentifier.class, ClassIdentifier::asClass); } + + public static class Loader extends IdentifierLoader { + + public Loader(String id) { + super(id); + } + + @Override + public Class getIdentifierClass() { + return ClassIdentifier.class; + } + + @Override + public void save(Data data, ClassIdentifier identifier) { + data.put("id", identifier.id.getName()); + } + + @Override + public ClassIdentifier load(Data data) { + try { + return new ClassIdentifier(Class.forName(data.get("id"))); + } catch (ClassNotFoundException ex) { + throw new DataException(ex); + } + } + } } diff --git a/src/main/java/nova/core/util/id/EnumIdentifier.java b/src/main/java/nova/core/util/id/EnumIdentifier.java index 0d2ce7f1d..35f672d28 100644 --- a/src/main/java/nova/core/util/id/EnumIdentifier.java +++ b/src/main/java/nova/core/util/id/EnumIdentifier.java @@ -5,6 +5,8 @@ */ package nova.core.util.id; +import nova.core.retention.Data; + import java.util.Objects; /** @@ -25,4 +27,31 @@ public E asEnum() { public boolean equals(Object other) { return equalsImpl(this, other, EnumIdentifier.class, EnumIdentifier::asEnum); } + + public static class Loader extends IdentifierLoader> { + + public Loader(String id) { + super(id); + } + + @Override + public Class> getIdentifierClass() { + return cast(EnumIdentifier.class); + } + + @Override + public void save(Data data, EnumIdentifier identifier) { + data.put("id", identifier.asEnum()); + } + + @Override + public EnumIdentifier load(Data data) { + return new EnumIdentifier(data.getEnum("id")); + } + + @SuppressWarnings("unchecked") + private T cast(Object o) { + return (T) o; + } + } } diff --git a/src/main/java/nova/core/util/id/IdentifierLoader.java b/src/main/java/nova/core/util/id/IdentifierLoader.java new file mode 100644 index 000000000..76d24e9e6 --- /dev/null +++ b/src/main/java/nova/core/util/id/IdentifierLoader.java @@ -0,0 +1,40 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package nova.core.util.id; + +import nova.core.retention.Data; + +/** + * Class used to load identifiers. + * + * @author ExE Boss + * @param The Identifier class + * @param The Identifier type + * @see Identifier + * @see IdentifierRegistry + */ +public abstract class IdentifierLoader implements Identifiable { + + protected final String id; + + /** + * @param id The ID of the Identifier to load. MUST be a string, as we will use this to determine the type. + */ + public IdentifierLoader(String id) { + this.id = id; + } + + public abstract Class getIdentifierClass(); + + public abstract void save(Data data, T identifier); + + public abstract T load(Data data); + + @Override + public final StringIdentifier getID() { + return new StringIdentifier(id); + } +} diff --git a/src/main/java/nova/core/util/id/IdentifierRegistry.java b/src/main/java/nova/core/util/id/IdentifierRegistry.java new file mode 100644 index 000000000..d8b3ab265 --- /dev/null +++ b/src/main/java/nova/core/util/id/IdentifierRegistry.java @@ -0,0 +1,83 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package nova.core.util.id; + +import nova.core.retention.Data; +import nova.core.util.registry.Registry; + +import java.util.Optional; + +/** + * Used to handle loading and saving of identifiers. + * + * @author ExE Boss + */ +public final class IdentifierRegistry extends Registry> { + private static IdentifierRegistry instance; + + private IdentifierRegistry() { + register(new StringIdentifier.Loader("String")); + register(new ClassIdentifier.Loader("Class")); + register(new UUIDIdentifier.Loader("UUID")); + register(new EnumIdentifier.Loader("Enum")); + } + + /** + * Returns the IdentifierRegistry instance. + * + * @return The IdentifierRegistry instance. + */ + public static IdentifierRegistry instance() { + if (instance == null) + instance = new IdentifierRegistry(); + + return instance; + } + + /** + * Loads an Identifier. + * + * @param data The data to load from. + * @return The Identifier instance. + */ + public Identifier load(Data data) { + assert data != null; + StringIdentifier id = new StringIdentifier(data.get("type")); + if (!contains(id)) + throw new NoSuchIDException("No Identifier class found for type: " + id); + return get(id).get().load(data); + } + + /** + * Saves an Identifier. + * + * @param data The data to save to. + * @param identifier The Identifier instance. + */ + public void save(Data data, Identifier identifier) { + final Class clazz = identifier.getClass(); + IdentifierLoader loader = stream().filter(l -> l.getIdentifierClass().equals(clazz)).findFirst() + .orElse(stream().filter(l -> l.getIdentifierClass().isAssignableFrom(clazz)).findFirst() + .orElseThrow(() -> new NoSuchIDException("No IdentifierLoader found for class: " + clazz.getSimpleName()))); + loader.save(data, cast(identifier)); + data.put("type", loader.getID().asString()); + } + + @SuppressWarnings("unchecked") + private T cast(Object o) { + return (T) o; + } + + /** + * Registers an IdentifierLoader for the given ID. + * + * @param loader The loader which will handle saving and loading of the identifier. + */ + @Override + public IdentifierLoader register(IdentifierLoader loader) { + return super.register(loader); + } +} diff --git a/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java b/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java index 8862de900..11e010544 100644 --- a/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java +++ b/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java @@ -5,6 +5,8 @@ */ package nova.core.util.id; +import nova.core.retention.Data; + /** * A Namespaced String Identifier. * diff --git a/src/main/java/nova/core/util/id/NoSuchIDException.java b/src/main/java/nova/core/util/id/NoSuchIDException.java new file mode 100644 index 000000000..6c6a95f1a --- /dev/null +++ b/src/main/java/nova/core/util/id/NoSuchIDException.java @@ -0,0 +1,34 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package nova.core.util.id; + +import nova.core.util.exception.NovaException; + +/** + * @author ExE Boss + */ +public class NoSuchIDException extends NovaException { + private static final long serialVersionUID = 2017_01_08L; + + public NoSuchIDException() { + } + + public NoSuchIDException(String message, Object... parameters) { + super(message, parameters); + } + + public NoSuchIDException(String message) { + super(message); + } + + public NoSuchIDException(String message, Throwable cause) { + super(message, cause); + } + + public NoSuchIDException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/nova/core/util/id/StringIdentifier.java b/src/main/java/nova/core/util/id/StringIdentifier.java index 74ea3c223..4e750c56c 100644 --- a/src/main/java/nova/core/util/id/StringIdentifier.java +++ b/src/main/java/nova/core/util/id/StringIdentifier.java @@ -1,5 +1,7 @@ package nova.core.util.id; +import nova.core.retention.Data; + import java.util.Objects; /** @@ -22,4 +24,26 @@ public StringIdentifier(String id) { public boolean equals(Object other) { return equalsImpl(this, other, StringIdentifier.class, Identifier::asString); } + + public static class Loader extends IdentifierLoader { + + public Loader(String id) { + super(id); + } + + @Override + public Class getIdentifierClass() { + return StringIdentifier.class; + } + + @Override + public void save(Data data, StringIdentifier identifier) { + data.put("id", identifier.asString()); + } + + @Override + public StringIdentifier load(Data data) { + return new StringIdentifier(data.get("id")); + } + } } diff --git a/src/main/java/nova/core/util/id/UUIDIdentifier.java b/src/main/java/nova/core/util/id/UUIDIdentifier.java index 6c7431711..76a28430b 100644 --- a/src/main/java/nova/core/util/id/UUIDIdentifier.java +++ b/src/main/java/nova/core/util/id/UUIDIdentifier.java @@ -1,5 +1,7 @@ package nova.core.util.id; +import nova.core.retention.Data; + import java.util.Objects; import java.util.UUID; @@ -32,4 +34,26 @@ public UUID asUUID() { public boolean equals(Object other) { return equalsImpl(this, other, UUIDIdentifier.class, UUIDIdentifier::asUUID); } + + public static class Loader extends IdentifierLoader { + + public Loader(String id) { + super(id); + } + + @Override + public Class getIdentifierClass() { + return UUIDIdentifier.class; + } + + @Override + public void save(Data data, UUIDIdentifier identifier) { + data.put("id", identifier.asString()); + } + + @Override + public UUIDIdentifier load(Data data) { + return new UUIDIdentifier(UUID.fromString(data.get("id"))); + } + } } diff --git a/src/main/java/nova/core/util/registry/Registry.java b/src/main/java/nova/core/util/registry/Registry.java index 52e20237d..c225cc520 100644 --- a/src/main/java/nova/core/util/registry/Registry.java +++ b/src/main/java/nova/core/util/registry/Registry.java @@ -96,4 +96,8 @@ public Spliterator spliterator() { public Stream stream() { return objects.values().stream(); } + + public Stream parallelStream() { + return objects.values().parallelStream(); + } } diff --git a/src/test/java/nova/core/retention/StorableTest.java b/src/test/java/nova/core/retention/StorableTest.java index 23ea1d444..eccd8a98e 100755 --- a/src/test/java/nova/core/retention/StorableTest.java +++ b/src/test/java/nova/core/retention/StorableTest.java @@ -22,6 +22,8 @@ import org.junit.Test; +import java.util.function.Consumer; + import static nova.testutils.NovaAssertions.assertThat; @@ -117,4 +119,33 @@ class TestCase implements Storable { assertThat(test.integer).isEqualTo(256); assertThat(test.string).isEqualTo("test"); } + + /** + * Prints the contents of Data to the console. + * + * @param data The data to print. + * @param print The method to use. Should insert a newline after every call. (eg. {@link java.io.PrintStream#println()}) + */ + public static void printData(Data data, Consumer print) { + System.out.println("Data:"); + printData(data, 0, print); + } + + private static void printData(Data data, int index, Consumer print) { + data.forEach((str, obj) -> { + if (obj instanceof Data) { + print.accept(prepend("- " + str + ":", index)); + printData((Data)obj, index + 1, print); + } else + print.accept(prepend("- " + str + ": " + obj, index)); + }); + } + + private static String prepend(String str, int index) { + StringBuilder sb = new StringBuilder(str.length() + index * 2); + for (int i = 0; i < index; i++) + sb.append(" "); + sb.append(str); + return sb.toString(); + } } diff --git a/src/test/java/nova/core/util/id/IdentifierRegistryTest.java b/src/test/java/nova/core/util/id/IdentifierRegistryTest.java new file mode 100644 index 000000000..2641047e8 --- /dev/null +++ b/src/test/java/nova/core/util/id/IdentifierRegistryTest.java @@ -0,0 +1,56 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package nova.core.util.id; + +import nova.core.retention.Data; +import nova.core.retention.StorableTest; +import nova.core.util.EnumExample; +import org.junit.Before; +import org.junit.Test; + +import java.util.UUID; +import java.util.function.Consumer; + +import static nova.testutils.NovaAssertions.assertThat; + +/** + * @author ExE Boss + */ +public class IdentifierRegistryTest { + + Data data; + + @Before + public void setUp() { + data = new Data(); + } + + @Test + public void testInstance() { + assertThat(IdentifierRegistry.instance()).isExactlyInstanceOf(IdentifierRegistry.class); + } + + @Test + public void testSaveAndLoad() { + data.put("StringTest", new StringIdentifier("not_namespaced")); + data.put("NamespacedStringTest", new NamespacedStringIdentifier("nova:namespaced")); + data.put("ClassTest", new ClassIdentifier(ClassIdentifier.class)); + data.put("UUIDTest", new UUIDIdentifier(new UUID(0, 0))); + data.put("EnumTest", new EnumIdentifier<>(EnumExample.EXAMPLE_42)); + + StorableTest.printData(data, System.out::println); + System.out.println(); + printIdentifier(data.getIdentifier("StringTest"), System.out::println); + printIdentifier(data.getIdentifier("NamespacedStringTest"), System.out::println); + printIdentifier(data.getIdentifier("ClassTest"), System.out::println); + printIdentifier(data.getIdentifier("UUIDTest"), System.out::println); + printIdentifier(data.getIdentifier("EnumTest"), System.out::println); + } + + private static void printIdentifier(Identifier identifier, Consumer print) { + print.accept(identifier.getClass() + ": " + identifier.asString()); + } +} diff --git a/src/test/java/nova/core/util/id/IdentifierTest.java b/src/test/java/nova/core/util/id/IdentifierTest.java index 9842ab3dd..6ded4bda6 100644 --- a/src/test/java/nova/core/util/id/IdentifierTest.java +++ b/src/test/java/nova/core/util/id/IdentifierTest.java @@ -11,10 +11,8 @@ import java.util.UUID; import static nova.testutils.NovaAssertions.assertThat; -import static org.assertj.core.api.Assertions.assertThat; /** - * * @author ExE Boss */ public class IdentifierTest { From fe9c0a9bd9734b979b3f9ae85519e401fad9fa25 Mon Sep 17 00:00:00 2001 From: ExE Boss Date: Sun, 8 Jan 2017 05:38:31 +0100 Subject: [PATCH 07/10] Improve the way Identifiers are stored + Allow serialization to string and back --- .../forge/v17/wrapper/data/DataWrapper.java | 8 +-- .../forge/v18/wrapper/data/DataWrapper.java | 8 +-- src/main/java/nova/core/retention/Data.java | 67 ++++++++++++++++--- .../nova/core/util/id/ClassIdentifier.java | 14 ++++ .../nova/core/util/id/EnumIdentifier.java | 37 ++++++++-- .../java/nova/core/util/id/Identifier.java | 10 +++ .../nova/core/util/id/IdentifierLoader.java | 12 ++++ .../nova/core/util/id/IdentifierRegistry.java | 42 +++++++++++- .../nova/core/util/id/StringIdentifier.java | 5 ++ .../nova/core/util/id/UUIDIdentifier.java | 5 ++ .../nova/core/util/id/IdentifierTest.java | 6 +- 11 files changed, 188 insertions(+), 26 deletions(-) diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/data/DataWrapper.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/data/DataWrapper.java index 592c51cff..e431626b7 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/data/DataWrapper.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/data/DataWrapper.java @@ -63,7 +63,7 @@ public Data toNova(NBTTagCompound nbt) { if (nbt != null) { data.className = nbt.getString("class"); Set keys = nbt.func_150296_c(); - keys.forEach(k -> data.put(k, load(nbt, k))); + keys.stream().filter(k -> !k.endsWith(":isBoolean")).forEach(k -> data.put(k, load(nbt, k))); } return data; } @@ -94,10 +94,10 @@ public NBTTagCompound toNative(NBTTagCompound nbt, Data data) { */ public NBTTagCompound save(NBTTagCompound tag, String key, Object value) { if (value instanceof Boolean) { - tag.setBoolean("isBoolean", true); + tag.setBoolean(key + ":isBoolean", true); tag.setBoolean(key, (boolean) value); } else if (value instanceof Byte) { - tag.setBoolean("isBoolean", false); + tag.setBoolean(key + ":isBoolean", false); tag.setByte(key, (byte) value); } else if (value instanceof Short) { tag.setShort(key, (short) value); @@ -142,7 +142,7 @@ public Object load(NBTTagCompound tag, String key) { } else if (saveTag instanceof NBTTagShort) { return tag.getShort(key); } else if (saveTag instanceof NBTTagByte) { - if (tag.getBoolean("isBoolean")) { + if (tag.getBoolean(key + ":isBoolean")) { return tag.getBoolean(key); } else { return tag.getByte(key); diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/data/DataWrapper.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/data/DataWrapper.java index aab29484f..352fcdf47 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/data/DataWrapper.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/data/DataWrapper.java @@ -63,7 +63,7 @@ public Data toNova(NBTTagCompound nbt) { if (nbt != null) { data.className = nbt.getString("class"); Set keys = nbt.getKeySet(); - keys.forEach(k -> data.put(k, load(nbt, k))); + keys.stream().filter(k -> !k.endsWith(":isBoolean")).forEach(k -> data.put(k, load(nbt, k))); } return data; } @@ -94,10 +94,10 @@ public NBTTagCompound toNative(NBTTagCompound nbt, Data data) { */ public NBTTagCompound save(NBTTagCompound tag, String key, Object value) { if (value instanceof Boolean) { - tag.setBoolean("isBoolean", true); + tag.setBoolean(key + ":isBoolean", true); tag.setBoolean(key, (boolean) value); } else if (value instanceof Byte) { - tag.setBoolean("isBoolean", false); + tag.setBoolean(key + ":isBoolean", false); tag.setByte(key, (byte) value); } else if (value instanceof Short) { tag.setShort(key, (short) value); @@ -142,7 +142,7 @@ public Object load(NBTTagCompound tag, String key) { } else if (saveTag instanceof NBTTagShort) { return tag.getShort(key); } else if (saveTag instanceof NBTTagByte) { - if (tag.getBoolean("isBoolean")) { + if (tag.getBoolean(key + ":isBoolean")) { return tag.getBoolean(key); } else { return tag.getByte(key); diff --git a/src/main/java/nova/core/retention/Data.java b/src/main/java/nova/core/retention/Data.java index 7ca2e9a46..72b3a5231 100755 --- a/src/main/java/nova/core/retention/Data.java +++ b/src/main/java/nova/core/retention/Data.java @@ -77,7 +77,7 @@ public Data() { } - public Data(Class clazz) { + public Data(Class clazz) { className = clazz.getName(); super.put("class", className); } @@ -95,6 +95,51 @@ public static Data serialize(Storable obj) { obj.save(data); return data; } + + /** + * Saves an object, serializing its data. + * This map can be reloaded and its class with be reconstructed. + * @param obj The object to store. + * @return The data of the object with + */ + public static Data serialize(Object value) { + try { + if (value instanceof Enum) { + Data enumData = new Data(value.getClass()); + enumData.put("value", ((Enum) value).name()); + return enumData; + } else if (value instanceof Vector3D) { + Data vectorData = new Data(Vector3D.class); + vectorData.put("x", ((Vector3D) value).getX()); + vectorData.put("y", ((Vector3D) value).getY()); + vectorData.put("z", ((Vector3D) value).getZ()); + return vectorData; + } else if (value instanceof Vector2D) { + Data vectorData = new Data(Vector2D.class); + vectorData.put("x", ((Vector2D) value).getX()); + vectorData.put("y", ((Vector2D) value).getY()); + return vectorData; + } else if (value instanceof UUID) { + Data uuidData = new Data(UUID.class); + uuidData.put("uuid", value.toString()); + return uuidData; + } else if (value instanceof Class) { + Data classData = new Data(Class.class); + classData.put("name", ((Class) value).getName()); + return classData; + } else if (value instanceof Identifier) { + Data identifierData = new Data(Identifier.class); + IdentifierRegistry.instance().save(identifierData, (Identifier) value); + return identifierData; + } else if (value instanceof Storable) { + return serialize((Storable) value); + } else { + return (Data) value; + } + } catch (Exception e) { + throw new DataException(e); + } + } /** * Loads an object from its stored data, with an unknown class. @@ -102,26 +147,28 @@ public static Data serialize(Storable obj) { * @param data The data * @return The object loaded with given data. */ - public static Object unserialize(Data data) { + @SuppressWarnings({"unchecked", "rawtypes"}) + public static T unserialize(Data data) { try { - Class clazz = (Class) Class.forName((String) data.get("class")); + Class clazz = Class.forName((String) data.get("class")); if (clazz.isEnum()) { - return Enum.valueOf(clazz, data.get("value")); + return (T) Enum.valueOf(clazz, data.get("value")); } else if (clazz == Vector3D.class) { - return new Vector3D(data.get("x"), data.get("y"), data.get("z")); + return (T) new Vector3D(data.get("x"), data.get("y"), data.get("z")); } else if (clazz == Vector2D.class) { - return new Vector2D(data.get("x"), (double) data.get("y")); + return (T) new Vector2D(data.get("x"), (double) data.get("y")); } else if (clazz == UUID.class) { - return UUID.fromString(data.get("uuid")); + return (T) UUID.fromString(data.get("uuid")); } else if (clazz == Class.class) { - return Class.forName(data.get("name")); + return (T) Class.forName(data.get("name")); + } else if (clazz == Identifier.class) { + return (T) IdentifierRegistry.instance().load(data); } else { - return unserialize(clazz, data); + return (T) unserialize(clazz, data); } } catch (Exception e) { throw new DataException(e); } - } /** diff --git a/src/main/java/nova/core/util/id/ClassIdentifier.java b/src/main/java/nova/core/util/id/ClassIdentifier.java index a082b7a21..b94114f0f 100644 --- a/src/main/java/nova/core/util/id/ClassIdentifier.java +++ b/src/main/java/nova/core/util/id/ClassIdentifier.java @@ -23,6 +23,11 @@ public ClassIdentifier(Class id) { @Override public String asString() { + return id.getName(); + } + + @Override + public String asShortString() { return id.getSimpleName(); } @@ -64,5 +69,14 @@ public ClassIdentifier load(Data data) { throw new DataException(ex); } } + + @Override + public ClassIdentifier load(String data) { + try { + return new ClassIdentifier(Class.forName(data)); + } catch (ClassNotFoundException ex) { + throw new DataException(ex); + } + } } } diff --git a/src/main/java/nova/core/util/id/EnumIdentifier.java b/src/main/java/nova/core/util/id/EnumIdentifier.java index 35f672d28..1b89f9235 100644 --- a/src/main/java/nova/core/util/id/EnumIdentifier.java +++ b/src/main/java/nova/core/util/id/EnumIdentifier.java @@ -6,8 +6,7 @@ package nova.core.util.id; import nova.core.retention.Data; - -import java.util.Objects; +import nova.core.retention.DataException; /** * @@ -19,21 +18,33 @@ public EnumIdentifier(E id) { super(id); } + @Override + public String asString() { + return id.getClass() + "::" + id.name(); + } + + @Override + public String asShortString() { + return id.name(); + } + public E asEnum() { return id; } @Override + @SuppressWarnings("rawtypes") public boolean equals(Object other) { return equalsImpl(this, other, EnumIdentifier.class, EnumIdentifier::asEnum); } + @SuppressWarnings({"unchecked", "rawtypes"}) public static class Loader extends IdentifierLoader> { public Loader(String id) { super(id); } - + @Override public Class> getIdentifierClass() { return cast(EnumIdentifier.class); @@ -41,12 +52,28 @@ public Class> getIdentifierClass() { @Override public void save(Data data, EnumIdentifier identifier) { - data.put("id", identifier.asEnum()); + data.put("id", identifier.id.getClass().getName()); + data.put("value", identifier.asEnum().name()); } @Override public EnumIdentifier load(Data data) { - return new EnumIdentifier(data.getEnum("id")); + try { + Class enumClass = (Class) Class.forName(data.get("id")); + return new EnumIdentifier(Enum.valueOf(enumClass, data.get("value"))); + } catch (Exception e) { + throw new DataException(e); + } + } + + @Override + public EnumIdentifier load(String data) { + try { + Class enumClass = (Class) Class.forName(data.substring(0, data.lastIndexOf("::"))); + return new EnumIdentifier(Enum.valueOf(enumClass, data.substring(data.lastIndexOf("::") + 2))); + } catch (Exception e) { + throw new DataException(e); + } } @SuppressWarnings("unchecked") diff --git a/src/main/java/nova/core/util/id/Identifier.java b/src/main/java/nova/core/util/id/Identifier.java index f959ade9f..a9925894b 100644 --- a/src/main/java/nova/core/util/id/Identifier.java +++ b/src/main/java/nova/core/util/id/Identifier.java @@ -16,4 +16,14 @@ public interface Identifier { * @return A string representation of this Identifier. */ String asString(); + + /** + * Converts this Identifier into a short String. + * The default implementation returns the same result as {@link #asString()}. + * + * @return A string representation of this Identifier. + */ + default String asShortString() { + return asString(); + } } diff --git a/src/main/java/nova/core/util/id/IdentifierLoader.java b/src/main/java/nova/core/util/id/IdentifierLoader.java index 76d24e9e6..bc9ffda00 100644 --- a/src/main/java/nova/core/util/id/IdentifierLoader.java +++ b/src/main/java/nova/core/util/id/IdentifierLoader.java @@ -33,6 +33,18 @@ public IdentifierLoader(String id) { public abstract T load(Data data); + /** + * This method creates a new Identifier instance. + * + * Implementations must ensure that + * {@link Object#equals(java.lang.Object) identifier.equals}{@code (load(}{@link Identifier#asString() identifier.asString()}{@code ))} + * is always true. + * + * @param data + * @return + */ + public abstract T load(String data); + @Override public final StringIdentifier getID() { return new StringIdentifier(id); diff --git a/src/main/java/nova/core/util/id/IdentifierRegistry.java b/src/main/java/nova/core/util/id/IdentifierRegistry.java index d8b3ab265..03004e0bf 100644 --- a/src/main/java/nova/core/util/id/IdentifierRegistry.java +++ b/src/main/java/nova/core/util/id/IdentifierRegistry.java @@ -8,7 +8,9 @@ import nova.core.retention.Data; import nova.core.util.registry.Registry; +import java.util.Objects; import java.util.Optional; +import java.util.function.Supplier; /** * Used to handle loading and saving of identifiers. @@ -47,7 +49,7 @@ public Identifier load(Data data) { assert data != null; StringIdentifier id = new StringIdentifier(data.get("type")); if (!contains(id)) - throw new NoSuchIDException("No Identifier class found for type: " + id); + throw noIdentifierClassFound(id).get(); return get(id).get().load(data); } @@ -80,4 +82,42 @@ private T cast(Object o) { public IdentifierLoader register(IdentifierLoader loader) { return super.register(loader); } + + public Optional getName(Class ID) { + Optional> loader = stream().filter(l -> l.getIdentifierClass().equals(ID)).findFirst(); + if (!loader.isPresent()) + loader = stream().filter(l -> l.getIdentifierClass().isAssignableFrom(ID)).findFirst(); + return loader.map(l -> l.getID()); + } + + public Optional getName(Identifier ID) { + Optional> loader = stream().filter(l -> l.getIdentifierClass().equals(ID.getClass())).findFirst(); + if (!loader.isPresent()) + loader = stream().filter(l -> l.getIdentifierClass().isAssignableFrom(ID.getClass())).findFirst(); + return loader.map(l -> l.getID()); + } + + public Optional> get(String ID) { + return super.get(new StringIdentifier(ID)); + } + + public boolean contains(String ID) { + return super.contains(new StringIdentifier(ID)); + } + + public static Supplier noIdentifierLoaderFound(Identifier id) { + return noIdentifierLoaderFound(id.getClass()); + } + + public static Supplier noIdentifierLoaderFound(Class clazz) { + return () -> new NoSuchIDException("No IdentifierLoader found for class: " + clazz.getSimpleName()); + } + + public static Supplier noIdentifierClassFound(Identifier type) { + return noIdentifierClassFound(type == null ? (String) null : type.asString()); + } + + public static Supplier noIdentifierClassFound(String type) { + return () -> new NoSuchIDException("No Identifier class found for type: " + type); + } } diff --git a/src/main/java/nova/core/util/id/StringIdentifier.java b/src/main/java/nova/core/util/id/StringIdentifier.java index 4e750c56c..ef9aa6038 100644 --- a/src/main/java/nova/core/util/id/StringIdentifier.java +++ b/src/main/java/nova/core/util/id/StringIdentifier.java @@ -45,5 +45,10 @@ public void save(Data data, StringIdentifier identifier) { public StringIdentifier load(Data data) { return new StringIdentifier(data.get("id")); } + + @Override + public StringIdentifier load(String data) { + return new StringIdentifier(data); + } } } diff --git a/src/main/java/nova/core/util/id/UUIDIdentifier.java b/src/main/java/nova/core/util/id/UUIDIdentifier.java index 76a28430b..153bd2070 100644 --- a/src/main/java/nova/core/util/id/UUIDIdentifier.java +++ b/src/main/java/nova/core/util/id/UUIDIdentifier.java @@ -55,5 +55,10 @@ public void save(Data data, UUIDIdentifier identifier) { public UUIDIdentifier load(Data data) { return new UUIDIdentifier(UUID.fromString(data.get("id"))); } + + @Override + public UUIDIdentifier load(String data) { + return new UUIDIdentifier(UUID.fromString(data)); + } } } diff --git a/src/test/java/nova/core/util/id/IdentifierTest.java b/src/test/java/nova/core/util/id/IdentifierTest.java index 6ded4bda6..6ad4f2b9a 100644 --- a/src/test/java/nova/core/util/id/IdentifierTest.java +++ b/src/test/java/nova/core/util/id/IdentifierTest.java @@ -11,6 +11,7 @@ import java.util.UUID; import static nova.testutils.NovaAssertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; /** * @author ExE Boss @@ -32,7 +33,8 @@ public void classEquals() { ClassIdentifier clazz = new ClassIdentifier(IdentifierTest.class); assertThat(clazz.asClass()).isEqualTo(IdentifierTest.class); - assertThat(clazz.asString()).isEqualTo(IdentifierTest.class.getSimpleName()); + assertThat(clazz.asString()).isEqualTo(IdentifierTest.class.getName()); + assertThat(clazz.asShortString()).isEqualTo(IdentifierTest.class.getSimpleName()); assertThat(clazz).isEqualTo(new ClassIdentifier(IdentifierTest.class)); } @@ -50,7 +52,7 @@ public void enumEquals() { EnumIdentifier enumIdentifier = new EnumIdentifier<>(EnumExample.EXAMPLE_42); assertThat(enumIdentifier.asEnum()).isEqualTo(EnumExample.EXAMPLE_42); - assertThat(enumIdentifier.asString()).isEqualTo(EnumExample.EXAMPLE_42.toString()); + assertThat(enumIdentifier.asShortString()).isEqualTo(EnumExample.EXAMPLE_42.toString()); assertThat(enumIdentifier).isEqualTo(new EnumIdentifier<>(EnumExample.EXAMPLE_42)); } } From 6d8c194a6ab0393a92e1a0a5c8334115b526913b Mon Sep 17 00:00:00 2001 From: ExE Boss Date: Sun, 8 Jan 2017 05:47:38 +0100 Subject: [PATCH 08/10] Fix Travis build --- .../core/recipes/crafting/ItemIngredient.java | 4 +- src/main/java/nova/core/retention/Data.java | 40 +++++++++---------- .../java/nova/core/util/id/Identifier.java | 3 +- .../nova/core/util/id/IdentifierLoader.java | 1 - 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/main/java/nova/core/recipes/crafting/ItemIngredient.java b/src/main/java/nova/core/recipes/crafting/ItemIngredient.java index fbacb0097..0c3737738 100755 --- a/src/main/java/nova/core/recipes/crafting/ItemIngredient.java +++ b/src/main/java/nova/core/recipes/crafting/ItemIngredient.java @@ -38,9 +38,9 @@ public interface ItemIngredient extends Identifiable { /** - * Retrieves an ingredient to represent a specific item. + * Retrieves an ingredient to represent a specific block. * - * @param item The item + * @param block The block * @return ingredient */ static ItemIngredient forBlock(BlockFactory block) { diff --git a/src/main/java/nova/core/retention/Data.java b/src/main/java/nova/core/retention/Data.java index 72b3a5231..e5b1b980c 100755 --- a/src/main/java/nova/core/retention/Data.java +++ b/src/main/java/nova/core/retention/Data.java @@ -102,39 +102,39 @@ public static Data serialize(Storable obj) { * @param obj The object to store. * @return The data of the object with */ - public static Data serialize(Object value) { + public static Data serialize(Object obj) { try { - if (value instanceof Enum) { - Data enumData = new Data(value.getClass()); - enumData.put("value", ((Enum) value).name()); + if (obj instanceof Enum) { + Data enumData = new Data(obj.getClass()); + enumData.put("value", ((Enum) obj).name()); return enumData; - } else if (value instanceof Vector3D) { + } else if (obj instanceof Vector3D) { Data vectorData = new Data(Vector3D.class); - vectorData.put("x", ((Vector3D) value).getX()); - vectorData.put("y", ((Vector3D) value).getY()); - vectorData.put("z", ((Vector3D) value).getZ()); + vectorData.put("x", ((Vector3D) obj).getX()); + vectorData.put("y", ((Vector3D) obj).getY()); + vectorData.put("z", ((Vector3D) obj).getZ()); return vectorData; - } else if (value instanceof Vector2D) { + } else if (obj instanceof Vector2D) { Data vectorData = new Data(Vector2D.class); - vectorData.put("x", ((Vector2D) value).getX()); - vectorData.put("y", ((Vector2D) value).getY()); + vectorData.put("x", ((Vector2D) obj).getX()); + vectorData.put("y", ((Vector2D) obj).getY()); return vectorData; - } else if (value instanceof UUID) { + } else if (obj instanceof UUID) { Data uuidData = new Data(UUID.class); - uuidData.put("uuid", value.toString()); + uuidData.put("uuid", obj.toString()); return uuidData; - } else if (value instanceof Class) { + } else if (obj instanceof Class) { Data classData = new Data(Class.class); - classData.put("name", ((Class) value).getName()); + classData.put("name", ((Class) obj).getName()); return classData; - } else if (value instanceof Identifier) { + } else if (obj instanceof Identifier) { Data identifierData = new Data(Identifier.class); - IdentifierRegistry.instance().save(identifierData, (Identifier) value); + IdentifierRegistry.instance().save(identifierData, (Identifier) obj); return identifierData; - } else if (value instanceof Storable) { - return serialize((Storable) value); + } else if (obj instanceof Storable) { + return serialize((Storable) obj); } else { - return (Data) value; + return (Data) obj; } } catch (Exception e) { throw new DataException(e); diff --git a/src/main/java/nova/core/util/id/Identifier.java b/src/main/java/nova/core/util/id/Identifier.java index a9925894b..afc1d7952 100644 --- a/src/main/java/nova/core/util/id/Identifier.java +++ b/src/main/java/nova/core/util/id/Identifier.java @@ -2,8 +2,9 @@ /** * The interface for all identifiers. The Identifier must be immutable. - *

+ *

* Implementations should override {@link Object#equals(Object)}, {@link Object#hashCode()} and {@link Object#toString()}. + *

* * @author SoniEx2, ExE Boss */ diff --git a/src/main/java/nova/core/util/id/IdentifierLoader.java b/src/main/java/nova/core/util/id/IdentifierLoader.java index bc9ffda00..80e89d9ba 100644 --- a/src/main/java/nova/core/util/id/IdentifierLoader.java +++ b/src/main/java/nova/core/util/id/IdentifierLoader.java @@ -12,7 +12,6 @@ * * @author ExE Boss * @param The Identifier class - * @param The Identifier type * @see Identifier * @see IdentifierRegistry */ From daad474240ef361c7be900e58e0e67db21a40bd6 Mon Sep 17 00:00:00 2001 From: ExE Boss Date: Sun, 8 Jan 2017 06:20:20 +0100 Subject: [PATCH 09/10] Fix wrappers + fluid id saving --- .../v17/recipes/MinecraftItemIngredient.java | 3 +- .../mc/forge/v17/recipes/RecipeConverter.java | 4 +-- .../v17/wrapper/block/BlockConverter.java | 6 ++-- .../v17/wrapper/block/forward/FWBlock.java | 6 +++- .../v17/wrapper/block/forward/FWTile.java | 15 +++++++--- .../wrapper/block/forward/FWTileLoader.java | 11 ++++--- .../v17/wrapper/entity/EntityConverter.java | 3 +- .../v17/wrapper/entity/forward/FWEntity.java | 30 ++++++++++++++----- .../forge/v17/wrapper/item/BWItemFactory.java | 3 +- .../forge/v17/wrapper/item/ItemConverter.java | 10 ++++--- .../v18/recipes/MinecraftItemIngredient.java | 3 +- .../mc/forge/v18/recipes/RecipeConverter.java | 6 ++-- .../v18/wrapper/block/BlockConverter.java | 7 +++-- .../v18/wrapper/block/forward/FWBlock.java | 6 +++- .../v18/wrapper/block/forward/FWTile.java | 11 ++++--- .../wrapper/block/forward/FWTileLoader.java | 12 ++++---- .../wrapper/block/forward/FWTileUpdater.java | 5 ++-- .../v18/wrapper/entity/EntityConverter.java | 3 +- .../v18/wrapper/entity/forward/FWEntity.java | 28 ++++++++++++----- .../forge/v18/wrapper/item/BWItemFactory.java | 3 +- .../forge/v18/wrapper/item/ItemConverter.java | 8 +++-- .../java/nova/core/component/fluid/Fluid.java | 4 +-- .../nova/core/util/id/UniqueIdentifiable.java | 4 +-- 23 files changed, 127 insertions(+), 64 deletions(-) diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java index ddf1fbe86..2da08910e 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java @@ -20,7 +20,6 @@ package nova.core.wrapper.mc.forge.v17.recipes; -import nova.core.item.Item; import nova.core.recipes.crafting.SpecificItemIngredient; import nova.internal.core.Game; @@ -29,6 +28,6 @@ */ public class MinecraftItemIngredient extends SpecificItemIngredient { public MinecraftItemIngredient(net.minecraft.item.ItemStack itemStack) { - super(((Item) Game.natives().toNova(itemStack)).getID().asString()); // TODO? + super(Game.natives().toNova(itemStack)); } } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java index f02af76db..b1e2bd395 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java @@ -74,7 +74,7 @@ private static Object getInternal(ItemIngredient ingredient) { if (ingredient instanceof SpecificItemIngredient) { return wrapSpecific((SpecificItemIngredient) ingredient); } else if (ingredient instanceof OreItemIngredient) { - return ((OreItemIngredient) ingredient).getName(); + return ((OreItemIngredient) ingredient).getID().asString(); } return null; @@ -84,7 +84,7 @@ private static ItemIngredient getIngredient(Object ingredient) { if (ingredient == null) { return null; } else if (ingredient instanceof ItemStack) { - return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID().asString()); // TODO? + return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID()); } else if (ingredient instanceof String) { return new OreItemIngredient((String) ingredient); } else if (ingredient instanceof List) { diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java index 9e7c845cc..71540175c 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java @@ -32,6 +32,8 @@ import nova.core.event.BlockEvent; import nova.core.loader.Loadable; import nova.core.nativewrapper.NativeConverter; +import nova.core.util.id.NamespacedStringIdentifier; +import nova.core.util.id.StringIdentifier; import nova.core.wrapper.mc.forge.v17.launcher.NovaMinecraft; import nova.core.wrapper.mc.forge.v17.util.ModCreativeTab; import nova.core.wrapper.mc.forge.v17.wrapper.block.backward.BWBlock; @@ -107,7 +109,7 @@ private void registerMinecraftToNOVA() { BlockManager blockManager = Game.blocks(); net.minecraft.block.Block.blockRegistry.forEach(obj -> blockManager.register( - new BlockFactory(net.minecraft.block.Block.blockRegistry.getNameForObject(obj).toString(), + new BlockFactory(new NamespacedStringIdentifier(net.minecraft.block.Block.blockRegistry.getNameForObject(obj)), () -> new BWBlock((net.minecraft.block.Block) obj), evt -> { }) ) @@ -118,7 +120,7 @@ private void registerNOVAToMinecraft() { BlockManager blockManager = Game.blocks(); //Register air block - BlockFactory airBlock = new BlockFactory("air", () -> new BWBlock(Blocks.air) { + BlockFactory airBlock = new BlockFactory(new StringIdentifier("air"), () -> new BWBlock(Blocks.air) { @Override public boolean canReplace() { return true; diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java index b4710f806..dc4888b35 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java @@ -102,6 +102,10 @@ public FWBlock(BlockFactory factory) { } } + public BlockFactory getFactory() { + return this.factory; + } + public Block getBlockInstance(net.minecraft.world.IBlockAccess access, Vector3D position) { /** * If this block has a TileEntity, forward the method into the Stateful @@ -169,7 +173,7 @@ public boolean hasTileEntity(int metadata) { @Override public TileEntity createTileEntity(World world, int metadata) { - return FWTileLoader.loadTile(dummy.getID().asString()); // TODO? + return FWTileLoader.loadTile(factory.getID()); } @Override diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWTile.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWTile.java index 445ff63ce..5ebc401c1 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWTile.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWTile.java @@ -29,17 +29,22 @@ import nova.core.network.Syncable; import nova.core.retention.Data; import nova.core.retention.Storable; +import nova.core.util.id.Identifier; +import nova.core.util.id.IdentifierRegistry; +import nova.core.util.id.StringIdentifier; import nova.core.wrapper.mc.forge.v17.network.netty.MCNetworkManager; import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; +import java.util.Objects; + /** * A Minecraft TileEntity to Nova block wrapper * @author Calclavia */ public class FWTile extends TileEntity { - private String blockID; + private Identifier blockID; private Block block; private Data cacheData = null; @@ -47,7 +52,7 @@ public FWTile() { } - public FWTile(String blockID) { + public FWTile(Identifier blockID) { this.blockID = blockID; } @@ -57,6 +62,7 @@ public Block getBlock() { public void setBlock(Block block) { this.block = block; + this.blockID = block.getID(); } @Override @@ -108,7 +114,8 @@ public boolean canUpdate() { public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); - nbt.setString("novaID", blockID); + // If we have a block, store its id instead + nbt.setTag("novaID", Game.natives().toNative(Data.serialize(block != null ? block.getID() : blockID))); if (block != null) { if (block instanceof Storable) { @@ -128,7 +135,7 @@ public void readFromNBT(NBTTagCompound nbt) { * wait until the block is injected withPriority World and Position data using * Future. */ - blockID = nbt.getString("novaID"); + blockID = ((Data)Game.natives().toNova(nbt)).getIdentifier("novaID"); cacheData = Game.natives().toNova(nbt.getCompoundTag("nova")); } } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWTileLoader.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWTileLoader.java index 64c75e154..e2ac5b834 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWTileLoader.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWTileLoader.java @@ -23,6 +23,9 @@ import net.minecraft.nbt.NBTTagCompound; import nova.core.block.Block; import nova.core.block.BlockFactory; +import nova.core.retention.Data; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import nova.core.wrapper.mc.forge.v17.asm.lib.ComponentInjector; import nova.internal.core.Game; @@ -40,7 +43,7 @@ private FWTileLoader() { public static FWTile loadTile(NBTTagCompound data) { try { - String blockID = data.getString("novaID"); + Identifier blockID = Data.unserialize(Game.natives().toNative(data.getTag("novaID"))); Block block = createBlock(blockID); FWTile tile = injector.inject(block, new Class[0], new Object[0]); tile.setBlock(block); @@ -50,10 +53,10 @@ public static FWTile loadTile(NBTTagCompound data) { } } - public static FWTile loadTile(String blockID) { + public static FWTile loadTile(Identifier blockID) { try { Block block = createBlock(blockID); - FWTile tile = injector.inject(block, new Class[] { String.class }, new Object[] { blockID }); + FWTile tile = injector.inject(block, new Class[] { Identifier.class }, new Object[] { blockID }); tile.setBlock(block); return tile; } catch (Exception e) { @@ -61,7 +64,7 @@ public static FWTile loadTile(String blockID) { } } - private static Block createBlock(String blockID) { + private static Block createBlock(Identifier blockID) { Optional blockFactory = Game.blocks().get(blockID); if (blockFactory.isPresent()) { return blockFactory.get().build(); diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/EntityConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/EntityConverter.java index 1fcb3a453..082b51dc4 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/EntityConverter.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/EntityConverter.java @@ -26,6 +26,7 @@ import nova.core.entity.EntityFactory; import nova.core.loader.Loadable; import nova.core.nativewrapper.NativeConverter; +import nova.core.util.id.ClassIdentifier; import nova.core.wrapper.mc.forge.v17.wrapper.entity.backward.BWEntity; import nova.core.wrapper.mc.forge.v17.wrapper.entity.backward.BWEntityFX; import nova.core.wrapper.mc.forge.v17.wrapper.entity.forward.FWEntity; @@ -55,7 +56,7 @@ public Entity toNova(net.minecraft.entity.Entity mcEntity) { //TODO: Make this BWRegistry non-lazy //Lazy registry - String id = mcEntity.getClass().getName(); + ClassIdentifier id = new ClassIdentifier(mcEntity.getClass()); // Minecraft uses Class as entity ID Optional entityFactory = Game.entities().get(id); if (entityFactory.isPresent()) { diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java index 9e4a91a4b..160637331 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java @@ -32,6 +32,8 @@ import nova.core.entity.EntityFactory; import nova.core.retention.Data; import nova.core.retention.Storable; +import nova.core.util.id.IdentifierRegistry; +import nova.core.util.id.StringIdentifier; import nova.core.util.shape.Cuboid; import nova.core.wrapper.mc.forge.v17.wrapper.data.DataWrapper; import nova.internal.core.Game; @@ -64,7 +66,7 @@ protected void readEntityFromNBT(NBTTagCompound nbt) { } if (wrapped == null) { //This entity was saved to disk. - setWrapped(Game.entities().get(nbt.getString("novaID")).get().build()); + setWrapped(Game.entities().get(((Data)Game.natives().toNova(nbt)).getIdentifier("novaID")).get().build()); } } @@ -75,16 +77,24 @@ protected void writeEntityToNBT(NBTTagCompound nbt) { ((Storable) wrapped).save(data); DataWrapper.instance().toNative(nbt, data); } - nbt.setString("novaID", wrapped.getID().asString()); // TODO? + Data identifierData = new Data(); + IdentifierRegistry.instance().save(identifierData, wrapped.getID()); + nbt.setTag("novaID", Game.natives().toNative(identifierData)); } @Override public void writeSpawnData(ByteBuf buffer) { //Write the ID of the entity to client - String id = wrapped.getID().asString(); // TODO? - char[] chars = id.toCharArray(); + String type = IdentifierRegistry.instance().getName(wrapped.getID()).get().asString(); + String id = wrapped.getID().asString(); + + char[] chars = type.toCharArray(); + buffer.writeInt(chars.length); + for (char c : chars) + buffer.writeChar(c); + + chars = id.toCharArray(); buffer.writeInt(chars.length); - for (char c : chars) buffer.writeChar(c); } @@ -92,12 +102,18 @@ public void writeSpawnData(ByteBuf buffer) { @Override public void readSpawnData(ByteBuf buffer) { //Load the client ID - String id = ""; + String type = ""; int length = buffer.readInt(); + for (int i = 0; i < length; i++) + type += buffer.readChar(); + + String id = ""; + length = buffer.readInt(); for (int i = 0; i < length; i++) id += buffer.readChar(); - setWrapped(Game.entities().get(id).get().build()); + setWrapped(Game.entities().get(IdentifierRegistry.instance().get(type) + .orElseThrow(IdentifierRegistry.noIdentifierClassFound(type)).load(id)).get().build()); } public Entity getWrapped() { diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItemFactory.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItemFactory.java index fa9f5ae35..5e5fae251 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItemFactory.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItemFactory.java @@ -25,6 +25,7 @@ import nova.core.item.Item; import nova.core.item.ItemFactory; import nova.core.retention.Data; +import nova.core.util.id.StringIdentifier; import nova.internal.core.Game; /** @@ -37,7 +38,7 @@ public class BWItemFactory extends ItemFactory { private final int meta; public BWItemFactory(net.minecraft.item.Item item, int meta) { - super(net.minecraft.item.Item.itemRegistry.getNameForObject(item) + (item.getHasSubtypes() ? ":" + meta : ""), () -> new BWItem(item, meta, null)); + super(new StringIdentifier(net.minecraft.item.Item.itemRegistry.getNameForObject(item) + (item.getHasSubtypes() ? ":" + meta : "")), () -> new BWItem(item, meta, null)); this.item = item; this.meta = meta; diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java index 17b988425..65f9ce817 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java @@ -35,6 +35,7 @@ import nova.core.loader.Loadable; import nova.core.nativewrapper.NativeConverter; import nova.core.retention.Data; +import nova.core.util.id.Identifier; import nova.core.wrapper.mc.forge.v17.launcher.NovaMinecraft; import nova.core.wrapper.mc.forge.v17.util.ModCreativeTab; import nova.core.wrapper.mc.forge.v17.wrapper.block.BlockConverter; @@ -75,11 +76,12 @@ public Item toNova(ItemStack itemStack) { return getNovaItem(itemStack).setCount(itemStack.stackSize); } - //TODO: Why is this method separate? + // This method is seperate because it recursively calls itself when the ItemStack's + // damage value is {@link net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE}. public Item getNovaItem(ItemStack itemStack) { if (itemStack.getItemDamage() == net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE) { // TODO: Deal withPriority wildcard meta values - important for the ore dictionary - return getNovaItem(new ItemStack(itemStack.getItem(), 1, 0)); + return getNovaItem(new ItemStack(itemStack.getItem(), itemStack.stackSize, 0)); } if (itemStack.getTagCompound() != null && itemStack.getTagCompound() instanceof FWNBTTagCompound) { @@ -106,7 +108,7 @@ public ItemStack toNative(Item item) { if (item instanceof BWItem) { return ((BWItem) item).makeItemStack(item.count()); } else { - ItemFactory itemFactory = Game.items().get(item.getID().asString()).get(); // TODO? + ItemFactory itemFactory = Game.items().get(item.getID()).get(); // TODO? FWNBTTagCompound tag = new FWNBTTagCompound(item); MinecraftItemMapping mapping = get(itemFactory); @@ -133,7 +135,7 @@ public ItemStack toNative(ItemFactory itemFactory) { return result; } - public ItemStack toNative(String id) { + public ItemStack toNative(Identifier id) { return toNative(Game.items().get(id).get().build().setCount(1)); } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java index 40701caf8..b35ba98fe 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java @@ -20,7 +20,6 @@ package nova.core.wrapper.mc.forge.v18.recipes; -import nova.core.item.Item; import nova.core.recipes.crafting.SpecificItemIngredient; import nova.internal.core.Game; @@ -29,6 +28,6 @@ */ public class MinecraftItemIngredient extends SpecificItemIngredient { public MinecraftItemIngredient(net.minecraft.item.ItemStack itemStack) { - super(((Item) Game.natives().toNova(itemStack)).getID().asString()); // TODO? + super(Game.natives().toNova(itemStack)); } } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java index 8547f577c..d6c804800 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java @@ -74,7 +74,7 @@ private static Object getInternal(ItemIngredient ingredient) { if (ingredient instanceof SpecificItemIngredient) { return wrapSpecific((SpecificItemIngredient) ingredient); } else if (ingredient instanceof OreItemIngredient) { - return ((OreItemIngredient) ingredient).getName(); + return ((OreItemIngredient) ingredient).getID().asString(); } return null; @@ -84,7 +84,7 @@ private static ItemIngredient getIngredient(Object ingredient) { if (ingredient == null) { return null; } else if (ingredient instanceof ItemStack) { - return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID().asString()); // TODO? + return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID()); } else if (ingredient instanceof String) { return new OreItemIngredient((String) ingredient); } else if (ingredient instanceof List) { @@ -99,7 +99,7 @@ private static ItemIngredient getIngredient(Object ingredient) { } } - private static String findOreDictEntryFor(List ingredient) { + private static String findOreDictEntryFor(List ingredient) { for (String key : net.minecraftforge.oredict.OreDictionary.getOreNames()) { if (net.minecraftforge.oredict.OreDictionary.getOres(key).equals(ingredient)) { return key; diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java index 680d891bb..c90df679f 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java @@ -32,6 +32,8 @@ import nova.core.event.BlockEvent; import nova.core.loader.Loadable; import nova.core.nativewrapper.NativeConverter; +import nova.core.util.id.NamespacedStringIdentifier; +import nova.core.util.id.StringIdentifier; import nova.core.wrapper.mc.forge.v18.launcher.NovaMinecraft; import nova.core.wrapper.mc.forge.v18.util.ModCreativeTab; import nova.core.wrapper.mc.forge.v18.wrapper.block.backward.BWBlock; @@ -41,6 +43,7 @@ import java.util.Arrays; import java.util.HashMap; +import java.util.Objects; import java.util.Optional; /** @@ -108,7 +111,7 @@ private void registerMinecraftToNOVA() { BlockManager blockManager = Game.blocks(); net.minecraft.block.Block.blockRegistry.forEach(obj -> blockManager.register( - new BlockFactory(net.minecraft.block.Block.blockRegistry.getNameForObject(obj).toString(), + new BlockFactory(new NamespacedStringIdentifier(Objects.toString(net.minecraft.block.Block.blockRegistry.getNameForObject(obj))), () -> new BWBlock((net.minecraft.block.Block) obj), evt -> { }) ) @@ -119,7 +122,7 @@ private void registerNOVAToMinecraft() { BlockManager blockManager = Game.blocks(); //Register air block - BlockFactory airBlock = new BlockFactory("air", () -> new BWBlock(Blocks.air) { + BlockFactory airBlock = new BlockFactory(new StringIdentifier("air"), () -> new BWBlock(Blocks.air) { @Override public boolean canReplace() { return true; diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java index 8a3a4c6f6..0bf188ca6 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java @@ -107,6 +107,10 @@ public FWBlock(BlockFactory factory) { this.translucent = !isOpaqueCube(); } + public BlockFactory getFactory() { + return this.factory; + } + public Block getBlockInstance(IBlockAccess access, Vector3D position) { /** * If this block has a TileEntity, forward the method into the Stateful @@ -179,7 +183,7 @@ public boolean hasTileEntity(IBlockState state) { @Override public TileEntity createTileEntity(World world, IBlockState state) { - FWTile fwTile = FWTileLoader.loadTile(dummy.getID().asString()); // TODO? + FWTile fwTile = FWTileLoader.loadTile(factory.getID()); if (lastExtendedStatePos != null) { fwTile.block.components.getOrAdd(new MCBlockTransform(dummy, Game.natives().toNova(world), new Vector3D(lastExtendedStatePos.getX(), lastExtendedStatePos.getY(), lastExtendedStatePos.getZ()))); lastExtendedStatePos = null; diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTile.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTile.java index 435a2f255..5eaa6742e 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTile.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTile.java @@ -28,6 +28,7 @@ import nova.core.network.Syncable; import nova.core.retention.Data; import nova.core.retention.Storable; +import nova.core.util.id.Identifier; import nova.core.wrapper.mc.forge.v18.network.netty.MCNetworkManager; import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; @@ -38,7 +39,7 @@ */ public class FWTile extends TileEntity { - protected String blockID; + protected Identifier blockID; protected Block block; protected Data cacheData = null; @@ -46,7 +47,7 @@ public FWTile() { } - public FWTile(String blockID) { + public FWTile(Identifier blockID) { this.blockID = blockID; } @@ -56,6 +57,7 @@ public Block getBlock() { public void setBlock(Block block) { this.block = block; + this.blockID = block.getID(); } @Override @@ -89,7 +91,8 @@ public void invalidate() { public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); - nbt.setString("novaID", blockID); + // If we have a block, store its id instead + nbt.setTag("novaID", Game.natives().toNative(Data.serialize(block != null ? block.getID() : blockID))); if (block != null) { if (block instanceof Storable) { @@ -104,7 +107,7 @@ public void writeToNBT(NBTTagCompound nbt) { public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); - blockID = nbt.getString("novaID"); + blockID = ((Data)Game.natives().toNova(nbt)).getIdentifier("novaID"); cacheData = Game.natives().toNova(nbt.getCompoundTag("nova")); } } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTileLoader.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTileLoader.java index 907633c88..a9c0b65bc 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTileLoader.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTileLoader.java @@ -24,6 +24,8 @@ import nova.core.block.Block; import nova.core.block.BlockFactory; import nova.core.component.Updater; +import nova.core.retention.Data; +import nova.core.util.id.Identifier; import nova.core.wrapper.mc.forge.v18.asm.lib.ComponentInjector; import nova.internal.core.Game; @@ -42,7 +44,7 @@ private FWTileLoader() { public static FWTile loadTile(NBTTagCompound data) { try { - String blockID = data.getString("novaID"); + Identifier blockID = Data.unserialize(Game.natives().toNative(data.getTag("novaID"))); Block block = createBlock(blockID); FWTile tile = (block instanceof Updater) ? updaterInjector.inject(block, new Class[0], new Object[0]) : injector.inject(block, new Class[0], new Object[0]); tile.setBlock(block); @@ -52,11 +54,11 @@ public static FWTile loadTile(NBTTagCompound data) { } } - public static FWTile loadTile(String blockID) { + public static FWTile loadTile(Identifier blockID) { try { Block block = createBlock(blockID); - FWTile tile = (block instanceof Updater) ? updaterInjector.inject(block, new Class[] { String.class }, new Object[] { blockID }) : injector.inject(block, new Class[] { - String.class }, new Object[] { blockID }); + FWTile tile = (block instanceof Updater) ? updaterInjector.inject(block, new Class[] { Identifier.class }, new Object[] { blockID }) : + injector.inject(block, new Class[] { Identifier.class }, new Object[] { blockID }); tile.setBlock(block); return tile; } catch (Exception e) { @@ -64,7 +66,7 @@ public static FWTile loadTile(String blockID) { } } - private static Block createBlock(String blockID) { + private static Block createBlock(Identifier blockID) { Optional blockFactory = Game.blocks().get(blockID); if (blockFactory.isPresent()) { return blockFactory.get().build(); diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTileUpdater.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTileUpdater.java index f0a46a1a9..0f4d83483 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTileUpdater.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTileUpdater.java @@ -22,6 +22,7 @@ import net.minecraft.server.gui.IUpdatePlayerListBox; import nova.core.component.Updater; +import nova.core.util.id.Identifier; /** * @author Calclavia @@ -31,8 +32,8 @@ public FWTileUpdater() { } - public FWTileUpdater(String blockID) { - this.blockID = blockID; + public FWTileUpdater(Identifier blockID) { + super(blockID); } /** diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/EntityConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/EntityConverter.java index 23c7ad671..7a3d3a177 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/EntityConverter.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/EntityConverter.java @@ -27,6 +27,7 @@ import nova.core.entity.EntityFactory; import nova.core.loader.Loadable; import nova.core.nativewrapper.NativeConverter; +import nova.core.util.id.ClassIdentifier; import nova.core.wrapper.mc.forge.v18.wrapper.entity.backward.BWEntity; import nova.core.wrapper.mc.forge.v18.wrapper.entity.backward.BWEntityFX; import nova.core.wrapper.mc.forge.v18.wrapper.entity.forward.FWEntity; @@ -56,7 +57,7 @@ public Entity toNova(net.minecraft.entity.Entity mcEntity) { //TODO: Make this BWRegistry non-lazy //Lazy registry - String id = mcEntity.getClass().getName(); + ClassIdentifier id = new ClassIdentifier(mcEntity.getClass()); // Minecraft uses Class as entity ID Optional entityFactory = Game.entities().get(id); if (entityFactory.isPresent()) { diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java index 72ae58935..dafe92863 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java @@ -32,6 +32,8 @@ import nova.core.entity.EntityFactory; import nova.core.retention.Data; import nova.core.retention.Storable; +import nova.core.util.id.IdentifierRegistry; +import nova.core.util.id.StringIdentifier; import nova.core.util.shape.Cuboid; import nova.core.wrapper.mc.forge.v18.wrapper.data.DataWrapper; import nova.internal.core.Game; @@ -64,7 +66,7 @@ protected void readEntityFromNBT(NBTTagCompound nbt) { } if (wrapped == null) { //This entity was saved to disk. - setWrapped(Game.entities().get(nbt.getString("novaID")).get().build()); + setWrapped(Game.entities().get(Data.unserialize(Game.natives().toNative(nbt.getTag("novaID")))).get().build()); } } @@ -75,16 +77,22 @@ protected void writeEntityToNBT(NBTTagCompound nbt) { ((Storable) wrapped).save(data); DataWrapper.instance().toNative(nbt, data); } - nbt.setString("novaID", wrapped.getID().asString()); // TODO? + nbt.setTag("novaID", Game.natives().toNative(Data.serialize(wrapped.getID()))); } @Override public void writeSpawnData(ByteBuf buffer) { //Write the ID of the entity to client - String id = wrapped.getID().asString(); // TODO? - char[] chars = id.toCharArray(); + String type = IdentifierRegistry.instance().getName(wrapped.getID()).get().asString(); + String id = wrapped.getID().asString(); + + char[] chars = type.toCharArray(); + buffer.writeInt(chars.length); + for (char c : chars) + buffer.writeChar(c); + + chars = id.toCharArray(); buffer.writeInt(chars.length); - for (char c : chars) buffer.writeChar(c); } @@ -92,12 +100,18 @@ public void writeSpawnData(ByteBuf buffer) { @Override public void readSpawnData(ByteBuf buffer) { //Load the client ID - String id = ""; + String type = ""; int length = buffer.readInt(); + for (int i = 0; i < length; i++) + type += buffer.readChar(); + + String id = ""; + length = buffer.readInt(); for (int i = 0; i < length; i++) id += buffer.readChar(); - setWrapped(Game.entities().get(id).get().build()); + setWrapped(Game.entities().get(IdentifierRegistry.instance().get(type) + .orElseThrow(IdentifierRegistry.noIdentifierClassFound(type)).load(id)).get().build()); } public Entity getWrapped() { diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItemFactory.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItemFactory.java index e28085d10..8fa50bcc6 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItemFactory.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItemFactory.java @@ -25,6 +25,7 @@ import nova.core.item.Item; import nova.core.item.ItemFactory; import nova.core.retention.Data; +import nova.core.util.id.StringIdentifier; import nova.internal.core.Game; /** @@ -37,7 +38,7 @@ public class BWItemFactory extends ItemFactory { private final int meta; public BWItemFactory(net.minecraft.item.Item item, int meta) { - super(net.minecraft.item.Item.itemRegistry.getNameForObject(item) + (item.getHasSubtypes() ? ":" + meta : ""), () -> new BWItem(item, meta, null)); + super(new StringIdentifier(net.minecraft.item.Item.itemRegistry.getNameForObject(item) + (item.getHasSubtypes() ? ":" + meta : "")), () -> new BWItem(item, meta, null)); this.item = item; this.meta = meta; diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java index 2b5c54df3..877218168 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java @@ -36,6 +36,7 @@ import nova.core.loader.Loadable; import nova.core.nativewrapper.NativeConverter; import nova.core.retention.Data; +import nova.core.util.id.Identifier; import nova.core.wrapper.mc.forge.v18.launcher.NovaMinecraft; import nova.core.wrapper.mc.forge.v18.util.ModCreativeTab; import nova.core.wrapper.mc.forge.v18.wrapper.block.BlockConverter; @@ -76,7 +77,8 @@ public Item toNova(ItemStack itemStack) { return getNovaItem(itemStack).setCount(itemStack.stackSize); } - //TODO: Why is this method separate? + // This method is seperate because it recursively calls itself when the ItemStack's + // damage value is {@link net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE}. public Item getNovaItem(ItemStack itemStack) { if (itemStack.getItemDamage() == net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE) { // TODO: Deal withPriority wildcard meta values - important for the ore dictionary @@ -107,7 +109,7 @@ public ItemStack toNative(Item item) { if (item instanceof BWItem) { return ((BWItem) item).makeItemStack(item.count()); } else { - ItemFactory itemFactory = Game.items().get(item.getID().asString()).get();// TODO? + ItemFactory itemFactory = Game.items().get(item.getID()).get(); FWNBTTagCompound tag = new FWNBTTagCompound(item); MinecraftItemMapping mapping = get(itemFactory); @@ -134,7 +136,7 @@ public ItemStack toNative(ItemFactory itemFactory) { return result; } - public ItemStack toNative(String id) { + public ItemStack toNative(Identifier id) { return toNative(Game.items().get(id).get().build().setCount(1)); } diff --git a/src/main/java/nova/core/component/fluid/Fluid.java b/src/main/java/nova/core/component/fluid/Fluid.java index 675c36a57..658169a9a 100644 --- a/src/main/java/nova/core/component/fluid/Fluid.java +++ b/src/main/java/nova/core/component/fluid/Fluid.java @@ -140,12 +140,12 @@ public int hashCode() { @Override public void save(Data data) { Storable.super.save(data); - data.put("id", factory.getID().asString()); // TODO? + data.put("id", factory.getID()); } @Override public void load(Data data) { Storable.super.load(data); - factory = Game.fluids().get(data.get("id")).get(); // FIXME + factory = Game.fluids().get(data.getIdentifier("id")).get(); } } diff --git a/src/main/java/nova/core/util/id/UniqueIdentifiable.java b/src/main/java/nova/core/util/id/UniqueIdentifiable.java index f8e939dd3..29bb62403 100644 --- a/src/main/java/nova/core/util/id/UniqueIdentifiable.java +++ b/src/main/java/nova/core/util/id/UniqueIdentifiable.java @@ -20,8 +20,6 @@ package nova.core.util.id; -import nova.core.util.id.UUIDIdentifier; - /** * A generic interface signifying that this object is uniquely identifiable * by an ID. @@ -45,5 +43,5 @@ default Identifier getID() { * @return the ID * @see #getID() */ - UUIDIdentifier getUniqueID(); // TODO maybe this should return a simple Identifier + UUIDIdentifier getUniqueID(); } From fca42491406e494775e8b69135675969f274dcb6 Mon Sep 17 00:00:00 2001 From: ExE Boss Date: Sun, 8 Jan 2017 12:58:42 +0100 Subject: [PATCH 10/10] IDs must be nonnull + rename _this to self in equalsImpl + make equals in base identifier types final --- .../java/nova/core/util/id/AbstractIdentifier.java | 11 ++++++----- src/main/java/nova/core/util/id/ClassIdentifier.java | 2 +- src/main/java/nova/core/util/id/EnumIdentifier.java | 2 +- src/main/java/nova/core/util/id/StringIdentifier.java | 2 +- src/main/java/nova/core/util/id/UUIDIdentifier.java | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/nova/core/util/id/AbstractIdentifier.java b/src/main/java/nova/core/util/id/AbstractIdentifier.java index d5e3111fc..0ce1858a9 100644 --- a/src/main/java/nova/core/util/id/AbstractIdentifier.java +++ b/src/main/java/nova/core/util/id/AbstractIdentifier.java @@ -20,6 +20,7 @@ public abstract class AbstractIdentifier implements Identifier { * @param id The ID. */ public AbstractIdentifier(T id) { + Objects.requireNonNull(id); this.id = id; } @@ -41,10 +42,10 @@ public int hashCode() { @Override public abstract boolean equals(Object other); - protected static final boolean equalsImpl(Identifier _this, Object other, Class superclass, Function getter) { - if (_this == other) return true; - if (_this == null || other == null) return false; - if (!superclass.isAssignableFrom(_this.getClass()) || !superclass.isAssignableFrom(other.getClass())) return false; - return Objects.equals(getter.apply((T)_this), getter.apply((T)other)); + protected static final boolean equalsImpl(Identifier self, Object other, Class superclass, Function getter) { + if (self == other) return true; + if (self == null || other == null) return false; + if (!superclass.isAssignableFrom(self.getClass()) || !superclass.isAssignableFrom(other.getClass())) return false; + return Objects.equals(getter.apply((T)self), getter.apply((T)other)); } } diff --git a/src/main/java/nova/core/util/id/ClassIdentifier.java b/src/main/java/nova/core/util/id/ClassIdentifier.java index b94114f0f..8bd2ee263 100644 --- a/src/main/java/nova/core/util/id/ClassIdentifier.java +++ b/src/main/java/nova/core/util/id/ClassIdentifier.java @@ -41,7 +41,7 @@ public Class asClass() { } @Override - public boolean equals(Object other) { + public final boolean equals(Object other) { return equalsImpl(this, other, ClassIdentifier.class, ClassIdentifier::asClass); } diff --git a/src/main/java/nova/core/util/id/EnumIdentifier.java b/src/main/java/nova/core/util/id/EnumIdentifier.java index 1b89f9235..f20f52214 100644 --- a/src/main/java/nova/core/util/id/EnumIdentifier.java +++ b/src/main/java/nova/core/util/id/EnumIdentifier.java @@ -34,7 +34,7 @@ public E asEnum() { @Override @SuppressWarnings("rawtypes") - public boolean equals(Object other) { + public final boolean equals(Object other) { return equalsImpl(this, other, EnumIdentifier.class, EnumIdentifier::asEnum); } diff --git a/src/main/java/nova/core/util/id/StringIdentifier.java b/src/main/java/nova/core/util/id/StringIdentifier.java index ef9aa6038..55331d644 100644 --- a/src/main/java/nova/core/util/id/StringIdentifier.java +++ b/src/main/java/nova/core/util/id/StringIdentifier.java @@ -21,7 +21,7 @@ public StringIdentifier(String id) { } @Override - public boolean equals(Object other) { + public final boolean equals(Object other) { return equalsImpl(this, other, StringIdentifier.class, Identifier::asString); } diff --git a/src/main/java/nova/core/util/id/UUIDIdentifier.java b/src/main/java/nova/core/util/id/UUIDIdentifier.java index 153bd2070..d81436356 100644 --- a/src/main/java/nova/core/util/id/UUIDIdentifier.java +++ b/src/main/java/nova/core/util/id/UUIDIdentifier.java @@ -31,7 +31,7 @@ public UUID asUUID() { } @Override - public boolean equals(Object other) { + public final boolean equals(Object other) { return equalsImpl(this, other, UUIDIdentifier.class, UUIDIdentifier::asUUID); }