Package net.sf.mrailsim.rails

Source Code of net.sf.mrailsim.rails.TrackManager

/************************************************************************************

    MRailSim - a model railway simulation program - http://mrailsim.sourceforge.net/
    Copyright (C) 2004,2007  Bernd Arnold

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

   
************************************************************************************/


package net.sf.mrailsim.rails;

import java.awt.Graphics;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.sf.mrailsim.main.Game;
import net.sf.mrailsim.shared.Coordinates;
import net.sf.mrailsim.shared.Logger;
import net.sf.mrailsim.signals.MainSectionSignal;
import net.sf.mrailsim.signals.MainSignal;
import net.sf.mrailsim.signals.PreSignal;
import net.sf.mrailsim.signals.Signal;

public class TrackManager {

  /**
   * The list with all tracks.
   */
  private ArrayList<Track> trackList;
 
  private ArrayList<TrackSection> trackSectionList;
 
  private ArrayList<Signal> signalList;
 
  /**
   * Class constructor; allocates a new empty track list.
   */
  public TrackManager() {
    trackList = new ArrayList<Track>();
    trackSectionList = new ArrayList<TrackSection>();
    signalList = new ArrayList<Signal>();
  }
 
  /**
   * Returns the total number of registered tracks.
   * @return  the count of tracks
   */
  public int getTrackCount() {
    return trackList.size();
  }
 
  /**
   * Returns the track object with the given id
   * @param id  the id of the track
   * @return    the track object or <code>null</code>, if not found
   */
  public Track getTrack( long id ) {
    for ( Track item: trackList ) {
      if ( item.getId() == id ) {
        return item;
      }
    }
    return null;
  }
 
  public TrackSection getTrackSection( long id ) {
    for ( TrackSection item: trackSectionList ) {
      if ( item.getId() == id ) {
        return item;
      }
    }
    return null;
  }

  public Signal getSignal( long id ) {
    for ( Signal item: signalList ) {
      if ( item.getId() == id ) {
        return item;
      }
    }
    return null;
  }
 
  /**
   * Adds a track to the list. This should be the only one function that adds
   * tracks to the track list.
   * @param track  the new track
   */
  void addTrack( Track track ) {
    // TODO: Check if id was already assigned - if yes, exception!
    trackList.add( track );
  }
 
  /**
   * Parses the string describing a new track and calls the addTrack(long, String, int, String) method.
   * @param s  describing the new track, for example: <code>Id=1,Type=Straight,Length=50,Nodes=(1,3)</code>
   * @see      #addTrack(long, String, int, String)
   */
  public void addTrack( String s ) {
    Pattern pattern = Pattern.compile( "^Id=(.*),Type=(.*),Length=(.*),Nodes=\\((.*)\\)$" );
    Matcher matcher = pattern.matcher( s );
    if ( ! matcher.matches() ) {
      // TODO: Handle right
      System.err.println( "addTrack mismatch: " + s );
      System.exit(1);
    }
    long id = Long.parseLong( matcher.group( 1 ) );
    String type = matcher.group( 2 );
    int length = Integer.parseInt( matcher.group( 3 ) );
    String nodes = matcher.group( 4 );

    addTrack( id, type, length, nodes );
  }
 
  public void addTrackSection( String s ) {
    Pattern pattern = Pattern.compile( "^Id=(.*)$" );
    Matcher matcher = pattern.matcher( s );
    if ( ! matcher.matches() ) {
      // TODO: Handle right
      System.err.println( "addTrackSection mismatch: " + s );
      System.exit(1);
    }
    long id = Long.parseLong( matcher.group( 1 ) );

    addTrackSection( id );
  }
 
  private void addTrackSection( long id ) {
    // TODO: Check if id was already added
    trackSectionList.add( new TrackSection( id ) );
  }
 
