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 * String constant for Property Change to Default Turnout Thrown Speed Change. 048 */ 049 String PROPERTY_DEFAULT_THROWN_SPEED = "DefaultTurnoutThrownSpeedChange"; 050 051 /** 052 * String constant for Property Change to Default Turnout Closed Speed Change. 053 */ 054 String PROPERTY_DEFAULT_CLOSED_SPEED = "DefaultTurnoutClosedSpeedChange"; 055 056 /** 057 * Get the Turnout with the user name, then system name if needed; if that fails, create a 058 * new Turnout. 059 * If the name is a valid system name, it will be used for the new Turnout. 060 * Otherwise, the {@link Manager#makeSystemName} method will attempt to turn it 061 * into a valid system name. 062 * <p> 063 * This provides the same function as {@link ProvidingManager#provide} 064 * which has a more generic form. 065 * 066 * @param name User name, system name, or address which can be promoted to 067 * system name 068 * @return Never null 069 * @throws IllegalArgumentException if Turnout doesn't already exist and the 070 * manager cannot create the Turnout due to 071 * an illegal name or name that can't 072 * be parsed. 073 */ 074 @Nonnull 075 Turnout provideTurnout(@Nonnull String name) throws IllegalArgumentException; 076 077 /** {@inheritDoc} */ 078 @Override 079 @Nonnull 080 default Turnout provide(@Nonnull String name) throws IllegalArgumentException { return provideTurnout(name); } 081 082 /** 083 * Get an existing Turnout or return null if it doesn't exist. 084 * 085 * Locates via user name, then system name if needed. 086 * 087 * @param name User name or system name to match 088 * @return null if no match found 089 */ 090 @CheckForNull 091 Turnout getTurnout(@Nonnull String name); 092 093 /** 094 * Get the Turnout with the given system name or null if no instance 095 * already exists. 096 * 097 * @param systemName the system name 098 * @return requested Turnout object or null if none exists 099 */ 100 @CheckForNull 101 @Override 102 Turnout getBySystemName(@Nonnull String systemName); 103 104 /** 105 * Get the Turnout with the given user name or null if no instance 106 * already exists. 107 * 108 * @param userName the user name 109 * @return requested Turnout object or null if none exists 110 */ 111 @CheckForNull 112 @Override 113 Turnout getByUserName(@Nonnull String userName); 114 115 /** 116 * Return a Turnout with the specified system and user names. 117 * Lookup by UserName then provide by System Name. 118 * <p> 119 * Note that 120 * two calls with the same arguments will get the same instance; there is 121 * only one Turnout object representing a given physical turnout and 122 * therefore only one with a specific system or user name. 123 * <p> 124 * This will always return a valid object reference; a new object will be 125 * created if necessary. In that case: 126 * <ul> 127 * <li>If a null reference is given for user name, no user name will be 128 * associated with the Turnout object created; a valid system name must be 129 * provided 130 * <li>If both names are provided, the system name defines the hardware 131 * access of the desired turnout, and the user address is associated with 132 * it. The system name must be valid. 133 * </ul> 134 * Note that it is possible to make an inconsistent request if both 135 * addresses are provided, but the given values are associated with 136 * different objects. This is a problem, and we don't have a good solution 137 * except to issue warnings. This will mostly happen if you're creating 138 * Turnouts when you should be looking them up. 139 * 140 * @param systemName the system name 141 * @param userName the user name (optional) 142 * @return requested Turnout object, newly created if needed 143 * @throws IllegalArgumentException if cannot create the Turnout; likely due 144 * to an illegal name or name that cannot 145 * be parsed 146 */ 147 @Nonnull 148 Turnout newTurnout(@Nonnull String systemName, @CheckForNull String userName) throws IllegalArgumentException; 149 150 /** 151 * Get text to be used for the Turnout.CLOSED state in user communication. 152 * Allows text other than "CLOSED" to be used with certain hardware system 153 * to represent the Turnout.CLOSED state. 154 * 155 * @return the textual representation of {@link jmri.Turnout#CLOSED} 156 */ 157 @Nonnull 158 String getClosedText(); 159 160 /** 161 * Get text to be used for the Turnout.THROWN state in user communication. 162 * Allows text other than "THROWN" to be use with certain hardware system to 163 * represent the Turnout.THROWN state. 164 * 165 * @return the textual representation of {@link jmri.Turnout#THROWN} 166 */ 167 @Nonnull 168 String getThrownText(); 169 170 /** 171 * Get a list of the valid TurnoutOperation subtypes for use with turnouts 172 * of this system. 173 * 174 * @return a list of subtypes or an empty list if turnout operations are not 175 * supported 176 */ 177 @Nonnull 178 String[] getValidOperationTypes(); 179 180 /** 181 * Get, from the user, the number of addressed bits used to control a 182 * turnout. Normally this is 1, and the default routine returns one 183 * automatically. Turnout Managers for systems that can handle multiple 184 * control bits should override this method with one which asks the user to 185 * specify the number of control bits. If the user specifies more than one 186 * control bit, this method should check if the additional bits are 187 * available (not assigned to another object). If the bits are not 188 * available, this method should return 0 for number of control bits, after 189 * informing the user of the problem. 190 * 191 * @param systemName the turnout system name 192 * @return the bit length for turnout control 193 */ 194 int askNumControlBits(@Nonnull String systemName); 195 196 /** 197 * Determine if the manager supports multiple control bits, as 198 * {@link #askNumControlBits(java.lang.String)} will always return a value 199 * even if it is not supported. 200 * 201 * @param systemName the turnout system name 202 * @return true if manager supports multiple control bits for the turnout; 203 * false otherwise 204 */ 205 boolean isNumControlBitsSupported(@Nonnull String systemName); 206 207 /** 208 * Get, from the user, the type of output to be used bits to control a 209 * turnout. Normally this is 0 for 'steady state' control, and the default 210 * routine returns 0 automatically. Turnout Managers for systems that can 211 * handle pulsed control as well as steady state control should override 212 * this method with one which asks the user to specify the type of control 213 * to be used. The routine should return 0 for 'steady state' control, or n 214 * for 'pulsed' control, where n specifies the duration of the pulse 215 * (normally in seconds). 216 * 217 * @param systemName the turnout system name 218 * @return 0 for steady state or the number of seconds for a pulse control 219 */ 220 int askControlType(@Nonnull String systemName); 221 222 /** 223 * Determine if the manager supports the handling of pulsed and steady state 224 * control as the {@link #askControlType(java.lang.String)} will always 225 * return a value even if it is not supported. 226 * 227 * @param systemName the turnout system name 228 * @return true if manager supports the control type returned by 229 * {@link #askControlType(java.lang.String)}; false otherwise 230 * 231 */ 232 boolean isControlTypeSupported(@Nonnull String systemName); 233 234 /** 235 * Get a system name for a given hardware address and system prefix. 236 * 237 * @param curAddress desired hardware address 238 * @param prefix system prefix used in system name 239 * @return the complete turnout system name for the prefix and current 240 * address 241 * @throws jmri.JmriException if unable to create a system name for the 242 * given address, possibly due to invalid address 243 * format 244 */ 245 String createSystemName(@Nonnull String curAddress, @Nonnull String prefix) throws JmriException; 246 247 void setDefaultClosedSpeed(@Nonnull String speed) throws JmriException; 248 249 void setDefaultThrownSpeed(@Nonnull String speed) throws JmriException; 250 251 String getDefaultThrownSpeed(); 252 253 String getDefaultClosedSpeed(); 254 255 /** 256 * Get the Interval (in ms) to wait between output commands. 257 * Configured in AdapterConfig, stored in memo. 258 * 259 * @return the (Turnout) Output Interval in milliseconds 260 */ 261 int getOutputInterval(); 262 263 /** 264 * Set the Interval (in ms) to wait between output commands. 265 * 266 * @param newInterval the new Output Interval in Milliseconds 267 */ 268 void setOutputInterval(int newInterval); 269 270 /** 271 * Get end time of latest OutputInterval, calculated from the current time. 272 * 273 * @return end time in milliseconds or current time if no interval was set or timer has completed 274 */ 275 @Nonnull 276 LocalDateTime outputIntervalEnds(); 277 278}