implemented small delay between setting signal to go and start of train. various GUI improvements
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>de.srsoftware</groupId>
|
||||
<artifactId>web4rail</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.3</version>
|
||||
<name>Web4Rail</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>Java Model Railway Control</description>
|
||||
|
||||
@@ -261,11 +261,15 @@ h4,ul{
|
||||
}
|
||||
|
||||
.window .disabled{
|
||||
background: red;
|
||||
background: orange;
|
||||
padding: 3px;
|
||||
display: table;
|
||||
}
|
||||
|
||||
.window tr.disabled {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
svg.disabled circle,
|
||||
svg.disabled line,
|
||||
svg.disabled polygon,
|
||||
@@ -309,6 +313,10 @@ table tr:hover td{
|
||||
background: #cadbdb;
|
||||
}
|
||||
|
||||
table tr.disabled:hover td {
|
||||
background: yellow;
|
||||
}
|
||||
|
||||
table.brake-times tr > *{
|
||||
border-style: solid;
|
||||
border-color: black;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
abort : abbrechen
|
||||
Accessory : Zubehör
|
||||
Actions : Aktionen
|
||||
Actions\: : Aktionen:
|
||||
Actions and contacts : Aktionen und Kontakte
|
||||
@@ -26,6 +27,7 @@ Address\: : Adresse:
|
||||
analyze : analysieren
|
||||
Analyze : analysieren
|
||||
Analyze may overwrite these routes! : Durch die Analyse können diese Fahrstraßen überschrieben werden!
|
||||
Analyzing plan... : Plan wird analysiert...
|
||||
and : und
|
||||
AndCondition : Und-Bedingung
|
||||
Apply : Übernehmen
|
||||
@@ -83,7 +85,6 @@ Current location\: {} : Aufenthaltsort: {}
|
||||
Current velocity\: {} {} : Aktuelle Geschwindigkeit: {} {}
|
||||
custom fields : benutzerdefinierte Felder
|
||||
Decoder address : Decoder-Adresse
|
||||
Delay : Verzögerung
|
||||
DelayedAction : verzögerte Aktion
|
||||
delete : entfernen
|
||||
delete route : Route löschen
|
||||
@@ -152,8 +153,10 @@ Lower speed limit : Minimale Geschwindigkeit
|
||||
Manage cars : Waggons verwalten
|
||||
Manage locos : Lokomotiven verwalten
|
||||
Manage trains : Züge verwalten
|
||||
Maximum delay : maximale Verzögerung
|
||||
Maximum Speed : Höchstgeschwindigkeit
|
||||
Maximum train length : maximale Zug-Länge
|
||||
Minimum delay : minimale Verzögerung
|
||||
Minimum and maximum times (in Miliseconds) trains with the respective tag have to wait in this block. : Minamle und maximale Block-Haltezeit (in Millisekunden) für Züge mit der entsprchender Markierung.
|
||||
Move tiles : Kacheln verschieben
|
||||
name\: : Name:
|
||||
@@ -194,9 +197,9 @@ quit autopilot : Autopilot beenden
|
||||
{} reached it`s destination! : {} ist am Ziel angekommen!
|
||||
ReactivateContact : Kontakt reaktivieren
|
||||
Relay : Relais
|
||||
Relays and Turnouts : Relais und Weichen
|
||||
Relay/Turnout : Relais/Weiche
|
||||
Relay/Signal/Turnout : Relais/Signal/Weiche
|
||||
Remove tag "{}" from train : Markierung "{}" von Zug entfernen
|
||||
Removed {} : {} gelöscht
|
||||
Report Issue : Problem melden
|
||||
reverse : wenden
|
||||
Reversed {}. : {} umgedreht.
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package de.srsoftware.web4rail;
|
||||
|
||||
import de.srsoftware.tools.Tag;
|
||||
|
||||
public interface Device {
|
||||
public static final String ADDRESS = "address";
|
||||
public static final String PORT = "port";
|
||||
public static final String PROTOCOL = "proto";
|
||||
|
||||
public int address();
|
||||
|
||||
public Tag link(String...args);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.file.Files;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -650,7 +650,7 @@ public class Plan extends BaseClass{
|
||||
return actions.addTo(actionMenu);
|
||||
}
|
||||
|
||||
private Window properties(HashMap<String, String> params) {
|
||||
public Window properties(HashMap<String, String> params) {
|
||||
if (params.containsKey(ID)) {
|
||||
Tile tile = get(Id.from(params), true);
|
||||
if (isSet(tile)) return tile.properties();
|
||||
@@ -689,18 +689,41 @@ public class Plan extends BaseClass{
|
||||
}
|
||||
|
||||
private Fieldset relayProperties() {
|
||||
Fieldset fieldset = new Fieldset(t("Relays and Turnouts"));
|
||||
Fieldset fieldset = new Fieldset(t("Accessory"));
|
||||
Table table = new Table();
|
||||
table.addHead(t("Address"),t("Relay/Turnout"));
|
||||
table.addHead(t("Address"),t("Relay/Signal/Turnout"));
|
||||
|
||||
List<Device> devices = BaseClass.listElements(Tile.class)
|
||||
.stream()
|
||||
.filter(tile -> tile instanceof Device )
|
||||
.map(tile -> (Device) tile)
|
||||
.sorted(Comparator.comparing(Device::address))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (Signal signal : BaseClass.listElements(Signal.class)) {
|
||||
for (int addr : signal.addresses()) {
|
||||
devices.add(new Device() {
|
||||
@Override
|
||||
public int address() {
|
||||
return addr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag link(String... args) {
|
||||
return signal.link(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return signal.toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(devices, (d1,d2) -> d1.address() - d2.address());
|
||||
|
||||
for (Device device : devices) {
|
||||
Tile tile = (Tile) device;
|
||||
table.addRow(device.address(),tile.link(tile.toString()));
|
||||
table.addRow(device.address(),device.link(device.toString()));
|
||||
if (device.address() % 4 == 1) table.children().lastElement().clazz("group");
|
||||
|
||||
}
|
||||
@@ -719,8 +742,17 @@ public class Plan extends BaseClass{
|
||||
Table table = new Table();
|
||||
table.addHead(t("Name"),t("Start"),t("End"),t("Actions"));
|
||||
List<Route> routes = BaseClass.listElements(Route.class);
|
||||
Collections.sort(routes, (r1,r2) -> r1.name().compareTo(r2.name()));
|
||||
for (Route route : routes) {
|
||||
table.addRow(route.link("span",route.name()),route.link("span", route.startBlock()),route.link("span", route.endBlock()),plan.button(t("simplify name"), Map.of(ACTION,ACTION_AUTO,ROUTE,route.id().toString())));
|
||||
Tag actions = new Tag("div");
|
||||
plan.button(t("simplify name"), Map.of(ACTION,ACTION_AUTO,ROUTE,route.id().toString())).addTo(actions);
|
||||
route.button(t("delete"), Map.of(ACTION,ACTION_DROP)).addTo(actions);
|
||||
Tag row = table.addRow(
|
||||
route.link("span",route.name()),
|
||||
route.link("span", route.startBlock()),
|
||||
route.link("span", route.endBlock()),
|
||||
actions);
|
||||
if (route.isDisabled()) row.clazz("disabled");
|
||||
}
|
||||
table.clazz("turnouts").addTo(fieldset);
|
||||
return fieldset;
|
||||
|
||||
@@ -24,7 +24,7 @@ import de.srsoftware.web4rail.Plan.Direction;
|
||||
import de.srsoftware.web4rail.actions.Action;
|
||||
import de.srsoftware.web4rail.actions.ActionList;
|
||||
import de.srsoftware.web4rail.actions.BrakeStart;
|
||||
import de.srsoftware.web4rail.actions.BrakeStop;
|
||||
import de.srsoftware.web4rail.actions.DelayedAction;
|
||||
import de.srsoftware.web4rail.actions.FinishRoute;
|
||||
import de.srsoftware.web4rail.actions.PreserveRoute;
|
||||
import de.srsoftware.web4rail.actions.SetSignal;
|
||||
@@ -177,7 +177,8 @@ public class Route extends BaseClass {
|
||||
switch (params.get(ACTION)) {
|
||||
case ACTION_DROP:
|
||||
route.remove();
|
||||
return t("Removed {}.",route);
|
||||
plan.stream(t("Removed {}.",route));
|
||||
return plan.properties(new HashMap<String,String>());
|
||||
case ACTION_PROPS:
|
||||
return route.properties();
|
||||
case ACTION_UPDATE:
|
||||
@@ -319,11 +320,6 @@ public class Route extends BaseClass {
|
||||
brakeProcessor = new BrakeProcessor(this,train);
|
||||
}
|
||||
|
||||
public void brakeStop() {
|
||||
train.setSpeed(0);
|
||||
if (isSet(brakeProcessor)) brakeProcessor.finish();
|
||||
}
|
||||
|
||||
protected Route clone() {
|
||||
Route clone = new Route();
|
||||
clone.startBlock = startBlock;
|
||||
@@ -349,18 +345,19 @@ public class Route extends BaseClass {
|
||||
trigger = secondContact.trigger();
|
||||
for (Signal signal : signals) add(trigger,new SetSignal(this).set(signal).to(Signal.RED));
|
||||
}
|
||||
if (!contacts.isEmpty()) {
|
||||
Contact lastContact = contacts.lastElement();
|
||||
add(lastContact.trigger(), new BrakeStop(this));
|
||||
add(lastContact.trigger(), new FinishRoute(this));
|
||||
}
|
||||
if (!contacts.isEmpty()) add(contacts.lastElement().trigger(), new FinishRoute(this));
|
||||
for (Entry<Turnout, Turnout.State> entry : turnouts.entrySet()) {
|
||||
Turnout turnout = entry.getKey();
|
||||
Turnout.State state = entry.getValue();
|
||||
add(ROUTE_SETUP,new SetTurnout(this).setTurnout(turnout).setState(state));
|
||||
}
|
||||
for (Signal signal : signals) add(ROUTE_START,new SetSignal(this).set(signal).to(Signal.GREEN));
|
||||
add(ROUTE_START,new SetSpeed(this).to(999));
|
||||
for (Signal signal : signals) add(ROUTE_SETUP,new SetSignal(this).set(signal).to(Signal.GREEN));
|
||||
if (signals.isEmpty()) {
|
||||
add(ROUTE_START,new SetSpeed(this).to(999));
|
||||
} else {
|
||||
DelayedAction da = new DelayedAction(this).setMinDelay(1000).setMaxDelay(7500);
|
||||
add(ROUTE_START,da.add(new SetSpeed(this).to(999)));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -427,11 +424,21 @@ public class Route extends BaseClass {
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
if (isSet(train)) {
|
||||
if (train.nextRoutePrepared()) {
|
||||
if (isSet(brakeProcessor)) brakeProcessor.abort();
|
||||
} else {
|
||||
train.setSpeed(0);
|
||||
if (isSet(brakeProcessor)) brakeProcessor.finish();
|
||||
}
|
||||
}
|
||||
|
||||
context.clear(); // prevent delayed actions from firing after route has finished
|
||||
setSignals(Signal.RED);
|
||||
for (Tile tile : path) try {
|
||||
for (Tile tile : path) try { // remove route from tiles on path
|
||||
tile.unset(this);
|
||||
} catch (IllegalArgumentException e) {}
|
||||
|
||||
Tile lastTile = path.lastElement();
|
||||
if (lastTile instanceof Contact) {
|
||||
lastTile.setTrain(null);
|
||||
@@ -447,7 +454,7 @@ public class Route extends BaseClass {
|
||||
train.setWaitTime(endBlock.getWaitTime(train,train.direction()));
|
||||
}
|
||||
if (train.route == this) train.route = null;
|
||||
if (!train.onTrace(startBlock) && startBlock.train() == train) startBlock.setTrain(null);
|
||||
if (startBlock.train() == train && !train.onTrace(startBlock)) startBlock.setTrain(null); // withdraw train from start block only if trace does not go back there
|
||||
}
|
||||
train = null;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ public abstract class Action extends BaseClass {
|
||||
AddRemoveTag.class,
|
||||
BrakeCancel.class,
|
||||
BrakeStart.class,
|
||||
BrakeStop.class,
|
||||
ConditionalAction.class,
|
||||
DelayedAction.class,
|
||||
DetermineTrainInBlock.class,
|
||||
|
||||
@@ -61,6 +61,20 @@ public class ActionList extends Action implements Iterable<Action>{
|
||||
public void clear() {
|
||||
while (!actions.isEmpty()) actions.firstElement().remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean correspondsTo(Action other) {
|
||||
if (other instanceof ActionList) {
|
||||
ActionList otherAL = (ActionList) other;
|
||||
if (actions.size() != otherAL.actions.size()) return false;
|
||||
for (int i=0; i<actions.size(); i++) {
|
||||
if (!actions.get(i).correspondsTo(otherAL.actions.get(i))) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean drop(Action action) {
|
||||
return actions.remove(action);
|
||||
@@ -125,7 +139,7 @@ public class ActionList extends Action implements Iterable<Action>{
|
||||
if (o instanceof JSONObject) {
|
||||
JSONObject jsonObject = (JSONObject) o;
|
||||
Action action = Action.create(jsonObject.getString(TYPE),this);
|
||||
if (action != null) add(action.load(jsonObject));
|
||||
if (isSet(action)) add(action.load(jsonObject));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package de.srsoftware.web4rail.actions;
|
||||
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
|
||||
public class BrakeStop extends Action {
|
||||
|
||||
public BrakeStop(BaseClass parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
if (isNull(context.route()) || isNull(context.route().train())) return false;
|
||||
context.route().brakeStop();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -15,15 +15,18 @@ import de.srsoftware.web4rail.tags.Input;
|
||||
public class DelayedAction extends ActionList {
|
||||
|
||||
public static final String DELAY = "delay";
|
||||
public static final String MIN_DELAY = "min_delay";
|
||||
public static final String MAX_DELAY = "max_delay";
|
||||
private static final int DEFAULT_DELAY = 1000;
|
||||
private int delay = DEFAULT_DELAY;
|
||||
private int min_delay = DEFAULT_DELAY;
|
||||
private int max_delay = DEFAULT_DELAY;
|
||||
|
||||
public DelayedAction(BaseClass parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
|
||||
public boolean equals(DelayedAction other) {
|
||||
return (delay+":"+actions).equals(other.delay+":"+other.actions);
|
||||
return (min_delay+":"+max_delay+":"+actions).equals(other.min_delay+":"+other.max_delay+":"+other.actions);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -31,8 +34,8 @@ public class DelayedAction extends ActionList {
|
||||
Application.threadPool.execute(new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(delay);
|
||||
LOG.debug("{} ms passed by, firing actions:",delay);
|
||||
Thread.sleep(min_delay + (min_delay < max_delay ? random.nextInt(max_delay - min_delay) : 0));
|
||||
LOG.debug("{} ms passed by, firing actions:",min_delay);
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warn("Interrupted Exception thrown while waiting:",e);
|
||||
}
|
||||
@@ -44,38 +47,69 @@ public class DelayedAction extends ActionList {
|
||||
|
||||
@Override
|
||||
public JSONObject json() {
|
||||
return super.json().put(DELAY, delay);
|
||||
return super.json().put(MIN_DELAY, min_delay).put(MAX_DELAY, max_delay);
|
||||
}
|
||||
|
||||
public DelayedAction load(JSONObject json) {
|
||||
super.load(json);
|
||||
delay = json.getInt(DELAY);
|
||||
if (json.has(DELAY)) {
|
||||
min_delay = json.getInt(DELAY);
|
||||
max_delay = json.getInt(DELAY);
|
||||
}
|
||||
if (json.has(MIN_DELAY)) min_delay = json.getInt(MIN_DELAY);
|
||||
if (json.has(MAX_DELAY)) max_delay = json.getInt(MAX_DELAY);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm) {
|
||||
formInputs.add(t("Delay"),new Input(DELAY,delay).numeric().addTo(new Tag("span")).content(NBSP+"ms"));
|
||||
formInputs.add(t("Minimum delay"),new Input(MIN_DELAY,min_delay).numeric().addTo(new Tag("span")).content(NBSP+"ms"));
|
||||
formInputs.add(t("Maximum delay"),new Input(MAX_DELAY,max_delay).numeric().addTo(new Tag("span")).content(NBSP+"ms"));
|
||||
return super.properties(preForm, formInputs, postForm);
|
||||
}
|
||||
|
||||
public DelayedAction setMaxDelay(int max_delay) {
|
||||
this.max_delay = max_delay;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DelayedAction setMinDelay(int min_delay) {
|
||||
this.min_delay = min_delay;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return t("Wait {} ms, then:",delay);
|
||||
public String toString() {
|
||||
return t("Wait {} ms, then:",min_delay < max_delay ? min_delay+"…"+max_delay : min_delay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object update(HashMap<String, String> params) {
|
||||
String d = params.get(DELAY);
|
||||
if (d != null) try {
|
||||
String d = params.get(MIN_DELAY);
|
||||
if (isSet(d)) try {
|
||||
int ms = Integer.parseInt(d);
|
||||
if (ms < 0) throw new NumberFormatException(t("Delay must not be less than zero!"));
|
||||
delay = ms;
|
||||
min_delay = ms;
|
||||
} catch (NumberFormatException nfe) {
|
||||
Window props = properties();
|
||||
props.children().insertElementAt(new Tag("div").content(nfe.getMessage()), 2);
|
||||
return props;
|
||||
}
|
||||
d = params.get(MAX_DELAY);
|
||||
if (isSet(d)) try {
|
||||
int ms = Integer.parseInt(d);
|
||||
if (ms < 0) throw new NumberFormatException(t("Delay must not be less than zero!"));
|
||||
max_delay = ms;
|
||||
} catch (NumberFormatException nfe) {
|
||||
Window props = properties();
|
||||
props.children().insertElementAt(new Tag("div").content(nfe.getMessage()), 2);
|
||||
return props;
|
||||
}
|
||||
if (min_delay > max_delay) {
|
||||
int dummy = min_delay;
|
||||
min_delay = max_delay;
|
||||
max_delay = dummy;
|
||||
}
|
||||
return super.update(params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,9 @@ public class PreserveRoute extends Action {
|
||||
if (isNull(train)) return false;
|
||||
if (isNull(route)) return false;
|
||||
|
||||
|
||||
// These are NOT errors:
|
||||
if (!train.usesAutopilot()) return true;
|
||||
if (train.destination() == route.endBlock()) return true;
|
||||
if (!train.usesAutopilot()) return true; // do not reserve routes, when not in auto-mode
|
||||
if (train.destination() == route.endBlock()) return true; // do not reserve routes, when destination has been reached
|
||||
|
||||
Range waitTime = route.endBlock().getWaitTime(train,route.endDirection);
|
||||
if (waitTime.max > 0) {
|
||||
|
||||
@@ -23,6 +23,15 @@ public class SetSignal extends Action {
|
||||
private Signal signal = null;
|
||||
private String state = Signal.RED;
|
||||
|
||||
@Override
|
||||
public boolean correspondsTo(Action other) {
|
||||
if (other instanceof SetSignal) {
|
||||
SetSignal otherSS = (SetSignal) other;
|
||||
return otherSS.signal == this.signal;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
if (isNull(signal)) return false;
|
||||
|
||||
@@ -50,7 +50,7 @@ public class BlockFree extends Condition {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (block == null) return t("[Click here to select block!]");
|
||||
if (block == null) return "["+t("Click here to select block!")+"]";
|
||||
return t(inverted ? "Block {} is occupied":"Block {} is free",block);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ public class Table extends Tag{
|
||||
super("table");
|
||||
}
|
||||
|
||||
public Table addRow(Object...cols) {
|
||||
public Tag addRow(Object...cols) {
|
||||
Tag row = new Tag("tr");
|
||||
for (Object column : cols) {
|
||||
Tag col = null;
|
||||
@@ -22,12 +22,13 @@ public class Table extends Tag{
|
||||
col.addTo(row);
|
||||
}
|
||||
row.addTo(this);
|
||||
return this;
|
||||
return row;
|
||||
}
|
||||
|
||||
public Table addHead(Object...cols) {
|
||||
Object[] tags = new Tag[cols.length];
|
||||
for (int i=0; i<cols.length; i++) tags[i]= cols[i] instanceof Tag ? ((Tag)cols[i]).addTo(new Tag("th")) : new Tag("th").content(cols[i].toString());
|
||||
return addRow(tags);
|
||||
addRow(tags);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package de.srsoftware.web4rail.tiles;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -305,7 +306,9 @@ public abstract class Block extends StretchableTile{
|
||||
if (isNull(exclude)) exclude = new Vector<Block>();
|
||||
Select select = new Select(Block.class.getSimpleName());
|
||||
new Tag("option").attr("value","0").content(t("unset")).addTo(select);
|
||||
for (Block block : BaseClass.listElements(Block.class)) {
|
||||
List<Block> blocks = BaseClass.listElements(Block.class);
|
||||
Collections.sort(blocks, (b1,b2) -> b1.name.compareTo(b2.name));
|
||||
for (Block block : blocks) {
|
||||
if (exclude.contains(block)) continue;
|
||||
Tag opt = select.addOption(block.id(), block);
|
||||
if (block == preselected) opt.attr("selected", "selected");
|
||||
|
||||
@@ -44,6 +44,14 @@ public abstract class Signal extends Tile {
|
||||
super();
|
||||
}
|
||||
|
||||
public HashSet<Integer> addresses(){
|
||||
HashSet<Integer> list = new HashSet<Integer>();
|
||||
for (HashSet<int[]> commands : aspects.values()) {
|
||||
for (int[] data : commands) list.add(data[0]);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vector<String> classes() {
|
||||
Vector<String> classes = super.classes();
|
||||
|
||||
Reference in New Issue
Block a user