001package jmri; 002 003import java.time.LocalDateTime; 004import javax.annotation.Nonnull; 005import javax.annotation.CheckForNull; 006 007/** 008 * Locate a Turnout object representing some specific turnout on the layout. 009 * <p> 010 * Turnout objects are obtained from a TurnoutManager, which in turn is 011 * generally located from the InstanceManager. A typical call sequence might be: 012 * <pre> 013 * Turnout turnout = InstanceManager.turnoutManagerInstance().provideTurnout("23"); 014 * </pre> 015 * <p> 016 * Each turnout has a two names. The "user" name is entirely free form, and can 017 * be used for any purpose. The "system" name is provided by the system-specific 018 * implementations, and provides a unique mapping to the layout control system 019 * (for example LocoNet or NCE) and address within that system. 020 * <p> 021 * Much of the book-keeping is implemented in the AbstractTurnoutManager class, 022 * which can form the basis for a system-specific implementation. 023 * <p> 024 * A sample use of the TurnoutManager interface can be seen in the 025 * jmri.jmrit.simpleturnoutctrl.SimpleTurnoutCtrlFrame class, which provides a 026 * simple GUI for controlling a single turnout. 027 * 028 * <p> 029 * This file is part of JMRI. 030 * <p> 031 * JMRI is free software; you can redistribute it and/or modify it under the 032 * terms of version 2 of the GNU General Public License as published by the Free 033 * Software Foundation. See the "COPYING" file for a copy of this license. 034 * <p> 035 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY 036 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 037 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 038 * 039 * @author Bob Jacobsen Copyright (C) 2001 040 * @see jmri.Turnout 041 * @see jmri.InstanceManager 042 * @see jmri.jmrit.simpleturnoutctrl.SimpleTurnoutCtrlFrame 043 */ 044public interface TurnoutManager extends ProvidingManager<Turnout>, NameIncrementingManager { 045 046 /** 047 * Get the Turnout with the user name, then system name if needed; if that fails, create a 048 * new Turnout. 049 * If the name is a valid system name, it will be used for the new Turnout. 050 * Otherwise, the {@link Manager#makeSystemName} method will attempt to turn it 051 * into a valid system name. 052 * <p> 053 * This provides the same function as {@link ProvidingManager#provide} 054 * which has a more generic form. 055 * 056 * @param name User name, system name, or address which can be promoted to 057 * system name 058 * @return Never null 059 * @throws IllegalArgumentException if Turnout doesn't already exist and the 060 * manager cannot create the Turnout due to 061 * an illegal name or name that can't 062 * be parsed. 063 */ 064 @Nonnull 065 Turnout provideTurnout(@Nonnull String name) throws IllegalArgumentException; 066 067 /** {@inheritDoc} */ 068 @Override 069 @Nonnull 070 default Turnout provide(@Nonnull String name) throws IllegalArgumentException { return provideTurnout(name); } 071 072 /** 073 * Get an existing Turnout or return null if it doesn't exist. 074 * 075 * Locates via user name, then system name if needed. 076 * 077 * @param name User name or system name to match 078 * @return null if no match found 079 */ 080 @CheckForNull 081 Turnout getTurnout(@Nonnull String name); 082 083 /** 084 * Get the Turnout with the given system name or null if no instance 085 * already exists. 086 * 087 * @param systemName the system name 088 * @return requested Turnout object or null if none exists 089 */ 090 @CheckForNull 091 @Override 092 Turnout getBySystemName(@Nonnull String systemName); 093 094 /** 095 * Get the Turnout with the given user name or null if no instance 096 * already exists. 097 * 098 * @param userName the user name 099 * @return requested Turnout object or null if none exists 100 */ 101 @CheckForNull 102 @Override 103 Turnout getByUserName(@Nonnull String userName); 104 105 /** 106 * Return a Turnout with the specified system and user names. 107 * Lookup by UserName then provide by System Name. 108 * <p> 109 * Note that 110 * two calls with the same arguments will get the same instance; there is 111 * only one Turnout object representing a given physical turnout and 112 * therefore only one with a specific system or user name. 113 * <p> 114 * This will always return a valid object reference; a new object will be 115 * created if necessary. In that case: 116 * <ul> 117 * <li>If a null reference is given for user name, no user name will be 118 * associated with the Turnout object created; a valid system name must be 119 * provided 120 * <li>If both names are provided, the system name defines the hardware 121 * access of the desired turnout, and the user address is associated with 122 * it. The system name must be valid. 123 * </ul> 124 * Note that it is possible to make an inconsistent request if both 125 * addresses are provided, but the given values are associated with 126 * different objects. This is a problem, and we don't have a good solution 127 * except to issue warnings. This will mostly happen if you're creating 128 * Turnouts when you should be looking them up. 129 * 130 * @param systemName the system name 131 * @param userName the user name (optional) 132 * @return requested Turnout object, newly created if needed 133 * @throws IllegalArgumentException if cannot create the Turnout; likely due 134 * to an illegal name or name that cannot 135 * be parsed 136 */ 137 @Nonnull 138 Turnout newTurnout(@Nonnull String systemName, @CheckForNull String userName) throws IllegalArgumentException; 139 140 /** 141 * Get text to be used for the Turnout.CLOSED state in user communication. 142 * Allows text other than "CLOSED" to be used with certain hardware system 143 * to represent the Turnout.CLOSED state. 144 * 145 * @return the textual representation of {@link jmri.Turnout#CLOSED} 146 */ 147 @Nonnull 148 String getClosedText(); 149 150 /** 151 * Get text to be used for the Turnout.THROWN state in user communication. 152 * Allows text other than "THROWN" to be use with certain hardware system to 153 * represent the Turnout.THROWN state. 154 * 155 * @return the textual representation of {@link jmri.Turnout#THROWN} 156 */ 157 @Nonnull 158 String getThrownText(); 159 160 /** 161 * Get a list of the valid TurnoutOperation subtypes for use with turnouts 162 * of this system. 163 * 164 * @return a list of subtypes or an empty list if turnout operations are not 165 * supported 166 */ 167 @Nonnull 168 String[] getValidOperationTypes(); 169 170 /** 171 * Get, from the user, the number of addressed bits used to control a 172 * turnout. Normally this is 1, and the default routine returns one 173 * automatically. Turnout Managers for systems that can handle multiple 174 * control bits should override this method with one which asks the user to 175 * specify the number of control bits. If the user specifies more than one 176 * control bit, this method should check if the additional bits are 177 * available (not assigned to another object). If the bits are not 178 * available, this method should return 0 for number of control bits, after 179 * informing the user of the problem. 180 * 181 * @param systemName the turnout system name 182 * @return the bit length for turnout control 183 */ 184 int askNumControlBits(@Nonnull String systemName); 185 186 /** 187 * Determine if the manager supports multiple control bits, as 188 * {@link #askNumControlBits(java.lang.String)} will always return a value 189 * even if it is not supported. 190 * 191 * @param systemName the turnout system name 192 * @return true if manager supports multiple control bits for the turnout; 193 * false otherwise 194 */ 195 boolean isNumControlBitsSupported(@Nonnull String systemName); 196 197 /** 198 * Get, from the user, the type of output to be used bits to control a 199 * turnout. Normally this is 0 for 'steady state' control, and the default 200 * routine returns 0 automatically. Turnout Managers for systems that can 201 * handle pulsed control as well as steady state control should override 202 * this method with one which asks the user to specify the type of control 203 * to be used. The routine should return 0 for 'steady state' control, or n 204 * for 'pulsed' control, where n specifies the duration of the pulse 205 * (normally in seconds). 206 * 207 * @param systemName the turnout system name 208 * @return 0 for steady state or the number of seconds for a pulse control 209 */ 210 int askControlType(@Nonnull String systemName); 211 212 /** 213 * Determine if the manager supports the handling of pulsed and steady state 214 * control as the {@link #askControlType(java.lang.String)} will always 215 * return a value even if it is not supported. 216 * 217 * @param systemName the turnout system name 218 * @return true if manager supports the control type returned by 219 * {@link #askControlType(java.lang.String)}; false otherwise 220 * 221 */ 222 boolean isControlTypeSupported(@Nonnull String systemName); 223 224 /** 225 * Get a system name for a given hardware address and system prefix. 226 * 227 * @param curAddress desired hardware address 228 * @param prefix system prefix used in system name 229 * @return the complete turnout system name for the prefix and current 230 * address 231 * @throws jmri.JmriException if unable to create a system name for the 232 * given address, possibly due to invalid address 233 * format 234 */ 235 String createSystemName(@Nonnull String curAddress, @Nonnull String prefix) throws JmriException; 236 237 void setDefaultClosedSpeed(@Nonnull String speed) throws JmriException; 238 239 void setDefaultThrownSpeed(@Nonnull String speed) throws JmriException; 240 241 String getDefaultThrownSpeed(); 242 243 String getDefaultClosedSpeed(); 244 245 /** 246 * Get the Interval (in ms) to wait between output commands. 247 * Configured in AdapterConfig, stored in memo. 248 * 249 * @return the (Turnout) Output Interval in milliseconds 250 */ 251 int getOutputInterval(); 252 253 /** 254 * Set the Interval (in ms) to wait between output commands. 255 * 256 * @param newInterval the new Output Interval in Milliseconds 257 */ 258 void setOutputInterval(int newInterval); 259 260 /** 261 * Get end time of latest OutputInterval, calculated from the current time. 262 * 263 * @return end time in milliseconds or current time if no interval was set or timer has completed 264 */ 265 @Nonnull 266 LocalDateTime outputIntervalEnds(); 267 268}