diff --git a/src/main/java/com/troblecodings/signals/core/SignalStateListener.java b/src/main/java/com/troblecodings/signals/core/SignalStateListener.java index 74e4c3dfc..f186aff73 100644 --- a/src/main/java/com/troblecodings/signals/core/SignalStateListener.java +++ b/src/main/java/com/troblecodings/signals/core/SignalStateListener.java @@ -8,6 +8,13 @@ public interface SignalStateListener { - public void update(final SignalStateInfo info, - final Map changedProperties, final ChangedState changedState); + public void update(final SignalStateInfo info, final Map changedProperties, + final ChangedState changedState); + + default SignalStateListener andThen(final SignalStateListener otherTask) { + return (info, properties, state) -> { + this.update(info, properties, state); + otherTask.update(info, properties, state); + }; + } } \ No newline at end of file diff --git a/src/main/java/com/troblecodings/signals/handler/NameHandler.java b/src/main/java/com/troblecodings/signals/handler/NameHandler.java index ca937f638..ab2b38ecb 100644 --- a/src/main/java/com/troblecodings/signals/handler/NameHandler.java +++ b/src/main/java/com/troblecodings/signals/handler/NameHandler.java @@ -57,6 +57,7 @@ public final class NameHandler implements INetworkSync { private static final Map> TASKS_WHEN_LOAD = new HashMap<>(); private static final Map>> LOAD_COUNTER = new HashMap<>(); private static ExecutorService writeService = Executors.newFixedThreadPool(5); + private static final ExecutorService threadService = Executors.newCachedThreadPool(); private static EventNetworkChannel channel; private static ResourceLocation channelName; @@ -92,7 +93,7 @@ public static void createName(final StateInfo info, final String name, final PlayerEntity creator) { if (info.world.isClientSide || name == null) return; - new Thread(() -> { + threadService.execute(() -> { setNameForNonSignal(info, name); final List> list = new ArrayList<>(); list.add(new LoadHolder<>(creator)); @@ -100,7 +101,7 @@ public static void createName(final StateInfo info, final String name, LOAD_COUNTER.put(info, list); } createToFile(info, name); - }, "OSNameHandler:createName").start(); + }); } public static void setNameForSignal(final StateInfo info, final String name) { @@ -117,12 +118,12 @@ public static void setNameForSignal(final StateInfo info, final String name) { public static void setNameForNonSignal(final StateInfo info, final String name) { if (info.world.isClientSide || name == null) return; - new Thread(() -> { + threadService.execute(() -> { synchronized (ALL_NAMES) { ALL_NAMES.put(info, name); } sendToAll(info, name); - }, "OSNameHandler:setName").start(); + }); } public static String getName(final StateInfo info) { @@ -336,7 +337,7 @@ public static void loadNames(final List infos, final @Nullable PlayerEntity player) { if (infos == null || infos.isEmpty()) return; - new Thread(() -> { + threadService.execute(() -> { infos.forEach(info -> { boolean isLoaded = false; synchronized (LOAD_COUNTER) { @@ -380,7 +381,7 @@ public static void loadNames(final List infos, } } }); - }, "NameHandler:loadNames").start(); + }); } public static void unloadName(final StateLoadHolder holder) { diff --git a/src/main/java/com/troblecodings/signals/handler/SignalStateHandler.java b/src/main/java/com/troblecodings/signals/handler/SignalStateHandler.java index c3d83c3c2..7441cf8b9 100644 --- a/src/main/java/com/troblecodings/signals/handler/SignalStateHandler.java +++ b/src/main/java/com/troblecodings/signals/handler/SignalStateHandler.java @@ -56,6 +56,7 @@ public final class SignalStateHandler implements INetworkSync { private static ExecutorService writeService = Executors.newFixedThreadPool(5); + private static final ExecutorService threadService = Executors.newCachedThreadPool(); private static final Map> CURRENTLY_LOADED_STATES = new HashMap<>(); private static final Map ALL_LEVEL_FILES = new HashMap<>(); private static final Map>> SIGNAL_COUNTER = new HashMap<>(); @@ -104,7 +105,7 @@ public static void createStates(final SignalStateInfo info, CURRENTLY_LOADED_STATES.put(info, ImmutableMap.copyOf(states)); } updateListeners(info, states, ChangedState.ADDED_TO_FILE); - new Thread(() -> { + threadService.execute(() -> { final List> list = new ArrayList<>(); list.add(new LoadHolder<>(creator)); synchronized (SIGNAL_COUNTER) { @@ -112,7 +113,7 @@ public static void createStates(final SignalStateInfo info, } sendToAll(info, states); createToFile(info, states); - }, "OSSignalStateHandler:createStates").start(); + }); } public static boolean isSignalLoaded(final SignalStateInfo info) { @@ -237,13 +238,13 @@ public static void setStates(final SignalStateInfo info, final Map { + threadService.execute(() -> { sendToAll(info, changedProperties); info.signal.getUpdate(info.world, info.pos); if (!contains.get()) { createToFile(info, changedProperties); } - }, "OSSignalStateHandler:setStates").start(); + }); info.world.getServer().execute(() -> info.world.updateNeighborsAt(info.pos, info.signal)); } @@ -547,7 +548,7 @@ public static void loadSignals(final List signals, final @Nullable PlayerEntity player) { if (signals == null || signals.isEmpty()) return; - new Thread(() -> { + threadService.execute(() -> { signals.forEach(info -> { boolean isLoaded = false; synchronized (SIGNAL_COUNTER) { @@ -582,7 +583,7 @@ public static void loadSignals(final List signals, } } }); - }, "OSSignalStateHandler:loadSignals").start(); + }); } public static void unloadSignal(final SignalStateLoadHoler info) { diff --git a/src/main/java/com/troblecodings/signals/signalbox/SignalBoxGrid.java b/src/main/java/com/troblecodings/signals/signalbox/SignalBoxGrid.java index fde6eb5f2..59d82f3e5 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/SignalBoxGrid.java +++ b/src/main/java/com/troblecodings/signals/signalbox/SignalBoxGrid.java @@ -184,19 +184,9 @@ protected void addPathway(final PathwayData data) { } protected void updatePrevious(final SignalBoxPathway pathway) { - SignalBoxPathway previousPath = pathway; - int count = 0; - while ((previousPath = endsToPath.get(previousPath.getFirstPoint())) != null) { - if (count > endsToPath.size()) { - break; - } + SignalBoxPathway previousPath = endsToPath.get(pathway.getFirstPoint()); + if (previousPath != null) { previousPath.setSignals(); - count++; - } - if (count == 0) { - if (OpenSignalsMain.isDebug()) { - OpenSignalsMain.getLogger().debug("Could not find previous! " + pathway); - } } } diff --git a/src/main/java/com/troblecodings/signals/signalbox/SignalBoxPathway.java b/src/main/java/com/troblecodings/signals/signalbox/SignalBoxPathway.java index f9317405c..522f69be7 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/SignalBoxPathway.java +++ b/src/main/java/com/troblecodings/signals/signalbox/SignalBoxPathway.java @@ -44,6 +44,7 @@ public class SignalBoxPathway implements IChunkLoadable { protected final PathwayData data; + protected final SignalConfig config; protected boolean isBlocked; protected boolean isAutoPathway = false; @@ -58,6 +59,7 @@ public void setTile(final SignalBoxTileEntity tile) { } public SignalBoxPathway(final PathwayData data) { + this.config = new SignalConfig(this); this.data = data; this.originalFirstPoint = new Point(data.getFirstPoint()); updatePathwayToAutomatic(); @@ -152,6 +154,12 @@ public void setPathStatus(final EnumPathUsage status) { setPathStatus(status, null); } + public void updatePrevious() { + if (grid == null) + return; + grid.updatePrevious(this); + } + protected SignalStateInfo lastSignalInfo = null; protected SignalStateInfo getLastSignalInfo() { @@ -198,9 +206,14 @@ protected void setSignals(final SignalStateInfo lastSignal) { if (first == null) return; final SignalStateInfo firstInfo = new SignalStateInfo(world, startSignal.pos, first); - SignalConfig.change(new ConfigInfo(firstInfo, lastSignal, data)); + config.change(new ConfigInfo(firstInfo, lastSignal, data)); updatePreSignals(); } + final SignalBoxPathway next = getNextPathway(); + if (next != null && (next.isEmptyOrBroken() || next.isBlocked)) { + updateSignalStates(); + return; + } final Map distantSignalPositions = data .getOtherSignals(); distantSignalPositions.forEach((holder, position) -> { @@ -213,9 +226,9 @@ protected void setSignals(final SignalStateInfo lastSignal) { new SignalStateInfo(world, position.pos, current), lastSignal, data, position.isRepeater); if (position.guiMode.equals(EnumGuiMode.HP)) { - SignalConfig.loadDisable(info); + config.loadDisable(info); } else { - SignalConfig.change(info); + config.change(info); } }); updateSignalStates(); @@ -225,6 +238,10 @@ private void updatePreSignals() { final MainSignalIdentifier startSignal = data.getStartSignal(); if (startSignal == null) return; + final SignalBoxPathway next = getNextPathway(); + if (next != null && (next.isEmptyOrBroken() || next.isBlocked)) { + return; + } final StateInfo identifier = new StateInfo(tile.getLevel(), tile.getBlockPos()); final Signal first = SignalBoxHandler.getSignal(identifier, startSignal.pos); if (first == null) @@ -235,7 +252,7 @@ private void updatePreSignals() { final Signal current = SignalBoxHandler.getSignal(identifier, posIdent.pos); if (current == null) return; - SignalConfig.change( + config.change( new ConfigInfo(new SignalStateInfo(tile.getLevel(), posIdent.pos, current), firstInfo, data, posIdent.isRepeater)); }); @@ -269,8 +286,12 @@ protected void updateSignalStates() { final SignalBoxPathway next = getNextPathway(); final SignalState previous = position.state; if (endSignal != null && next != null && !next.isEmptyOrBroken()) { - if (!next.isExecutingSignalSet) + if (!next.isExecutingSignalSet) { position.state = SignalState.GREEN; + } + if (next.isBlocked) { + position.state = SignalState.RED; + } } else { position.state = SignalState.RED; } @@ -422,7 +443,6 @@ public void resetPathway(final @Nullable Point point) { resetFirstSignal(); System.out.println(getListOfNodes()); if (data.totalPathwayReset(point)) { - this.isBlocked = false; resetOther(); resetAllTrainNumbers(); sendTrainNumberUpdates(); @@ -603,7 +623,7 @@ private void resetAllTrainNumbers() { } private void resetAllTrainNumbers(final List trainNumberDisplays) { - if (grid != null) + if (grid != null && trainNumberDisplays != null) trainNumberDisplays.forEach(ident -> grid.getNode(ident.point).getOption(ident.mode) .orElse(new PathOptionEntry()).removeEntry(PathEntryType.TRAINNUMBER)); } diff --git a/src/main/java/com/troblecodings/signals/signalbox/config/SignalConfig.java b/src/main/java/com/troblecodings/signals/signalbox/config/SignalConfig.java index 362bf8e0b..340bc0888 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/config/SignalConfig.java +++ b/src/main/java/com/troblecodings/signals/signalbox/config/SignalConfig.java @@ -18,19 +18,23 @@ import com.troblecodings.signals.handler.SignalStateHandler; import com.troblecodings.signals.handler.SignalStateInfo; import com.troblecodings.signals.properties.PredicatedPropertyBase.ConfigProperty; +import com.troblecodings.signals.signalbox.SignalBoxPathway; public final class SignalConfig { private static final LoadHolder> LOAD_HOLDER = new LoadHolder<>( SignalConfig.class); - private SignalConfig() { + private final SignalBoxPathway pathway; + + public SignalConfig(final SignalBoxPathway pathway) { + this.pathway = pathway; } - public static void change(final ConfigInfo info) { + public void change(final ConfigInfo info) { final Signal currentSignal = info.currentinfo.signal; if (info.type.equals(PathType.NORMAL)) { - if (info.nextinfo != null) { + if (info.nextinfo != null && info.nextinfo.isValid()) { final Signal nextSignal = info.nextinfo.signal; final List values = ChangeConfigParser.CHANGECONFIGS .get(Maps.immutableEntry(currentSignal, nextSignal)); @@ -45,13 +49,15 @@ public static void change(final ConfigInfo info) { } else if (info.type.equals(PathType.SHUNTING)) { final List shuntingValues = OneSignalNonPredicateConfigParser.SHUNTINGCONFIGS .get(currentSignal); - if (shuntingValues != null) { + if (shuntingValues != null && info.currentinfo.isValid()) { loadWithoutPredicate(shuntingValues, info.currentinfo); } } } - private static void loadDefault(final ConfigInfo info) { + private void loadDefault(final ConfigInfo info) { + if (!info.currentinfo.isValid()) + return; final List defaultValues = OneSignalPredicateConfigParser.DEFAULTCONFIGS .get(info.currentinfo.signal); if (defaultValues != null) { @@ -79,11 +85,10 @@ public static void reset(final ResetInfo info) { }); if (!propertiesToSet.isEmpty()) SignalStateHandler.setStates(info.current, propertiesToSet); - unloadSignal(stateInfo); }); } - public static void loadDisable(final ConfigInfo info) { + public void loadDisable(final ConfigInfo info) { final List disableValues = OneSignalPredicateConfigParser.DISABLECONFIGS .get(info.currentinfo.signal); if (disableValues != null) { @@ -91,22 +96,20 @@ public static void loadDisable(final ConfigInfo info) { } } - private static void changeIfPresent(final List values, final ConfigInfo info) { + private void changeIfPresent(final List values, final ConfigInfo info) { loadSignalAndRunTask(info.currentinfo, (stateInfo, oldProperties, _u) -> { if (info.nextinfo != null) { loadSignalAndRunTask(info.nextinfo, (nextInfo, nextProperties, _u2) -> { changeSignals(values, info, oldProperties, nextProperties); - unloadSignal(nextInfo); }); } else { changeSignals(values, info, oldProperties, null); } - unloadSignal(stateInfo); }); } - private static void changeSignals(final List values, final ConfigInfo info, + private void changeSignals(final List values, final ConfigInfo info, final Map oldProperties, final Map nextProperties) { final Map, Object> object = new HashMap<>(); @@ -122,11 +125,13 @@ private static void changeSignals(final List values, final Confi .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); } }); - if (!propertiesToSet.isEmpty()) + if (!propertiesToSet.isEmpty()) { SignalStateHandler.setStates(info.currentinfo, propertiesToSet); + pathway.updatePrevious(); + } } - private static void loadWithoutPredicate(final List values, + private void loadWithoutPredicate(final List values, final SignalStateInfo current) { if (values != null) { loadSignalAndRunTask(current, (info, oldProperties, _u) -> { @@ -138,18 +143,19 @@ private static void loadWithoutPredicate(final List values, }); if (!propertiesToSet.isEmpty()) SignalStateHandler.setStates(current, propertiesToSet); - unloadSignal(info); + pathway.updatePrevious(); }); } } private static void loadSignalAndRunTask(final SignalStateInfo info, final SignalStateListener task) { - SignalStateHandler.loadSignal(new SignalStateLoadHoler(info, LOAD_HOLDER)); + final boolean isSignalLoaded = SignalStateHandler.isSignalLoaded(info); + if (!isSignalLoaded) { + SignalStateHandler.loadSignal(new SignalStateLoadHoler(info, LOAD_HOLDER)); + task.andThen((_u1, _u2, _u3) -> SignalStateHandler + .unloadSignal(new SignalStateLoadHoler(info, LOAD_HOLDER))); + } SignalStateHandler.runTaskWhenSignalLoaded(info, task); } - - private static void unloadSignal(final SignalStateInfo info) { - SignalStateHandler.unloadSignal(new SignalStateLoadHoler(info, LOAD_HOLDER)); - } }