summaryrefslogtreecommitdiff
path: root/src/main/java/net/cshift/transit
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/net/cshift/transit')
-rw-r--r--src/main/java/net/cshift/transit/Transit.java47
-rw-r--r--src/main/java/net/cshift/transit/network/Channel.java146
-rw-r--r--src/main/java/net/cshift/transit/network/INode.java74
-rw-r--r--src/main/java/net/cshift/transit/network/PoolManifest.java42
-rw-r--r--src/main/java/net/cshift/transit/network/packet/DynamicPacket.java43
-rw-r--r--src/main/java/net/cshift/transit/network/packet/IDynamicPacket.java11
-rw-r--r--src/main/java/net/cshift/transit/network/packet/IStaticPacket.java23
-rw-r--r--src/main/java/net/cshift/transit/network/packet/StaticPacket.java36
-rw-r--r--src/main/java/net/cshift/transit/type/SimpleTypes.java43
-rw-r--r--src/main/java/net/cshift/transit/type/TFluid.java34
-rw-r--r--src/main/java/net/cshift/transit/type/TItem.java57
-rw-r--r--src/main/java/net/cshift/transit/type/TMana.java31
-rw-r--r--src/main/java/net/cshift/transit/type/Type.java282
-rw-r--r--src/main/java/net/cshift/transit/type/group/GroupRegistry.java116
-rw-r--r--src/main/java/net/cshift/transit/type/group/SimpleGroups.java58
-rw-r--r--src/main/java/net/cshift/transit/type/group/TypeGroup.java230
16 files changed, 1273 insertions, 0 deletions
diff --git a/src/main/java/net/cshift/transit/Transit.java b/src/main/java/net/cshift/transit/Transit.java
new file mode 100644
index 0000000..3663fbe
--- /dev/null
+++ b/src/main/java/net/cshift/transit/Transit.java
@@ -0,0 +1,47 @@
+/*
+ MIT License
+
+ Copyright (c) 2023 Kyle Gunger
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+package net.cshift.transit;
+
+import net.fabricmc.api.ModInitializer;
+
+import org.slf4j.*;
+
+import net.cshift.transit.type.group.*;
+
+/**
+ * @author Kyle Gunger
+ * @apiNote This is the main entry point for Transit. The api is mostly intended for use on server-side connections.
+ */
+public class Transit implements ModInitializer {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger("Transit API");
+
+ @Override
+ public void onInitialize() {
+ LOGGER.info("Transit API: Providing a thin wrapper over reality!");
+ SimpleGroups.init();
+ }
+
+}
diff --git a/src/main/java/net/cshift/transit/network/Channel.java b/src/main/java/net/cshift/transit/network/Channel.java
new file mode 100644
index 0000000..311ed4b
--- /dev/null
+++ b/src/main/java/net/cshift/transit/network/Channel.java
@@ -0,0 +1,146 @@
+/*
+ MIT License
+
+ Copyright (c) 2023 Kyle Gunger
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+package net.cshift.transit.network;
+
+import net.cshift.transit.network.packet.IStaticPacket;
+import net.cshift.transit.type.group.GroupRegistry;
+import net.cshift.transit.type.group.TypeGroup;
+
+/**
+ * @author Kyle Gunger
+ * @apiNote A channel represents a connection between two nodes. It is able to send data in packets, and serves as a way to organize incoming traffic.
+ * @param <D> The type of data the packets will be transfering
+ */
+public final class Channel<D> {
+ private INode to;
+ private int id;
+ private String group;
+ private Class<D> baseClass;
+
+ /** This constructor should be called by a node approving a connection. The approving node can give the connection an ID and group.
+ * Negative IDs indicate a terminated connection, so do not initialize the class with a negative ID.
+ *
+ * @param node The recieving node
+ * @param id The channel's id, as assigned by the recieving node. In most cases, this will match the pool ID as a way to match channels to pools.
+ * @param group
+ */
+ public Channel(INode node, int id, String group, Class<D> baseClass)
+ {
+ to = node;
+ this.id = id;
+ this.group = group;
+ this.baseClass = baseClass;
+ }
+
+
+
+ // ####################
+ // # Channel specific #
+ // ####################
+
+ /** The recieving INode
+ *
+ * @return
+ */
+ public INode getReciever()
+ {
+ return to;
+ }
+
+ /** The ID of the connection, assigned by the recieving INode
+ *
+ * @return
+ */
+ public int getID()
+ {
+ return id;
+ }
+
+ /** The group that the channel operates on
+ *
+ * @return
+ */
+ public TypeGroup<D> getGroup() {
+ return GroupRegistry.<D>groupByID(group, baseClass);
+ }
+
+ /** Returns true if the connection has been terminated
+ *
+ * @return
+ */
+ public boolean isTerminated()
+ {
+ return id < 0;
+ }
+
+
+
+ // ################################
+ // # Info from the recieving node #
+ // ################################
+
+ /** Pressure
+ *
+ * @apiNote This part of the api is not properly documented yet, and it's use is not reccommended for cross-mod communications.
+ * @return A Number representing the pressure from the channel (in base group units).
+ */
+ public Number pressure()
+ {
+ return to.getPressure(this);
+ }
+
+ /** Max transfer rate
+ *
+ * @return A Number representing the max transfer rate from the channel (in base group units per tick).
+ */
+ public Number rate()
+ {
+ return to.getRate(this);
+ }
+
+
+
+ // ################################
+ // # Interact with the other node #
+ // ################################
+
+ /** Terminates the connection and relays the termination to the recieving node
+ */
+ public void terminate()
+ {
+ id = -1;
+ to.onTerminate(this);
+ }
+
+ /** Send a packet to the recieving node
+ *
+ * @param packet the packet to send
+ * @return The overflow data if the packet is only partially accepted. {@code null} otherwise.
+ */
+ public IStaticPacket<D> send(IStaticPacket<D> packet)
+ {
+ return to.<D>accept(packet, this);
+ }
+}
diff --git a/src/main/java/net/cshift/transit/network/INode.java b/src/main/java/net/cshift/transit/network/INode.java
new file mode 100644
index 0000000..2a6e865
--- /dev/null
+++ b/src/main/java/net/cshift/transit/network/INode.java
@@ -0,0 +1,74 @@
+package net.cshift.transit.network;
+
+import net.cshift.transit.network.packet.*;
+
+/**
+ * @author Kyle Gunger
+ * @apiNote A node inside or outside a system.
+ */
+public interface INode
+{
+ /** Returns a pool manifest for the INode
+ *
+ */
+ public PoolManifest getManifest();
+
+
+
+ // ###############
+ // # Connections #
+ // ###############
+
+ /** Call this function to establish a specific connection with a node.
+ *
+ * @param <T> The type of connection being asked for
+ * @param poolID The ID of the pool the channel will interface with (see PoolManifest)
+ * @param asker The asking node
+ * @return A channel if the node accepts the request, {@code null} otherwise
+ */
+ public <T> Channel<T> connect(int poolID, String group, INode asker);
+
+ /** Call this function to establish a default connection with a node.
+ *
+ * @param <T> The type of connection being asked for
+ * @param group The group that is being connected to
+ * @param asker The asking node
+ * @return A channel if the node accepts the request, {@code null} otherwise
+ */
+ public <T> Channel<T> connectDefault(String group, INode asker);
+
+ /** Accept a packet from a channel (or not).
+ *
+ * @apiNote Do not call this function, use Channel.send(packet) instead.
+ * @param <T> The type of the packet and channel
+ * @param packet The packet to be vetted
+ * @param channel The channel which the packet is coming through
+ * @return The overflow data if the packet is only partially accepted. {@code null} otherwise.
+ */
+ public <T> IStaticPacket<T> accept(IStaticPacket<T> packet, Channel<T> channel);
+
+ /** Pressure
+ *
+ * @apiNote Do not call this function, use Channel.pressure() instead.
+ * @param channel The channel asking for the pressure
+ * @return A Number representing the pressure from the channel (in base group units).
+ */
+ public <T> Number getPressure(Channel<T> channel);
+
+ /** Transfer rate
+ *
+ * @apiNote Do not call this function, use Channel.rate() instead.
+ * @param channel The channel asking for the transfer rate
+ * @return A Number representing the transfer rate from the channel (in base group units per tick).
+ */
+ public <T> Number getRate(Channel<T> channel);
+
+ /** Called when a channel is terminated
+ *
+ * @apiNote Do not call this function, use Channel.terminate() instead.
+ * @param <T> The type of the channel
+ * @param channel The channel being terminated
+ */
+ public <T> void onTerminate(Channel<T> channel);
+
+}
diff --git a/src/main/java/net/cshift/transit/network/PoolManifest.java b/src/main/java/net/cshift/transit/network/PoolManifest.java
new file mode 100644
index 0000000..bc406fe
--- /dev/null
+++ b/src/main/java/net/cshift/transit/network/PoolManifest.java
@@ -0,0 +1,42 @@
+package net.cshift.transit.network;
+
+/**
+ * @author Kyle Gunger
+ * @apiNote A pool manifest represents a set of possible data/resource pools that another node can request a channel to.
+ */
+public abstract class PoolManifest {
+
+ /** Represents the number of pools that the node has access to.
+ * @apiNote A "pool" in this context represents an independent network of resources.
+ * Each network in the pool may represent a different TypeGroup.
+ * Pool zero should be the default group that simple nodes will attempt to connect to.
+ * @param group The TypeGroup that the pool belongs to
+ */
+ public abstract int poolCount();
+
+ /** If the mod supports named pools, the names can be queried through this function.
+ *
+ * @param group The TypeGroup the pool belongs to
+ * @param pool Array-like index for pool (gotten from poolCount)
+ */
+ public String poolName(int pool) {
+ return "";
+ }
+
+ /** Returns true if the pool with the given id supports the given group
+ *
+ * @param pool The pool ID to query
+ * @param group The TypeGroup to query
+ * @return {@code true} if the pool supports the specified group, {@code false} otherwise
+ */
+ public abstract boolean poolProvides(int pool, String group);
+
+ /** If the mod supports pool descriptions, they can be accessed by this method.
+ *
+ * @param group The TypeGroup the pool belongs to
+ * @param pool Array-like index for pool (gotten from poolCount)
+ */
+ public String poolDescription(int pool) {
+ return "";
+ }
+}
diff --git a/src/main/java/net/cshift/transit/network/packet/DynamicPacket.java b/src/main/java/net/cshift/transit/network/packet/DynamicPacket.java
new file mode 100644
index 0000000..beeea97
--- /dev/null
+++ b/src/main/java/net/cshift/transit/network/packet/DynamicPacket.java
@@ -0,0 +1,43 @@
+package net.cshift.transit.network.packet;
+
+import net.cshift.transit.type.Type;
+
+/**
+ * Simple packet which stores a value which can change.
+ *
+ * @param <D> The type parameter of the Type being transported
+ * @author Kyle Gunger
+ *
+ */
+public class DynamicPacket<D> implements IDynamicPacket<D> {
+ private Object data;
+ private Type<D> type;
+
+ /** Constructor. Stores the given data and uses the given type.
+ *
+ * @param dat The packet's data
+ * @param t The packet's type
+ */
+ public DynamicPacket(Object dat, Type<D> t)
+ {
+ data = dat;
+ type = t;
+ }
+
+ @Override
+ public Object getData()
+ {
+ return data;
+ }
+
+ @Override
+ public void setData(Object dat)
+ {
+ data = dat;
+ }
+
+ @Override
+ public Type<D> getType() {
+ return type;
+ }
+}
diff --git a/src/main/java/net/cshift/transit/network/packet/IDynamicPacket.java b/src/main/java/net/cshift/transit/network/packet/IDynamicPacket.java
new file mode 100644
index 0000000..fca43e5
--- /dev/null
+++ b/src/main/java/net/cshift/transit/network/packet/IDynamicPacket.java
@@ -0,0 +1,11 @@
+package net.cshift.transit.network.packet;
+
+/** Interface describing a packet where the data can change as it's transferred.
+ *
+ * @param <D> The type parameter of the Type being transported
+ * @author Kyle Gunger
+ */
+public interface IDynamicPacket<D> extends IStaticPacket<D>{
+ /** Set the packet's data. */
+ public void setData(Object dat);
+}
diff --git a/src/main/java/net/cshift/transit/network/packet/IStaticPacket.java b/src/main/java/net/cshift/transit/network/packet/IStaticPacket.java
new file mode 100644
index 0000000..506a166
--- /dev/null
+++ b/src/main/java/net/cshift/transit/network/packet/IStaticPacket.java
@@ -0,0 +1,23 @@
+package net.cshift.transit.network.packet;
+
+import net.cshift.transit.type.*;
+
+/** Interface describing an unchanging packet.
+ *
+ * @param <D> The type parameter of the Type being transported
+ * @author Kyle Gunger
+ */
+public interface IStaticPacket<D>
+{
+ /**Get the packet's data.
+ *
+ * @return The packet's data
+ */
+ public Object getData();
+
+ /**Get the packet's type.
+ *
+ * @return IType<?> The type of the packet
+ */
+ public Type<D> getType();
+}
diff --git a/src/main/java/net/cshift/transit/network/packet/StaticPacket.java b/src/main/java/net/cshift/transit/network/packet/StaticPacket.java
new file mode 100644
index 0000000..3daefb0
--- /dev/null
+++ b/src/main/java/net/cshift/transit/network/packet/StaticPacket.java
@@ -0,0 +1,36 @@
+package net.cshift.transit.network.packet;
+
+import net.cshift.transit.type.*;
+
+/** Simple packet which stores an unchanging value.
+ * @author Kyle Gunger
+ *
+ * @param <D> The data type (Object) that the packet transfers.
+ */
+public class StaticPacket<D> implements IStaticPacket<D>
+{
+ private Object data;
+ private Type<D> type;
+
+ /** Constructor. Stores the given data and uses the given type.
+ *
+ * @param dat The packet's data
+ * @param t The packet's type
+ */
+ public StaticPacket(Object dat, Type<D> t)
+ {
+ data = dat;
+ type = t;
+ }
+
+ @Override
+ public Object getData()
+ {
+ return data;
+ }
+
+ @Override
+ public Type<D> getType() {
+ return type;
+ }
+}
diff --git a/src/main/java/net/cshift/transit/type/SimpleTypes.java b/src/main/java/net/cshift/transit/type/SimpleTypes.java
new file mode 100644
index 0000000..1d3d89e
--- /dev/null
+++ b/src/main/java/net/cshift/transit/type/SimpleTypes.java
@@ -0,0 +1,43 @@
+/*
+ MIT License
+
+ Copyright (c) 2023 Kyle Gunger
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+package net.cshift.transit.type;
+
+public final class SimpleTypes {
+ /** Transfers energy. Energy is stored as a numeric.
+ */
+ public static final Type<Long> TransitJoule = new Type<Long>("Joule", "ENERGY", Long.class);
+
+ /** Transfers mana. TMana stores mana count and type.
+ */
+ public static final Type<TMana> TransitMana = new Type<TMana>("TMana", "MANA", TMana.class);
+
+ /** Transfers items. TItem stores an item and an item count.
+ */
+ public static final Type<TItem> TransitItem = new Type<TItem>("TItem", "ITEM", TItem.class);
+
+ /** Transfers fluid. TFluid stores fluid and mB.
+ */
+ public static final Type<TFluid> TransitFluid = new Type<TFluid>("TFluid", "FLUID", TFluid.class);
+}
diff --git a/src/main/java/net/cshift/transit/type/TFluid.java b/src/main/java/net/cshift/transit/type/TFluid.java
new file mode 100644
index 0000000..c979830
--- /dev/null
+++ b/src/main/java/net/cshift/transit/type/TFluid.java
@@ -0,0 +1,34 @@
+package net.cshift.transit.type;
+
+import net.minecraft.fluid.*;
+
+/** Units of fluid.
+ * @author Kyle Gunger
+ */
+public class TFluid {
+ private Fluid fluid;
+ private Number mb;
+
+ /** Constructor.
+ * Since a bucket of fluid is the same as a block of a fluid, mb can be called millibuckets or milliblocks.
+ *
+ * @param f Fluid stored (Water/Lava/etc.)
+ * @param mB Count of fluid (droplets)
+ */
+ public TFluid(Fluid f, Number mB) {
+ fluid = f;
+ mb = mB;
+ }
+
+ /** Get the fluid stored.
+ */
+ public Fluid getFluid() {
+ return fluid;
+ }
+
+ /** Get the millibuckets stored.
+ */
+ public Number getMilliBuckets() {
+ return mb;
+ }
+}
diff --git a/src/main/java/net/cshift/transit/type/TItem.java b/src/main/java/net/cshift/transit/type/TItem.java
new file mode 100644
index 0000000..ad59e9f
--- /dev/null
+++ b/src/main/java/net/cshift/transit/type/TItem.java
@@ -0,0 +1,57 @@
+/*
+ MIT License
+
+ Copyright (c) 2023 Kyle Gunger
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+package net.cshift.transit.type;
+
+import net.minecraft.item.*;
+
+/** Item storage
+ * @author Kyle Gunger
+ */
+public class TItem {
+ private Item item;
+ private Number count;
+
+ /** Constructor.
+ *
+ * @param i Item stored
+ * @param c Item count
+ */
+ public TItem(Item i, Number c) {
+ item = i;
+ count = c;
+ }
+
+ /** Get the item stored.
+ */
+ public Item getItem() {
+ return item;
+ }
+
+ /** Get the item count.
+ */
+ public Number getCount() {
+ return count;
+ }
+}
diff --git a/src/main/java/net/cshift/transit/type/TMana.java b/src/main/java/net/cshift/transit/type/TMana.java
new file mode 100644
index 0000000..468b04f
--- /dev/null
+++ b/src/main/java/net/cshift/transit/type/TMana.java
@@ -0,0 +1,31 @@
+package net.cshift.transit.type;
+
+/** Units of mana.
+ * @author Kyle Gunger
+ */
+public class TMana {
+ private String type;
+ private Number count;
+
+ /** Constructor
+ *
+ * @param t Type of mana (Fire/Water/Dark/Light/etc.) leave empty string for an untyped mana system.
+ * @param ct Count of mana
+ */
+ public TMana(String t, Number ct) {
+ type = t;
+ count = ct;
+ }
+
+ /** Get the mana type.
+ */
+ public String getType() {
+ return type;
+ }
+
+ /** Get the mana stored.
+ */
+ public Number getCount() {
+ return count;
+ }
+}
diff --git a/src/main/java/net/cshift/transit/type/Type.java b/src/main/java/net/cshift/transit/type/Type.java
new file mode 100644
index 0000000..e7e38b9
--- /dev/null
+++ b/src/main/java/net/cshift/transit/type/Type.java
@@ -0,0 +1,282 @@
+/*
+ MIT License
+
+ Copyright (c) 2023 Kyle Gunger
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+package net.cshift.transit.type;
+
+import net.cshift.transit.network.packet.*;
+
+/**@author Kyle Gunger
+ *
+ * @param <T> The type of object transfered by packets of this type
+ */
+public class Type<T>
+{
+ protected final String typeID;
+ protected final String groupID;
+ private final Class<?> underlying;
+
+ // Should not override, but you can if you must
+ public Type(String tID, String gID, Class<?> underlying)
+ {
+ typeID = tID;
+ groupID = gID;
+ this.underlying = underlying;
+ }
+
+
+
+ // ##########################################
+ // # Converting from this type to base type #
+ // ##########################################
+
+ /** Return the data formatted in the given group's base type.
+ * If creating a new type, override this function if required.
+ *
+ * @param data The data (of this type)
+ * @param group The group asking for the conversion
+ * @return The data in the group's base type
+ */
+ @SuppressWarnings("unchecked")
+ public T toBase(Object data, String group)
+ {
+ // Assume the underlying is the same as T for this very simple case
+ if (data.getClass().equals(this.getUnderlying()))
+ return (T) data;
+ return null;
+ }
+
+ /** Return the data formatted in the default group's base type.
+ *
+ * @param data The data (of this type)
+ * @return The data in the group's base type
+ */
+ public final T toBase(Object data)
+ {
+ return this.toBase(data, this.groupID);
+ }
+
+ /** Return the packet's data formatted in the given group's base type.
+ *
+ * @param packet The packet (of this type)
+ * @param group The group asking for the conversion
+ * @return The packet's data in the group's base type
+ */
+ public final T toBase(IStaticPacket<T> packet, String group)
+ {
+ if(packet.getType().equals(this))
+ return this.toBase(packet.getData(), group);
+ return null;
+ }
+
+ /** Return the packet's data formatted in the default group's base type.
+ *
+ * @param packet The packet (of this type)
+ * @return The packet's data in the group's base type
+ */
+ public final T toBase(IStaticPacket<T> packet)
+ {
+ return this.toBase(packet, this.groupID);
+ }
+
+
+
+ // ##########################################
+ // # Converting from base type to this type #
+ // ##########################################
+
+ /** Convert data from the given group's base type to this type.
+ * If creating a new type, override this function if required.
+ *
+ * @param data The base data
+ * @param group The group asking for the conversion
+ * @return The converted data, in the Type's underlying
+ */
+ public Object fromBase(T data, String group)
+ {
+ // Assume T is the same as the underlying
+ return data;
+ }
+
+ /** Convert data from the default group's base type to this type.
+ *
+ * @param data The base data
+ * @return The converted data, in the Type's underlying
+ */
+ public final Object fromBase(T data)
+ {
+ return fromBase(data, this.groupID);
+ }
+
+ /** Create a packet from data formatted in the given group's base type.
+ *
+ * @param data The base data
+ * @param group The group asking for the conversion
+ * @return A packet containing the converted data in the Type's underlying
+ */
+ public final IStaticPacket<T> packetFromBase(T data, String group)
+ {
+ return new StaticPacket<T>(this.fromBase(data, group), this);
+ }
+
+ /** Create a packet from data formatted in the default group's base type.
+ *
+ * @param data The base data
+ * @return The packet's data in the group's base type
+ */
+ public final IStaticPacket<T> packetFromBase(T data)
+ {
+ return packetFromBase(data, this.groupID);
+ }
+
+
+
+ // ###########################################
+ // # Converting from other type to this type #
+ // ###########################################
+
+ /** Convert data from another type to this type in the given group.
+ * If creating a new type, override this function if required.
+ *
+ * @param from The type to convert from
+ * @param group The group we are converting within
+ * @param data The data to convert
+ * @return The data formatted in this type
+ */
+ public Object convertFrom(Type<T> from, Object data, String group) {
+ return this.fromBase(from.toBase(data, group), group);
+ }
+
+ /** Convert data from another type to this type in the default group.
+ *
+ * @param from The type to convert from
+ * @param data The data to convert
+ * @return The data formatted in this type
+ */
+ public final Object convertFrom(Type<T> from, Object data) {
+ return convertFrom(from, data, from.groupID);
+ }
+
+ /** Convert a packet using another type to a packet using this type within the given group.
+ *
+ * @param packet The packet to convert
+ * @param group The group to convert within
+ * @return The new packet formatted in this type
+ */
+ public final IStaticPacket<T> convertFrom(IStaticPacket<T> packet, String group) {
+ return new StaticPacket<T>(convertFrom(packet.getType(), packet.getData(), group), this);
+ }
+
+ /** Convert a packet using another type to a packet using this type within the default group.
+ *
+ * @param packet The packet to convert
+ * @return The new packet formatted in this type
+ */
+ public final IStaticPacket<T> convertFrom(IStaticPacket<T> packet) throws ClassCastException {
+ return this.convertFrom(packet, packet.getType().groupID);
+ }
+
+
+
+ // ###########################################
+ // # Converting from other type to this type #
+ // ###########################################
+
+ /** Convert data from this type to another type in the given group.
+ *
+ * @param from The type to convert from
+ * @param group The group we are converting within
+ * @param data The data to convert
+ * @return The data formatted in this type
+ */
+ public final Object convertTo(Type<T> to, Object data, String group) {
+ return to.convertFrom(this, data, group);
+ }
+
+ /** Convert data from this type to another type in the default group.
+ *
+ * @param from The type to convert from
+ * @param data The data to convert
+ * @return The data formatted in this type
+ */
+ public final Object convertTo(Type<T> to, Object data) {
+ return to.convertFrom(this, data, this.groupID);
+ }
+
+ /** Convert a packet using this type to a packet using another type within the given group.
+ *
+ * @param packet The packet to convert
+ * @param group The group to convert within
+ * @return The new packet formatted in this type
+ */
+ public final IStaticPacket<T> convertTo(Type<T> to, IStaticPacket<T> packet, String group) {
+ return to.convertFrom(packet, group);
+ }
+
+ /** Convert a packet using this type to a packet using another type within the default group.
+ *
+ * @param packet The packet to convert
+ * @return The new packet formatted in this type
+ */
+ public final IStaticPacket<T> convertTo(Type<T> to, IStaticPacket<T> packet) {
+ return to.convertFrom(packet, this.groupID);
+ }
+
+
+
+ // ##############################
+ // # Utility and info functions #
+ // ##############################
+
+ /** The type identifier. Gives the normal type identity of the type.
+ *
+ * @return String
+ */
+ public final String getType()
+ {
+ return typeID;
+ }
+
+ /** The group identifier. Gives the normal group identity of the type.
+ *
+ * @return String
+ */
+ public final String getGroup()
+ {
+ return groupID;
+ }
+
+ /** The underlying class which this Type uses to implement functionality within the mod
+ *
+ * @return Class<?>
+ */
+ public final Class<?> getUnderlying()
+ {
+ return underlying;
+ }
+
+ @Override
+ public final String toString() {
+ return groupID + ":" + typeID;
+ }
+}
diff --git a/src/main/java/net/cshift/transit/type/group/GroupRegistry.java b/src/main/java/net/cshift/transit/type/group/GroupRegistry.java
new file mode 100644
index 0000000..2c0b592
--- /dev/null
+++ b/src/main/java/net/cshift/transit/type/group/GroupRegistry.java
@@ -0,0 +1,116 @@
+/*
+ MIT License
+
+ Copyright (c) 2023 Kyle Gunger
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+package net.cshift.transit.type.group;
+
+import java.security.InvalidKeyException;
+import java.util.HashMap;
+
+import org.slf4j.*;
+
+import net.cshift.transit.type.Type;
+
+public final class GroupRegistry {
+ private static final HashMap<String, TypeGroup<?>> GROUPS = new HashMap<String, TypeGroup<?>>();
+
+ private static final Logger LOGGER = LoggerFactory.getLogger("Transit API/Group Registry");
+
+ private GroupRegistry() {}
+
+ public static final boolean addGroup(TypeGroup<?> group) {
+ if (GROUPS.containsKey(group.getGroup())) {
+ LOGGER.warn("Failed to add group " + group + " to the registry. Did another mod add a group with the same name?");
+ return false;
+ }
+
+ GROUPS.put(group.getGroup(), group);
+ LOGGER.info("Successfully added group " + group + " to the registry.");
+
+ return true;
+ }
+
+ /** Get the requested type group via ID
+ *
+ * @param <B> The base type of the type group
+ * @param groupID
+ * @param baseClass
+ * @throws ClassCastException if the group is not of the provided class type
+ * @return The group (properly casted) if it exists, or null otherwise
+ */
+ @SuppressWarnings("unchecked")
+ public static final <B> TypeGroup<B> groupByID(String groupID, Class<B> baseClass) throws ClassCastException {
+ if (GROUPS.containsKey(groupID)) {
+ TypeGroup<?> g = GROUPS.get(groupID);
+ if (g.getBaseClass().equals(baseClass)) {
+ return (TypeGroup<B>) g;
+ } else {
+ throw new ClassCastException(
+ "Group " + g.getGroup() + " was requested as TypeGroup<" +
+ baseClass.getName() + ">, but the group is actually TypeGroup<" +
+ g.getBaseClass().getName() + ">"
+ );
+ }
+ }
+
+ return null;
+ }
+
+ /** Get the wildcard generic TypeGroup via the groupID
+ *
+ * @param groupID The ID of the group to get
+ * @return The group if it exists, or null otherwise
+ */
+ public static final TypeGroup<?> groupByID(String groupID) {
+ if (GROUPS.containsKey(groupID)) {
+ return GROUPS.get(groupID);
+ }
+
+ return null;
+ }
+
+ /** Get the requested type via
+ *
+ * @param <B>
+ * @param groupID
+ * @param typeID
+ * @param baseClass
+ * @return
+ * @throws ClassCastException
+ */
+ public static final <B> Type<B> typeByIdentity(String groupID, String typeID, Class<B> baseClass) throws ClassCastException {
+ TypeGroup<B> group = GroupRegistry.<B>groupByID(groupID, baseClass);
+
+ if(group != null && group.isInGroup(typeID)) {
+ try {
+ return group.getType(typeID);
+ } catch (InvalidKeyException e) {
+ // Should never happen, since we just checked that the type is in the group
+ LOGGER.error("Unreachable in typeByIdentity: trying to get type '" + groupID + ":" + typeID + "'");
+ e.printStackTrace();
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/src/main/java/net/cshift/transit/type/group/SimpleGroups.java b/src/main/java/net/cshift/transit/type/group/SimpleGroups.java
new file mode 100644
index 0000000..6046db5
--- /dev/null
+++ b/src/main/java/net/cshift/transit/type/group/SimpleGroups.java
@@ -0,0 +1,58 @@
+/*
+ MIT License
+
+ Copyright (c) 2023 Kyle Gunger
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+package net.cshift.transit.type.group;
+
+import org.slf4j.*;
+
+import net.cshift.transit.type.*;
+
+public final class SimpleGroups {
+ /** Transfers energy. Basic unit is TJoule (Transit Joule).
+ */
+ public static final TypeGroup<Long> ENERGY = new TypeGroup<Long>(SimpleTypes.TransitJoule, Long.class);
+
+ /** Transfers mana. Basic unit is TMana (Transit Mana).
+ */
+ public static final TypeGroup<TMana> MANA = new TypeGroup<TMana>(SimpleTypes.TransitMana, TMana.class);
+
+ /** Transfers items. Basic unit is TItem.
+ */
+ public static final TypeGroup<TItem> ITEM = new TypeGroup<TItem>(SimpleTypes.TransitItem, TItem.class);
+
+ /** Transfers fluids. Basic unit is TFluid.
+ */
+ public static final TypeGroup<TFluid> FLUID = new TypeGroup<TFluid>(SimpleTypes.TransitFluid, TFluid.class);
+
+ private static final Logger LOGGER = LoggerFactory.getLogger("Transit API/Simple Groups");
+
+ public static final void init()
+ {
+ LOGGER.info("Initializing simple groups");
+ GroupRegistry.addGroup(ENERGY);
+ GroupRegistry.addGroup(MANA);
+ GroupRegistry.addGroup(ITEM);
+ GroupRegistry.addGroup(FLUID);
+ }
+}
diff --git a/src/main/java/net/cshift/transit/type/group/TypeGroup.java b/src/main/java/net/cshift/transit/type/group/TypeGroup.java
new file mode 100644
index 0000000..ee19885
--- /dev/null
+++ b/src/main/java/net/cshift/transit/type/group/TypeGroup.java
@@ -0,0 +1,230 @@
+/*
+ MIT License
+
+ Copyright (c) 2023 Kyle Gunger
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+package net.cshift.transit.type.group;
+
+import java.security.InvalidKeyException;
+import java.util.HashMap;
+
+import org.slf4j.*;
+
+import net.cshift.transit.type.Type;
+
+/**
+ * @author Kyle Gunger
+ * @param <B> The base object which all grouped Types should convert between.
+ */
+public final class TypeGroup<B>
+{
+ // The basic class of the base type which is being transferred
+ private Class<B> baseClass;
+
+ // The base Type (provides the group's identifier)
+ private Type<B> baseType;
+
+ // The list of types.
+ private final HashMap<String, Type<B>> TYPES;
+
+ // Logger for events in the TypeGroup.
+ private static final Logger LOGGER = LoggerFactory.getLogger("Transit API/Type Group");
+
+
+ public TypeGroup(Type<B> base, Class<B> baseClass)
+ {
+ TYPES = new HashMap<String, Type<B>>();
+ baseType = base;
+ this.baseClass = baseClass;
+ addType(base);
+ }
+
+
+ // Type management
+
+ /** Add a Type to the TypeGroup.
+ * The Type must have a group-type combo not already found in this TypeGroup.
+ * Returns {@code true} if the group was added.
+ *
+ * @param type The Type to add
+ * @return
+ */
+ public boolean addType(Type<B> type)
+ {
+ if(TYPES.containsKey(type.getType()))
+ {
+ LOGGER.info("Failed to add type " + type + " to group " + getGroup() + ". Was the type already added?");
+ return false;
+ }
+
+ TYPES.put(type.toString(), type);
+ LOGGER.info("Added type " + type + " to group " + getGroup());
+ return true;
+
+ }
+
+ /** Remove a Type from the TypeGroup.
+ *
+ * @param type The Type to remove
+ * @return
+ */
+ public boolean removeType(Type<B> type)
+ {
+ if(type.toString().equals(baseType.toString())) {
+ LOGGER.warn("Failed to remove type " + type + " from group " + getGroup() + ". This is the base type and can not be removed.");
+ return false;
+ }
+
+ if(TYPES.containsKey(type.toString()))
+ {
+ LOGGER.info("Removed type " + TYPES.remove(type.toString()) + " from group " + getGroup());
+ return true;
+ }
+
+ LOGGER.warn("Failed to remove type " + type + " from group " + getGroup() + ". Are we sure that the type was added to the group first?");
+ return false;
+ }
+
+ /** Remove a type from the group based on it's group-type identifier.
+ *
+ * @param type
+ * @return
+ */
+ public boolean removeType(String groupID, String typeID)
+ {
+ String typeString = groupID + ":" + typeID;
+
+ if(baseType.toString().equals(typeString)) {
+ LOGGER.warn("Failed to remove type " + baseType + " from group " + getGroup() + ". This is the base type and can not be removed.");
+ return false;
+ }
+
+ if(TYPES.containsKey(typeString))
+ {
+ LOGGER.info("Removed type " + TYPES.remove(typeString) + " from group " + getGroup());
+ return true;
+ }
+
+ LOGGER.warn("Failed to remove type " + typeString + " from group " + getGroup() + ". Are we sure that the type was added to the group first?");
+ return false;
+ }
+
+ /** Remove a type from the group based on it's group-type identifier.
+ *
+ * @param type
+ * @return
+ */
+ public boolean removeType(String typeID)
+ {
+ return removeType(getGroup(), typeID);
+ }
+
+
+ // Check if a type is in the group
+
+ /**Check if the type is in the group
+ *
+ * @param type
+ * @return boolean
+ */
+ public boolean isInGroup(Type<B> type)
+ {
+ return TYPES.containsKey(type.toString()) && TYPES.get(type.toString()) == type;
+ }
+
+ /**Check if the type is in the group
+ *
+ * @param groupID
+ * @param typeID
+ * @return boolean
+ */
+ public boolean isInGroup(String groupID, String typeID)
+ {
+ return TYPES.containsKey(groupID + ":" + typeID);
+ }
+
+ /**Check if the type is in the group
+ *
+ * @param typeID
+ * @return boolean
+ */
+ public boolean isInGroup(String typeID)
+ {
+ return isInGroup(getGroup(), typeID);
+ }
+
+ // Get a type in the group
+
+ /**Get the type from the group
+ *
+ * @param groupID The ID of the group the type is originally from
+ * @param typeID The ID of the type
+ * @return Type
+ */
+ public Type<B> getType(String groupID, String typeID) throws InvalidKeyException
+ {
+ String typeString = groupID + ":" + typeID;
+ if (!TYPES.containsKey(typeString))
+ throw new InvalidKeyException("Invalid key in getType (" + typeString + "is not in group" + getGroup() + ")");
+ return TYPES.get(typeString);
+ }
+
+ /**Get the type from the group
+ *
+ * @param typeID The ID of the type
+ * @return Type
+ */
+ public Type<B> getType(String typeID) throws InvalidKeyException
+ {
+ return getType(getGroup(), typeID);
+ }
+
+
+ // DO ALL TYPE CONVERSION USING TYPES.
+
+ /** The group identifier. Given by the Base Group
+ * @return String
+ */
+ public final String getGroup()
+ {
+ return baseType.getGroup();
+ }
+
+ /** The base group type
+ * @return Type<B>
+ */
+ public final Type<B> getBase() {
+ return baseType;
+ }
+
+ /** A Class object which represents the type that the base type uses to transfer data
+ * @return Class<B>
+ */
+ public final Class<B> getBaseClass() {
+ return baseClass;
+ }
+
+ @Override
+ public final String toString() {
+ return this.getGroup();
+ }
+}