From 69079dab94a2f95eb96dffa0e54ed0f6ef689868 Mon Sep 17 00:00:00 2001 From: SpaceToad Date: Sun, 5 Jan 2014 17:47:48 +0100 Subject: [PATCH] Fixed lasers looking for tables on a regular basis, fix #1400 Attempt at improving SafeTimeTracker interface and implement automatic randomization. If interface is confirmed, other places in the code will need to be updated to the interface. --- .../buildcraft/api/core/SafeTimeTracker.java | 45 +++++++++++++++++-- common/buildcraft/silicon/TileLaser.java | 25 +++++------ 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/common/buildcraft/api/core/SafeTimeTracker.java b/common/buildcraft/api/core/SafeTimeTracker.java index 44e1531e..14d94230 100644 --- a/common/buildcraft/api/core/SafeTimeTracker.java +++ b/common/buildcraft/api/core/SafeTimeTracker.java @@ -13,10 +13,45 @@ public class SafeTimeTracker { private long lastMark = Long.MIN_VALUE; private long duration = -1; + private long randomRange = 0; + private long lastRandomDelay = 0; + private long internalDelay = 1; + + /** + * @deprecated should use constructors with parameters instead + */ + public SafeTimeTracker () { + + } + + public SafeTimeTracker (long delay) { + internalDelay = delay; + } + + /** + * In many situations, it is a bad idea to have all objects of the same + * kind to be waiting for the exact same amount of time, as that can lead + * to some situation where they're all synchronized and got to work all + * at the same time. When created with a random range, the mark that is set + * when reaching the expect delay will be added with a random number + * between [0, range[, meaning that the event will take between 0 and range + * more tick to run. + */ + public SafeTimeTracker (long delay, long random) { + internalDelay = delay; + randomRange = random; + } + + public boolean markTimeIfDelay(World world) { + return markTimeIfDelay(world, internalDelay); + } /** * Return true if a given delay has passed since last time marked was called * successfully. + * + * @deprecated should use the constructor with a delay instead, and call + * this function without a parameter */ public boolean markTimeIfDelay(World world, long delay) { if (world == null) @@ -27,13 +62,15 @@ public class SafeTimeTracker { if (currentTime < lastMark) { lastMark = currentTime; return false; - } else if (lastMark + delay <= currentTime) { + } else if (lastMark + delay + lastRandomDelay <= currentTime) { duration = currentTime - lastMark; lastMark = currentTime; - return true; - } else - return false; + lastRandomDelay = (int) (Math.random() * randomRange); + return true; + } else { + return false; + } } public long durationOfLastDelay() { diff --git a/common/buildcraft/silicon/TileLaser.java b/common/buildcraft/silicon/TileLaser.java index f38fb1e6..735d7336 100644 --- a/common/buildcraft/silicon/TileLaser.java +++ b/common/buildcraft/silicon/TileLaser.java @@ -32,14 +32,11 @@ public class TileLaser extends TileBuildCraft implements IPowerReceptor, IAction private static final float LASER_OFFSET = 2.0F / 16.0F; private EntityEnergyLaser laser = null; - private final SafeTimeTracker laserTickTracker = new SafeTimeTracker(); - private final SafeTimeTracker searchTracker = new SafeTimeTracker(); - private final SafeTimeTracker networkTracker = new SafeTimeTracker(); + private final SafeTimeTracker laserTickTracker = new SafeTimeTracker(10); + private final SafeTimeTracker searchTracker = new SafeTimeTracker(100, 100); + private final SafeTimeTracker networkTracker = new SafeTimeTracker(3); private ILaserTarget laserTarget; protected PowerHandler powerHandler; - private int nextNetworkUpdate = 3; - private int nextLaserUpdate = 10; - private int nextLaserSearch = 100; private ActionMachineControl.Mode lastMode = ActionMachineControl.Mode.Unknown; private static final PowerHandler.PerditionCalculator PERDITION = new PowerHandler.PerditionCalculator(0.5F); @@ -66,11 +63,10 @@ public class TileLaser extends TileBuildCraft implements IPowerReceptor, IAction return; } - // Check for available tables if none is linked to this laser. - if (!isValidTable()) - if (canFindTable()) { - findTable(); - } + // Check for any available tables at a regular basis + if (canFindTable()) { + findTable(); + } // If we still don't have a valid table or the existing has // become invalid, we disable the laser and do nothing. @@ -117,11 +113,11 @@ public class TileLaser extends TileBuildCraft implements IPowerReceptor, IAction } protected boolean canFindTable() { - return searchTracker.markTimeIfDelay(worldObj, nextLaserSearch); + return searchTracker.markTimeIfDelay(worldObj); } protected boolean canUpdateLaser() { - return laserTickTracker.markTimeIfDelay(worldObj, nextLaserUpdate); + return laserTickTracker.markTimeIfDelay(worldObj); } protected boolean isValidTable() { @@ -235,7 +231,6 @@ public class TileLaser extends TileBuildCraft implements IPowerReceptor, IAction } protected void removeLaser() { - if (laser != null) { laser.setDead(); laser = null; @@ -253,7 +248,7 @@ public class TileLaser extends TileBuildCraft implements IPowerReceptor, IAction @Override public void sendNetworkUpdate() { - if (networkTracker.markTimeIfDelay(worldObj, nextNetworkUpdate)) { + if (networkTracker.markTimeIfDelay(worldObj)) { super.sendNetworkUpdate(); } }