@ -38,109 +38,81 @@ import de.srsoftware.web4rail.tags.Window;
@@ -38,109 +38,81 @@ import de.srsoftware.web4rail.tags.Window;
* @author Stephan Richter , SRSoftware
*
* /
public abstract class Tile extends BaseClass implements Comparable < Tile > {
public enum Status {
FREE ( "free" ) ,
ALLOCATED ( "allocated" ) ,
LOCKED ( "locked" ) ,
OCCUPIED ( "occupied" ) ;
public abstract class Tile extends BaseClass implements Comparable < Tile > {
public enum Status {
DISABLED ( "disabled" ) , FREE ( "free" ) , RESERVED ( "reserved" ) , LOCKED ( "locked" ) , OCCUPIED ( "occupied" ) ;
private String tx ;
Status ( String s ) {
tx = s ;
}
@Override
public String toString ( ) {
return tx ;
}
}
protected static Logger LOG = LoggerFactory . getLogger ( Tile . class ) ;
protected static Logger LOG = LoggerFactory . getLogger ( Tile . class ) ;
private static int DEFAUT_LENGTH = 100 ; // 10cm
private static final String LENGTH = "length" ;
private static final String ONEW_WAY = "one_way" ;
private static final String POS = "pos" ;
private static final String TYPE = "type" ;
private static final String X = "x" ;
private static final String Y = "y" ;
private boolean disabled = false ;
private boolean isTrack = true ;
private int length = DEFAUT_LENGTH ;
protected Direction oneWay = null ;
private TreeSet < Route > routes = new TreeSet < > ( ( r1 , r2 ) - > r1 . toString ( ) . compareTo ( r2 . toString ( ) ) ) ;
private Status status = Status . FREE ;
protected Train train = null ;
public Integer x = null ;
public Integer y = null ;
public void add ( Route route ) {
this . routes . add ( route ) ;
}
public boolean canNeEnteredBy ( Train newTrain ) {
LOG . debug ( "{}.canNeEnteredBy({})" , this , newTrain ) ;
if ( disabled ) {
LOG . debug ( "{} is disabled!" , this ) ;
return false ;
}
if ( isNull ( train ) ) {
LOG . debug ( "→ free" ) ;
return true ;
}
if ( newTrain = = train ) { // during train.reserveNext, we may encounter, parts, that are already reserved by the respective train, but having another route. do not compare routes in that case!
LOG . debug ( "already reserved by {} → true" , train ) ;
return true ;
}
private static final String LENGTH = "length" ;
private static final String ONEW_WAY = "one_way" ;
private static final String POS = "pos" ;
private static final String TYPE = "type" ;
private static final String X = "x" ;
private static final String Y = "y" ;
if ( isSet ( newTrain ) & & newTrain . isShunting ( ) ) {
LOG . debug ( "occupied by {}. Allowed for shunting {}" , train , newTrain ) ;
return true ;
}
LOG . debug ( "occupied by {} → false" , train ) ;
return false ;
private boolean isTrack = true ;
private int length = DEFAUT_LENGTH ;
protected Direction oneWay = null ;
private TreeSet < Route > routes = new TreeSet < > ( ( r1 , r2 ) - > r1 . toString ( ) . compareTo ( r2 . toString ( ) ) ) ;
private Train train = null ;
protected Status status = Status . FREE ;
public Integer x = null ;
public Integer y = null ;
public void add ( Route route ) {
this . routes . add ( route ) ;
}
protected HashSet < String > classes ( ) {
protected HashSet < String > classes ( ) {
HashSet < String > classes = new HashSet < String > ( ) ;
classes . add ( "tile" ) ;
classes . add ( getClass ( ) . getSimpleName ( ) ) ;
classes . add ( getClass ( ) . getSimpleName ( ) ) ;
if ( ! is ( Status . FREE ) ) classes . add ( status . toString ( ) ) ;
if ( disabled ) classes . add ( DISABLED ) ;
return classes ;
}
public Object click ( boolean shift ) throws IOException {
LOG . debug ( "{}.click()" , getClass ( ) . getSimpleName ( ) ) ;
LOG . debug ( "{}.click()" , getClass ( ) . getSimpleName ( ) ) ;
if ( isSet ( train ) & & shift ) return train . properties ( ) ;
return properties ( ) ;
}
@Override
public int compareTo ( Tile other ) {
if ( x = = other . x ) return y - other . y ;
if ( x = = other . x ) return y - other . y ;
return x - other . x ;
}
public JSONObject config ( ) {
return new JSONObject ( ) ;
}
public Map < Connector , Turnout . State > connections ( Direction from ) {
public Map < Connector , Turnout . State > connections ( Direction from ) {
return new HashMap < > ( ) ;
}
public void free ( ) {
public boolean free ( Train t ) {
if ( t ! = train ) return false ;
train = null ;
status = Status . FREE ;
plan . place ( this ) ;
return true ;
}
public int height ( ) {
return 1 ;
}
@ -148,60 +120,89 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
@@ -148,60 +120,89 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
public Id id ( ) {
return Tile . id ( x , y ) ;
}
public static Id id ( int x , int y ) {
return new Id ( x + "-" + y ) ;
return new Id ( x + "-" + y ) ;
}
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 ) ;
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 . load ( json ) . register ( ) ;
if ( tile instanceof TileWithShadow ) ( ( TileWithShadow ) tile ) . placeShadows ( ) ;
if ( tile instanceof TileWithShadow ) ( ( TileWithShadow ) tile ) . placeShadows ( ) ;
plan . place ( tile ) ;
}
public boolean is ( Status . . . states ) {
for ( Status s : states ) {
public boolean is ( Status . . . states ) {
for ( Status s : states ) {
if ( status = = s ) return true ;
}
return false ;
}
public boolean isFreeFor ( Context newTrain ) {
LOG . debug ( "{}.isFreeFor({})" , this , newTrain ) ;
if ( is ( Status . DISABLED ) ) {
LOG . debug ( "{} is disabled!" , this ) ;
return false ;
}
if ( isNull ( train ) ) {
LOG . debug ( "→ free" ) ;
return true ;
}
if ( newTrain . train ( ) = = train ) { // during train.reserveNext, we may encounter, parts, that are already reserved
// by the respective train, but having another route. do not compare routes
// in that case!
LOG . debug ( "already reserved by {} → true" , train ) ;
return true ;
}
if ( isSet ( newTrain . train ( ) ) & & newTrain . train ( ) . isShunting ( ) ) {
LOG . debug ( "occupied by {}. Allowed for shunting {}" , train , newTrain . train ( ) ) ;
return true ;
}
LOG . debug ( "occupied by {} → false" , train ) ;
return false ;
}
public JSONObject json ( ) {
JSONObject json = super . json ( ) ;
json . put ( TYPE , getClass ( ) . getSimpleName ( ) ) ;
if ( isSet ( x ) & & isSet ( y ) ) json . put ( POS , new JSONObject ( Map . of ( X , x , Y , y ) ) ) ;
if ( isSet ( oneWay ) ) json . put ( ONEW_WAY , oneWay ) ;
if ( disabled ) json . put ( DISABLED , true ) ;
if ( isSet ( train ) ) json . put ( REALM_TRAIN , train . id ( ) ) ;
if ( isSet ( x ) & & isSet ( y ) ) json . put ( POS , new JSONObject ( Map . of ( X , x , Y , y ) ) ) ;
if ( isSet ( oneWay ) ) json . put ( ONEW_WAY , oneWay ) ;
if ( is ( Status . DISABLED ) ) json . put ( DISABLED , true ) ;
if ( isSet ( train ) ) json . put ( REALM_TRAIN , train . id ( ) ) ;
json . put ( LENGTH , length ) ;
return json ;
}
public int length ( ) {
return length ;
}
public Tile length ( int newLength ) {
length = Math . max ( 0 , newLength ) ;
return this ;
}
/ * *
* If arguments are given , the first is taken as content , the second as tag type .
* If no content is supplied , id ( ) is set as content .
* If no type is supplied , "span" is preset .
* If arguments are given , the first is taken as content , the second as tag
* type . If no content is supplied , id ( ) is set as content . If no type is
* supplied , "span" is preset .
*
* @param args
* @return
* /
public Tag link ( String . . . args ) {
String tx = args . length < 1 ? id ( ) + NBSP : args [ 0 ] ;
String type = args . length < 2 ? "span" : args [ 1 ] ;
return super . link ( type , ( Object ) tx , Map . of ( ACTION , ACTION_CLICK ) ) ;
public Tag link ( String . . . args ) {
String tx = args . length < 1 ? id ( ) + NBSP : args [ 0 ] ;
String type = args . length < 2 ? "span" : args [ 1 ] ;
return super . link ( type , ( Object ) tx , Map . of ( ACTION , ACTION_CLICK ) ) ;
}
public static void load ( Object object , Plan plan ) {
if ( object instanceof JSONObject ) {
JSONObject json = ( JSONObject ) object ;
@ -210,10 +211,12 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
@@ -210,10 +211,12 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
clazz = AlterDirection . class . getSimpleName ( ) ;
}
try {
Tile . inflate ( clazz , json , plan ) ;
} catch ( InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | ClassNotFoundException | IOException e ) {
Tile . inflate ( clazz , json , plan ) ;
} catch ( InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException | ClassNotFoundException
| IOException e ) {
e . printStackTrace ( ) ;
}
}
}
}
@ -223,89 +226,92 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
@@ -223,89 +226,92 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
if ( json . has ( POS ) ) {
JSONObject pos = json . getJSONObject ( POS ) ;
x = pos . getInt ( X ) ;
y = pos . getInt ( Y ) ;
y = pos . getInt ( Y ) ;
}
if ( json . has ( DISABLED ) ) disabled = json . getBoolean ( DISABLED ) ;
if ( json . has ( LENGTH ) ) length = json . getInt ( LENGTH ) ;
if ( json . has ( ONEW_WAY ) ) oneWay = Direction . valueOf ( json . getString ( ONEW_WAY ) ) ;
if ( json . has ( DISABLED ) & & json . getBoolean ( DISABLED ) ) status = Status . DISABLED ;
if ( json . has ( LENGTH ) ) length = json . getInt ( LENGTH ) ;
if ( json . has ( ONEW_WAY ) ) oneWay = Direction . valueOf ( json . getString ( ONEW_WAY ) ) ;
return this ;
}
public boolean move ( int dx , int dy ) {
int destX = x + ( dx > 0 ? width ( ) : dx ) ;
int destY = y + ( dy > 0 ? height ( ) : dy ) ;
int destX = x + ( dx > 0 ? width ( ) : dx ) ;
int destY = y + ( dy > 0 ? height ( ) : dy ) ;
if ( destX < 0 | | destY < 0 ) return false ;
Tile tileAtDestination = plan . get ( id ( destX , destY ) , true ) ;
Tile tileAtDestination = plan . get ( id ( destX , destY ) , true ) ;
if ( isSet ( tileAtDestination ) & & ! tileAtDestination . move ( dx , dy ) ) return false ;
plan . drop ( this ) ;
position ( x + dx , y + dy ) ;
plan . drop ( this ) ;
position ( x + dx , y + dy ) ;
plan . place ( this ) ;
return true ;
}
protected void noTrack ( ) {
isTrack = false ;
isTrack = false ;
}
public Tile position ( int x , int y ) {
this . x = x ;
this . y = y ;
return this ;
}
public List < Direction > possibleDirections ( ) {
return new Vector < Plan . Direction > ( ) ;
}
@Override
protected Window properties ( List < Fieldset > preForm , FormInput formInputs , List < Fieldset > postForm , String . . . errors ) {
protected Window properties ( List < Fieldset > preForm , FormInput formInputs , List < Fieldset > postForm ,
String . . . errors ) {
Fieldset fieldset = null ;
if ( isSet ( train ) ) {
fieldset = new Fieldset ( t ( "Train" ) ) ;
train . link ( "span" , t ( "Train" ) + ":" + NBSP + train + NBSP ) . addTo ( fieldset ) ;
train . link ( "span" , t ( "Train" ) + ":" + NBSP + train + NBSP ) . addTo ( fieldset ) ;
if ( isSet ( train . route ( ) ) ) {
train . button ( t ( "stop" ) , Map . of ( ACTION , ACTION_STOP ) ) . addTo ( fieldset ) ;
train . button ( t ( "stop" ) , Map . of ( ACTION , ACTION_STOP ) ) . addTo ( fieldset ) ;
} else {
train . button ( t ( "depart" ) , Map . of ( ACTION , ACTION_START ) ) . addTo ( fieldset ) ;
train . button ( t ( "depart" ) , Map . of ( ACTION , ACTION_START ) ) . addTo ( fieldset ) ;
}
if ( train . usesAutopilot ( ) ) {
train . button ( t ( "quit autopilot" ) , Map . of ( ACTION , ACTION_QUIT ) ) . addTo ( fieldset ) ;
train . button ( t ( "quit autopilot" ) , Map . of ( ACTION , ACTION_QUIT ) ) . addTo ( fieldset ) ;
} else {
train . button ( t ( "auto" ) , Map . of ( ACTION , ACTION_AUTO ) ) . addTo ( fieldset ) ;
train . button ( t ( "auto" ) , Map . of ( ACTION , ACTION_AUTO ) ) . addTo ( fieldset ) ;
}
}
if ( isSet ( fieldset ) ) preForm . add ( fieldset ) ;
if ( isTrack ) {
formInputs . add ( t ( "Length" ) , new Input ( LENGTH , length ) . numeric ( ) . addTo ( new Tag ( "span" ) ) . content ( NBSP + lengthUnit ) ) ;
Checkbox checkbox = new Checkbox ( DISABLED , t ( "disabled" ) , disabled ) ;
if ( disabled ) checkbox . clazz ( "disabled" ) ;
formInputs . add ( t ( "State" ) , checkbox ) ;
formInputs . add ( t ( "Length" ) ,
new Input ( LENGTH , length ) . numeric ( ) . addTo ( new Tag ( "span" ) ) . content ( NBSP + lengthUnit ) ) ;
Checkbox checkbox = new Checkbox ( DISABLED , t ( "disabled" ) , is ( Status . DISABLED ) ) ;
if ( is ( Status . DISABLED ) ) checkbox . clazz ( "disabled" ) ;
formInputs . add ( t ( "State" ) , checkbox ) ;
}
List < Direction > pd = possibleDirections ( ) ;
if ( ! pd . isEmpty ( ) ) {
Tag div = new Tag ( "div" ) ;
new Radio ( "oneway" , "none" , t ( "No" ) , isNull ( oneWay ) ) . addTo ( div ) ;
for ( Direction d : pd ) {
new Radio ( "oneway" , d . toString ( ) , t ( d . toString ( ) ) , d = = oneWay ) . addTo ( div ) ;
new Radio ( "oneway" , "none" , t ( "No" ) , isNull ( oneWay ) ) . addTo ( div ) ;
for ( Direction d : pd ) {
new Radio ( "oneway" , d . toString ( ) , t ( d . toString ( ) ) , d = = oneWay ) . addTo ( div ) ;
}
formInputs . add ( t ( "One way" ) , div ) ;
formInputs . add ( t ( "One way" ) , div ) ;
}
if ( ! routes . isEmpty ( ) ) {
fieldset = new Fieldset ( t ( "Routes" ) ) . id ( "props-routes" ) ;
Tag routeList = new Tag ( "ol" ) ;
boolean empty = true ;
for ( Route route : routes ) {
if ( route . isDisabled ( ) ) continue ;
Tag li = route . link ( "span" , route . name ( ) + ( route . isDisabled ( ) ? " [" + t ( "disabled" ) + "]" : "" ) + NBSP ) . addTo ( new Tag ( "li" ) . clazz ( "link" ) ) ;
route . button ( t ( "delete route" ) , Map . of ( ACTION , ACTION_DROP ) ) . addTo ( li ) ;
button ( t ( "simplify name" ) , Map . of ( ACTION , ACTION_AUTO , ROUTE , route . id ( ) . toString ( ) ) ) . addTo ( li ) ;
Tag li = route
. link ( "span" , route . name ( ) + ( route . isDisabled ( ) ? " [" + t ( "disabled" ) + "]" : "" ) + NBSP )
. addTo ( new Tag ( "li" ) . clazz ( "link" ) ) ;
route . button ( t ( "delete route" ) , Map . of ( ACTION , ACTION_DROP ) ) . addTo ( li ) ;
button ( t ( "simplify name" ) , Map . of ( ACTION , ACTION_AUTO , ROUTE , route . id ( ) . toString ( ) ) ) . addTo ( li ) ;
li . addTo ( routeList ) ;
empty = false ;
}
@ -314,14 +320,16 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
@@ -314,14 +320,16 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
routeList . addTo ( fieldset ) ;
postForm . add ( fieldset ) ;
}
routeList = new Tag ( "ol" ) ;
empty = true ;
for ( Route route : routes ) {
if ( ! route . isDisabled ( ) ) continue ;
Tag li = route . link ( "span" , route . name ( ) + ( route . isDisabled ( ) ? " [" + t ( "disabled" ) + "]" : "" ) + NBSP ) . addTo ( new Tag ( "li" ) . clazz ( "link" ) ) ;
route . button ( t ( "delete route" ) , Map . of ( ACTION , ACTION_DROP ) ) . addTo ( li ) ;
button ( t ( "simplify name" ) , Map . of ( ACTION , ACTION_AUTO , ROUTE , route . id ( ) . toString ( ) ) ) . addTo ( li ) ;
Tag li = route
. link ( "span" , route . name ( ) + ( route . isDisabled ( ) ? " [" + t ( "disabled" ) + "]" : "" ) + NBSP )
. addTo ( new Tag ( "li" ) . clazz ( "link" ) ) ;
route . button ( t ( "delete route" ) , Map . of ( ACTION , ACTION_DROP ) ) . addTo ( li ) ;
button ( t ( "simplify name" ) , Map . of ( ACTION , ACTION_AUTO , ROUTE , route . id ( ) . toString ( ) ) ) . addTo ( li ) ;
li . addTo ( routeList ) ;
empty = false ;
}
@ -330,84 +338,90 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
@@ -330,84 +338,90 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
routeList . addTo ( fieldset ) ;
}
}
return super . properties ( preForm , formInputs , postForm , errors ) ;
return super . properties ( preForm , formInputs , postForm , errors ) ;
}
private static String replace ( String line , Entry < String , Object > replacement ) {
String key = replacement . getKey ( ) ;
String key = replacement . getKey ( ) ;
Object val = replacement . getValue ( ) ;
int start = line . indexOf ( key ) ;
int len = key . length ( ) ;
while ( start > 0 ) {
int end = line . indexOf ( "\"" , start ) ;
int end2 = line . indexOf ( "<" , start ) ;
if ( end2 > 0 & & ( end < 0 | | end2 < end ) ) end = end2 ;
while ( start > 0 ) {
int end = line . indexOf ( "\"" , start ) ;
int end2 = line . indexOf ( "<" , start ) ;
if ( end2 > 0 & & ( end < 0 | | end2 < end ) ) end = end2 ;
String tag = line . substring ( start , end ) ;
if ( tag . length ( ) > len ) val = Integer . parseInt ( tag . substring ( len ) ) + ( int ) val ;
line = line . replace ( tag , "" + val ) ;
if ( tag . length ( ) > len ) val = Integer . parseInt ( tag . substring ( len ) ) + ( int ) val ;
line = line . replace ( tag , "" + val ) ;
start = line . indexOf ( key ) ;
}
return line ;
}
public TreeSet < Route > routes ( ) {
return routes ;
}
public static void saveAll ( String filename ) throws IOException {
BufferedWriter file = new BufferedWriter ( new FileWriter ( filename ) ) ;
for ( Tile tile : BaseClass . listElements ( Tile . class ) ) {
if ( isNull ( tile ) | | tile instanceof Shadow | | tile instanceof BlockContact ) continue ;
file . append ( tile . json ( ) + "\n" ) ;
file . append ( tile . json ( ) + "\n" ) ;
}
file . close ( ) ;
}
public boolean setState ( Status newState , Train newTrain ) {
public boolean setTrain ( Train newTrain ) {
if ( isNull ( newTrain ) ) return false ;
if ( isSet ( train ) & & newTrain ! = train ) return false ; // already locked by other train
if ( is ( Status . OCCUPIED , newState ) ) return true ; // do not downgrade occupied tiles, accept current state
train = newTrain ;
status = newState ;
plan . place ( this ) ;
if ( isSet ( train ) & & newTrain ! = train ) return false ;
switch ( status ) { // bisheriger Status
case DISABLED :
return false ;
case FREE :
case RESERVED :
case LOCKED :
train = newTrain ;
status = Status . OCCUPIED ;
plan . place ( this ) ;
break ;
case OCCUPIED :
break ;
}
return true ;
}
public Tag tag ( Map < String , Object > replacements ) throws IOException {
int width = 100 * width ( ) ;
int height = 100 * height ( ) ;
public Tag tag ( Map < String , Object > replacements ) throws IOException {
int width = 100 * width ( ) ;
int height = 100 * height ( ) ;
if ( isNull ( replacements ) ) replacements = new HashMap < String , Object > ( ) ;
replacements . put ( "%width%" , width ) ;
replacements . put ( "%height%" , height ) ;
replacements . put ( "%width%" , width ) ;
replacements . put ( "%height%" , height ) ;
String style = "" ;
Tag svg = new Tag ( "svg" )
. id ( isSet ( x ) & & isSet ( y ) ? id ( ) . toString ( ) : getClass ( ) . getSimpleName ( ) )
. clazz ( classes ( ) )
. size ( 100 , 100 )
. attr ( "name" , getClass ( ) . getSimpleName ( ) )
. attr ( "viewbox" , "0 0 " + width + " " + height ) ;
if ( isSet ( x ) ) style = "left: " + ( 30 * x ) + "px; top: " + ( 30 * y ) + "px;" ;
if ( width ( ) > 1 ) style + = " width: " + ( 30 * width ( ) ) + "px;" ;
if ( height ( ) > 1 ) style + = " height: " + ( 30 * height ( ) ) + "px;" ;
Tag svg = new Tag ( "svg" ) . id ( isSet ( x ) & & isSet ( y ) ? id ( ) . toString ( ) : getClass ( ) . getSimpleName ( ) )
. clazz ( classes ( ) ) . size ( 100 , 100 ) . attr ( "name" , getClass ( ) . getSimpleName ( ) )
. attr ( "viewbox" , "0 0 " + width + " " + height ) ;
if ( isSet ( x ) ) style = "left: " + ( 30 * x ) + "px; top: " + ( 30 * y ) + "px;" ;
if ( width ( ) > 1 ) style + = " width: " + ( 30 * width ( ) ) + "px;" ;
if ( height ( ) > 1 ) style + = " height: " + ( 30 * height ( ) ) + "px;" ;
if ( ! style . isEmpty ( ) ) svg . style ( style ) ;
File file = new File ( System . getProperty ( "user.dir" ) + "/resources/svg/" + getClass ( ) . getSimpleName ( ) + ".svg" ) ;
File file = new File ( System . getProperty ( "user.dir" ) + "/resources/svg/" + getClass ( ) . getSimpleName ( ) + ".svg" ) ;
if ( file . exists ( ) ) {
Scanner scanner = new Scanner ( file , StandardCharsets . UTF_8 ) ;
StringBuffer sb = new StringBuffer ( ) ;
while ( scanner . hasNextLine ( ) ) {
String line = scanner . nextLine ( ) ;
if ( line . startsWith ( "<svg" ) | | line . endsWith ( "svg>" ) ) continue ;
for ( Entry < String , Object > replacement : replacements . entrySet ( ) ) line = replace ( line , replacement ) ;
sb . append ( line + "\n" ) ;
for ( Entry < String , Object > replacement : replacements . entrySet ( ) ) line = replace ( line , replacement ) ;
sb . append ( line + "\n" ) ;
}
scanner . close ( ) ;
svg . content ( sb . toString ( ) ) ;
if ( isSet ( oneWay ) ) {
switch ( oneWay ) {
switch ( oneWay ) {
case EAST :
new Tag ( "polygon" ) . clazz ( "oneway" ) . attr ( "points" , "100,50 75,35 75,65" ) . addTo ( svg ) ;
break ;
@ -426,54 +440,97 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
@@ -426,54 +440,97 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
String title = title ( ) ;
if ( isSet ( title ) ) new Tag ( "title" ) . content ( title ( ) ) . addTo ( svg ) ;
} else {
new Tag ( "title" ) . content ( t ( "No display defined for this tile ({})" , getClass ( ) . getSimpleName ( ) ) ) . addTo ( svg ) ;
new Tag ( "text" )
. pos ( 35 , 70 )
. content ( "?" )
. addTo ( svg ) ;
new Tag ( "title" ) . content ( t ( "No display defined for this tile ({})" , getClass ( ) . getSimpleName ( ) ) ) . addTo ( svg ) ;
new Tag ( "text" ) . pos ( 35 , 70 ) . content ( "?" ) . addTo ( svg ) ;
}
return svg ;
}
public String title ( ) {
return getClass ( ) . getSimpleName ( ) + " @ (" + x + ", " + y + ")" ;
return getClass ( ) . getSimpleName ( ) + " @ (" + x + ", " + y + ")" ;
}
@Override
public String toString ( ) {
return t ( "{}({},{})" , getClass ( ) . getSimpleName ( ) , x , y ) ;
return t ( "{}({},{})" , getClass ( ) . getSimpleName ( ) , x , y ) ;
}
public Train train ( ) {
return train ;
}
@Override
public BaseClass remove ( ) {
while ( ! routes . isEmpty ( ) ) routes . first ( ) . remove ( ) ;
return super . remove ( ) ;
}
@Override
public void removeChild ( BaseClass child ) {
String childAsString = child . toString ( ) ;
if ( childAsString . length ( ) > 20 ) childAsString = childAsString . substring ( 0 , 20 ) + "…" ;
LOG . debug ( "Removing {} from {}" , childAsString , this ) ;
if ( childAsString . length ( ) > 20 ) childAsString = childAsString . substring ( 0 , 20 ) + "…" ;
LOG . debug ( "Removing {} from {}" , childAsString , this ) ;
if ( child instanceof Route ) routes . remove ( child ) ;
if ( child = = train ) train = null ;
super . removeChild ( child ) ;
plan . place ( this ) ;
}
public void setEnabled ( boolean newState ) {
disabled = ! newState ;
public boolean lockFor ( Context context ) {
Train newTrain = context . train ( ) ;
LOG . debug ( "{}.lockFor({})" , this , newTrain ) ;
if ( isNull ( newTrain ) ) return false ;
if ( isSet ( train ) & & train ! = newTrain ) return false ;
switch ( status ) {
case DISABLED :
return false ;
case FREE :
case RESERVED :
status = Status . LOCKED ;
plan . place ( this ) ;
break ;
case OCCUPIED :
case LOCKED :
break ; // do not downgrade
}
return true ;
}
public boolean reserveFor ( Context context ) {
Train newTrain = context . train ( ) ;
LOG . debug ( "{}.reserverFor({})" , this , newTrain ) ;
if ( isNull ( newTrain ) ) return false ;
if ( isSet ( train ) & & train ! = newTrain ) return false ;
switch ( status ) {
case DISABLED :
return false ;
case FREE :
status = Status . RESERVED ;
train = newTrain ;
plan . place ( this ) ;
break ;
case OCCUPIED :
case LOCKED :
case RESERVED :
break ; // do not downgrade
}
return true ;
}
public void setEnabled ( boolean enabled ) {
if ( ! enabled ) {
status = Status . DISABLED ;
} else if ( is ( Status . DISABLED ) ) { // Status nur ändern, wenn er bisher DISABLED war
status = isNull ( train ) ? Status . FREE : Status . OCCUPIED ;
}
plan . place ( this ) ;
}
public Tile update ( HashMap < String , String > params ) {
LOG . debug ( "{}.update({})" , getClass ( ) . getSimpleName ( ) , params ) ;
LOG . debug ( "{}.update({})" , getClass ( ) . getSimpleName ( ) , params ) ;
String oneWayDir = params . get ( "oneway" ) ;
if ( isSet ( oneWayDir ) ) {
try {
@ -482,17 +539,15 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
@@ -482,17 +539,15 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
oneWay = null ;
}
}
disabled = "on" . equals ( params . get ( DISABLED ) ) ;
if ( "on" . equals ( params . get ( DISABLED ) ) ) status = Status . DISABLED ;
String len = params . get ( LENGTH ) ;
if ( isSet ( len ) ) length ( Integer . parseInt ( len ) ) ;
super . update ( params ) ;
plan . place ( this ) ;
return this ;
}
public int width ( ) {
return 1 ;
}
}