From 917b1107d9278397a9bb9ca113bec13bde352927 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Thu, 12 Nov 2020 16:52:47 +0100 Subject: [PATCH] added new condition: BlockFree --- .../translations/Application.de.translation | 10 ++- .../de/srsoftware/web4rail/Application.java | 7 +-- .../de/srsoftware/web4rail/BaseClass.java | 2 +- .../de/srsoftware/web4rail/PathFinder.java | 2 +- .../java/de/srsoftware/web4rail/Plan.java | 7 +-- .../java/de/srsoftware/web4rail/Route.java | 4 +- .../srsoftware/web4rail/actions/Action.java | 12 ---- .../web4rail/actions/SendCommand.java | 4 +- .../srsoftware/web4rail/actions/SetPower.java | 2 +- .../web4rail/conditions/BlockFree.java | 61 +++++++++++++++++++ .../web4rail/conditions/Condition.java | 1 + .../de/srsoftware/web4rail/tiles/Block.java | 31 +++++++++- .../de/srsoftware/web4rail/tiles/Contact.java | 2 +- .../de/srsoftware/web4rail/tiles/Tile.java | 11 ---- 14 files changed, 115 insertions(+), 41 deletions(-) create mode 100644 src/main/java/de/srsoftware/web4rail/conditions/BlockFree.java diff --git a/resources/translations/Application.de.translation b/resources/translations/Application.de.translation index fb9da9d..b4bd7d3 100644 --- a/resources/translations/Application.de.translation +++ b/resources/translations/Application.de.translation @@ -14,6 +14,9 @@ Address\: : Adresse: Analyze : analysieren Apply : Übernehmen Availability : Verfügbarkeit +BlockFree : Blockbelegung +Block {} is free : Block {} ist frei +Block {} is occupied : Block {} ist belegt Block properties : Block-Eigenschaften {}bound : nach {} Cars\: : Waggons: @@ -23,6 +26,8 @@ Condition type\: : Bedingungs-Typ: Control unit : Zentrale Current location\: : Aktueller Ort: Actions and contacts : Aktionen und Kontakte +[Click here to select block!] : [Hier klicken, um Block auszuwählen!] +[Click here to select train!] : [Hier klicken, um Zug auszuwählen!] click here to setup contact : Hier klicken, um Kontakt auszuwählen click here to setup relay : Hier klicken, um Relais einzurichten Command to send to control unit\: : Kommando, welches zur Zentrale gesendet werden soll: @@ -90,11 +95,13 @@ Report Issue : Problem melden RIGHT : rechts Right port\: : Port für rechts Routes using this tile\: : Fahrstraßen, die diesen Abschnitt verwenden: -Route will only be available to trains fulfilling all conditions. : Route ist nur für Züge verfügbar, die alle Bedingungen erfüllen. +Route will only be available, if all conditions are fulfilled. : Route ist nur verfügbar, wenn alle Bedingungen erfüllt sind. Save : speichern +Select block\: : Block auswählen: Select contact\: : Kotakt auswählen: Select from plan : Auf Plan auswählen Select relay\: : Relais auswählen: +Select train\: : Zug auswählen: SendCommand : Kommando senden Send command \"{}\" to control unit : Kommando „{}“ an Zentrale senden SetRelay : Relais schalten @@ -118,6 +125,7 @@ Tag : Markierung Tags : Markierungen Toggle : umschalten Toggle power : Stom umschalten +Train : Zug Train\: : Zug: train does not have tag "{}" : Zug hat keine Markierung „{}“ train has tag "{}" : Zug hat Markierung „{}“ diff --git a/src/main/java/de/srsoftware/web4rail/Application.java b/src/main/java/de/srsoftware/web4rail/Application.java index 8effbc3..e021c51 100644 --- a/src/main/java/de/srsoftware/web4rail/Application.java +++ b/src/main/java/de/srsoftware/web4rail/Application.java @@ -38,8 +38,7 @@ import de.srsoftware.web4rail.tiles.Contact; * @author Stephan Richter, SRSoftware * */ -public class Application implements Constants{ - private static Plan plan; // the track layout in use +public class Application extends BaseClass{ private static final Logger LOG = LoggerFactory.getLogger(Application.class); /** @@ -67,7 +66,7 @@ public class Application implements Constants{ server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool()); server.start(); try { - plan = Plan.load(Plan.DEFAULT_NAME); + Plan.load(Plan.DEFAULT_NAME); } catch (FileNotFoundException e) { plan = new Plan(); } @@ -124,7 +123,7 @@ public class Application implements Constants{ case REALM_PLAN: return plan.action(params); case REALM_ROUTE: - return Route.action(params,plan); + return Route.action(params); case REALM_TRAIN: return Train.action(params,plan); } diff --git a/src/main/java/de/srsoftware/web4rail/BaseClass.java b/src/main/java/de/srsoftware/web4rail/BaseClass.java index 70c11c2..7727128 100644 --- a/src/main/java/de/srsoftware/web4rail/BaseClass.java +++ b/src/main/java/de/srsoftware/web4rail/BaseClass.java @@ -9,7 +9,7 @@ import org.json.JSONObject; import de.srsoftware.tools.Tag; public abstract class BaseClass implements Constants{ - + protected static Plan plan; // the track layout in use public static final Random random = new Random(); public static Tag link(String tagClass,Map params,Object caption) { diff --git a/src/main/java/de/srsoftware/web4rail/PathFinder.java b/src/main/java/de/srsoftware/web4rail/PathFinder.java index 71f4336..6e2fae2 100644 --- a/src/main/java/de/srsoftware/web4rail/PathFinder.java +++ b/src/main/java/de/srsoftware/web4rail/PathFinder.java @@ -92,7 +92,7 @@ public class PathFinder extends BaseClass{ routeSet.add(routeCandidate); if (routeCandidate.endBlock() == destination) break; // direct connection to destination discovered, quit search } - LOG.debug("{}→ Routes from {}: {}",inset,block,availableRoutes.isEmpty()?"none":""); + if (!availableRoutes.isEmpty()) LOG.debug("{}→ Routes from {}: {}",inset,block,availableRoutes.isEmpty()?"none":""); for (Entry> entry : availableRoutes.entrySet()) { LOG.debug("{} - Priority {}:",inset,entry.getKey()); for (Route r : entry.getValue()) { diff --git a/src/main/java/de/srsoftware/web4rail/Plan.java b/src/main/java/de/srsoftware/web4rail/Plan.java index b74c8b3..dc26440 100644 --- a/src/main/java/de/srsoftware/web4rail/Plan.java +++ b/src/main/java/de/srsoftware/web4rail/Plan.java @@ -383,8 +383,8 @@ public class Plan extends BaseClass{ * @throws NoSuchMethodException * @throws SecurityException */ - public static Plan load(String filename) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { - Plan plan = new Plan(); + public static void load(String filename) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { + plan = new Plan(); try { Car.loadAll(filename+".cars",plan); } catch (Exception e) { @@ -411,7 +411,6 @@ public class Plan extends BaseClass{ } catch (Exception e) { LOG.warn("Was not able to establish connection to control unit!"); } - return plan; } /** @@ -666,7 +665,7 @@ public class Plan extends BaseClass{ * @param tile */ private void setIntern(int x, int y, Tile tile) { - tile.position(x, y).plan(this); + tile.position(x, y); tiles.put(tile.id(),tile); } diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java index e516b4a..0b8adad 100644 --- a/src/main/java/de/srsoftware/web4rail/Route.java +++ b/src/main/java/de/srsoftware/web4rail/Route.java @@ -88,7 +88,7 @@ public class Route extends BaseClass{ * @return * @throws IOException */ - public static Object action(HashMap params,Plan plan) throws IOException { + public static Object action(HashMap params) throws IOException { Route route = plan.route(Integer.parseInt(params.get(ID))); if (isNull(route)) return t("Unknown route: {}",params.get(ID)); switch (params.get(ACTION)) { @@ -367,7 +367,7 @@ public class Route extends BaseClass{ train.set(endBlock); if (endBlock == train.destination()) { train.destination(null).quitAutopilot(); - endBlock.plan().stream(t("{} reached it`s destination!",train)); + plan.stream(t("{} reached it`s destination!",train)); } else { train.setWaitTime(endBlock.getWaitTime(train)); } diff --git a/src/main/java/de/srsoftware/web4rail/actions/Action.java b/src/main/java/de/srsoftware/web4rail/actions/Action.java index 0c25c71..c3cf54f 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/Action.java +++ b/src/main/java/de/srsoftware/web4rail/actions/Action.java @@ -2,7 +2,6 @@ package de.srsoftware.web4rail.actions; import java.io.IOException; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map.Entry; import java.util.TreeMap; @@ -15,7 +14,6 @@ import de.keawe.tools.translations.Translation; import de.srsoftware.tools.Tag; import de.srsoftware.web4rail.Application; import de.srsoftware.web4rail.BaseClass; -import de.srsoftware.web4rail.Plan; import de.srsoftware.web4rail.Plan.Direction; import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.Window; @@ -37,7 +35,6 @@ public abstract class Action extends BaseClass { protected int id; public static class Context { - public Plan plan = null; public Contact contact = null; public Route route = null; public Train train = null; @@ -46,7 +43,6 @@ public abstract class Action extends BaseClass { public Context(Contact c) { contact = c; - setPlan(contact.plan()); setRoute(contact.route()); } @@ -80,14 +76,6 @@ public abstract class Action extends BaseClass { private void setBlock(Block block) { this.block = block; } - - private void setPlan(Plan plan) { - this.plan = plan; - } - - - - @Override public String toString() { diff --git a/src/main/java/de/srsoftware/web4rail/actions/SendCommand.java b/src/main/java/de/srsoftware/web4rail/actions/SendCommand.java index 29269c8..c3230cc 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/SendCommand.java +++ b/src/main/java/de/srsoftware/web4rail/actions/SendCommand.java @@ -19,12 +19,12 @@ public class SendCommand extends Action{ @Override public boolean fire(Context context) { - context.plan.queue(new Command(command) { + plan.queue(new Command(command) { @Override public void onResponse(Reply reply) { super.onResponse(reply); - context.plan.stream(reply.message()); + plan.stream(reply.message()); } }); diff --git a/src/main/java/de/srsoftware/web4rail/actions/SetPower.java b/src/main/java/de/srsoftware/web4rail/actions/SetPower.java index 353858c..4b9efaf 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/SetPower.java +++ b/src/main/java/de/srsoftware/web4rail/actions/SetPower.java @@ -23,7 +23,7 @@ public class SetPower extends Action{ @Override public boolean fire(Context context) { - ControlUnit cu = context.contact.plan().controlUnit(); + ControlUnit cu = plan.controlUnit(); switch (pc) { case ON: cu.set(true); diff --git a/src/main/java/de/srsoftware/web4rail/conditions/BlockFree.java b/src/main/java/de/srsoftware/web4rail/conditions/BlockFree.java new file mode 100644 index 0000000..3b054ab --- /dev/null +++ b/src/main/java/de/srsoftware/web4rail/conditions/BlockFree.java @@ -0,0 +1,61 @@ +package de.srsoftware.web4rail.conditions; + +import java.util.HashMap; + +import org.json.JSONObject; + +import de.srsoftware.tools.Tag; +import de.srsoftware.web4rail.actions.Action.Context; +import de.srsoftware.web4rail.tags.Label; +import de.srsoftware.web4rail.tiles.Block; + +public class BlockFree extends Condition { + + private static final String BLOCK = Block.class.getSimpleName(); + private Block block; + + @Override + public boolean fulfilledBy(Context context) { + return block.isFreeFor(null) != inverted; + } + + @Override + public JSONObject json() { + return super.json().put(BLOCK, block.id()); + } + + public Condition load(JSONObject json) { + super.load(json); + block(Block.get(json.getString(BLOCK))); + return this; + } + + @Override + public Tag propForm(HashMap params) { + Tag form = super.propForm(params); + Block.selector(block, null).addTo(new Label(t("Select block:")+NBSP)).addTo(form); + return form; + } + + @Override + public String toString() { + if (block == null) return t("[Click here to select block!]"); + return t(inverted ? "Block {} is occupied":"Block {} is free",block); + } + + private BlockFree block(Block block) { + this.block = block; + return this; + } + + + @Override + protected Object update(HashMap params) { + if (!params.containsKey(BLOCK)) return t("No block id passed to BlockFree.update()!"); + String bid = params.get(BLOCK); + Block block = Block.get(bid); + if (block == null) return t("No block with id {} found!",bid); + this.block = block; + return super.update(params); + } +} diff --git a/src/main/java/de/srsoftware/web4rail/conditions/Condition.java b/src/main/java/de/srsoftware/web4rail/conditions/Condition.java index 7e26c55..77b0d44 100644 --- a/src/main/java/de/srsoftware/web4rail/conditions/Condition.java +++ b/src/main/java/de/srsoftware/web4rail/conditions/Condition.java @@ -88,6 +88,7 @@ public abstract class Condition extends BaseClass { private static List> list() { return List.of( + BlockFree.class, PushPullTrain.class, TrainHasTag.class, TrainSelect.class, diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Block.java b/src/main/java/de/srsoftware/web4rail/tiles/Block.java index 5bfa94c..1f914ca 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Block.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Block.java @@ -1,10 +1,12 @@ package de.srsoftware.web4rail.tiles; import java.io.IOException; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.TreeSet; import java.util.Vector; import org.json.JSONArray; @@ -28,7 +30,7 @@ import de.srsoftware.web4rail.tags.Select; * @author Stephan Richter, SRSoftware * */ -public abstract class Block extends StretchableTile{ +public abstract class Block extends StretchableTile implements Comparable{ private static final String ALLOW_TURN = "allowTurn"; private static final String NAME = "name"; private static final String NO_TAG = "[default]"; @@ -113,6 +115,11 @@ public abstract class Block extends StretchableTile{ private Vector waitTimes = new Vector(); + + @Override + public int compareTo(Block other) { + return name.compareTo(other.name); + } @Override public JSONObject config() { @@ -134,6 +141,12 @@ public abstract class Block extends StretchableTile{ return this; } + public static Block get(String blockId) { + Tile tile = plan.get(blockId, false); + if (tile instanceof Block) return (Block) tile; + return null; + } + private WaitTime getWaitTime(String tag) { if (tag == null) return null; for (WaitTime wt : waitTimes) { @@ -273,6 +286,22 @@ public abstract class Block extends StretchableTile{ } return this; } + + public static Tag selector(Block preselected,Collection exclude) { + if (isNull(exclude)) exclude = new Vector(); + Select select = new Select(Block.class.getSimpleName()); + new Tag("option").attr("value","0").content(t("unset")).addTo(select); + TreeSet blocks = new TreeSet(); + for (Tile tile : plan.tiles.values()) { + if (tile instanceof Block) blocks.add((Block) tile); + } + for (Block block : blocks) { + if (exclude.contains(block)) continue; + Tag opt = select.addOption(block.id(), block); + if (block == preselected) opt.attr("selected", "selected"); + } + return select; + } public abstract List startPoints(); diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Contact.java b/src/main/java/de/srsoftware/web4rail/tiles/Contact.java index 6a6b160..690c831 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Contact.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Contact.java @@ -106,7 +106,7 @@ public class Contact extends Tile{ if (contact == null) return t("No contact with id {} found!",id); Tag propMenu = contact.propMenu(); propMenu.children().insertElementAt(new Tag("div").content(t("Trigger a feedback sensor to assign it with this contact!")), 1); - contact.plan.learn(contact); + plan.learn(contact); return propMenu; } return t("Unknown action: {}",action); diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java index a55e706..eb904fa 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java @@ -59,7 +59,6 @@ public abstract class Tile extends BaseClass{ private boolean disabled = false; private int length = DEFAUT_LENGTH; protected Direction oneWay = null; - protected Plan plan = null;; protected Route route = null; private HashSet routes = new HashSet<>(); protected HashSet shadows = new HashSet<>(); @@ -113,7 +112,6 @@ public abstract class Tile extends BaseClass{ private static void inflate(String clazz, JSONObject json, Plan plan) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException, IOException { clazz = Tile.class.getName().replace(".Tile", "."+clazz); Tile tile = (Tile) Tile.class.getClassLoader().loadClass(clazz).getDeclaredConstructor().newInstance(); - tile.plan(plan); tile.load(json); plan.set(tile.x, tile.y, tile); } @@ -175,15 +173,6 @@ public abstract class Tile extends BaseClass{ return this; } - public Plan plan() { - return plan; - } - - public Tile plan(Plan plan) { - this.plan = plan; - return this; - } - public Tile position(int x, int y) { this.x = x; this.y = y;