-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
428 additions
and
184 deletions.
There are no files selected for viewing
41 changes: 41 additions & 0 deletions
41
src/main/java/com/clussmanproductions/railstuff/event/WorldEventHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.clussmanproductions.railstuff.event; | ||
|
||
import com.clussmanproductions.railstuff.ModRailStuff; | ||
import com.clussmanproductions.railstuff.scanner.ScannerThread; | ||
|
||
import net.minecraftforge.event.world.WorldEvent; | ||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; | ||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; | ||
|
||
@EventBusSubscriber | ||
public class WorldEventHandler { | ||
@SubscribeEvent | ||
public static void onLoad(WorldEvent.Load e) | ||
{ | ||
if (e.getWorld().isRemote || !ModRailStuff.IR_INSTALLED) | ||
{ | ||
return; | ||
} | ||
|
||
ScannerThread thread = new ScannerThread(e.getWorld()); | ||
ScannerThread.ThreadsByWorld.put(e.getWorld(), thread); | ||
thread.start(); | ||
} | ||
|
||
@SubscribeEvent | ||
public static void onUnload(WorldEvent.Unload e) | ||
{ | ||
if (e.getWorld().isRemote || !ModRailStuff.IR_INSTALLED) | ||
{ | ||
return; | ||
} | ||
|
||
if (ScannerThread.ThreadsByWorld.containsKey(e.getWorld())) | ||
{ | ||
ScannerThread thread = ScannerThread.ThreadsByWorld.get(e.getWorld()); | ||
thread.requestStop(); | ||
|
||
while(thread.isAlive()) {} | ||
} | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/main/java/com/clussmanproductions/railstuff/scanner/IScannerSubscriber.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.clussmanproductions.railstuff.scanner; | ||
|
||
import java.util.List; | ||
|
||
public interface IScannerSubscriber { | ||
List<ScanRequest> getScanRequests(); | ||
void onScanComplete(ScanCompleteData scanCompleteData); | ||
} |
23 changes: 23 additions & 0 deletions
23
src/main/java/com/clussmanproductions/railstuff/scanner/ScanCompleteData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.clussmanproductions.railstuff.scanner; | ||
|
||
import net.minecraft.util.EnumFacing; | ||
|
||
public class ScanCompleteData { | ||
private ScanRequest scanRequest; | ||
private boolean timedOut; | ||
private boolean trainFound; | ||
private boolean trainMovingTowardsDestination; | ||
|
||
public ScanCompleteData(ScanRequest scanRequest, boolean timedOut, boolean trainFound, boolean trainMovingTowardsDestination) | ||
{ | ||
this.scanRequest = scanRequest; | ||
this.timedOut = timedOut; | ||
this.trainFound = trainFound; | ||
this.trainMovingTowardsDestination = trainMovingTowardsDestination; | ||
} | ||
|
||
public ScanRequest getScanRequest() { return scanRequest; } | ||
public boolean getTimedOut() { return timedOut; } | ||
public boolean getTrainFound() { return trainFound; } | ||
public boolean getTrainMovingTowardsDestination() { return trainMovingTowardsDestination; } | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/com/clussmanproductions/railstuff/scanner/ScanRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.clussmanproductions.railstuff.scanner; | ||
|
||
import java.util.UUID; | ||
|
||
import net.minecraft.util.EnumFacing; | ||
import net.minecraft.util.math.BlockPos; | ||
|
||
public class ScanRequest { | ||
private UUID requestID; | ||
private BlockPos startingPos; | ||
private BlockPos endingPos; | ||
private EnumFacing startDirection; | ||
|
||
public ScanRequest(UUID requestID, BlockPos startingPos, BlockPos endingPos, EnumFacing startDirection) | ||
{ | ||
this.requestID = requestID; | ||
this.startingPos = startingPos; | ||
this.endingPos = endingPos; | ||
this.startDirection = startDirection; | ||
} | ||
|
||
public UUID getRequestID() { return requestID; } | ||
public BlockPos getStartingPos() { return startingPos; } | ||
public BlockPos getEndingPos() { return endingPos; } | ||
public EnumFacing getStartDirection() { return startDirection; } | ||
} |
92 changes: 92 additions & 0 deletions
92
src/main/java/com/clussmanproductions/railstuff/scanner/ScannerData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package com.clussmanproductions.railstuff.scanner; | ||
|
||
import java.util.HashSet; | ||
import java.util.concurrent.locks.ReentrantReadWriteLock; | ||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; | ||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; | ||
|
||
import com.google.common.collect.ImmutableList; | ||
|
||
import net.minecraft.nbt.NBTTagCompound; | ||
import net.minecraft.util.math.BlockPos; | ||
import net.minecraft.world.storage.WorldSavedData; | ||
|
||
public class ScannerData extends WorldSavedData { | ||
|
||
private HashSet<BlockPos> tileEntitySubscriptions = new HashSet<BlockPos>(); | ||
private ReentrantReadWriteLock tileEntitySubscriptionLock = new ReentrantReadWriteLock(); | ||
|
||
public ScannerData(String mapName) | ||
{ | ||
super(mapName); | ||
} | ||
|
||
public ScannerData() | ||
{ | ||
super("RS_scanner_data"); | ||
} | ||
|
||
@Override | ||
public void readFromNBT(NBTTagCompound nbt) { | ||
int i = 0; | ||
WriteLock lock = tileEntitySubscriptionLock.writeLock(); | ||
lock.lock(); | ||
while(nbt.hasKey("blockpos" + i)) | ||
{ | ||
long serializedBlockPos = nbt.getLong("blockpos" + i); | ||
tileEntitySubscriptions.add(BlockPos.fromLong(serializedBlockPos)); | ||
|
||
i++; | ||
} | ||
lock.unlock(); | ||
} | ||
|
||
@Override | ||
public NBTTagCompound writeToNBT(NBTTagCompound compound) { | ||
int i = 0; | ||
ReadLock lock = tileEntitySubscriptionLock.readLock(); | ||
lock.lock(); | ||
for(BlockPos pos : tileEntitySubscriptions) | ||
{ | ||
compound.setLong("blockpos" + i, pos.toLong()); | ||
} | ||
lock.unlock(); | ||
|
||
return compound; | ||
} | ||
|
||
public ImmutableList<BlockPos> getSubscribers() | ||
{ | ||
ReadLock lock = tileEntitySubscriptionLock.readLock(); | ||
|
||
lock.lock(); | ||
ImmutableList<BlockPos> list = ImmutableList.copyOf(tileEntitySubscriptions); | ||
lock.unlock(); | ||
|
||
return list; | ||
} | ||
|
||
public void addSubscriber(BlockPos pos) | ||
{ | ||
WriteLock lock = tileEntitySubscriptionLock.writeLock(); | ||
|
||
lock.lock(); | ||
if (tileEntitySubscriptions.add(pos)) | ||
{ | ||
markDirty(); | ||
} | ||
lock.unlock(); | ||
} | ||
|
||
public void removeSubscriber(BlockPos pos) | ||
{ | ||
WriteLock lock = tileEntitySubscriptionLock.writeLock(); | ||
|
||
lock.lock(); | ||
if (tileEntitySubscriptions.remove(pos)) | ||
{ | ||
markDirty(); | ||
} | ||
lock.unlock(); | ||
} | ||
} |
153 changes: 153 additions & 0 deletions
153
src/main/java/com/clussmanproductions/railstuff/scanner/ScannerThread.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
package com.clussmanproductions.railstuff.scanner; | ||
|
||
import java.util.HashMap; | ||
import java.util.List; | ||
|
||
import com.clussmanproductions.railstuff.Config; | ||
import com.clussmanproductions.railstuff.tile.SignalTileEntity.LastSwitchInfo; | ||
import com.clussmanproductions.railstuff.util.ImmersiveRailroadingHelper; | ||
|
||
import cam72cam.immersiverailroading.entity.EntityMoveableRollingStock; | ||
import net.minecraft.tileentity.TileEntity; | ||
import net.minecraft.util.EnumFacing; | ||
import net.minecraft.util.math.BlockPos; | ||
import net.minecraft.util.math.Vec3d; | ||
import net.minecraft.world.World; | ||
|
||
public class ScannerThread extends Thread | ||
{ | ||
public static HashMap<World, ScannerThread> ThreadsByWorld = new HashMap<World, ScannerThread>(); | ||
|
||
private World _world; | ||
private boolean _stop = false; | ||
private ScannerData _data; | ||
public ScannerThread(World world) | ||
{ | ||
super(); | ||
_world = world; | ||
} | ||
|
||
public void requestStop() | ||
{ | ||
_stop = true; | ||
} | ||
|
||
public <T extends TileEntity & IScannerSubscriber> void subscribe(T subscriber) | ||
{ | ||
_data.addSubscriber(subscriber.getPos()); | ||
} | ||
|
||
@Override | ||
public void run() { | ||
_data = (ScannerData)_world.loadData(ScannerData.class, "RS_scanner_data"); | ||
if (_data == null) | ||
{ | ||
_data = new ScannerData(); | ||
_world.setData(_data.mapName, _data); | ||
} | ||
|
||
while(true) | ||
{ | ||
if (_stop) | ||
{ | ||
return; | ||
} | ||
|
||
for(BlockPos pos : _data.getSubscribers()) | ||
{ | ||
if (!_world.isBlockLoaded(pos)) | ||
{ | ||
continue; | ||
} | ||
|
||
TileEntity tileEntity = _world.getTileEntity(pos); | ||
if (!(tileEntity instanceof IScannerSubscriber)) | ||
{ | ||
_data.removeSubscriber(pos); | ||
continue; | ||
} | ||
|
||
IScannerSubscriber subscriber = (IScannerSubscriber)tileEntity; | ||
for(ScanRequest req : subscriber.getScanRequests()) | ||
{ | ||
if (_stop) | ||
{ | ||
return; | ||
} | ||
|
||
ScanCompleteData data = performScan(req); | ||
|
||
if (_stop) | ||
{ | ||
return; | ||
} | ||
|
||
if (!_world.isBlockLoaded(pos)) | ||
{ | ||
break; | ||
} | ||
|
||
subscriber.onScanComplete(data); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private ScanCompleteData performScan(ScanRequest req) | ||
{ | ||
boolean foundTrain; | ||
boolean trainMovingTowardsDestination; | ||
|
||
Vec3d currentPosition = new Vec3d(req.getStartingPos().getX(), req.getStartingPos().getY(), req.getStartingPos().getZ()); | ||
Vec3d motion = new Vec3d(req.getStartDirection().getDirectionVec()); | ||
|
||
ScanCompleteData earlyData = checkPosition(req, currentPosition, motion); | ||
if (earlyData != null) | ||
{ | ||
return earlyData; | ||
} | ||
|
||
LastSwitchInfo lastSwitchInfo = new LastSwitchInfo(); | ||
BlockPos endingPosition = req.getEndingPos(); | ||
Vec3d endingVec = new Vec3d(endingPosition.getX(), endingPosition.getY(), endingPosition.getZ()); | ||
for(int i = 0; i < Config.signalDistanceTimeout; i++) | ||
{ | ||
Vec3d nextPosition = ImmersiveRailroadingHelper.getNextPosition(currentPosition, motion, _world, lastSwitchInfo); | ||
|
||
if (nextPosition.equals(currentPosition) || endingPosition.equals(new BlockPos(nextPosition.x, nextPosition.y, nextPosition.z))) | ||
{ | ||
return new ScanCompleteData(req, nextPosition.equals(currentPosition), false, false); | ||
} | ||
|
||
motion = new Vec3d(nextPosition.x - currentPosition.x, | ||
nextPosition.y - currentPosition.y, | ||
nextPosition.z - currentPosition.z); | ||
|
||
currentPosition = nextPosition; | ||
ScanCompleteData data = checkPosition(req, currentPosition, motion); | ||
if (data != null) | ||
{ | ||
return data; | ||
} | ||
} | ||
|
||
return new ScanCompleteData(req, true, false, false); | ||
} | ||
|
||
private ScanCompleteData checkPosition(ScanRequest req, Vec3d position, Vec3d motion) | ||
{ | ||
List<EntityMoveableRollingStock> moveableRollingStockNearby = ImmersiveRailroadingHelper.hasStockNearby(position, _world); | ||
if (!moveableRollingStockNearby.isEmpty()) | ||
{ | ||
EntityMoveableRollingStock stock = moveableRollingStockNearby.get(0); | ||
Vec3d stockVelocity = stock.getVelocity().internal; | ||
EnumFacing stockMovementFacing = EnumFacing.getFacingFromVector((float)stockVelocity.x, (float)stockVelocity.y, (float)stockVelocity.z); | ||
EnumFacing motionFacing = EnumFacing.getFacingFromVector((float)motion.x, (float)motion.y, (float)motion.z); | ||
|
||
boolean trainMovingTowardsDestination = motionFacing.equals(stockMovementFacing); | ||
return new ScanCompleteData(req, false, true, trainMovingTowardsDestination); | ||
} | ||
|
||
return null; | ||
} | ||
} |
Oops, something went wrong.