  /**
   * Adds a new track.
   * @param id           id of the track
   * @param type         type of the track
   * @param length       the length of the track
   * @param nodeString   the nodes of the track
   */
  private void addTrack( long id, String type, int length, String nodeString ) {
    Track track = null;
    Node nodes[];
    Junction j = new Junction();

    Logger.log( Logger.Component.TRACK, Logger.Level.INFORMATION,
        String.format( "Adding track #%d, %s, nodes: %s.",
            id, type, nodeString )
            );
   
    String nodeStrings[] = nodeString.split( "," );
    long nodeIds[] = new long[ nodeStrings.length ];
    for ( int i = 0; i < nodeStrings.length; i++ ) {
      nodeIds[ i ] = Integer.parseInt( nodeStrings[ i ] );
    }
    nodeStrings = null;
   
    if ( type.toLowerCase().equals( "straight" ) ) {
      // nodes should be like '1,2'
      if ( nodeIds.length == 2 ) {
        track = new TrackStraight( id, length, j );
        nodes = Game.nodeManager.registerNodes( nodeIds, track );
        Position p = new Position( new NodeConnector( nodes[ 0 ], nodes[ 1 ] ) ) ;
        j.add( p );
      }
    }

    if ( type.toLowerCase().equals( "x" ) ) {
      // nodes should be like '1,2,3,4'
      if ( nodeIds.length == 4 ) {
        track = new TrackX( id, length, j );
        nodes = Game.nodeManager.registerNodes( nodeIds, track );
        j.add( new Position(
            new NodeConnector( nodes[ 0 ], nodes[ 1 ] ),
            new NodeConnector( nodes[ 2 ], nodes[ 3 ] ) ) );
      }
    }

    if ( type.toLowerCase().equals( "switch_1" ) ) {
      // nodes should be like '1,2,3'
      if ( nodeIds.length == 3 ) {
        track = new TrackSwitch1( id, length, j );
        nodes = Game.nodeManager.registerNodes( nodeIds, track );
        j.add( new Position( new NodeConnector( nodes[ 0 ], nodes[ 1 ] ) ) );
        j.add( new Position( new NodeConnector( nodes[ 0 ], nodes[ 2 ] ) ) );
      }
    }

    if ( type.toLowerCase().equals( "switch_2" ) ) {
      // nodes should be like '1,2,3,4'
      if ( nodeIds.length == 4 ) {
        track = new TrackSwitch2( id, length, j );
        nodes = Game.nodeManager.registerNodes( nodeIds, track );
        j.add( new Position( new NodeConnector( nodes[ 0 ], nodes[ 1 ] ) ) );
        j.add( new Position( new NodeConnector( nodes[ 0 ], nodes[ 2 ] ) ) );
        j.add( new Position( new NodeConnector( nodes[ 0 ], nodes[ 3 ] ) ) );
      }
    }

    if ( type.toLowerCase().equals( "switch_x" ) ) {
      // nodes should be like '1,2,3,4'
      if ( nodeIds.length == 4 ) {
        track = new TrackSwitchX( id, length, j );
        nodes = Game.nodeManager.registerNodes( nodeIds, track );
        j.add( new Position(
            new NodeConnector( nodes[ 0 ], nodes[ 1 ] ),
            new NodeConnector( nodes[ 2 ], nodes[ 3 ] ) ) );
        j.add( new Position(
            new NodeConnector( nodes[ 0 ], nodes[ 2 ] ),
            new NodeConnector( nodes[ 3 ], nodes[ 1 ] ) ) );
      }
    }

    if ( track != null ) {
      addTrack( track );
      return;
    }
   
    // TODO: Do it right and remove all these silly lines
    System.err.println( "addTrack unkown: " + id + ", type " + type + ", nodes " + nodeString );
    System.exit( 1 );
  }

  /**
   * Prints on the console which way a train would drive. Each track
   * a train would enter is printed as well as the node ids of the
   * incoming and outgoing nodes.
   *
   * @param track  the track where to start
   * @param node   the node where the track was entered
   * @param depth  the number of following tracks that should be investigated
   */
  public void printWayFrom( Track track, Node node, int depth ) {
    Track currentTrack = track;
    Node lastNode = node;
    System.out.println( "The way goes just like this:" );
    System.out.println( "  Started at track: #" + currentTrack.getId() + ", node #" + lastNode.getId() );

    while ( depth > 0 ) {
      Node nextNode = null;
      Track nextTrack = null;
      Node followingNode = null;
     
      try {
        nextNode = currentTrack.getOutgoingNode( lastNode );
        nextTrack = nextNode.getOtherTrack( currentTrack );
        followingNode = nextTrack.getOutgoingNode( nextNode );
      } catch (Exception e) {
        e.printStackTrace();
        System.exit( 2 );
      }
     
      String out = String.format( "  Next track: %5d, entered at node #%5d, will leave at node #%5d.",
          nextTrack.getId(), nextNode.getId(), followingNode.getId() );
      System.out.println( out );
     
      currentTrack = nextTrack;
      lastNode = nextNode;
      depth--;
    }
  }

