Package jmri

Class TurnoutOperation

  • All Implemented Interfaces:
    java.lang.Comparable<java.lang.Object>, PropertyChangeFirer, PropertyChangeProvider
    Direct Known Subclasses:

    public abstract class TurnoutOperation
    extends PropertyChangeSupport
    implements java.lang.Comparable<java.lang.Object>
    Framework for automating reliable turnout operation. This interface allows a particular style (e.g. retries) to be implemented and then to have multiple instances for variations in parameters if required

    This mechanism is designed to extensible to allow new operation types (e.g. for Tortoise-style point machines) and to allow individual system types to change it, for example to allow operation with alternative feedback arrangements.

    The TurnoutOperation class is at the heart of things, although there are several other classes, partly to fit in with JMRI's package structure. Each specific retry scheme has its own concrete subclass of TurnoutOperation. One instance of each such class is created at startup. It has the same name as the prefix to the class, and is called the "defining instance". Further instances can exist with different parameter values (e.g. number of retries).

    The TurnoutOperationManager class (only one instance) keeps track of the instances and can retrieve them by name. It can also supply a suitable TurnoutOperation for a given turnout, based on the feedback type, if the turnout does not identify one for itself.

    Each AbstractTurnout may have a reference to a TurnoutOperation class, which may be unique to this turnout or may be shared. When the turnout is thrown, if it has its own TurnoutOperation, this is used (unless the turnout has selected no automation). Otherwise, the TurnoutOperationManager is asked to find one.

    The TurnoutOperation has a factory method (getOperation) which is called when a turnout is operated, to supply the operator. Each subclass of TurnoutOperation has a corresponding subclass of TurnoutOperator, which contains the logic for the retry scheme. Each operator runs in its own thread, which terminates when the operation is complete. If another operation of the same turnout is made before the first one completes, the older thread terminates itself when it realises it is no longer the active operation for the turnout.

    The parameters of a TurnoutOperation can be edited. Each subclass has its own xxxTurnoutOperationConfig class, which knows how to display the parameters in a JPanel and gather them up again and store them afterwards.

    Each subclass also has its own xxxTurnoutOperationXml class, which knows how to store the information in an XML element, and restore it.

    The current code defines three operations, NoFeedback, Raw and Sensor. Because these have so much in common (only the xxxTurnoutOperator class has any differences), most of them are implemented in the CommonTurnout... classes. This family is not part of the general structure, although it can be reused if it helps.


    To write a new type of operation:

    1. Create the xxxTurnoutOperation class
    2. Create the xxxTurnoutOperator class, including the logic for what you're trying to do
    3. Create the xxxTurnoutOperationConfig class - the CommonTurnoutOperationConfig class can be used as a reference
    4. Create the xxxTurnoutOperationXml class - again the Common... class can be used as a reference
    5. Add the prefix to the class name (e.g. "Tortoise") to the list AbstractTurnoutManager.validOperationTypes, otherwise it will not be instantiated at startup and hence will not be available

    To change the behavior for a particular system type:

    There are some functions which can be overridden in the system-specific subclasses to change default behaviour if desired. These mechanisms are orthogonal to the operation subclasses.

    1. Override AbstractTurnoutManager.getValidOperationTypes to change the operation types allowed for this system
    2. Override AbstractTurnout.getFeedbackModeForOperation to map system-specific feedback modes into modes that the general classes know about
    3. Override AbstractTurnout.getTurnoutOperator if you want to do something really different
    • Method Detail

      • makeCopy

        public abstract TurnoutOperation makeCopy​(@Nonnull
                                                  java.lang.String n)
        Factory to make a copy of an operation identical in all respects except the name.
        n - name for new copy
        TurnoutOperation of same concrete class as this
      • setFeedbackModes

        protected void setFeedbackModes​(int fm)
        Set feedback modes - part of construction but done separately for ordering problems.
        fm - valid feedback modes for this class
      • getName

        public java.lang.String getName()
        Get the descriptive name of the operation.
      • compareTo

        public int compareTo​(java.lang.Object other)
        Ordering by name so operations can be sorted on name.
        Specified by:
        compareTo in interface java.lang.Comparable<java.lang.Object>
        other - other TurnoutOperation object
        usual compareTo return values
      • equals

        public boolean equals​(java.lang.Object ro)
        The identity of an operation is its name.
        equals in class java.lang.Object
      • hashCode

        public int hashCode()
        hashCode in class java.lang.Object
      • equivalentTo

        public abstract boolean equivalentTo​(TurnoutOperation other)
        other - another TurnoutOperation
        true if the two operations are equivalent, i.e. same subclass and same parameters
      • rename

        public boolean rename​(@Nonnull
                              java.lang.String newName)
        Rename an operation.
        newName - new name to use for rename attempt
        true if the name was changed to the new value - otherwise name is unchanged
      • getDefinitive

        public TurnoutOperation getDefinitive()
        Get the definitive operation for this parameter variation.
        definitive operation
      • isDefinitive

        public boolean isDefinitive()
        true if this is the "defining instance" of the class, which we determine by the name of the instance being the same as the prefix of the class
      • getOperator

        public abstract TurnoutOperator getOperator​(@Nonnull
                                                    AbstractTurnout t)
        Get an instance of the operator for this operation type, set up and started to do its thing in a private thread for the specified turnout.
        t - the turnout to apply the operation to
        the operator
      • dispose

        public void dispose()
        Delete all knowledge of this operation. Reset any turnouts using it to the default.
      • isInUse

        public boolean isInUse()
        See if operation is in use (needed by the UI).
        true if any turnouts are using it
      • isNonce

        public boolean isNonce()
        Nonce support. A nonce is a TurnoutOperation created specifically for one turnout, which can't be directly referred to by name. It does have a name, which is the turnout it was created for, prefixed by "*"
        true if this object is a nonce
      • setNonce

        public void setNonce​(boolean n)
      • matchFeedbackMode

        public boolean matchFeedbackMode​(int mode)
        mode - feedback mode for a turnout
        true if this operation's feedback mode is one we know how to deal with
      • getToolTip

        public java.lang.String getToolTip()
        Get the ToolTip for the Turnout Operator.
        String or null.