Mechanical network is now multithreaded

This commit is contained in:
Calclavia 2014-03-05 22:17:47 +08:00
parent 81c71391bf
commit a15631c4fb
8 changed files with 132 additions and 23 deletions

View file

@ -68,8 +68,6 @@ public class MechanicalNode extends EnergyNode
{
prevAngularVelocity = angularVelocity;
onUpdate();
angle += angularVelocity / 20;
if (angle % (Math.PI * 2) != angle)
@ -117,7 +115,7 @@ public class MechanicalNode extends EnergyNode
*/
float ratio = adjacentMech.getRatio(dir.getOpposite(), this) / getRatio(dir, adjacentMech);
boolean inverseRotation = inverseRotation(dir, adjacentMech) && adjacentMech.inverseRotation(dir.getOpposite(), this);
System.out.println(ratio);
int inversion = inverseRotation ? -1 : 1;
if (Math.abs(torque + inversion * (adjacentMech.getTorque() / ratio * acceleration)) < Math.abs(adjacentMech.getTorque() / ratio))
@ -133,6 +131,8 @@ public class MechanicalNode extends EnergyNode
}
}
}
onUpdate();
}
protected void onUpdate()

View file

@ -28,7 +28,7 @@ public abstract class TileMechanical extends TileAdvanced implements IMechanical
@Override
protected void onUpdate()
{
if (Math.abs(prevAngularVelocity - angularVelocity) > 0.01f)
if (Math.abs(prevAngularVelocity - angularVelocity) > 0.001 || (prevAngularVelocity != angularVelocity && (prevAngularVelocity == 0 || angularVelocity == 0)))
{
prevAngularVelocity = angularVelocity;
markPacketUpdate = true;

View file

@ -53,7 +53,7 @@ public class TileGrinderWheel extends TileMechanical implements IRotatable
{
return !(dir.offsetX > 0 || dir.offsetZ < 0 || dir.offsetY < 0);
}
};
}.setLoad(3);
}
@Override

View file

@ -24,11 +24,6 @@ public class ClientProxy extends CommonProxy
MinecraftForge.EVENT_BUS.register(SoundHandler.INSTANCE);
}
@Override
public void postInit()
{
}
@Override
public boolean isPaused()
{

View file

@ -3,6 +3,7 @@
*/
package resonantinduction.core;
import resonantinduction.core.grid.ThreadedGridTicker;
import net.minecraft.world.World;
import universalelectricity.api.vector.Vector3;
import calclavia.lib.prefab.ProxyBase;
@ -13,6 +14,12 @@ import calclavia.lib.prefab.ProxyBase;
*/
public class CommonProxy extends ProxyBase
{
@Override
public void postInit()
{
ThreadedGridTicker.INSTANCE.start();
}
public boolean isPaused()
{
return false;

View file

@ -128,6 +128,7 @@ public class ResonantInduction
ResonantInduction.LOGGER.fine("Languages Loaded:" + LanguageUtility.loadLanguages(Reference.LANGUAGE_DIRECTORY, Reference.LANGUAGES));
// Set Mod Metadata
Settings.setModMetadata(metadata, ID, NAME);
proxy.init();
}
@EventHandler
@ -136,5 +137,6 @@ public class ResonantInduction
Settings.save();
// Generate Resources
ResourceGenerator.generateOreResources();
proxy.postInit();
}
}

View file

@ -0,0 +1,113 @@
package resonantinduction.core.grid;
import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.TickType;
import net.minecraft.server.MinecraftServer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.Event;
import universalelectricity.api.net.IUpdate;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* A ticker to update all grids. This is multithreaded.
*
* @author Calclavia
*/
public class ThreadedGridTicker extends Thread
{
public static final ThreadedGridTicker INSTANCE = new ThreadedGridTicker();
/** For updaters to be ticked. */
private final Set<IUpdate> updaters = Collections.newSetFromMap(new WeakHashMap<IUpdate, Boolean>());
/** For queuing Forge events to be invoked the next tick. */
private final Queue<Event> queuedEvents = new ConcurrentLinkedQueue<Event>();
private ThreadedGridTicker()
{
setName("Universal Electricity");
setPriority(MIN_PRIORITY);
}
public static void addNetwork(IUpdate updater)
{
synchronized (INSTANCE.updaters)
{
INSTANCE.updaters.add(updater);
}
}
public static synchronized void queueEvent(Event event)
{
synchronized (INSTANCE.queuedEvents)
{
INSTANCE.queuedEvents.add(event);
}
}
@Override
public void run()
{
try
{
long last = System.currentTimeMillis();
while (true)
{
long current = System.currentTimeMillis();
long delta = current - last;
/** Tick all updaters. */
synchronized (updaters)
{
Set<IUpdate> removeUpdaters = Collections.newSetFromMap(new WeakHashMap<IUpdate, Boolean>());
Iterator<IUpdate> updaterIt = new HashSet<IUpdate>(updaters).iterator();
try
{
while (updaterIt.hasNext())
{
IUpdate updater = updaterIt.next();
if (updater.canUpdate())
{
updater.update();
}
if (!updater.continueUpdate())
{
removeUpdaters.add(updater);
}
}
updaters.removeAll(removeUpdaters);
}
catch (Exception e)
{
System.out.println("Universal Electricity Threaded Ticker: Failed while tcking updater. This is a bug! Clearing all tickers for self repair.");
updaters.clear();
e.printStackTrace();
}
}
/** Perform all queued events */
synchronized (queuedEvents)
{
while (!queuedEvents.isEmpty())
{
MinecraftForge.EVENT_BUS.post(queuedEvents.poll());
}
}
Thread.sleep(50L);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

View file

@ -10,7 +10,7 @@ public class TickingGrid<N extends Node> extends NodeGrid<N> implements IUpdate
{
super(type);
add(node);
NetworkTickHandler.addNetwork(this);
ThreadedGridTicker.addNetwork(this);
}
/**
@ -20,21 +20,13 @@ public class TickingGrid<N extends Node> extends NodeGrid<N> implements IUpdate
@Override
public void update()
{
new Thread()
synchronized (nodes)
{
@Override
public void run()
for (Node node : nodes)
{
synchronized (nodes)
{
for (Node node : nodes)
{
node.update(1 / 20f);
}
}
node.update(1 / 20f);
}
}.start();
}
}
@Override