  /**
   * Sets a new position of a track. The new position is transmitted
   * to the specified track and handled there.
   * @param s  specifies which track and position, for example
   *           <code>Id=5,Newpos=1</code> or <code>Id=5,Nextpos</code>
   * @see  Track#setPosition(int)
   */
  public void setPosition( String s ) {
    Pattern pattern;
    Matcher matcher;

    pattern = Pattern.compile( "^Id=(\\d+),Newpos=(\\d+)$" );
    matcher = pattern.matcher( s );
    if ( matcher.matches() ) {
      long id = Long.parseLong( matcher.group( 1 ) );
      int pos = Integer.parseInt( matcher.group( 2 ) );

      Track track = getTrack( id );
      if ( track != null ) {
        track.setPosition( pos );
      } else {
        // TODO: Handle better
        System.err.println( "setPosition(String): Track #" + id + " does not exist." );
      }
     
      return;
    }

    pattern = Pattern.compile( "^Id=(\\d+),Nextpos$" );
    matcher = pattern.matcher( s );
    if ( matcher.matches() ) {
      long id = Long.parseLong( matcher.group( 1 ) );

      Track track = getTrack( id );
      if ( track != null ) {
        track.setNextPosition();
      } else {
        // TODO: Handle better
        System.err.println( "setPosition(String): Track #" + id + " does not exist." );
      }
     
      return;
    }

    // TODO: Handle right
    System.err.println( "setPosition mismatch: " + s );
    System.exit(1);
  }

  /**
   * Draw all the tracks and signals into the given graphic context.
   * @param g  The graphic context.
   */
  public void draw( Graphics g ) {
    for ( Track item : trackList ) {
      item.draw( g );
    }
    for ( Signal item : signalList ) {
      item.draw( g );
    }
  }

  public void setTrackSection( String s ) {
    Pattern pattern = Pattern.compile( "^Section=(\\d+),Track=(\\d+)$" );
    Matcher matcher = pattern.matcher( s );
    if ( ! matcher.matches() ) {
      // TODO: Handle right
      System.err.println( "setTrackSection mismatch: " + s );
      System.exit(1);
    }
    long sectionId = Long.parseLong( matcher.group( 1 ) );
    long trackId = Integer.parseInt( matcher.group( 2 ) );

    TrackSection trackSection = getTrackSection( sectionId );
    if ( trackSection != null ) {
      trackSection.addTrack( trackId );
    } else {
      // TODO: Handle better
      System.err.println( "setSection(String): Section #" + sectionId + " does not exist." );
    }
  }

  public void addSignal( String s ) {
    Pattern pattern;
    Matcher matcher;
   
    pattern = Pattern.compile( "^Id=(.*),Section=(.*)$" );
    matcher = pattern.matcher( s );
    if ( matcher.matches() ) {
      long signalId = Long.parseLong( matcher.group( 1 ) );
      long sectionId = Long.parseLong( matcher.group( 2 ) );
      addSectionSignal( signalId, sectionId );
     
      return;
    }

    pattern = Pattern.compile( "^Id=(.*),Lookahead=(.*),StartTrack=(.*),StartNode=(.*)$" );
    matcher = pattern.matcher( s );
    if ( matcher.matches() ) {
      long signalId = Long.parseLong( matcher.group( 1 ) );
      int lookAmount = Integer.parseInt( matcher.group( 2 ) );
      long trackId = Long.parseLong( matcher.group( 3 ) );
      long nodeId = Long.parseLong( matcher.group( 4 ) );
      addLookaheadSignal( signalId, lookAmount, trackId, nodeId );
     
      return;
    }

    pattern = Pattern.compile( "^Id=(.*),Main=(.*),BoundTrack=(.*),BoundNode=(.*)$" );
    matcher = pattern.matcher( s );
    if ( matcher.matches() ) {
      long signalId = Long.parseLong( matcher.group( 1 ) );
      long mainId = Long.parseLong( matcher.group( 2 ) );
      long trackId = Long.parseLong( matcher.group( 3 ) );
      long nodeId = Long.parseLong( matcher.group( 4 ) );
      addPreSignal( signalId, mainId, trackId, nodeId );
     
      return;
    }

    // TODO: Handle right
    System.err.println( "addSignal mismatch: " + s );
    System.exit( 1 );
  }

