Finished new node grid

This commit is contained in:
Calclavia 2014-03-05 19:37:24 +08:00
parent f90c513986
commit 61aec43d44
12 changed files with 192 additions and 171 deletions

View file

@ -47,18 +47,6 @@ public class BlockConveyorBelt extends BlockTile
}
}
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, int par5)
{
TileEntity t = world.getBlockTileEntity(x, y, z);
if (t != null && t instanceof TileConveyorBelt)
{
TileConveyorBelt tileEntity = (TileConveyorBelt) t;
tileEntity.mechanicalNode.reconstruct();
}
}
@Override
public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z)
{

View file

@ -1,30 +0,0 @@
package resonantinduction.mechanical.energy.network;
import resonantinduction.core.grid.NodeGrid;
import universalelectricity.core.net.NetworkTickHandler;
/**
* A mechanical network for translate speed and force using mechanical rotations.
*
* Useful Formula:
*
* Power is the work per unit time.
* Power (W) = Torque (Strength of the rotation, Newton Meters) x Speed (Angular Velocity, RADIAN
* PER SECOND).
* *OR*
* Power = Torque / Time
*
* Torque = r (Radius) * F (Force) * sin0 (Direction/Angle of the force applied. 90 degrees if
* optimal.)
*
* @author Calclavia
*/
public class MechanicalNetwork extends NodeGrid<MechanicalNode>
{
public MechanicalNetwork(MechanicalNode node)
{
super(MechanicalNode.class);
add(node);
NetworkTickHandler.addNetwork(this);
}
}

View file

@ -1,22 +1,35 @@
package resonantinduction.mechanical.energy.network;
import java.util.AbstractMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.WeakHashMap;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.core.grid.IGrid;
import resonantinduction.core.grid.Grid;
import resonantinduction.core.grid.TickingGrid;
import universalelectricity.api.vector.Vector3;
import codechicken.multipart.TMultiPart;
/**
* A mechanical node for mechanical energy.
*
* Useful Formula:
*
* Power is the work per unit time.
* Power (W) = Torque (Strength of the rotation, Newton Meters) x Speed (Angular Velocity, RADIAN
* PER SECOND).
* *OR*
* Power = Torque / Time
*
* Torque = r (Radius) * F (Force) * sin0 (Direction/Angle of the force applied. 90 degrees if
* optimal.)
*
* @author Calclavia
*/
public class MechanicalNode extends EnergyNode
{
protected final AbstractMap<MechanicalNode, ForgeDirection> connections = new WeakHashMap<MechanicalNode, ForgeDirection>();
public final IMechanicalNodeProvider parent;
public double torque = 0;
@ -54,7 +67,7 @@ public class MechanicalNode extends EnergyNode
public void update(float deltaTime)
{
power = getEnergy() / deltaTime;
prevAngularVelocity = angularVelocity;
onUpdate();
@ -71,7 +84,7 @@ public class MechanicalNode extends EnergyNode
if (world() != null && !world().isRemote)
{
double acceleration = this.acceleration * deltaTime;
System.out.println("UPDATED");
/**
* Loss energy
*/
@ -190,12 +203,6 @@ System.out.println("UPDATED");
}
}
@Override
public AbstractMap<MechanicalNode, ForgeDirection> getConnections()
{
return connections;
}
public World world()
{
return parent instanceof TMultiPart ? ((TMultiPart) parent).world() : parent instanceof TileEntity ? ((TileEntity) parent).getWorldObj() : null;
@ -224,9 +231,9 @@ System.out.println("UPDATED");
}
@Override
public IGrid newGrid()
public Grid newGrid()
{
return new MechanicalNetwork(this);
return new TickingGrid<MechanicalNode>(this);
}
@Override

View file

@ -79,22 +79,10 @@ public abstract class PartMechanical extends JCuboidPart implements JNormalOcclu
node.reconstruct();
}
@Override
public void onNeighborChanged()
{
node.reconstruct();
}
@Override
public void onPartChanged(TMultiPart part)
{
node.reconstruct();
}
@Override
public void onWorldSeparate()
{
node.split();
node.deconstruct();
}
/** Packet Code. */

View file

@ -57,7 +57,7 @@ public class TileMechanicalTurbine extends TileTurbine implements IMechanicalNod
@Override
public void invalidate()
{
node.split();
node.deconstruct();
super.invalidate();
}

View file

@ -16,7 +16,7 @@ import universalelectricity.core.net.ConnectionPathfinder;
*
* @param <N> - The node type.
*/
public abstract class Grid<N> implements IGrid<N>
public abstract class Grid<N>
{
/**
* A set of connectors (e.g conductors).
@ -29,7 +29,6 @@ public abstract class Grid<N> implements IGrid<N>
nodeType = type;
}
@Override
public void add(N node)
{
synchronized (nodes)
@ -38,7 +37,6 @@ public abstract class Grid<N> implements IGrid<N>
}
}
@Override
public void remove(N node)
{
synchronized (nodes)
@ -47,21 +45,20 @@ public abstract class Grid<N> implements IGrid<N>
}
}
@Override
public Set<N> getNodes()
{
return nodes;
}
/**
* A simple reconstruct class to rebuild the grid.
* A simple reconstruct class to rebuild the grid. The set "nodes" is copied due to the fact
* that this method will allow the modification of nodes while looping.
*/
@Override
public void reconstruct()
{
synchronized (nodes)
{
Iterator<N> it = nodes.iterator();
Iterator<N> it = new HashSet<N>(nodes).iterator();
while (it.hasNext())
{
@ -84,6 +81,19 @@ public abstract class Grid<N> implements IGrid<N>
return nodeType.isAssignableFrom(node.getClass());
}
protected void reconstructNode(N node)
{
}
public void deconstruct()
{
synchronized (nodes)
{
nodes.clear();
}
}
/**
* Gets the first connector in the set.
*
@ -91,22 +101,19 @@ public abstract class Grid<N> implements IGrid<N>
*/
public N getFirstNode()
{
for (N node : getNodes())
synchronized (nodes)
{
return node;
for (N node : nodes)
{
return node;
}
}
return null;
}
protected void reconstructNode(N node)
{
}
@Override
public String toString()
{
return getClass().getSimpleName() + "[" + hashCode() + ", Connectors: " + nodes.size() + "]";
return getClass().getSimpleName() + "[" + hashCode() + ", Nodes: " + nodes.size() + "]";
}
}

View file

@ -1,14 +0,0 @@
package resonantinduction.core.grid;
import java.util.Set;
public interface IGrid<N>
{
public void add(N node);
public void remove(N node);
public Set<N> getNodes();
public void reconstruct();
}

View file

@ -1,29 +0,0 @@
package resonantinduction.core.grid;
import java.util.AbstractMap;
import net.minecraftforge.common.ForgeDirection;
public interface INode<G extends IGrid>
{
/**
* Updates the node. This may be called on a different thread.
*
* @param deltaTime - The time in seconds that has passed between the successive updates.
*/
void update(float deltaTime);
/**
* @return A map consisting of the connected object and a ForgeDirection.
*/
AbstractMap<?, ForgeDirection> getConnections();
G getGrid();
void setGrid(G grid);
/**
* Called whenever the node changes to update its cached connections and network.
*/
void reconstruct();
}

View file

@ -2,7 +2,7 @@ package resonantinduction.core.grid;
import net.minecraftforge.common.ForgeDirection;
public interface INodeProvider<N extends INode>
public interface INodeProvider<N extends Node>
{
public N getNode(ForgeDirection from);
}

View file

@ -1,13 +1,17 @@
package resonantinduction.core.grid;
import resonantinduction.mechanical.energy.network.PartMechanical;
import net.minecraft.nbt.NBTTagCompound;
import java.util.AbstractMap;
import java.util.WeakHashMap;
public abstract class Node<G extends IGrid> implements INode<G>
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.ForgeDirection;
public abstract class Node<G extends Grid, N>
{
protected final AbstractMap<N, ForgeDirection> connections = new WeakHashMap<N, ForgeDirection>();
public G grid = null;
@Override
public final G getGrid()
{
if (grid == null)
@ -18,37 +22,90 @@ public abstract class Node<G extends IGrid> implements INode<G>
protected abstract G newGrid();
@Override
public final void setGrid(G grid)
{
this.grid = grid;
}
@Override
public void update(float deltaTime)
{
}
/**
* This constructs the node. It should be called whenever the connections of the node are
* updated OR when the node is first initiated and can access its connections.
*/
public void reconstruct()
{
recache();
getGrid().reconstruct();
synchronized (connections)
{
recache();
getGrid().add(this);
getGrid().reconstruct();
}
}
// TODO: Fix this.
public void split()
/**
* This destroys the node, removing it from the grid and also destroying all references to it.
*/
public void deconstruct()
{
synchronized (connections)
{
/**
* Remove self from all connections.
*/
for (N connection : connections.keySet())
{
if (getGrid().isValidNode(connection))
{
((Node) connection).getConnections().remove(this);
}
}
getGrid().remove(this);
getGrid().deconstruct();
}
}
/**
* Called for a node to recache all its connections.
*/
public void recache()
{
}
/**
* Returns all the connections in this node.
*
* @return
*/
public AbstractMap<N, ForgeDirection> getConnections()
{
return connections;
}
/**
* Must be called to load the node's data.
*/
public void load(NBTTagCompound nbt)
{
}
/**
* Must be called to save the node's data.
*/
public void save(NBTTagCompound nbt)
{
}
@Override
public String toString()
{
return getClass().getSimpleName() + "[" + hashCode() + ", Connections: " + connections.size() + ", Grid:" + getGrid() + "]";
}
}

View file

@ -1,57 +1,39 @@
package resonantinduction.core.grid;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.mechanical.energy.network.MechanicalNode;
import universalelectricity.api.net.IConnectable;
import universalelectricity.api.net.IUpdate;
public class NodeGrid<N extends INode> extends Grid<N> implements IUpdate
public abstract class NodeGrid<N extends Node> extends Grid<N>
{
public NodeGrid(Class<? extends N> type)
{
super(type);
}
/**
* An grid update called only server side.
*/
@Override
public void update()
{
synchronized (nodes)
{
for (INode node : nodes)
{
node.update(1 / 20f);
}
}
}
@Override
public boolean canUpdate()
{
return nodes.size() > 0;
}
@Override
public boolean continueUpdate()
{
return canUpdate();
}
@Override
protected void reconstructNode(N node)
{
node.recache();
node.setGrid(this);
AbstractMap<Object, ForgeDirection> connections = node.getConnections();
for (Object connection : connections.keySet())
{
if (isValidNode(connection) && connection instanceof INode)
if (isValidNode(connection) && connection instanceof Node)
{
INode connectedNode = (INode) connection;
Node connectedNode = (Node) connection;
if (connectedNode.getGrid() != this)
{
@ -63,4 +45,22 @@ public class NodeGrid<N extends INode> extends Grid<N> implements IUpdate
}
}
}
@Override
public void deconstruct()
{
synchronized (nodes)
{
Iterator<N> it = new HashSet<N>(nodes).iterator();
while (it.hasNext())
{
N node = it.next();
node.setGrid(null);
node.reconstruct();
}
nodes.clear();
}
}
}

View file

@ -0,0 +1,47 @@
package resonantinduction.core.grid;
import resonantinduction.mechanical.energy.network.MechanicalNode;
import universalelectricity.api.net.IUpdate;
import universalelectricity.core.net.NetworkTickHandler;
public class TickingGrid<N extends Node> extends NodeGrid<N> implements IUpdate
{
public TickingGrid(N node, Class type)
{
super(type);
add(node);
NetworkTickHandler.addNetwork(this);
}
public TickingGrid(N node)
{
this(node, node.getClass());
}
/**
* An grid update called only server side.
*/
@Override
public void update()
{
synchronized (nodes)
{
for (Node node : nodes)
{
node.update(1 / 20f);
}
}
}
@Override
public boolean canUpdate()
{
return nodes.size() > 0;
}
@Override
public boolean continueUpdate()
{
return canUpdate();
}
}