updated thread handling:
- threads are no longer pooled (this makes naming threads difficult) - threads are now named by their causing event, which improves logging updated calls to thread.sleep: those are now provided by new class Delayed Execution
This commit is contained in:
@@ -14,8 +14,6 @@ import java.net.URLDecoder;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -42,9 +40,9 @@ import de.srsoftware.web4rail.tiles.Contact;
|
||||
public class Application extends BaseClass{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Application.class);
|
||||
private static final String START_TRAINS = "--start-trains";
|
||||
public static final ExecutorService threadPool = Executors.newCachedThreadPool();
|
||||
private static final String FILENAME = "filename";
|
||||
private static Configuration config;
|
||||
private static int threadCounter = 0;
|
||||
|
||||
/**
|
||||
* entry point for the application:<br/>
|
||||
@@ -69,7 +67,6 @@ public class Application extends BaseClass{
|
||||
server.createContext("/css" , client -> sendFile(client));
|
||||
server.createContext("/js" , client -> sendFile(client));
|
||||
server.createContext("/stream", client -> stream(client));
|
||||
server.setExecutor(threadPool);
|
||||
server.start();
|
||||
try {
|
||||
Plan.load(planName);
|
||||
@@ -324,4 +321,8 @@ public class Application extends BaseClass{
|
||||
OutputStreamWriter sseWriter = new OutputStreamWriter(client.getResponseBody());
|
||||
plan.addClient(sseWriter);
|
||||
}
|
||||
|
||||
public static String threadName(Object owner) {
|
||||
return (++threadCounter )+":"+((owner instanceof String) ? (String) owner : owner.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,8 @@ public class ControlUnit extends Thread implements Constants{
|
||||
private Plan plan;
|
||||
|
||||
public ControlUnit(Plan plan) {
|
||||
this.plan = plan;
|
||||
this.plan = plan;
|
||||
setName(Application.threadName(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,7 +208,7 @@ public class ControlUnit extends Thread implements Constants{
|
||||
*/
|
||||
public ControlUnit restart() {
|
||||
end();
|
||||
Application.threadPool.execute(this);
|
||||
start();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -295,7 +296,7 @@ public class ControlUnit extends Thread implements Constants{
|
||||
private void startInfoThread() {
|
||||
infoSocket = commandSocket; // handshake läuft immer über commandSocket und commandScanner
|
||||
infoScanner = commandScanner;
|
||||
Runnable infoThread = new Runnable() {
|
||||
Thread infoThread = new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -313,12 +314,14 @@ public class ControlUnit extends Thread implements Constants{
|
||||
case FEEDBACK:
|
||||
int addr = Integer.parseInt(parts[5]);
|
||||
boolean active = !parts[6].equals("0");
|
||||
Application.threadPool.execute(new Thread() {
|
||||
Thread thread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
ControlUnit.this.plan.sensor(addr,active);
|
||||
}
|
||||
});
|
||||
};
|
||||
thread.setName(Application.threadName("CU.FeedBack("+addr+")"));
|
||||
thread.start();
|
||||
case ACESSORY:
|
||||
break;
|
||||
default:
|
||||
@@ -337,11 +340,16 @@ public class ControlUnit extends Thread implements Constants{
|
||||
LOG.info("Closed info socket.");
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Was not able to close info socket:",e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CU.InfoThread";
|
||||
}
|
||||
};
|
||||
Application.threadPool.execute(infoThread);
|
||||
infoThread.setName(Application.threadName("CU.InfoThread"));
|
||||
infoThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
26
src/main/java/de/srsoftware/web4rail/DelayedExecution.java
Normal file
26
src/main/java/de/srsoftware/web4rail/DelayedExecution.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package de.srsoftware.web4rail;
|
||||
|
||||
public abstract class DelayedExecution extends Thread {
|
||||
private int delay;
|
||||
|
||||
public DelayedExecution(Object cause) {
|
||||
this(1000,cause);
|
||||
}
|
||||
|
||||
public DelayedExecution(int delay,Object cause) {
|
||||
this.delay = delay;
|
||||
|
||||
setName(Application.threadName(cause));
|
||||
start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sleep(delay);
|
||||
} catch (InterruptedException e) {}
|
||||
execute();
|
||||
}
|
||||
|
||||
public abstract void execute();
|
||||
}
|
||||
@@ -119,6 +119,12 @@ public class Plan extends BaseClass{
|
||||
* This thread sends a heartbea to the client
|
||||
*/
|
||||
private class Heartbeat extends Thread {
|
||||
|
||||
public Heartbeat() {
|
||||
setName(Application.threadName(this));
|
||||
start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
@@ -159,7 +165,7 @@ public class Plan extends BaseClass{
|
||||
*/
|
||||
public Plan() {
|
||||
BaseClass.resetRegistry();
|
||||
Application.threadPool.execute(new Heartbeat());
|
||||
new Heartbeat();
|
||||
name = DEFAULT_NAME;
|
||||
}
|
||||
|
||||
@@ -293,7 +299,7 @@ public class Plan extends BaseClass{
|
||||
return win;
|
||||
}
|
||||
|
||||
Application.threadPool.execute(new Thread() {
|
||||
Thread analyzer = new Thread() {
|
||||
public void run() {
|
||||
Vector<Route> newRoutes = new Vector<Route>();
|
||||
for (Block block : BaseClass.listElements(Block.class)) {
|
||||
@@ -309,8 +315,10 @@ public class Plan extends BaseClass{
|
||||
}
|
||||
|
||||
stream(t("Found {} routes.",newRoutes.size()));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
analyzer.setName(Application.threadName("Plan.Analyzer"));
|
||||
analyzer.start();
|
||||
|
||||
return t("Analyzing plan...");
|
||||
}
|
||||
@@ -534,7 +542,7 @@ public class Plan extends BaseClass{
|
||||
LOG.warn("Was not able to load control unit settings!",e);
|
||||
}
|
||||
try {
|
||||
Application.threadPool.execute(plan.controlUnit);
|
||||
plan.controlUnit.start();
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Was not able to establish connection to control unit!");
|
||||
}
|
||||
|
||||
@@ -105,7 +105,8 @@ public class Route extends BaseClass {
|
||||
timeStep = brakeTimes.get(brakeId);
|
||||
|
||||
if (isNull(timeStep) || timeStep>1000000) timeStep = 256; // if no brake time is available for this train
|
||||
Application.threadPool.execute(this);
|
||||
setName(Application.threadName("BrakeProcessor("+train+")"));
|
||||
start();
|
||||
}
|
||||
|
||||
protected void abort() {
|
||||
@@ -177,11 +178,12 @@ public class Route extends BaseClass {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
setName(Application.threadName("BreakeProcessor("+train+")"));
|
||||
LOG.debug("started BrakeProcessor ({} → {}) for {} with timestep = {} ms.",train.speed,endSpeed,train,timeStep);
|
||||
estimatedDistance = 0;
|
||||
latestTick = timestamp();
|
||||
while (train.speed > endSpeed) {
|
||||
if (finished) return;
|
||||
if (finished || aborted) return;
|
||||
increaseDistance();
|
||||
LOG.debug("BrakeProcessor({}) setting Speed of {}.",route,train);
|
||||
train.setSpeed(Math.max(train.speed - SPEED_STEP,endSpeed));
|
||||
@@ -456,7 +458,7 @@ public class Route extends BaseClass {
|
||||
ActionList actions = triggeredActions.get(contact.trigger());
|
||||
LOG.debug("Contact has id {} / trigger {} and is assigned with {}",contact.id(),contact.trigger(),isNull(actions)?t("nothing"):actions);
|
||||
if (isNull(actions)) return;
|
||||
actions.fire(context);
|
||||
actions.fire(context,"Route.Contact("+contact.addr()+")");
|
||||
}
|
||||
|
||||
public Vector<Contact> contacts() {
|
||||
@@ -513,7 +515,10 @@ public class Route extends BaseClass {
|
||||
|
||||
if (isSet(train)) {
|
||||
Route nextRoute = train.nextRoute();
|
||||
if (!isSet(nextRoute)) {
|
||||
if (isSet(nextRoute)) {
|
||||
LOG.debug("{} has next route: {}",train,nextRoute);
|
||||
if (isSet(brakeProcessor)) brakeProcessor.abort();
|
||||
} else {
|
||||
LOG.debug("{} has no next route.",train);
|
||||
if (isSet(brakeProcessor)) {
|
||||
brakeProcessor.finish();
|
||||
@@ -825,10 +830,11 @@ public class Route extends BaseClass {
|
||||
train.destination(null); // unset old destination
|
||||
String destTag = train.destinationTag();
|
||||
if (isSet(destTag)) {
|
||||
LOG.debug("destination tag: {}",destTag);
|
||||
LOG.debug("destination list: {}",destTag);
|
||||
String[] parts = destTag.split(Train.DESTINATION_PREFIX);
|
||||
for (int i=0; i<parts.length;i++) LOG.debug(" part {}: {}",i+1,parts[i]);
|
||||
String destId = parts[1];
|
||||
LOG.debug("destination tag: {}",destId);
|
||||
boolean turn = false;
|
||||
|
||||
for (int i=destId.length()-1; i>0; i--) {
|
||||
@@ -839,6 +845,7 @@ public class Route extends BaseClass {
|
||||
break;
|
||||
case Train.TURN_FLAG:
|
||||
turn = true;
|
||||
LOG.debug("Turn flag is set!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -893,7 +900,7 @@ public class Route extends BaseClass {
|
||||
if (state == State.PREPARED || state == State.STARTED) return true;
|
||||
LOG.debug("{}.prepare()",this);
|
||||
ActionList setupActions = triggeredActions.get(ROUTE_SETUP);
|
||||
if (isSet(setupActions) && !setupActions.fire(context)) return false;
|
||||
if (isSet(setupActions) && !setupActions.fire(context,this+".prepare()")) return false;
|
||||
state = State.PREPARED;
|
||||
return true;
|
||||
}
|
||||
@@ -1036,13 +1043,13 @@ public class Route extends BaseClass {
|
||||
|
||||
public boolean start(Train newTrain) {
|
||||
if (state == State.STARTED) return true;
|
||||
LOG.debug("{}.start({})",this,newTrain);
|
||||
LOG.debug("{}.start()",this);
|
||||
if (isNull(newTrain)) return false; // can't set route's train to null
|
||||
if (isSet(train)) {
|
||||
if (newTrain != train) return false; // can't alter route's train
|
||||
} else train = newTrain; // set new train
|
||||
ActionList startActions = triggeredActions.get(ROUTE_START);
|
||||
if (isSet(startActions) && !startActions.fire(context)) return false; // start actions failed
|
||||
if (isSet(startActions) && !startActions.fire(context,this+".start("+train.name()+")")) return false; // start actions failed
|
||||
state = State.STARTED;
|
||||
triggeredContacts.clear();
|
||||
return true;
|
||||
|
||||
@@ -94,7 +94,7 @@ public abstract class Action extends BaseClass {
|
||||
return this.toString().equals(other.toString());
|
||||
}
|
||||
|
||||
public abstract boolean fire(Context context);
|
||||
public abstract boolean fire(Context context,Object cause);
|
||||
|
||||
public static Action get(Id actionId) {
|
||||
return actions.get(actionId);
|
||||
|
||||
@@ -80,15 +80,15 @@ public class ActionList extends Action implements Iterable<Action>{
|
||||
return actions.remove(action);
|
||||
}
|
||||
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (context.invalidated()) {
|
||||
LOG.debug("Context has been invalidated, aborting {}",this);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isEmpty()) LOG.debug("{}.fire({})",this,context);
|
||||
for (Action action : actions) {
|
||||
if (!action.fire(context)) return false;
|
||||
LOG.debug("firing \"{}\"",action);
|
||||
if (!action.fire(context,cause)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ import java.util.Map;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.tools.Tag;
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.moving.Train;
|
||||
import de.srsoftware.web4rail.tags.Checkbox;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
@@ -30,7 +30,7 @@ public class AddDestination extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
Train train = context.train();
|
||||
if (isNull(train)) return false;
|
||||
if (isNull(destination)) { // clear destinations!
|
||||
@@ -73,17 +73,13 @@ public class AddDestination extends Action {
|
||||
Id blockId = new Id(json.getString(Train.DESTINATION));
|
||||
destination = BaseClass.get(blockId);
|
||||
if (isNull(destination)) {
|
||||
Application.threadPool.execute(new Thread() {
|
||||
new DelayedExecution(this) {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
public void execute() {
|
||||
destination = BaseClass.get(blockId);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
return super.load(json);
|
||||
|
||||
@@ -24,7 +24,7 @@ public class AddRemoveTag extends Action{
|
||||
private boolean remove = false;
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (isNull(context.train())) return false;
|
||||
if (remove) {
|
||||
context.train().removeTag(tag);
|
||||
|
||||
@@ -28,7 +28,7 @@ public class AlterDirection extends Action{
|
||||
|
||||
@SuppressWarnings("incomplete-switch")
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
Train train = context.train();
|
||||
if (isNull(train)) return false;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ public class BrakeStart extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (isNull(context.route())) return false;
|
||||
context.route().brakeStart();
|
||||
LOG.debug("Started brake process...");
|
||||
|
||||
@@ -27,11 +27,11 @@ public class ConditionalAction extends ActionList {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
for (Condition condition : conditions) {
|
||||
if (!condition.fulfilledBy(context)) return true; // wenn die Bedingung nicht erfüllt ist, ist das kein Fehler!
|
||||
}
|
||||
return super.fire(context.clone()); // actions, that happen within the conditional action list must not modify the global context.
|
||||
return super.fire(context.clone(),cause); // actions, that happen within the conditional action list must not modify the global context.
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,7 @@ public class CoupleTrain extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
Train train = context.train();
|
||||
if (isNull(train)) return false;
|
||||
Block block = train.currentBlock();
|
||||
|
||||
@@ -6,8 +6,8 @@ import java.util.List;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.tools.Tag;
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
import de.srsoftware.web4rail.tags.Input;
|
||||
import de.srsoftware.web4rail.tags.Window;
|
||||
@@ -30,19 +30,17 @@ public class DelayedAction extends ActionList {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
Application.threadPool.execute(new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
int delay = min_delay + (min_delay < max_delay ? random.nextInt(max_delay - min_delay) : 0);
|
||||
Thread.sleep(delay);
|
||||
LOG.debug("{} ms passed by, firing actions:",delay);
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warn("Interrupted Exception thrown while waiting:",e);
|
||||
}
|
||||
DelayedAction.super.fire(context);
|
||||
};
|
||||
});
|
||||
public boolean fire(Context context,Object cause) {
|
||||
int delay = min_delay + (min_delay < max_delay ? random.nextInt(max_delay - min_delay) : 0);
|
||||
|
||||
new DelayedExecution(delay,cause) {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
LOG.debug("{} ms passed by, firing actions:",delay);
|
||||
DelayedAction.super.fire(context,cause);
|
||||
}
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ import java.util.Map;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
import de.srsoftware.web4rail.tags.Window;
|
||||
import de.srsoftware.web4rail.tiles.Block;
|
||||
@@ -22,7 +22,7 @@ public class DetermineTrainInBlock extends Action {
|
||||
private Block block = null;
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
context.block(block);
|
||||
context.train(block.train());
|
||||
return true;
|
||||
@@ -42,16 +42,13 @@ public class DetermineTrainInBlock extends Action {
|
||||
if (isSet(blockId)) {
|
||||
block = Block.get(blockId);
|
||||
if (isNull(block)) {
|
||||
Application.threadPool.execute(new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
new DelayedExecution(this) {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
block = Block.get(blockId);
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
||||
@@ -7,8 +7,8 @@ import java.util.Map;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.tools.Tag;
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
import de.srsoftware.web4rail.tags.Radio;
|
||||
import de.srsoftware.web4rail.tags.Window;
|
||||
@@ -26,7 +26,7 @@ public class DisableEnableBlock extends Action {
|
||||
private boolean disable = true;
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (isNull(block)) block = context.block();
|
||||
if (isNull(block)) return false;
|
||||
block.setEnabled(!disable);
|
||||
@@ -48,16 +48,13 @@ public class DisableEnableBlock extends Action {
|
||||
if (isSet(blockId)) {
|
||||
block = Block.get(blockId);
|
||||
if (isNull(block)) {
|
||||
Application.threadPool.execute(new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
new DelayedExecution(this) {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
block = Block.get(blockId);
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
if (json.has(STATE)) {
|
||||
|
||||
@@ -6,8 +6,8 @@ import java.util.Map;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
import de.srsoftware.web4rail.tags.Window;
|
||||
import de.srsoftware.web4rail.tiles.Decoupler;
|
||||
@@ -24,7 +24,7 @@ public class EngageDecoupler extends Action {
|
||||
private Decoupler decoupler = null;
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (isNull(decoupler)) return false;
|
||||
decoupler.engage();
|
||||
return true;
|
||||
@@ -45,14 +45,13 @@ public class EngageDecoupler extends Action {
|
||||
if (json.has(DECOUPLER)) {
|
||||
String decouplerId = json.getString(DECOUPLER);
|
||||
decoupler = BaseClass.get(new Id(decouplerId));
|
||||
if (isNull(decoupler)) Application.threadPool.execute(new Thread() { // if relay not loaded, yet: wait one sec and try again
|
||||
public void run() {
|
||||
try {
|
||||
sleep(1000);
|
||||
} catch (InterruptedException e) {}
|
||||
if (isNull(decoupler)) new DelayedExecution(this) {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
decoupler = BaseClass.get(new Id(decouplerId));
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ public class FinishRoute extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
Route route = context.route();
|
||||
if (isSet(route)) route.finish();
|
||||
return true;
|
||||
|
||||
@@ -29,7 +29,7 @@ public class Loop extends ActionList {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (isNull(object)) return false;
|
||||
List<? extends BaseClass> elements = null;
|
||||
switch (object) {
|
||||
@@ -53,7 +53,7 @@ public class Loop extends ActionList {
|
||||
break;
|
||||
}
|
||||
if (elements == null) return false;
|
||||
for (BaseClass element : elements) super.fire(context.setMain(element));
|
||||
for (BaseClass element : elements) super.fire(context.setMain(element),cause);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ public class PreserveRoute extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
Train train = context.train();
|
||||
Route route = context.route();
|
||||
// These are errors:
|
||||
|
||||
@@ -9,7 +9,7 @@ public class ReactivateContact extends Action{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (isNull(context.contact())) return false;
|
||||
if (isNull(context.route())) return false;
|
||||
return context.route().reactivate(context.contact());
|
||||
|
||||
@@ -11,7 +11,7 @@ public class SavePlan extends Action{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
try {
|
||||
plan.stream(plan.save());
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -30,7 +30,7 @@ public class SendCommand extends Action{
|
||||
private Target target = Target.SRCP;
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
switch (target) {
|
||||
case SRCP:
|
||||
plan.queue(new Command(command) {
|
||||
|
||||
@@ -5,8 +5,8 @@ import java.util.List;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.moving.Train;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
import de.srsoftware.web4rail.tags.Window;
|
||||
@@ -20,7 +20,7 @@ public class SetContextTrain extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
context.train(train);
|
||||
return true;
|
||||
}
|
||||
@@ -39,14 +39,13 @@ public class SetContextTrain extends Action {
|
||||
Id trainId = Id.from(json,REALM_TRAIN);
|
||||
if (isSet(trainId)) {
|
||||
train = Train.get(trainId);
|
||||
if (isNull(train)) Application.threadPool.execute(new Thread() { // load asynchronously, as referred tile may not be available,yet
|
||||
public void run() {
|
||||
try {
|
||||
sleep(1000);
|
||||
train = Train.get(trainId);
|
||||
} catch (InterruptedException e) {}
|
||||
};
|
||||
});
|
||||
if (isNull(train)) new DelayedExecution(this) {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
train = Train.get(trainId);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
||||
@@ -6,8 +6,8 @@ import java.util.Map;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
import de.srsoftware.web4rail.tags.Label;
|
||||
import de.srsoftware.web4rail.tags.Window;
|
||||
@@ -24,7 +24,7 @@ public class SetDisplayText extends TextAction{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
plan.place(display.text(fill(text, context)));
|
||||
return true;
|
||||
}
|
||||
@@ -44,14 +44,13 @@ public class SetDisplayText extends TextAction{
|
||||
@Override
|
||||
public Action load(JSONObject json) {
|
||||
if (json.has(DISPLAY)) {
|
||||
Application.threadPool.execute(new Thread() { // load asynchronously, as referred tile may not be available,yet
|
||||
public void run() {
|
||||
try {
|
||||
sleep(1000);
|
||||
display = (TextDisplay) plan.get(Id.from(json,DISPLAY), false);
|
||||
} catch (InterruptedException e) {}
|
||||
new DelayedExecution(this) {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
display = (TextDisplay) plan.get(Id.from(json,DISPLAY), false);
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
return super.load(json);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class SetPower extends Action{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
ControlUnit cu = plan.controlUnit();
|
||||
switch (pc) {
|
||||
case ON:
|
||||
@@ -85,6 +85,6 @@ public class SetPower extends Action{
|
||||
LOG.debug("update: {}",params);
|
||||
String newState = params.get(STATE);
|
||||
if (isSet(newState)) pc = POWERCHANGE.valueOf(newState);
|
||||
return properties();
|
||||
return parent().properties();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import java.util.Map;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.tools.Tag;
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
import de.srsoftware.web4rail.tags.Select;
|
||||
import de.srsoftware.web4rail.tags.Window;
|
||||
@@ -28,7 +28,7 @@ public class SetRelayOrSwitch extends Action {
|
||||
private boolean state = false;
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (isNull(relayOrSwitch)) return false;
|
||||
if (relayOrSwitch instanceof Relay) ((Relay)relayOrSwitch).state(state);
|
||||
if (relayOrSwitch instanceof Switch) ((Switch)relayOrSwitch).state(state);
|
||||
@@ -55,26 +55,24 @@ public class SetRelayOrSwitch extends Action {
|
||||
if (json.has(RELAY)) {
|
||||
String relayId = json.getString(RELAY);
|
||||
relayOrSwitch = BaseClass.get(new Id(relayId));
|
||||
if (isNull(relayOrSwitch)) Application.threadPool.execute(new Thread() { // if relay not loaded, yet: wait one sec and try again
|
||||
public void run() {
|
||||
try {
|
||||
sleep(1000);
|
||||
} catch (InterruptedException e) {}
|
||||
if (isNull(relayOrSwitch)) new DelayedExecution(this) {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
relayOrSwitch = BaseClass.get(new Id(relayId));
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
if (json.has(SWITCH)) {
|
||||
String relayId = json.getString(SWITCH);
|
||||
relayOrSwitch = BaseClass.get(new Id(relayId));
|
||||
if (isNull(relayOrSwitch)) Application.threadPool.execute(new Thread() { // if relay not loaded, yet: wait one sec and try again
|
||||
public void run() {
|
||||
try {
|
||||
sleep(1000);
|
||||
} catch (InterruptedException e) {}
|
||||
if (isNull(relayOrSwitch)) new DelayedExecution(this) {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
relayOrSwitch = BaseClass.get(new Id(relayId));
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
if (json.has(STATE)) state = json.getBoolean(STATE);
|
||||
return this;
|
||||
|
||||
@@ -34,7 +34,7 @@ public class SetSignal extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (isNull(signal)) return false;
|
||||
return signal.state(state);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ public class SetSpeed extends Action{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (isNull(context.train())) return false;
|
||||
context.train().setSpeed(speed);
|
||||
return true;
|
||||
|
||||
@@ -7,8 +7,8 @@ import java.util.Map;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.tools.Tag;
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
import de.srsoftware.web4rail.tags.Select;
|
||||
import de.srsoftware.web4rail.tags.Window;
|
||||
@@ -25,7 +25,7 @@ public class SetTurnout extends Action {
|
||||
private Turnout.State state = State.STRAIGHT;
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (isNull(turnout)) return false;
|
||||
if (!turnout.state(state).succeeded()) return false;
|
||||
if (turnout.address() == 0) return true;
|
||||
@@ -53,19 +53,13 @@ public class SetTurnout extends Action {
|
||||
Id turnoutId = json.has(TURNOUT) ? new Id(json.getString(TURNOUT)) : null;
|
||||
if (isSet(turnoutId)) {
|
||||
turnout = BaseClass.get(turnoutId);
|
||||
if (isNull(turnout)) {
|
||||
Application.threadPool.execute(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
turnout = BaseClass.get(turnoutId);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (isNull(turnout)) new DelayedExecution(this) {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
turnout = BaseClass.get(turnoutId);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (json.has(Turnout.STATE)) state = Turnout.State.valueOf(json.getString(Turnout.STATE));
|
||||
return this;
|
||||
|
||||
@@ -11,7 +11,7 @@ public class ShowText extends TextAction{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
plan.stream(fill(text,context));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public class SplitTrain extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
Train train = context.train();
|
||||
if (isNull(train)) return false;
|
||||
return train.splitAfter(position);
|
||||
|
||||
@@ -20,7 +20,7 @@ public class StartStopAuto extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (isNull(context.train())) return false;
|
||||
if (inverted) {
|
||||
context.train().automatic();
|
||||
|
||||
@@ -9,7 +9,7 @@ public class StopTrain extends Action{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (isNull(context.train())) return false;
|
||||
LOG.debug("{}.fire() called, context = {}",this,context);
|
||||
context.train().stopNow();
|
||||
|
||||
@@ -27,7 +27,7 @@ public class SwitchFunction extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (isNull(context) || isNull(context.train())) return false;
|
||||
switch (effect) {
|
||||
case TOGGLE:
|
||||
|
||||
@@ -20,7 +20,7 @@ public class TriggerContact extends Action {
|
||||
private Contact contact = null;
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
if (isSet(contact)) return contact.trigger(200);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import java.util.Map;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.tools.Tag;
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
import de.srsoftware.web4rail.tags.Input;
|
||||
import de.srsoftware.web4rail.tags.Window;
|
||||
@@ -30,34 +30,29 @@ public class WaitForContact extends ActionList {
|
||||
private int timeout = 10000;
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
public boolean fire(Context context,Object cause) {
|
||||
LOG.debug("{}.fire(...) called, waiting for {}.",this,contact);
|
||||
if (isNull(contact)) return false;
|
||||
fired = false;
|
||||
Listener listener = new Listener() {
|
||||
@Override
|
||||
public void fired() {
|
||||
public void fired(Object cause) {
|
||||
LOG.debug("{} triggered, firing {}",contact,actions);
|
||||
fired = true;
|
||||
contact.removeListener(this);
|
||||
WaitForContact.super.fire(context);
|
||||
WaitForContact.super.fire(context,cause);
|
||||
}
|
||||
};
|
||||
contact.addListener(listener);
|
||||
Application.threadPool.execute(new Thread() { // remove listener after timout
|
||||
new DelayedExecution(timeout,cause) {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sleep(timeout);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
public void execute() {
|
||||
contact.removeListener(listener);
|
||||
LOG.debug("{} timed out, firing {}",this,timeoutActions);
|
||||
if (!fired) timeoutActions.fire(context);
|
||||
if (!fired) timeoutActions.fire(context,cause);
|
||||
}
|
||||
});
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -90,19 +85,13 @@ public class WaitForContact extends ActionList {
|
||||
if (json.has(CONTACT)) {
|
||||
String cid = json.getString(CONTACT);
|
||||
contact = BaseClass.get(new Id(cid));
|
||||
if (isNull(contact)) {
|
||||
Application.threadPool.execute(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
contact = BaseClass.get(new Id(cid));
|
||||
}
|
||||
});
|
||||
}
|
||||
if (isNull(contact)) new DelayedExecution(this) {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
contact = BaseClass.get(new Id(cid));
|
||||
}
|
||||
};
|
||||
}
|
||||
if (json.has(TIMEOUT)) timeout = json.getInt(TIMEOUT);
|
||||
if (json.has(TIMEOUT_ACTIONS)) timeoutActions.load(json.getJSONObject(TIMEOUT_ACTIONS));
|
||||
|
||||
@@ -6,8 +6,8 @@ import java.util.Map;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
import de.srsoftware.web4rail.tags.Window;
|
||||
import de.srsoftware.web4rail.tiles.Block;
|
||||
@@ -39,17 +39,12 @@ public class BlockFree extends Condition {
|
||||
Id bid = new Id(json.getString(BLOCK));
|
||||
block(BaseClass.get(bid));
|
||||
if (isNull(block)) {
|
||||
Application.threadPool.execute(new Thread() {
|
||||
new DelayedExecution(this) {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
public void execute() {
|
||||
block(BaseClass.get(bid));
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
||||
@@ -6,8 +6,8 @@ import java.util.Map;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.Route;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
import de.srsoftware.web4rail.tags.Window;
|
||||
@@ -44,15 +44,13 @@ public class RouteEndBlock extends Condition{
|
||||
if (isSet(block)) {
|
||||
block(block);
|
||||
} else {
|
||||
Application.threadPool.execute(new Thread() {
|
||||
new DelayedExecution(this) {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sleep(1000);
|
||||
} catch (InterruptedException e) {}
|
||||
public void execute() {
|
||||
block(BaseClass.get(bid));
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
@@ -2,14 +2,16 @@ package de.srsoftware.web4rail.conditions;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
import de.srsoftware.web4rail.tags.Window;
|
||||
import de.srsoftware.web4rail.tiles.Switch;
|
||||
import de.srsoftware.web4rail.tiles.Tile;
|
||||
|
||||
public class SwitchIsOn extends Condition {
|
||||
|
||||
@@ -36,17 +38,13 @@ public class SwitchIsOn extends Condition {
|
||||
if (json.has(SWITCH)) {
|
||||
swtch = BaseClass.get(new Id(json.getString(SWITCH)));
|
||||
if (isNull(swtch)) {
|
||||
Application.threadPool.execute(new Thread() {
|
||||
new DelayedExecution(this) {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
public void execute() {
|
||||
swtch = BaseClass.get(new Id(json.getString(SWITCH)));
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
return this;
|
||||
@@ -54,21 +52,22 @@ public class SwitchIsOn extends Condition {
|
||||
|
||||
@Override
|
||||
protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm) {
|
||||
formInputs.add(t("Select switch"),Switch.selector(swtch));
|
||||
|
||||
formInputs.add(t("Select switch")+": "+(isNull(swtch) ? t("unset") : swtch),button(t("Select from plan"),Map.of(ACTION,ACTION_UPDATE,ASSIGN,SWITCH)));
|
||||
|
||||
return super.properties(preForm, formInputs, postForm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (isNull(SWITCH)) return "["+t("Click here to select switch!")+"]";
|
||||
if (isNull(swtch)) return "["+t("Click here to select switch!")+"]";
|
||||
return t(inverted ? "{} is off" : "{} is on",swtch) ;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object update(HashMap<String, String> params) {
|
||||
String switchId = params.get(Switch.class.getSimpleName());
|
||||
if (isSet(switchId)) swtch = BaseClass.get(new Id(switchId));
|
||||
String switchId = params.get(SWITCH);
|
||||
Tile tile = isSet(switchId) ? BaseClass.get(new Id(switchId)) : null;
|
||||
if (tile instanceof Switch) swtch = (Switch) tile;
|
||||
return super.update(params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,8 +51,8 @@ public class Car extends BaseClass implements Comparable<Car>{
|
||||
|
||||
private String name;
|
||||
public int length;
|
||||
protected String stockId = "";
|
||||
private Train train;
|
||||
protected String stockId = "";
|
||||
protected int maxSpeedForward = 0;
|
||||
protected int maxSpeedReverse = 0;
|
||||
protected boolean orientation = FORWARD;
|
||||
@@ -327,8 +327,10 @@ public class Car extends BaseClass implements Comparable<Car>{
|
||||
new Tag("option").attr("value","0").content(firstEntry).addTo(select);
|
||||
List<Car> cars = BaseClass.listElements(Car.class);
|
||||
cars.sort((c1,c2) -> {
|
||||
if (isSet(c1.stockId)) return c1.stockId.compareTo(c2.stockId);
|
||||
return c1.name().compareTo(c2.name());
|
||||
String n1 = (isSet(c1.stockId) && !c1.stockId.isEmpty() ? c1.stockId : "00")+c1.name();
|
||||
String n2 = (isSet(c2.stockId) && !c2.stockId.isEmpty() ? c2.stockId : "00")+c2.name();
|
||||
|
||||
return n1.compareTo(n2);
|
||||
});
|
||||
for (Car car : cars) {
|
||||
if (exclude.contains(car)) continue;
|
||||
|
||||
@@ -99,6 +99,11 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
boolean stop = false;
|
||||
int waitTime = 100;
|
||||
|
||||
public Autopilot() {
|
||||
setName(Application.threadName("Autopilot("+Train.this+")"));
|
||||
start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
@@ -107,16 +112,22 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
if (isNull(route)) {
|
||||
Thread.sleep(waitTime);
|
||||
if (waitTime > 100) waitTime /=2;
|
||||
if (stop) return;
|
||||
if (stop) break;
|
||||
if (isNull(route)) { // may have been set by start action in between
|
||||
Object o = Train.this.start();
|
||||
String message = Train.this.start();
|
||||
if (isSet(route)) {
|
||||
LOG.debug("{}.start called, route now is {}",Train.this,route);
|
||||
if (o instanceof String) plan.stream((String)o);
|
||||
plan.stream(message);
|
||||
//if (isSet(destination)) Thread.sleep(1000); // limit load on PathFinder
|
||||
} else waitTime = 1000; // limit load on PathFinder
|
||||
} else {
|
||||
LOG.debug(message);
|
||||
waitTime = 1000; // limit load on PathFinder
|
||||
}
|
||||
}
|
||||
} else Thread.sleep(250);
|
||||
} else {
|
||||
if (stop) break;
|
||||
Thread.sleep(250);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -210,7 +221,6 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
public String automatic() {
|
||||
if (isNull(autopilot)) {
|
||||
autopilot = new Autopilot();
|
||||
Application.threadPool.execute(autopilot);
|
||||
if (isSet(currentBlock)) plan.place(currentBlock);
|
||||
}
|
||||
return t("{} now in auto-mode",this);
|
||||
@@ -381,10 +391,13 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
}
|
||||
|
||||
public Block destination() {
|
||||
//LOG.debug("{}.destination()",this);
|
||||
if (isNull(destination)) {
|
||||
String destTag = destinationTag();
|
||||
//LOG.debug("→ processing \"{}\"...",destTag);
|
||||
if (isSet(destTag)) {
|
||||
destTag = destTag.split(DESTINATION_PREFIX)[1];
|
||||
//LOG.debug("....processing \"{}\"…",destTag);
|
||||
for (int i=destTag.length()-1; i>0; i--) {
|
||||
switch (destTag.charAt(i)) {
|
||||
case FLAG_SEPARATOR:
|
||||
@@ -392,19 +405,21 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
i=0;
|
||||
break;
|
||||
case SHUNTING_FLAG:
|
||||
//LOG.debug("....enabled shunting option");
|
||||
shunting = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Block block = BaseClass.get(new Id(destTag));
|
||||
if (isSet(block)) destination = block;
|
||||
if (isSet(block)) destination(block);
|
||||
}
|
||||
}
|
||||
}// else LOG.debug("→ heading towards {}",destination);
|
||||
return destination;
|
||||
}
|
||||
|
||||
public Train destination(Block dest) {
|
||||
LOG.debug("destination({})",dest);
|
||||
destination = dest;
|
||||
return this;
|
||||
}
|
||||
@@ -753,6 +768,10 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
public void reserveNext() {
|
||||
if (reserving) return;
|
||||
LOG.debug("{}.reserveNext()",this);
|
||||
if (isSet(nextRoute)) {
|
||||
LOG.debug("Train already has next route: {}",nextRoute);
|
||||
return;
|
||||
}
|
||||
Context context = new Context(this).route(route).block(route.endBlock()).direction(route.endDirection);
|
||||
Route newRoute = PathFinder.chooseRoute(context);
|
||||
if (isNull(newRoute)) {
|
||||
@@ -842,12 +861,12 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
}
|
||||
}
|
||||
|
||||
private String setDestination(HashMap<String, String> params) {
|
||||
private Object setDestination(HashMap<String, String> params) {
|
||||
String dest = params.get(DESTINATION);
|
||||
if (isNull(dest)) return t("No destination supplied!");
|
||||
if (dest.isEmpty()) {
|
||||
destination = null;
|
||||
return t("Dropped destination of {}.",this);
|
||||
return properties();
|
||||
}
|
||||
Tile tile = plan.get(new Id(dest), true);
|
||||
if (isNull(tile)) return t("Tile {} not known!",dest);
|
||||
@@ -946,7 +965,7 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
}
|
||||
|
||||
|
||||
public Object start() throws IOException {
|
||||
public String start() throws IOException {
|
||||
LOG.debug("{}.start()",this);
|
||||
if (isNull(currentBlock)) return t("{} not in a block",this);
|
||||
if (maxSpeed() == 0) return t("Train has maximum speed of 0 {}, cannot go!",speedUnit);
|
||||
@@ -960,14 +979,16 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
nextRoute = null;
|
||||
route.set(new Context(this).block(currentBlock).direction(direction));
|
||||
} else {
|
||||
if (reserving) return t("Route chooser already active");
|
||||
Context context = new Context(this).block(currentBlock).direction(direction);
|
||||
route = PathFinder.chooseRoute(context);
|
||||
if (isNull(route)) return t("No free routes from {}",currentBlock);
|
||||
LOG.debug("Chosen route: {}",route);
|
||||
if (!route.lock()) error = t("Was not able to lock {}",route);
|
||||
route.set(context);
|
||||
if (isNull(error) && !route.prepare()) error = t("Was not able to fire all setup actions of route!");
|
||||
}
|
||||
if (isNull(route)) return this; // route may have been canceled in between
|
||||
if (isNull(route)) return t("Route cancelled"); // route may have been canceled in between
|
||||
if (isNull(error) && direction != route.startDirection) turn();
|
||||
|
||||
if (isNull(error) && !route.start(this)) error = t("Was not able to assign {} to {}!",this,route);
|
||||
@@ -979,8 +1000,9 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
}
|
||||
startSimulation();
|
||||
|
||||
plan.stream(t("Started {}",this));
|
||||
return this;
|
||||
String res = t("Started {}",this);
|
||||
plan.stream(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void startAll() {
|
||||
@@ -999,7 +1021,7 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
plan.stream(t("Simulating movement of {}...",this));
|
||||
Application.threadPool.execute(new Thread() {
|
||||
Thread simulation = new Thread() {
|
||||
public void run() {
|
||||
for (Tile tile : route.path()) {
|
||||
if (isNull(route)) break;
|
||||
@@ -1016,7 +1038,9 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
simulation.setName(Application.threadName("Simulation("+Train.this+")"));
|
||||
simulation.start();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -1076,7 +1100,7 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
return reverse();
|
||||
}
|
||||
|
||||
protected Train update(HashMap<String, String> params) {
|
||||
protected Window update(HashMap<String, String> params) {
|
||||
LOG.debug("update({})",params);
|
||||
pushPull = params.containsKey(PUSH_PULL) && params.get(PUSH_PULL).equals("on");
|
||||
shunting = params.containsKey(SHUNTING) && params.get(SHUNTING).equals("on");
|
||||
@@ -1089,7 +1113,7 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
if (!tag.isEmpty()) tags.add(tag);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
return properties();
|
||||
}
|
||||
|
||||
public boolean usesAutopilot() {
|
||||
|
||||
@@ -7,9 +7,9 @@ import java.util.Map;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.tools.Tag;
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.Connector;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.Route;
|
||||
import de.srsoftware.web4rail.moving.Train;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
@@ -52,17 +52,12 @@ public abstract class Bridge extends Tile {
|
||||
@Override
|
||||
public Tile load(JSONObject json) {
|
||||
if (json.has(COUNTERPART)) {
|
||||
Application.threadPool.execute(new Thread() {
|
||||
new DelayedExecution(this) {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
public void execute() {
|
||||
counterpart = (Bridge) plan.get(Id.from(json, COUNTERPART), false);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
return super.load(json);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.slf4j.LoggerFactory;
|
||||
import de.srsoftware.tools.Tag;
|
||||
import de.srsoftware.web4rail.Application;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.DelayedExecution;
|
||||
import de.srsoftware.web4rail.Route;
|
||||
import de.srsoftware.web4rail.actions.Action;
|
||||
import de.srsoftware.web4rail.actions.ActionList;
|
||||
@@ -36,7 +37,7 @@ public class Contact extends Tile{
|
||||
private HashSet<Listener> listeners = new HashSet<Listener>();
|
||||
|
||||
public interface Listener{
|
||||
public void fired();
|
||||
public void fired(Object cause);
|
||||
}
|
||||
|
||||
public Contact() {
|
||||
@@ -52,7 +53,8 @@ public class Contact extends Tile{
|
||||
boolean aborted = false;
|
||||
|
||||
public OffTimer() {
|
||||
Application.threadPool.execute(this);
|
||||
setName(Application.threadName("OffTimer("+Contact.this+")"));
|
||||
start();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,12 +89,10 @@ public class Contact extends Tile{
|
||||
Context context = isSet(route) ? route.context().contact(this) : new Context(this);
|
||||
|
||||
if (isSet(route)) route.traceTrainFrom(this);
|
||||
actions.fire(context);
|
||||
actions.fire(context,"Contact("+addr+")");
|
||||
if (isSet(route)) route.contact(this);
|
||||
|
||||
for (Listener listener : listeners) {
|
||||
listener.fired();
|
||||
}
|
||||
for (Listener listener : listeners) listener.fired("Contact("+addr+")");
|
||||
|
||||
stream();
|
||||
}
|
||||
@@ -253,14 +253,13 @@ public class Contact extends Tile{
|
||||
|
||||
public boolean trigger(int duration) {
|
||||
activate(true);
|
||||
Application.threadPool.execute(new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
sleep(duration);
|
||||
activate(false);
|
||||
} catch (Exception e) {}
|
||||
new DelayedExecution(duration,"Contact("+Contact.this.addr+")") {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
activate(false);
|
||||
}
|
||||
});
|
||||
};
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
|
||||
@@ -163,16 +163,19 @@ public class Switch extends Tile{
|
||||
|
||||
public void state(boolean newState) {
|
||||
state = newState;
|
||||
Application.threadPool.execute(new Runnable() {
|
||||
|
||||
Thread thread = new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Context context = new Context(Switch.this);
|
||||
if (state) {
|
||||
actionsOn.fire(context);
|
||||
} else actionsOff.fire(context);
|
||||
actionsOn.fire(context,Switch.this);
|
||||
} else actionsOff.fire(context,Switch.this);
|
||||
}
|
||||
});
|
||||
};
|
||||
thread.setName(Application.threadName(this));
|
||||
thread.start();
|
||||
stream();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user