  private void addSectionSignal( long signalId, long sectionId ) {
    TrackSection section = getTrackSection( sectionId );
    if ( section == null ) {
      // TODO: Handle right
      System.err.println( "addSectionSignal: section #" + sectionId + " not found." );
      System.exit(1);
    }
    // TODO: Check if id was already added
    MainSectionSignal signal = new MainSectionSignal( signalId );
    signal.setTrackSection( section );
    signalList.add( signal );
  }

  private void addLookaheadSignal( long signalId, int aheadAmount, long trackId, long nodeId ) {
    Track track = getTrack( trackId );
    Node node = Game.nodeManager.getNode( nodeId );
   
    if ( track == null ) {
      // TODO: Handle right
      System.err.println( "addLookAheadSignal: track #" + trackId + " not found." );
      System.exit(1);
    }
    if ( node == null ) {
      // TODO: Handle right
      System.err.println( "addLookAheadSignal: node #" + nodeId + " not found." );
      System.exit(1);
    }

    // TODO: Remove and handle right
//    if ( aheadAmount != 1 ) {
//      System.err.println( "addLookAheadSignal: signal #" + signalId + " amount not 1." );
//      System.exit(1);
//    }
   
    // TODO: Check if id was already added
//    MainLookaheadSignal signal = new MainLookaheadSignal( signalId );
//    signal.setLookaheads( aheadAmount, track, node );
    MainSignal signal = new MainSignal( signalId );
    signal.setBound( track, node );
    signal.makeLookaheadSignal( aheadAmount );
    signal.update();
    signalList.add( signal );
  }

  private void addPreSignal( long preSignalId, long mainSignalId, long trackId, long nodeId ) {
    Signal signal = getSignal( mainSignalId );
   
    if ( ! ( signal instanceof MainSignal ) ) {
      // TODO: Handle right
      System.err.println( "addPreSignal: signal #" + mainSignalId + " not a main signal." );
      System.exit(1);
    }
   
    // TODO: Check if id was already added
    PreSignal preSignal = new PreSignal( preSignalId );
    preSignal.setMainSignal( (MainSignal) signal );
    preSignal.setBound( getTrack( trackId ), Game.nodeManager.getNode( nodeId ) );
    signalList.add( preSignal );
  }

  public void setSignalCoordinates( String s ) {
    Pattern pattern = Pattern.compile( "^Id=(\\d+),X=(\\d+),Y=(\\d+)$" );
    Matcher matcher = pattern.matcher( s );
    if ( ! matcher.matches() ) {
      // TODO: Handle right
      System.err.println( "setSignalCoordinates mismatch: " + s );
      System.exit(1);
    }
    long id = Long.parseLong( matcher.group( 1 ) );
    int x = Integer.parseInt( matcher.group( 2 ) );
    int y = Integer.parseInt( matcher.group( 3 ) );

    Signal signal = getSignal( id );
    if ( signal != null ) {
      signal.setCoordinates( new Coordinates( x, y ) );
    } else {
      // TODO: Handle better
      System.err.println( "setSignalCoordinates(String): Signal #" + id + " does not exist." );
    }
  }

  public void mouseClickedOn( int x, int y ) {
    for ( Signal s : signalList ) {
      if ( s.matchCoordinates( x, y ) ) {
        s.handleMouseClick();
      }
    }
  }
 
}
TOP

Related Classes of net.sf.mrailsim.rails.TrackManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.