Rewrote All the Things #81
@@ -11,7 +11,6 @@ import net.minecraft.network.packet.Packet1Login;
|
||||
import net.minecraft.network.packet.Packet250CustomPayload;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||
import StevenDimDoors.mod_pocketDim.messages.IDataMessage;
|
||||
import cpw.mods.fml.common.network.IConnectionHandler;
|
||||
import cpw.mods.fml.common.network.Player;
|
||||
|
||||
@@ -41,12 +40,11 @@ public class ConnectionHandler implements IConnectionHandler
|
||||
//Send information about all the registered dimensions and links to the client
|
||||
try
|
||||
{
|
||||
IDataMessage message = PocketManager.getState();
|
||||
Packet250CustomPayload packet = new Packet250CustomPayload();
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
DataOutputStream writer = new DataOutputStream(buffer);
|
||||
writer.writeByte(PacketConstants.CLIENT_JOIN_PACKET_ID);
|
||||
message.writeToStream(writer);
|
||||
PocketManager.writePacket(writer);
|
||||
writer.close();
|
||||
packet.channel = PacketConstants.CHANNEL_NAME;
|
||||
packet.data = buffer.toByteArray();
|
||||
|
||||
@@ -7,8 +7,9 @@ import java.io.IOException;
|
||||
import net.minecraft.network.INetworkManager;
|
||||
import net.minecraft.network.packet.Packet250CustomPayload;
|
||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||
import StevenDimDoors.mod_pocketDim.messages.IDataMessage;
|
||||
import StevenDimDoors.mod_pocketDim.messages.IUpdateWatcher;
|
||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||
import StevenDimDoors.mod_pocketDim.watcher.ClientDimData;
|
||||
import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher;
|
||||
import cpw.mods.fml.common.network.IPacketHandler;
|
||||
import cpw.mods.fml.common.network.PacketDispatcher;
|
||||
import cpw.mods.fml.common.network.Player;
|
||||
@@ -22,54 +23,39 @@ public class ServerPacketHandler implements IPacketHandler
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player)
|
||||
{
|
||||
|
||||
}
|
||||
public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player) { }
|
||||
|
||||
private class DimWatcher implements IUpdateWatcher
|
||||
private static class DimWatcher implements IUpdateWatcher<ClientDimData>
|
||||
{
|
||||
@Override
|
||||
public void onCreated(IDataMessage message)
|
||||
public void onCreated(ClientDimData message)
|
||||
{
|
||||
sendMessageToAllPlayers(PacketConstants.CREATE_DIM_PACKET_ID, message);
|
||||
sendDimPacket(PacketConstants.CREATE_DIM_PACKET_ID, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdated(IDataMessage message)
|
||||
public void onDeleted(ClientDimData message)
|
||||
{
|
||||
sendMessageToAllPlayers(PacketConstants.UPDATE_DIM_PACKET_ID, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleted(IDataMessage message)
|
||||
{
|
||||
sendMessageToAllPlayers(PacketConstants.DELETE_DIM_PACKET_ID, message);
|
||||
sendDimPacket(PacketConstants.DELETE_DIM_PACKET_ID, message);
|
||||
}
|
||||
}
|
||||
|
||||
private class LinkWatcher implements IUpdateWatcher
|
||||
private static class LinkWatcher implements IUpdateWatcher<Point4D>
|
||||
{
|
||||
@Override
|
||||
public void onCreated(IDataMessage message)
|
||||
public void onCreated(Point4D message)
|
||||
{
|
||||
sendMessageToAllPlayers(PacketConstants.CREATE_LINK_PACKET_ID, message);
|
||||
sendLinkPacket(PacketConstants.CREATE_LINK_PACKET_ID, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdated(IDataMessage message)
|
||||
public void onDeleted(Point4D message)
|
||||
{
|
||||
sendMessageToAllPlayers(PacketConstants.UPDATE_LINK_PACKET_ID, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleted(IDataMessage message)
|
||||
{
|
||||
sendMessageToAllPlayers(PacketConstants.DELETE_LINK_PACKET_ID, message);
|
||||
sendLinkPacket(PacketConstants.DELETE_LINK_PACKET_ID, message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendMessageToAllPlayers(byte id, IDataMessage message)
|
||||
private static void sendDimPacket(byte id, ClientDimData data)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -77,7 +63,29 @@ public class ServerPacketHandler implements IPacketHandler
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
DataOutputStream writer = new DataOutputStream(buffer);
|
||||
writer.writeByte(id);
|
||||
message.writeToStream(writer);
|
||||
data.write(writer);
|
||||
writer.close();
|
||||
packet.channel = PacketConstants.CHANNEL_NAME;
|
||||
packet.data = buffer.toByteArray();
|
||||
packet.length = packet.data.length;
|
||||
PacketDispatcher.sendPacketToAllPlayers(packet);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
//This shouldn't happen...
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendLinkPacket(byte id, Point4D data)
|
||||
{
|
||||
try
|
||||
{
|
||||
Packet250CustomPayload packet = new Packet250CustomPayload();
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
DataOutputStream writer = new DataOutputStream(buffer);
|
||||
writer.writeByte(id);
|
||||
Point4D.write(data, writer);
|
||||
writer.close();
|
||||
packet.channel = PacketConstants.CHANNEL_NAME;
|
||||
packet.data = buffer.toByteArray();
|
||||
|
||||
@@ -1,30 +1,29 @@
|
||||
package StevenDimDoors.mod_pocketDim.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||
|
||||
public abstract class DimLink
|
||||
{
|
||||
private static final int EXPECTED_CHILDREN = 2;
|
||||
|
||||
{
|
||||
protected Point4D source;
|
||||
protected DimLink parent;
|
||||
protected LinkTail tail;
|
||||
protected ArrayList<DimLink> children;
|
||||
protected List<DimLink> children;
|
||||
|
||||
protected DimLink(Point4D source, DimLink parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.source = source;
|
||||
this.tail = parent.tail;
|
||||
this.children = new ArrayList<DimLink>(EXPECTED_CHILDREN);
|
||||
this.children = new LinkedList<DimLink>();
|
||||
parent.children.add(this);
|
||||
}
|
||||
|
||||
protected DimLink(Point4D source, int linkType)
|
||||
{
|
||||
if (linkType < LinkTypes.ENUM_MIN || linkType > LinkTypes.ENUM_MAX)
|
||||
if (linkType < LinkTypes.ENUM_MIN || linkType > LinkTypes.ENUM_MAX && linkType != LinkTypes.UNKNOWN)
|
||||
{
|
||||
throw new IllegalArgumentException("The specified link type is invalid.");
|
||||
}
|
||||
@@ -32,7 +31,7 @@ public abstract class DimLink
|
||||
this.parent = null;
|
||||
this.source = source;
|
||||
this.tail = new LinkTail(linkType, null);
|
||||
this.children = new ArrayList<DimLink>(EXPECTED_CHILDREN);
|
||||
this.children = new LinkedList<DimLink>();
|
||||
}
|
||||
|
||||
public Point4D source()
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package StevenDimDoors.mod_pocketDim.core;
|
||||
|
||||
public interface IDimRegistrationCallback
|
||||
{
|
||||
public NewDimData registerDimension(int dimensionID, int rootID);
|
||||
}
|
||||
@@ -7,6 +7,8 @@ public class LinkTypes
|
||||
public static final int ENUM_MIN = 0;
|
||||
public static final int ENUM_MAX = 8;
|
||||
|
||||
public static final int UNKNOWN = -1337;
|
||||
|
||||
public static final int NORMAL = 0;
|
||||
public static final int LIMBO = 1;
|
||||
public static final int POCKET = 2;
|
||||
|
||||
@@ -10,10 +10,8 @@ import net.minecraft.world.World;
|
||||
import StevenDimDoors.mod_pocketDim.DDProperties;
|
||||
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
|
||||
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack;
|
||||
import StevenDimDoors.mod_pocketDim.messages.IDataMessage;
|
||||
import StevenDimDoors.mod_pocketDim.messages.IUpdateWatcher;
|
||||
import StevenDimDoors.mod_pocketDim.messages.LinkMessageBuilder;
|
||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||
import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher;
|
||||
|
||||
public abstract class NewDimData
|
||||
{
|
||||
@@ -106,19 +104,8 @@ public abstract class NewDimData
|
||||
parent = null;
|
||||
tail = new LinkTail(linkType, null);
|
||||
}
|
||||
|
||||
public IDataMessage toMessage()
|
||||
{
|
||||
return linkMessageBuilder.createMessage(this);
|
||||
}
|
||||
|
||||
public IDataMessage toKey()
|
||||
{
|
||||
return linkMessageBuilder.createKey(this);
|
||||
}
|
||||
}
|
||||
|
||||
private static LinkMessageBuilder linkMessageBuilder = new LinkMessageBuilder();
|
||||
private static Random random = new Random();
|
||||
|
||||
private final int id;
|
||||
@@ -134,13 +121,12 @@ public abstract class NewDimData
|
||||
private Point4D origin;
|
||||
private int orientation;
|
||||
private DungeonData dungeon;
|
||||
private final IUpdateWatcher dimWatcher;
|
||||
private final IUpdateWatcher linkWatcher;
|
||||
private final IUpdateWatcher<Point4D> linkWatcher;
|
||||
|
||||
protected NewDimData(int id, NewDimData parent, boolean isPocket, boolean isDungeon,
|
||||
IUpdateWatcher dimWatcher, IUpdateWatcher linkWatcher)
|
||||
IUpdateWatcher<Point4D> linkWatcher)
|
||||
{
|
||||
//The isPocket flag is redundant. It's meant as an integrity safeguard.
|
||||
// The isPocket flag is redundant. It's meant as an integrity safeguard.
|
||||
if (isPocket == (parent != null))
|
||||
{
|
||||
throw new NullPointerException("Dimensions can be pocket dimensions if and only if they have a parent dimension.");
|
||||
@@ -161,7 +147,6 @@ public abstract class NewDimData
|
||||
this.orientation = 0;
|
||||
this.origin = null;
|
||||
this.dungeon = null;
|
||||
this.dimWatcher = dimWatcher;
|
||||
this.linkWatcher = linkWatcher;
|
||||
|
||||
//Register with parent
|
||||
@@ -179,8 +164,32 @@ public abstract class NewDimData
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract IDataMessage toMessage();
|
||||
protected abstract IDataMessage toKey();
|
||||
protected NewDimData(int id, NewDimData root)
|
||||
{
|
||||
// This constructor is meant for client-side code only
|
||||
this.id = id;
|
||||
this.linkMapping = new TreeMap<Point4D, InnerDimLink>(); //Should be stored in oct tree -- temporary solution
|
||||
this.linkList = new ArrayList<InnerDimLink>(); //Should be stored in oct tree -- temporary solution
|
||||
this.children = new ArrayList<NewDimData>();
|
||||
this.parent = null;
|
||||
this.packDepth = 0;
|
||||
this.isDungeon = false;
|
||||
this.isFilled = false;
|
||||
this.orientation = 0;
|
||||
this.origin = null;
|
||||
this.dungeon = null;
|
||||
this.linkWatcher = null;
|
||||
this.depth = 0;
|
||||
if (root != null)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.root = this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public DimLink findNearestRift(World world, int range, int x, int y, int z)
|
||||
{
|
||||
@@ -251,7 +260,7 @@ public abstract class NewDimData
|
||||
link.overwrite(linkType);
|
||||
}
|
||||
//Link created!
|
||||
linkWatcher.onCreated(link.toMessage());
|
||||
linkWatcher.onCreated(link.source);
|
||||
return link;
|
||||
}
|
||||
|
||||
@@ -278,14 +287,14 @@ public abstract class NewDimData
|
||||
linkList.add(link);
|
||||
|
||||
//Link created!
|
||||
linkWatcher.onCreated(link.toMessage());
|
||||
linkWatcher.onCreated(link.source);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (link.overwrite(parent))
|
||||
{
|
||||
//Link created!
|
||||
linkWatcher.onCreated(link.toMessage());
|
||||
linkWatcher.onCreated(link.source);
|
||||
}
|
||||
}
|
||||
return link;
|
||||
@@ -302,7 +311,7 @@ public abstract class NewDimData
|
||||
{
|
||||
linkList.remove(target);
|
||||
//Raise deletion event
|
||||
linkWatcher.onDeleted(target.toKey());
|
||||
linkWatcher.onDeleted(target.source);
|
||||
target.clear();
|
||||
}
|
||||
return (target != null);
|
||||
@@ -316,7 +325,7 @@ public abstract class NewDimData
|
||||
{
|
||||
linkList.remove(target);
|
||||
//Raise deletion event
|
||||
linkWatcher.onDeleted(target.toKey());
|
||||
linkWatcher.onDeleted(target.source);
|
||||
target.clear();
|
||||
}
|
||||
return (target != null);
|
||||
@@ -345,7 +354,7 @@ public abstract class NewDimData
|
||||
|
||||
public boolean isPocketDimension()
|
||||
{
|
||||
return (parent != null);
|
||||
return (root != this);
|
||||
}
|
||||
|
||||
public boolean isDungeon()
|
||||
@@ -361,8 +370,6 @@ public abstract class NewDimData
|
||||
public void setFilled(boolean isFilled)
|
||||
{
|
||||
this.isFilled = isFilled;
|
||||
//Raise the dim update event
|
||||
dimWatcher.onUpdated(this.toMessage());
|
||||
}
|
||||
|
||||
public int id()
|
||||
@@ -412,7 +419,7 @@ public abstract class NewDimData
|
||||
|
||||
public int linkCount()
|
||||
{
|
||||
return linkMapping.size();
|
||||
return linkList.size();
|
||||
}
|
||||
|
||||
public Iterable<NewDimData> children()
|
||||
@@ -420,6 +427,11 @@ public abstract class NewDimData
|
||||
return children;
|
||||
}
|
||||
|
||||
public Iterable<? extends DimLink> links()
|
||||
{
|
||||
return linkList;
|
||||
}
|
||||
|
||||
public void initializeDungeon(int originX, int originY, int originZ, int orientation, DimLink incoming, DungeonData dungeon)
|
||||
{
|
||||
if (!isDungeon)
|
||||
@@ -436,8 +448,6 @@ public abstract class NewDimData
|
||||
this.orientation = orientation;
|
||||
this.dungeon = dungeon;
|
||||
this.packDepth = calculatePackDepth(parent, dungeon);
|
||||
//Raise the dim update event
|
||||
dimWatcher.onUpdated(this.toMessage());
|
||||
}
|
||||
|
||||
private static int calculatePackDepth(NewDimData parent, DungeonData current)
|
||||
@@ -486,16 +496,12 @@ public abstract class NewDimData
|
||||
setDestination(incoming, originX, originY, originZ);
|
||||
this.origin = incoming.destination();
|
||||
this.orientation = orientation;
|
||||
//Raise the dim update event
|
||||
dimWatcher.onUpdated(this.toMessage());
|
||||
}
|
||||
|
||||
public void setDestination(DimLink incoming, int x, int y, int z)
|
||||
{
|
||||
InnerDimLink link = (InnerDimLink) incoming;
|
||||
link.setDestination(x, y, z, this);
|
||||
//Raise update event
|
||||
linkWatcher.onUpdated(link.toMessage());
|
||||
}
|
||||
|
||||
public DimLink getRandomLink()
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package StevenDimDoors.mod_pocketDim.core;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
@@ -13,13 +12,13 @@ import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import StevenDimDoors.mod_pocketDim.DDProperties;
|
||||
import StevenDimDoors.mod_pocketDim.helpers.Compactor;
|
||||
import StevenDimDoors.mod_pocketDim.helpers.DeleteFolder;
|
||||
import StevenDimDoors.mod_pocketDim.messages.DimMessageBuilder;
|
||||
import StevenDimDoors.mod_pocketDim.messages.IDataMessage;
|
||||
import StevenDimDoors.mod_pocketDim.messages.IUpdateWatcher;
|
||||
import StevenDimDoors.mod_pocketDim.messages.UpdateWatcherProxy;
|
||||
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift;
|
||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||
import StevenDimDoors.mod_pocketDim.watcher.ClientDimData;
|
||||
import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher;
|
||||
import StevenDimDoors.mod_pocketDim.watcher.UpdateWatcherProxy;
|
||||
|
||||
/**
|
||||
* This class regulates all the operations involving the storage and manipulation of dimensions. It handles saving dim data, teleporting the player, and
|
||||
@@ -29,41 +28,40 @@ public class PocketManager
|
||||
{
|
||||
private static class InnerDimData extends NewDimData
|
||||
{
|
||||
//This inner class allows us to instantiate NewDimData indirectly without exposing
|
||||
//a public constructor from NewDimData. It's meant to stop us from constructing instances
|
||||
//of NewDimData without using PocketManager's functions. In turn, that enforces that any
|
||||
//link destinations must be real dimensions controlled by PocketManager.
|
||||
// This class allows us to instantiate NewDimData indirectly without exposing
|
||||
// a public constructor from NewDimData. It's meant to stop us from constructing
|
||||
// instances of NewDimData going through PocketManager. In turn, that enforces
|
||||
// that any link destinations must be real dimensions controlled by PocketManager.
|
||||
|
||||
public InnerDimData(int id, NewDimData parent, boolean isPocket, boolean isDungeon,
|
||||
IUpdateWatcher dimWatcher, IUpdateWatcher linkWatcher)
|
||||
public InnerDimData(int id, InnerDimData parent, boolean isPocket, boolean isDungeon,
|
||||
IUpdateWatcher<Point4D> linkWatcher)
|
||||
{
|
||||
super(id, parent, isPocket, isDungeon, dimWatcher, linkWatcher);
|
||||
super(id, parent, isPocket, isDungeon, linkWatcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IDataMessage toMessage()
|
||||
|
||||
public InnerDimData(int id, InnerDimData root)
|
||||
{
|
||||
return dimMessageBuilder.createMessage(this);
|
||||
// This constructor is meant for client-side code only
|
||||
super(id, root);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IDataMessage toKey()
|
||||
|
||||
public InnerDimData(int id)
|
||||
{
|
||||
return dimMessageBuilder.createKey(this);
|
||||
// This constructor is meant for client-side code only
|
||||
super(id, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static DimMessageBuilder dimMessageBuilder = new DimMessageBuilder();
|
||||
private static int OVERWORLD_DIMENSION_ID = 0;
|
||||
|
||||
private static volatile boolean isLoading = false;
|
||||
private static volatile boolean isLoaded = false;
|
||||
private static volatile boolean isSaving = false;
|
||||
private static UpdateWatcherProxy linkWatcher = null;
|
||||
private static UpdateWatcherProxy dimWatcher = null;
|
||||
private static UpdateWatcherProxy<Point4D> linkWatcher = null;
|
||||
private static UpdateWatcherProxy<ClientDimData> dimWatcher = null;
|
||||
|
||||
//HashMap that maps all the dimension IDs registered with DimDoors to their DD data.
|
||||
private static HashMap<Integer, NewDimData> dimensionData = new HashMap<Integer, NewDimData>();
|
||||
private static HashMap<Integer, InnerDimData> dimensionData = null;
|
||||
|
||||
public static boolean isLoaded()
|
||||
{
|
||||
@@ -87,16 +85,17 @@ public class PocketManager
|
||||
|
||||
isLoading = true;
|
||||
|
||||
//Set up watcher proxies
|
||||
dimWatcher = new UpdateWatcherProxy();
|
||||
linkWatcher = new UpdateWatcherProxy();
|
||||
|
||||
loadInternal();
|
||||
//Set up fields
|
||||
dimensionData = new HashMap<Integer, InnerDimData>();
|
||||
dimWatcher = new UpdateWatcherProxy<ClientDimData>();
|
||||
linkWatcher = new UpdateWatcherProxy<Point4D>();
|
||||
|
||||
//Register Limbo
|
||||
DDProperties properties = DDProperties.instance();
|
||||
registerDimension(properties.LimboDimensionID, null, false, false);
|
||||
|
||||
loadInternal();
|
||||
|
||||
//Register pocket dimensions
|
||||
registerPockets(properties);
|
||||
|
||||
@@ -134,7 +133,7 @@ public class PocketManager
|
||||
DeleteFolder.deleteFolder(save);
|
||||
}
|
||||
//Raise the dim deleted event
|
||||
dimWatcher.onDeleted(dimension.toKey());
|
||||
dimWatcher.onDeleted(new ClientDimData(dimension));
|
||||
//dimension.implode()??? -- more like delete, but yeah
|
||||
return true;
|
||||
}
|
||||
@@ -184,9 +183,7 @@ public class PocketManager
|
||||
|
||||
/**
|
||||
* loads the dim data from the saved hashMap. Also handles compatibility with old saves, see OldSaveHandler
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void loadInternal()
|
||||
{
|
||||
// SenseiKiwi: This is a temporary function for testing purposes.
|
||||
@@ -196,10 +193,9 @@ public class PocketManager
|
||||
DimensionManager.getCurrentSaveRootDirectory() != null)
|
||||
{
|
||||
System.out.println("Loading Dimensional Doors save data...");
|
||||
File saveFile = new File(DimensionManager.getCurrentSaveRootDirectory() + "/dimdoors.dat");
|
||||
//Missing code for converting the binary data in the file into an IOpaqueMessage
|
||||
IDataMessage saveData;
|
||||
setState(saveData);
|
||||
/*File saveFile = new File(DimensionManager.getCurrentSaveRootDirectory() + "/dimdoors.dat");
|
||||
|
||||
setState(saveData);*/
|
||||
System.out.println("Loaded successfully!");
|
||||
}
|
||||
}
|
||||
@@ -228,7 +224,7 @@ public class PocketManager
|
||||
try
|
||||
{
|
||||
System.out.println("Writing Dimensional Doors save data...");
|
||||
String tempPath = DimensionManager.getCurrentSaveRootDirectory() + "/dimdoors.tmp";
|
||||
/*String tempPath = DimensionManager.getCurrentSaveRootDirectory() + "/dimdoors.tmp";
|
||||
String savePath = DimensionManager.getCurrentSaveRootDirectory() + "/dimdoors.dat";
|
||||
File tempFile = new File(tempPath);
|
||||
File saveFile = new File(savePath);
|
||||
@@ -236,17 +232,17 @@ public class PocketManager
|
||||
getState().writeToStream(writer);
|
||||
writer.close();
|
||||
saveFile.delete();
|
||||
tempFile.renameTo(saveFile);
|
||||
tempFile.renameTo(saveFile);*/
|
||||
System.out.println("Saved successfully!");
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
/*catch (FileNotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}*/
|
||||
finally
|
||||
{
|
||||
isSaving = false;
|
||||
@@ -291,17 +287,17 @@ public class PocketManager
|
||||
DDProperties properties = DDProperties.instance();
|
||||
int dimensionID = DimensionManager.getNextFreeDimId();
|
||||
DimensionManager.registerDimension(dimensionID, properties.PocketProviderID);
|
||||
return registerDimension(dimensionID, parent, true, isDungeon);
|
||||
return registerDimension(dimensionID, (InnerDimData) parent, true, isDungeon);
|
||||
}
|
||||
|
||||
private static NewDimData registerDimension(int dimensionID, NewDimData parent, boolean isPocket, boolean isDungeon)
|
||||
private static NewDimData registerDimension(int dimensionID, InnerDimData parent, boolean isPocket, boolean isDungeon)
|
||||
{
|
||||
if (dimensionData.containsKey(dimensionID))
|
||||
{
|
||||
throw new IllegalArgumentException("Cannot register a dimension with ID = " + dimensionID + " because it has already been registered.");
|
||||
}
|
||||
|
||||
NewDimData dimension = new InnerDimData(dimensionID, parent, isPocket, isDungeon, dimWatcher, linkWatcher);
|
||||
InnerDimData dimension = new InnerDimData(dimensionID, parent, isPocket, isDungeon, linkWatcher);
|
||||
dimensionData.put(dimensionID, dimension);
|
||||
return dimension;
|
||||
}
|
||||
@@ -330,14 +326,18 @@ public class PocketManager
|
||||
public static void unload()
|
||||
{
|
||||
save();
|
||||
dimWatcher = null;
|
||||
linkWatcher = null;
|
||||
dimensionData = null;
|
||||
unregisterPockets();
|
||||
dimensionData.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
* This isn't needed right now and it's causing me problems due to the iterator's generic type -_-
|
||||
public static Iterable<NewDimData> getDimensions()
|
||||
{
|
||||
return dimensionData.values();
|
||||
}
|
||||
}*/
|
||||
|
||||
public static DimLink getLink(int x, int y, int z, World world)
|
||||
{
|
||||
@@ -357,37 +357,96 @@ public class PocketManager
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerDimWatcher(IUpdateWatcher watcher)
|
||||
public static void registerDimWatcher(IUpdateWatcher<ClientDimData> watcher)
|
||||
{
|
||||
dimWatcher.registerReceiver(watcher);
|
||||
}
|
||||
|
||||
public static boolean unregisterDimWatcher(IUpdateWatcher watcher)
|
||||
public static boolean unregisterDimWatcher(IUpdateWatcher<ClientDimData> watcher)
|
||||
{
|
||||
return dimWatcher.unregisterReceiver(watcher);
|
||||
}
|
||||
|
||||
public static void registerLinkWatcher(IUpdateWatcher watcher)
|
||||
public static void registerLinkWatcher(IUpdateWatcher<Point4D> watcher)
|
||||
{
|
||||
linkWatcher.registerReceiver(watcher);
|
||||
}
|
||||
|
||||
public static boolean unregisterLinkWatcher(IUpdateWatcher watcher)
|
||||
public static boolean unregisterLinkWatcher(IUpdateWatcher<Point4D> watcher)
|
||||
{
|
||||
return linkWatcher.unregisterReceiver(watcher);
|
||||
}
|
||||
|
||||
public static IDataMessage getState()
|
||||
public static void writePacket(DataOutputStream output) throws IOException
|
||||
{
|
||||
|
||||
// Write a very compact description of our dimensions and links to be sent to a client
|
||||
Compactor.write(dimensionData.values(), output);
|
||||
}
|
||||
|
||||
public static void setState(IDataMessage state)
|
||||
public static void readPacket(DataInputStream input) throws IOException
|
||||
{
|
||||
if (isLoaded)
|
||||
{
|
||||
throw new IllegalStateException("Pocket dimensions have already been loaded!");
|
||||
}
|
||||
if (isLoading)
|
||||
{
|
||||
throw new IllegalStateException("Pocket dimensions are already loading!");
|
||||
}
|
||||
|
||||
isLoading = true;
|
||||
|
||||
// Set up fields
|
||||
dimensionData = new HashMap<Integer, InnerDimData>();
|
||||
dimWatcher = new UpdateWatcherProxy<ClientDimData>();
|
||||
linkWatcher = new UpdateWatcherProxy<Point4D>();
|
||||
|
||||
// Load compacted client-side dimension data
|
||||
Compactor.readDimensions(input, new DimRegistrationCallback());
|
||||
|
||||
// Register pocket dimensions
|
||||
DDProperties properties = DDProperties.instance();
|
||||
registerPockets(properties);
|
||||
|
||||
isLoaded = true;
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
private static class DimRegistrationCallback implements IDimRegistrationCallback
|
||||
{
|
||||
// We use this class to provide Compactor with the ability to send us dim data without
|
||||
// having to instantiate a bunch of data containers and without exposing an "unsafe"
|
||||
// creation method for anyone to call. Integrity protection for the win! It's like
|
||||
// exposing a private constructor ONLY to a very specific trusted class.
|
||||
|
||||
@Override
|
||||
public NewDimData registerDimension(int dimensionID, int rootID)
|
||||
{
|
||||
// No need to raise events here since this code should only run on the client side
|
||||
// We assume that the root dimension has already been registered to avoid dependency issues
|
||||
|
||||
InnerDimData root = dimensionData.get(rootID);
|
||||
InnerDimData dimension;
|
||||
|
||||
if (rootID != dimensionID)
|
||||
{
|
||||
dimension = dimensionData.get(dimensionID);
|
||||
if (dimension == null)
|
||||
{
|
||||
dimension = new InnerDimData(dimensionID, root);
|
||||
dimensionData.put(dimension.id(), dimension);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (root == null)
|
||||
{
|
||||
root = new InnerDimData(rootID);
|
||||
dimensionData.put(root.id(), root);
|
||||
}
|
||||
dimension = root;
|
||||
}
|
||||
return dimension;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
83
StevenDimDoors/mod_pocketDim/helpers/Compactor.java
Normal file
83
StevenDimDoors/mod_pocketDim/helpers/Compactor.java
Normal file
@@ -0,0 +1,83 @@
|
||||
package StevenDimDoors.mod_pocketDim.helpers;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
|
||||
import StevenDimDoors.mod_pocketDim.core.DimLink;
|
||||
import StevenDimDoors.mod_pocketDim.core.IDimRegistrationCallback;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||
|
||||
public class Compactor
|
||||
{
|
||||
|
||||
private static class DimComparator implements Comparator<NewDimData>
|
||||
{
|
||||
@Override
|
||||
public int compare(NewDimData a, NewDimData b)
|
||||
{
|
||||
return a.id() - b.id();
|
||||
}
|
||||
}
|
||||
|
||||
public static void write(Collection<? extends NewDimData> values, DataOutputStream output) throws IOException
|
||||
{
|
||||
// SenseiKiwi: Just encode the data straight up for now. I'll implement fancier compression later.
|
||||
output.writeInt(values.size());
|
||||
for (NewDimData dimension : values)
|
||||
{
|
||||
output.writeInt(dimension.id());
|
||||
output.writeInt(dimension.root().id());
|
||||
output.writeInt(dimension.linkCount());
|
||||
for (DimLink link : dimension.links())
|
||||
{
|
||||
Point4D.write(link.source(), output);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Note to self: the root ID can be "compressed" by grouping
|
||||
// dimensions by their root ID and then only sending it once
|
||||
|
||||
/*
|
||||
// To compress the dimension IDs, we'll sort them by ID
|
||||
// and write the _difference_ between their ID numbers.
|
||||
NewDimData[] dimensions = new NewDimData[values.size()];
|
||||
dimensions = values.toArray(dimensions);
|
||||
Arrays.sort(dimensions, new DimComparator());
|
||||
*/
|
||||
}
|
||||
|
||||
public static void readDimensions(DataInputStream input, IDimRegistrationCallback callback) throws IOException
|
||||
{
|
||||
// Read in the dimensions one by one. Make sure we register root dimensions before
|
||||
// attempting to register the dimensions under them.
|
||||
|
||||
HashSet<Integer> rootIDs = new HashSet<Integer>();
|
||||
|
||||
int dimCount = input.readInt();
|
||||
for (int k = 0; k < dimCount; k++)
|
||||
{
|
||||
int id = input.readInt();
|
||||
int rootID = input.readInt();
|
||||
|
||||
if (rootIDs.add(rootID))
|
||||
{
|
||||
callback.registerDimension(rootID, rootID);
|
||||
}
|
||||
// Don't check if (id != rootID) - we want to retrieve the reference anyway
|
||||
NewDimData dimension = callback.registerDimension(id, rootID);
|
||||
int linkCount = input.readInt();
|
||||
for (int h = 0; h < linkCount; h++)
|
||||
{
|
||||
Point4D source = Point4D.read(input);
|
||||
dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.UNKNOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
package StevenDimDoors.mod_pocketDim.messages;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import StevenDimDoors.mod_pocketDim.core.DimLink;
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData.InnerDimLink;
|
||||
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
|
||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
public class DimMessageBuilder implements IMessageBuilder<NewDimData>
|
||||
{
|
||||
public static class DimMessage implements IDataMessage
|
||||
{
|
||||
//We'll use public fields here since this is a data container object and all the fields are immutable
|
||||
//We will not transfer dungeon, link data, or any data on child dimensions
|
||||
//As far as I can tell, the children will handle updating their parents anyway
|
||||
|
||||
public final int ID;
|
||||
public final boolean IsDungeon;
|
||||
public final boolean IsFilled;
|
||||
public final int Depth;
|
||||
public final int PackDepth;
|
||||
public final Integer ParentID;
|
||||
public final int RootID;
|
||||
public final Point4D Origin;
|
||||
public final int Orientation;
|
||||
|
||||
private DimMessage(NewDimData dimension)
|
||||
{
|
||||
ID = dimension.id();
|
||||
IsDungeon = dimension.isDungeon();
|
||||
IsFilled = dimension.isFilled();
|
||||
Depth = dimension.depth();
|
||||
PackDepth = dimension.packDepth();
|
||||
ParentID = (dimension.parent() != null) ? dimension.parent().id() : null;
|
||||
RootID = dimension.root().id();
|
||||
Origin = dimension.origin();
|
||||
Orientation = dimension.orientation();
|
||||
}
|
||||
|
||||
private DimMessage(DataInputStream stream) throws IOException
|
||||
{
|
||||
ID = stream.readInt();
|
||||
IsDungeon = stream.readBoolean();
|
||||
IsFilled = stream.readBoolean();
|
||||
Depth = stream.readInt();
|
||||
PackDepth = stream.readInt();
|
||||
ParentID = stream.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToStream(DataOutputStream stream) throws IOException
|
||||
{
|
||||
//Write a flag indicating that this is a full message and not a key
|
||||
stream.writeBoolean(true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static class DimKeyMessage implements IDataMessage
|
||||
{
|
||||
//We'll use public fields here since this is a data container object and all the fields are immutable
|
||||
public final int ID;
|
||||
|
||||
private DimKeyMessage(NewDimData dimension)
|
||||
{
|
||||
ID = dimension.id();
|
||||
}
|
||||
|
||||
private DimKeyMessage(DataInputStream stream) throws IOException
|
||||
{
|
||||
ID = stream.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToStream(DataOutputStream stream) throws IOException
|
||||
{
|
||||
//Write a flag indicating that this is a key
|
||||
stream.writeBoolean(false);
|
||||
stream.writeInt(ID);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDataMessage createKey(NewDimData target)
|
||||
{
|
||||
return new DimKeyMessage(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDataMessage createMessage(NewDimData target)
|
||||
{
|
||||
return new DimMessage(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDataMessage read(DataInputStream source) throws IOException
|
||||
{
|
||||
//Check whether the message is a full message or just a key
|
||||
if (source.readBoolean())
|
||||
{
|
||||
return new DimMessage(source);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DimKeyMessage(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package StevenDimDoors.mod_pocketDim.messages;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface IDataMessage
|
||||
{
|
||||
public void writeToStream(DataOutputStream stream) throws IOException;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package StevenDimDoors.mod_pocketDim.messages;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface IMessageBuilder<T>
|
||||
{
|
||||
public IDataMessage createKey(T target);
|
||||
public IDataMessage createMessage(T target);
|
||||
public IDataMessage read(DataInputStream source) throws IOException;
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package StevenDimDoors.mod_pocketDim.messages;
|
||||
|
||||
public interface IUpdateWatcher
|
||||
{
|
||||
public void onCreated(IDataMessage message);
|
||||
public void onUpdated(IDataMessage message);
|
||||
public void onDeleted(IDataMessage message);
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
package StevenDimDoors.mod_pocketDim.messages;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import StevenDimDoors.mod_pocketDim.core.DimLink;
|
||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
public class LinkMessageBuilder implements IMessageBuilder<DimLink>
|
||||
{
|
||||
public static class LinkMessage implements IDataMessage
|
||||
{
|
||||
//We'll use public fields here since this is a data container object and all the fields are immutable
|
||||
public final Point4D Source;
|
||||
public final Point4D Destination;
|
||||
public final int LinkType;
|
||||
public final Point4D Parent;
|
||||
public final ImmutableList<Point4D> Children;
|
||||
|
||||
private LinkMessage(DimLink link)
|
||||
{
|
||||
// TODO: In the case that a child's parent has been removed but the rest of the group still exists,
|
||||
// this group bond will be lost to this link on the client side. Currently, that's not a problem since
|
||||
// destination data and groups don't matter to the client, but it's something to think about later.
|
||||
|
||||
Source = link.source();
|
||||
Destination = link.destination();
|
||||
LinkType = link.linkType();
|
||||
Parent = link.parent().source();
|
||||
ImmutableList.Builder<Point4D> builder = new ImmutableList.Builder<Point4D>();
|
||||
for (DimLink child : link.children())
|
||||
{
|
||||
builder.add(child.source());
|
||||
}
|
||||
Children = builder.build();
|
||||
}
|
||||
|
||||
private LinkMessage(DataInputStream stream) throws IOException
|
||||
{
|
||||
Source = Point4D.read(stream);
|
||||
Parent = Point4D.read(stream);
|
||||
if (Parent == null)
|
||||
{
|
||||
Destination = Point4D.read(stream);
|
||||
LinkType = stream.readInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
Destination = null;
|
||||
LinkType = -1;
|
||||
}
|
||||
int childCount = stream.readInt();
|
||||
ImmutableList.Builder<Point4D> builder = new ImmutableList.Builder<Point4D>();
|
||||
for (int k = 0; k < childCount; k++)
|
||||
{
|
||||
builder.add(Point4D.read(stream));
|
||||
}
|
||||
Children = builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToStream(DataOutputStream stream) throws IOException
|
||||
{
|
||||
//Write a flag indicating that this is a full message and not a key
|
||||
stream.writeBoolean(true);
|
||||
Point4D.write(Source, stream);
|
||||
Point4D.write(Parent, stream);
|
||||
//A link only has its own destination information if it has no parent to provide it
|
||||
if (Parent == null)
|
||||
{
|
||||
Point4D.write(Destination, stream);
|
||||
stream.writeInt(LinkType);
|
||||
}
|
||||
stream.writeInt(Children.size());
|
||||
for (Point4D child : Children)
|
||||
{
|
||||
Point4D.write(child, stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class LinkKeyMessage implements IDataMessage
|
||||
{
|
||||
//We'll use public fields here since this is a data container object and all the fields are immutable
|
||||
public final Point4D Source;
|
||||
|
||||
private LinkKeyMessage(DimLink link)
|
||||
{
|
||||
Source = link.source();
|
||||
}
|
||||
|
||||
private LinkKeyMessage(DataInputStream stream) throws IOException
|
||||
{
|
||||
Source = Point4D.read(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToStream(DataOutputStream stream) throws IOException
|
||||
{
|
||||
//Write a flag indicating that this is a key
|
||||
stream.writeBoolean(false);
|
||||
Point4D.write(Source, stream);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDataMessage createKey(DimLink target)
|
||||
{
|
||||
return new LinkKeyMessage(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDataMessage createMessage(DimLink target)
|
||||
{
|
||||
return new LinkMessage(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDataMessage read(DataInputStream source) throws IOException
|
||||
{
|
||||
//Check whether the message is a full message or just a key
|
||||
if (source.readBoolean())
|
||||
{
|
||||
return new LinkMessage(source);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new LinkKeyMessage(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package StevenDimDoors.mod_pocketDim.messages;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class UpdateWatcherProxy implements IUpdateWatcher
|
||||
{
|
||||
private List<IUpdateWatcher> watchers;
|
||||
|
||||
public UpdateWatcherProxy()
|
||||
{
|
||||
watchers = new ArrayList<IUpdateWatcher>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreated(IDataMessage message)
|
||||
{
|
||||
for (IUpdateWatcher receiver : watchers)
|
||||
{
|
||||
receiver.onCreated(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdated(IDataMessage message)
|
||||
{
|
||||
for (IUpdateWatcher receiver : watchers)
|
||||
{
|
||||
receiver.onUpdated(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleted(IDataMessage message)
|
||||
{
|
||||
for (IUpdateWatcher receiver : watchers)
|
||||
{
|
||||
receiver.onDeleted(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerReceiver(IUpdateWatcher receiver)
|
||||
{
|
||||
watchers.add(receiver);
|
||||
}
|
||||
|
||||
public boolean unregisterReceiver(IUpdateWatcher receiver)
|
||||
{
|
||||
return watchers.remove(receiver);
|
||||
}
|
||||
}
|
||||
37
StevenDimDoors/mod_pocketDim/watcher/ClientDimData.java
Normal file
37
StevenDimDoors/mod_pocketDim/watcher/ClientDimData.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package StevenDimDoors.mod_pocketDim.watcher;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||
|
||||
public class ClientDimData
|
||||
{
|
||||
//We'll use public fields since this is just a data container and it's immutable
|
||||
public final int ID;
|
||||
public final int RootID;
|
||||
|
||||
public ClientDimData(int id, int rootID)
|
||||
{
|
||||
ID = id;
|
||||
RootID = rootID;
|
||||
}
|
||||
|
||||
public ClientDimData(NewDimData dimension)
|
||||
{
|
||||
ID = dimension.id();
|
||||
RootID = dimension.root().id();
|
||||
}
|
||||
|
||||
public void write(DataOutputStream output) throws IOException
|
||||
{
|
||||
output.writeInt(ID);
|
||||
output.writeInt(RootID);
|
||||
}
|
||||
|
||||
public static ClientDimData read(DataInputStream input) throws IOException
|
||||
{
|
||||
return new ClientDimData(input.readInt(), input.readInt());
|
||||
}
|
||||
}
|
||||
7
StevenDimDoors/mod_pocketDim/watcher/IUpdateWatcher.java
Normal file
7
StevenDimDoors/mod_pocketDim/watcher/IUpdateWatcher.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package StevenDimDoors.mod_pocketDim.watcher;
|
||||
|
||||
public interface IUpdateWatcher<T>
|
||||
{
|
||||
public void onCreated(T message);
|
||||
public void onDeleted(T message);
|
||||
}
|
||||
42
StevenDimDoors/mod_pocketDim/watcher/UpdateWatcherProxy.java
Normal file
42
StevenDimDoors/mod_pocketDim/watcher/UpdateWatcherProxy.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package StevenDimDoors.mod_pocketDim.watcher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class UpdateWatcherProxy<T> implements IUpdateWatcher<T>
|
||||
{
|
||||
private List<IUpdateWatcher<T>> watchers;
|
||||
|
||||
public UpdateWatcherProxy()
|
||||
{
|
||||
watchers = new ArrayList<IUpdateWatcher<T>>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreated(T message)
|
||||
{
|
||||
for (IUpdateWatcher<T> receiver : watchers)
|
||||
{
|
||||
receiver.onCreated(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleted(T message)
|
||||
{
|
||||
for (IUpdateWatcher<T> receiver : watchers)
|
||||
{
|
||||
receiver.onDeleted(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerReceiver(IUpdateWatcher<T> receiver)
|
||||
{
|
||||
watchers.add(receiver);
|
||||
}
|
||||
|
||||
public boolean unregisterReceiver(IUpdateWatcher<T> receiver)
|
||||
{
|
||||
return watchers.remove(receiver);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user