Skip to content

Commit

Permalink
More routing refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Sm0keySa1m0n committed Sep 4, 2023
1 parent 2cc3e2a commit b880066
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 96 deletions.
14 changes: 6 additions & 8 deletions src/api/java/mods/railcraft/api/track/SwitchActuator.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package mods.railcraft.api.track;

import org.jetbrains.annotations.Nullable;
import net.minecraft.world.entity.vehicle.AbstractMinecart;

public interface SwitchActuator {

/**
* This method is used by the switch track to ask the actuator
* device whether it thinks the track should be switched or not. Ultimately,
* the track itself will decide whether it will be switched, however the
* track will usually try to honor results of this method when possible.
* This method is used by the switch track to ask the actuator device whether it thinks the track
* should be switched or not. Ultimately, the track itself will decide whether it will be
* switched, however the track will usually try to honour results of this method when possible.
*
* @param cart The cart that the switch may use to determine switch status.
* Implementations should expect null values.
* @param cart - the cart that the switch may use to determine switch status
* @return true if the actuator would like the track switched
*/
boolean shouldSwitch(@Nullable AbstractMinecart cart);
boolean shouldSwitch(AbstractMinecart cart);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import mods.railcraft.client.gui.widget.button.MultiButton;
import mods.railcraft.network.NetworkChannel;
import mods.railcraft.network.play.SetSwitchTrackRouterAttributesMessage;
import mods.railcraft.util.routing.RoutingLogic;
import mods.railcraft.util.routing.RoutingLogicException;
import mods.railcraft.world.inventory.SwitchTrackRouterMenu;
import mods.railcraft.world.level.block.entity.SwitchTrackRouterBlockEntity;
Expand Down Expand Up @@ -42,16 +41,15 @@ public SwitchTrackRouterScreen(SwitchTrackRouterMenu menu, Inventory inventory,
this.registerWidgetRenderer(new WidgetRenderer<>(menu.getErrorWidget()) {
@Override
public List<Component> getTooltip() {
return menu.getLogic()
.map(RoutingLogic::getError)
.map(RoutingLogicException::getToolTip)
return menu.getSwitchTrackRouter().logicError()
.map(RoutingLogicException::getTooltip)
.orElse(null);
}

@Override
public void render(ResourceLocation widgetLocation, GuiGraphics guiGraphics, int centreX,
int centreY, int mouseX, int mouseY) {
if (getTooltip() != null) {
if (this.getTooltip() != null) {
super.render(widgetLocation, guiGraphics, centreX, centreY, mouseX, mouseY);
}
}
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/mods/railcraft/util/routing/Router.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package mods.railcraft.util.routing;


import java.util.Optional;
import com.mojang.datafixers.util.Either;

public interface Router {

void resetLogic();

Optional<Either<RoutingLogic, RoutingLogicException>> logicResult();

default Optional<RoutingLogic> logic() {
return this.logicResult().flatMap(Either::left);
}

default Optional<RoutingLogicException> logicError() {
return this.logicResult().flatMap(Either::right);
}
}

16 changes: 0 additions & 16 deletions src/main/java/mods/railcraft/util/routing/RouterLogic.java

This file was deleted.

35 changes: 3 additions & 32 deletions src/main/java/mods/railcraft/util/routing/RoutingLogic.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.NoSuchElementException;
import org.jetbrains.annotations.Nullable;
import mods.railcraft.Translations;
import mods.railcraft.api.carts.NeedsFuel;
import mods.railcraft.api.carts.Paintable;
Expand All @@ -22,39 +21,11 @@
import mods.railcraft.util.routing.expression.condition.TypeCondition;
import net.minecraft.world.entity.vehicle.AbstractMinecart;

public class RoutingLogic {
public record RoutingLogic(Deque<Expression> expressions) {

public static final String REGEX_SYMBOL = "\\?";

private Deque<Expression> expressions;
private RoutingLogicException error;

private RoutingLogic(@Nullable Deque<String> data) {
try {
if (data != null) {
this.parseTable(data);
} else {
throw new RoutingLogicException(Translations.RoutingTable.ERROR_BLANK);
}
} catch (RoutingLogicException ex) {
this.error = ex;
}
}

public static RoutingLogic buildLogic(@Nullable Deque<String> data) {
return new RoutingLogic(data);
}

@Nullable
public RoutingLogicException getError() {
return this.error;
}

public boolean isValid() {
return this.expressions != null;
}

private void parseTable(Deque<String> data) throws RoutingLogicException {
public static RoutingLogic parseTable(Deque<String> data) throws RoutingLogicException {
Deque<Expression> stack = new ArrayDeque<>();
var it = data.descendingIterator();
while (it.hasNext()) {
Expand All @@ -64,7 +35,7 @@ private void parseTable(Deque<String> data) throws RoutingLogicException {
}
stack.push(parseLine(line, stack));
}
expressions = stack;
return new RoutingLogic(stack);
}

private static AbstractMinecart getRoutableCart(AbstractMinecart cart) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@

public class RoutingLogicException extends Exception {

private static final long serialVersionUID = -8668211003307380722L;

private final List<Component> tooltip;

public RoutingLogicException(String errorKey) {
tooltip = List.of(Component.translatable(errorKey).withStyle(ChatFormatting.RED));
this.tooltip = List.of(Component.translatable(errorKey).withStyle(ChatFormatting.RED));
}

public RoutingLogicException(String errorKey, String line) {
var error = Component.translatable(errorKey).withStyle(ChatFormatting.RED);
var lineLiteral = Component.literal("\"" + line + "\"");
tooltip = List.of(error, lineLiteral);
this.tooltip = List.of(error, lineLiteral);
}

public List<Component> getToolTip() {
public List<Component> getTooltip() {
return this.tooltip;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package mods.railcraft.world.inventory;

import java.util.Optional;
import mods.railcraft.gui.widget.Widget;
import mods.railcraft.util.routing.RoutingLogic;
import mods.railcraft.world.item.RoutingTableBookItem;
import mods.railcraft.world.level.block.entity.SwitchTrackRouterBlockEntity;
import net.minecraft.world.entity.player.Inventory;
Expand All @@ -17,7 +15,8 @@ public class SwitchTrackRouterMenu extends RailcraftMenu {

public SwitchTrackRouterMenu(int id, Inventory inventory,
SwitchTrackRouterBlockEntity blockEntity) {
super(RailcraftMenuTypes.SWITCH_TRACK_ROUTER.get(), id, inventory.player, blockEntity::isStillValid);
super(RailcraftMenuTypes.SWITCH_TRACK_ROUTER.get(), id, inventory.player,
blockEntity::isStillValid);
this.switchTrackRouter = blockEntity;

var routingTableBookSlot = new Slot(switchTrackRouter, 0, 35, 24) {
Expand All @@ -43,7 +42,7 @@ public boolean allowModification(Player player) {
public void setChanged() {
super.setChanged();
switchTrackRouter.resetLogic();
switchTrackRouter.getLogic().ifPresent(logic -> error.hidden = logic.getError() == null);
error.hidden = switchTrackRouter.logicError().isEmpty();
}
};

Expand All @@ -59,8 +58,4 @@ public SwitchTrackRouterBlockEntity getSwitchTrackRouter() {
public Widget getErrorWidget() {
return this.error;
}

public Optional<RoutingLogic> getLogic() {
return this.switchTrackRouter.getLogic();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.stream.Collectors;
import org.jetbrains.annotations.Nullable;
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.util.Either;
import mods.railcraft.Translations;
import mods.railcraft.api.track.SwitchActuator;
import mods.railcraft.api.util.EnumUtil;
Expand All @@ -19,8 +20,9 @@
import mods.railcraft.util.container.AdvancedContainer;
import mods.railcraft.util.container.ForwardingContainer;
import mods.railcraft.util.routing.RouterBlockEntity;
import mods.railcraft.util.routing.RouterLogic;
import mods.railcraft.util.routing.Router;
import mods.railcraft.util.routing.RoutingLogic;
import mods.railcraft.util.routing.RoutingLogicException;
import mods.railcraft.world.entity.vehicle.CartTools;
import mods.railcraft.world.inventory.SwitchTrackRouterMenu;
import mods.railcraft.world.level.block.track.actuator.SwitchTrackActuatorBlock;
Expand All @@ -39,11 +41,11 @@
import net.minecraft.world.level.block.state.BlockState;

public class SwitchTrackRouterBlockEntity extends LockableSwitchTrackActuatorBlockEntity
implements ForwardingContainer, MenuProvider, RouterBlockEntity, RouterLogic, SwitchActuator {
implements ForwardingContainer, MenuProvider, RouterBlockEntity, Router, SwitchActuator {

private final AdvancedContainer container;
@Nullable
private RoutingLogic logic;
private Either<RoutingLogic, RoutingLogicException> logic;
private Railway railway = Railway.PUBLIC;
private boolean powered;

Expand Down Expand Up @@ -109,32 +111,36 @@ public boolean isPowered() {
}

@Override
public Optional<RoutingLogic> getLogic() {
refreshLogic();
return Optional.ofNullable(logic);
public Optional<Either<RoutingLogic, RoutingLogicException>> logicResult() {
this.refreshLogic();
return Optional.ofNullable(this.logic);
}

@Override
public void resetLogic() {
logic = null;
this.logic = null;
}

private void refreshLogic() {
if (logic == null && !container.getItem(0).isEmpty()) {
var item = container.getItem(0);
if (this.logic == null && !this.container.getItem(0).isEmpty()) {
var item = this.container.getItem(0);
if (item.getTag() != null && item.getTag().contains("pages")) {
var content = loadPages(item.getTag());
logic = RoutingLogic.buildLogic(content);
try {
this.logic = Either.left(RoutingLogic.parseTable(content));
} catch (RoutingLogicException e) {
this.logic = Either.right(e);
}
}
}
}

@Override
public boolean shouldSwitch(@Nullable AbstractMinecart cart) {
boolean shouldSwitch = getLogic()
.map(l -> cart != null && l.isValid() && l.matches(this, cart))
public boolean shouldSwitch(AbstractMinecart cart) {
var shouldSwitch = this.logic()
.map(logic -> logic.matches(this, cart))
.orElse(false);
if (cart != null && railway.equals(Railway.PRIVATE)) {
if (this.railway == Railway.PRIVATE) {
var cartOwner = CartTools.getCartOwner(cart);
if (cartOwner == null) {
shouldSwitch = false;
Expand All @@ -150,7 +156,7 @@ public boolean shouldSwitch(@Nullable AbstractMinecart cart) {
private static Deque<String> loadPages(CompoundTag tag) {
Deque<String> contents = new LinkedList<>();
var pages = tag.getList("pages", Tag.TAG_STRING).copy();
for(int i = 0; i < pages.size(); i++) {
for (int i = 0; i < pages.size(); i++) {
var page = pages.getString(i).split("\n");
contents.addAll(Arrays.asList(page));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,21 +170,20 @@ public final BlockPos getActuatorBlockPos() {
* whether the switch is sprung or not. It caches the server responses for the clients to use.
* Note: This method should not modify any variables except the cache, we leave that to update().
*/
public boolean shouldSwitchForCart(@Nullable AbstractMinecart cart) {
if (cart == null || this.level.isClientSide())
return false;

if (this.springingCarts.contains(cart.getUUID()))
public boolean shouldSwitchForCart(AbstractMinecart cart) {
if (this.springingCarts.contains(cart.getUUID())) {
return true; // Carts at the spring entrance always are on switched tracks
}

if (this.lockingCarts.contains(cart.getUUID()))
if (this.lockingCarts.contains(cart.getUUID())) {
return false; // Carts at the locking entrance always are on locked tracks
}

var sameTrain = this.currentCart() != null && RollingStock.getOrThrow(cart)
.isSameTrainAs(this.currentCart());
var sameTrain = this.currentCart() != null
&& RollingStock.getOrThrow(cart).isSameTrainAs(this.currentCart());

boolean shouldSwitch = false;
var actuatorBlockEntity = this.level.getBlockEntity(this.getActuatorBlockPos());
var actuatorBlockEntity = this.level.getBlockEntity(this.getActuatorBlockPos());
if (actuatorBlockEntity instanceof SwitchActuator switchActuator) {
shouldSwitch = switchActuator.shouldSwitch(cart);
}
Expand Down

0 comments on commit b880066

Please sign in to comment.