Class Block
- All Implemented Interfaces:
Comparable<NamedBean>,PropertyChangeProvider,NamedBean,PhysicalLocationReporter
- Direct Known Subclasses:
OBlock
A Block (at least in this implementation) corresponds exactly to the track covered by at most one sensor. That could be generalized in the future.
As trains move around the layout, a set of Block objects that are attached to sensors can interact to keep track of which train is where, going in which direction. As a result of this, the set of Block objects pass around "token" (value) Objects representing the trains. This could be e.g. a Throttle to control the train, or something else.
A block maintains a "direction" flag that is set from the direction of the incoming train. When an arriving train is detected via the connected sensor and the Block's status information is sufficient to determine that it is arriving via a particular Path, that Path's getFromBlockDirection becomes the direction of the train in this Block.
Optionally, a Block can be associated with a Reporter. In this case, the Reporter will provide the Block with the "token" (value). This could be e.g an RFID reader reading an ID tag attached to a locomotive. Depending on the specific Reporter implementation, either the current reported value or the last reported value will be relevant, this can be configured.
Objects of this class are Named Beans, so can be manipulated through tables, have listeners, etc.
The type letter used in the System Name is 'B' for 'Block'. The default implementation is not system-specific, so a system letter of 'I' is appropriate. This leads to system names like "IB201".
Issues:
- The tracking doesn't handle a train pulling in behind another well:
- When the 2nd train arrives, the Sensor is already active, so the value is unchanged (but the value can only be a single object anyway)
- When the 1st train leaves, the Sensor stays active, so the value remains that of the 1st train
- The assumption is that a train will only go through a set turnout. For example, a train could come into the turnout block from the main even if the turnout is set to the siding. (Ignoring those layouts where this would cause a short; it doesn't do so on all layouts)
- Does not handle closely-following trains where there is only one electrical block per signal. To do this, it probably needs some type of "assume a train doesn't back up" logic. A better solution is to have multiple sensors and Block objects between each signal head.
- If a train reverses in a block and goes back the way it came (e.g. b1 to b2 to b1), the block that's re-entered will get an updated direction, but the direction of this block (b2 in the example) is not updated. In other words, we're not noticing that the train must have reversed to go back out.
Do not assume that a Block object uniquely represents a piece of track. To allow independent development, it must be possible for multiple Block objects to take care of a particular section of track.
Possible state values:
- UNKNOWN - The sensor shows UNKNOWN, so this block doesn't know if it's occupied or not.
- INCONSISTENT - The sensor shows INCONSISTENT, so this block doesn't know if it's occupied or not.
- OCCUPIED - This sensor went active. Note that OCCUPIED will be set even if the logic is unable to figure out which value to take.
- UNOCCUPIED - No content, because the sensor has determined this block is unoccupied.
- UNDETECTED - No sensor configured.
Possible Curvature attributes (optional) User can set the curvature if desired for use in automatic running of trains, to indicate where slow down is required.
- NONE - No curvature in Block track, or Not entered.
- GRADUAL - Gradual curve - no action by engineer is warranted - full speed OK
- TIGHT - Tight curve in Block track - Train should slow down some
- SEVERE - Severe curve in Block track - Train should slow down a lot
The length of the block may also optionally be entered if desired. This attribute is for use in automatic running of trains. Length should be the actual length of model railroad track in the block. It is always stored here in millimeter units. A length of 0.0 indicates no entry of length by the user.
-
Nested Class Summary
Nested classes/interfaces inherited from interface jmri.NamedBean
NamedBean.BadNameException, NamedBean.BadSystemNameException, NamedBean.BadUserNameException, NamedBean.DisplayOptions, NamedBean.DuplicateSystemNameExceptionNested classes/interfaces inherited from interface jmri.PhysicalLocationReporter
PhysicalLocationReporter.Direction -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringProperty name change fired when the Block Curvature changes.static final StringProperty name change fired when the Block Length changes.static final StringProperty name change fired when the Block Permissive Status changes.static final StringProperty name change fired when a Sensor is set to / removed from a Block.static final StringProperty name change fired when the Block reporting Current flag changes.static final StringProperty name change fired when the Block Speed changes.static final StringProperty name change fired when the Block ghost Status changes.static final intGradual Curvature.static final intNo Curvature.static final StringProperty name change fired when a Sensor is set to / removed from a Block.static final intstatic final StringString constant for property changes to allocated.static final StringString constant for property changes to direction.static final StringString constant for property changes to value.static final intSevere Curvature.static final intTight Curvature.static final intUndetected status, i.e a "Dark" block.static final intFields inherited from class jmri.implementation.AbstractNamedBean
listenerRefs, mSystemName, registerFields inherited from interface jmri.NamedBean
DISPLAY_NAME_FORMAT, INCONSISTENT, PROPERTY_COMMENT, PROPERTY_ENABLED, PROPERTY_KNOWN_STATE, PROPERTY_STATE, PROPERTY_USERNAME, QUOTED_NAME_FORMAT, UNKNOWN -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidaddBlockDenyList(String pName) Add to the Block Deny List.voidaddBlockDenyList(Block blk) voidAdd a Path to List of Paths.describeState(int state) Provide human-readable, localized version of state value.booleanNote: this has to make choices about identity values (always the same) and operation values (can change as the block works).Find which path this Block became Active, without actually modifying the state of this block.For instances in the code where we are dealing with just a bean and a message needs to be passed to the user or in a log.intGet Block Curvature Constant.intGet Block Direction of Travel.getDirection(String rep) Parses out a (possibly old) LnReporter-generated report string to extract the direction from within it based on this object's protocol.booleanGet if Block is a ghost.floatGet Block Length in Centimetres.floatGet Block Length in Inches.floatGet Block Length in Millimetres.getLocoAddress(String rep) Parse a given string and return the LocoAddress value that is presumed stored within it based on this object's protocol.getPaths()Get a copy of the list of Paths.booleanGet if Block can have permissive working.Return this Block's physical location, if it exists.Return this Block's physical location, if it exists.Retrieve the Reporter that is linked to this BlockGet the Block Occupancy Sensor.floatintgetState()Get the Block State.getUsageReport(NamedBean bean) Get a list of references for the specified bean.getValue()Get the Block Contents Value.voidHandles Block sensor going ACTIVE: this block is now occupied, figure out from who and copy their value.voidHandles Block sensor going INACTIVE: this block is emptyvoidvoid(package private) voidHandle change in Reporter value.(package private) voidHandle change in sensor state.inthashCode()booleanCheck if Block has a particular Path.booleanisBlockDenied(String deny) booleanisBlockDenied(Block deny) booleanDetermine if the Block's value is being populated from thecurrent reportor from thelast report.voidvoidremoveBlockDenyList(Block blk) voidremovePath(Path p) Remove a Path from the Block.(package private) voidvoidsetAllocated(Boolean boo) This allows the layout block to inform any listeners to the block that the higher level layout block has been set to "useExtraColor" which is an indication that it has been allocated to a section by the AutoDispatcher.(package private) booleanvoidSet the Block Speed, preferred method.voidSet the Block Speed Name.voidsetCurvature(int c) Set Block Curvature Constant.voidsetDirection(int direction) Set Block Direction of Travel.voidsetIsGhost(boolean w) Set if the block is a ghost Fires propertyChange "BlockGhost" when changed.voidsetLength(float l) Set length in millimeters.voidSet Block Occupancy Sensor.voidsetPermissiveWorking(boolean w) Set Block as permissive.voidsetReporter(Reporter reporter) Set the Reporter that should provide the data value for this block.voidsetReportingCurrent(boolean reportingCurrent) Define if the Block's value should be populated from thecurrent reportor from thelast report.booleanSet the sensor by name.voidsetState(int v) Provide a general method for updating the report.voidSet the value retained by this Block.Create a Debug String, this should only be used for debugging...voidMethods inherited from class jmri.implementation.AbstractNamedBean
addPropertyChangeListener, addPropertyChangeListener, addPropertyChangeListener, addPropertyChangeListener, compareSystemNameSuffix, dispose, firePropertyChange, getComment, getDisplayName, getDisplayName, getListenerRef, getListenerRefs, getNumPropertyChangeListeners, getProperty, getPropertyChangeListeners, getPropertyChangeListeners, getPropertyChangeListenersByReference, getPropertyKeys, getSystemName, getUserName, removeProperty, removePropertyChangeListener, removePropertyChangeListener, setComment, setProperty, setUserName, toString, toStringSuffix, updateListenerRefMethods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, waitMethods inherited from interface jmri.NamedBean
compareTo, getRecommendedToolTip
-
Field Details
-
OCCUPIED
- See Also:
-
UNOCCUPIED
- See Also:
-
UNDETECTED
Undetected status, i.e a "Dark" block. A Block with unknown status could be waiting on feedback from a Sensor, hence undetected may be more appropriate if no Sensor.OBlocks use this constant in combination with other OBlock status flags. Block uses this constant as initial status, also when a Sensor is unset from the block.
- See Also:
-
NONE
No Curvature.- See Also:
-
GRADUAL
Gradual Curvature.- See Also:
-
TIGHT
Tight Curvature.- See Also:
-
SEVERE
Severe Curvature.- See Also:
-
OCC_SENSOR_CHANGE
Property name change fired when a Sensor is set to / removed from a Block. The fired event includes old value: Sensor Bean Object if previously set, else null new value: Sensor Bean Object if being set, may be null if Sensor removed.- See Also:
-
BLOCK_REPORTER_CHANGE
Property name change fired when a Sensor is set to / removed from a Block. The fired event includes old value: Sensor Bean Object if previously set, else null new value: Sensor Bean Object if being set, may be null if Sensor removed.- See Also:
-
BLOCK_REPORTING_CURRENT
Property name change fired when the Block reporting Current flag changes. The fired event includes old value: previous value, Boolean. new value: new value, Boolean.- See Also:
-
BLOCK_PERMISSIVE_CHANGE
Property name change fired when the Block Permissive Status changes. The fired event includes old value: previous permissive status. new value: new permissive status.- See Also:
-
GHOST_CHANGE
Property name change fired when the Block ghost Status changes. The fired event includes old value: previous ghost status. new value: new ghost status.- See Also:
-
BLOCK_SPEED_CHANGE
Property name change fired when the Block Speed changes. The fired event includes old value: previous speed String. new value: new speed String.- See Also:
-
BLOCK_CURVATURE_CHANGE
Property name change fired when the Block Curvature changes. The fired event includes old value: previous Block Curvature Constant. new value: new Block Curvature Constant.- See Also:
-
BLOCK_LENGTH_CHANGE
Property name change fired when the Block Length changes. The fired event includes old value: previous float length (mm). new value: new float length (mm).- See Also:
-
PROPERTY_VALUE
String constant for property changes to value.- See Also:
-
PROPERTY_DIRECTION
String constant for property changes to direction.- See Also:
-
PROPERTY_ALLOCATED
String constant for property changes to allocated.- See Also:
-
-
Constructor Details
-
Block
Create a new Block.- Parameters:
systemName- Block System Name.
-
Block
Create a new Block.- Parameters:
systemName- system name.userName- user name.
-
-
Method Details
-
toDebugString
Create a Debug String, this should only be used for debugging...- Returns:
- Block User name, System name, current state as string value.
-
setSensor
Set the sensor by name. Fires propertyChange "OccupancySensorChange" when changed.- Parameters:
pName- the name of the Sensor to set- Returns:
- true if a Sensor is set and is not null; false otherwise
-
setNamedSensor
Set Block Occupancy Sensor. If Sensor set, Adds PCL, sets Block Occupancy Status to Sensor. Block State PropertyChange Event will fire. Does NOT route initial Sensor Status via goingUnknown() / goingActive() etc.If Sensor null, removes PCL on previous Sensor, sets Block status to UNDETECTED.
- Parameters:
s- Handle for Sensor.
-
getSensor
Get the Block Occupancy Sensor.- Returns:
- Sensor if one attached to Block, may be null.
-
getNamedSensor
-
setReporter
Set the Reporter that should provide the data value for this block. Fires propertyChange "BlockReporterChange" when changed.- Parameters:
reporter- Reporter object to link, or null to clear- See Also:
-
getReporter
Retrieve the Reporter that is linked to this Block- Returns:
- linked Reporter object, or null if not linked
- See Also:
-
setReportingCurrent
Define if the Block's value should be populated from thecurrent reportor from thelast report. Fires propertyChange "BlockReportingCurrent" when changed.- Parameters:
reportingCurrent- true if to use current report; false if to use last report- See Also:
-
isReportingCurrent
Determine if the Block's value is being populated from thecurrent reportor from thelast report.- Returns:
- true if populated by
current report; false if fromlast report. - See Also:
-
getState
Get the Block State. OBlocks may well return a combination of states, Blocks will return a single State. -
addPath
Add a Path to List of Paths.- Parameters:
p- Path to add, not null.
-
removePath
Remove a Path from the Block.- Parameters:
p- Path to remove.
-
hasPath
Check if Block has a particular Path.- Parameters:
p- Path to test against.- Returns:
- true if Block has the Path, else false.
-
getPaths
Get a copy of the list of Paths.- Returns:
- the paths or an empty list
-
setState
Provide a general method for updating the report. Fires propertyChange "state" when called. -
setValue
Set the value retained by this Block. Also used when the Block itself gathers a value from an adjacent Block. This can be overridden in a subclass if e.g. you want to keep track of Blocks elsewhere, but make sure you also eventually invoke the super.setValue() here. Fires propertyChange "value" when changed.- Parameters:
value- The new Object resident in this block, or null if none
-
getValue
Get the Block Contents Value.- Returns:
- object with current value, could be null.
-
setDirection
Set Block Direction of Travel. Fires propertyChange "direction" when changed.- Parameters:
direction- Path Constant form, seePath.java
-
getDirection
Get Block Direction of Travel.- Returns:
- direction in Path Constant form, see
Path.java
-
addBlockDenyList
Add to the Block Deny List. The block deny list, is used by higher level code, to determine if traffic/trains should be allowed to enter from an attached block, the list only deals with blocks that access should be denied from.If we want to prevent traffic from following from this Block to another, then this Block must be added to the deny list of the other Block. By default no Block is barred, so traffic flow is bi-directional.
- Parameters:
pName- name of the block to add, which must exist
-
addBlockDenyList
-
removeBlockDenyList
-
removeBlockDenyList
-
getDeniedBlocks
-
isBlockDenied
-
isBlockDenied
-
getPermissiveWorking
Get if Block can have permissive working. Blocks default to non-permissive, i.e. false.- Returns:
- true if permissive, else false.
-
setPermissiveWorking
Set Block as permissive. Fires propertyChange "BlockPermissiveWorking" when changed.- Parameters:
w- true permissive, false NOT permissive
-
getIsGhost
Get if Block is a ghost. Blocks default to non-ghost, i.e. false.- Returns:
- true if ghost, else false.
-
setIsGhost
Set if the block is a ghost Fires propertyChange "BlockGhost" when changed.- Parameters:
w- true ghost, false NOT ghost
-
getSpeedLimit
-
getBlockSpeed
-
setBlockSpeedName
Set the Block Speed Name.Does not perform name validity checking. Does not send Property Change Event.
- Parameters:
s- new Speed Name String.
-
setBlockSpeed
Set the Block Speed, preferred method.Fires propertyChange "BlockSpeedChange" when changed.
- Parameters:
s- Speed String- Throws:
JmriException- if Value of requested block speed is not valid.
-
setCurvature
Set Block Curvature Constant. Valid values : Block.NONE, Block.GRADUAL, Block.TIGHT, Block.SEVERE Fires propertyChange "BlockCurvatureChange" when changed.- Parameters:
c- Constant, e.g. Block.GRADUAL
-
getCurvature
Get Block Curvature Constant. Defaults to Block.NONE- Returns:
- constant, e.g. Block.TIGHT
-
setLength
Set length in millimeters. Paths will inherit this length, if their length is not specifically set. This length is the maximum length of any Path in the block. Path lengths exceeding this will be set to the default length.Fires propertyChange "BlockLengthChange" when changed, float values in mm.
- Parameters:
l- length in millimeters
-
getLengthMm
Get Block Length in Millimetres. Default 0.0f.- Returns:
- length in mm.
-
getLengthCm
Get Block Length in Centimetres. Courtesy method using result from getLengthMm.- Returns:
- length in centimetres.
-
getLengthIn
Get Block Length in Inches. Courtesy method using result from getLengthMm.- Returns:
- length in inches.
-
equals
Note: this has to make choices about identity values (always the same) and operation values (can change as the block works). Might be missing some identity values.- Overrides:
equalsin classAbstractNamedBean- Parameters:
obj- the reference object with which to compare.- Returns:
trueif this object is the same as the obj argument;falseotherwise.
-
hashCode
Description copied from class:AbstractNamedBean- Overrides:
hashCodein classAbstractNamedBean- Returns:
- hash code value is based on the system name.
-
resetCandidateEntrancePaths
void resetCandidateEntrancePaths() -
setAsEntryBlockIfPossible
-
handleSensorChange
Handle change in sensor state.Defers real work to goingActive, goingInactive methods.
- Parameters:
e- the event
-
goingUnknown
-
goingInconsistent
-
handleReporterChange
Handle change in Reporter value.- Parameters:
e- PropertyChangeEvent
-
goingInactive
Handles Block sensor going INACTIVE: this block is empty -
goingActive
Handles Block sensor going ACTIVE: this block is now occupied, figure out from who and copy their value. -
findFromPath
Find which path this Block became Active, without actually modifying the state of this block.(this is largely a copy of the 'Search' part of the logic from goingActive())
- Returns:
- the next path
-
setAllocated
This allows the layout block to inform any listeners to the block that the higher level layout block has been set to "useExtraColor" which is an indication that it has been allocated to a section by the AutoDispatcher. The value set is not retained in any form by the block, it is purely to trigger a propertyChangeEvent.- Parameters:
boo- Allocation status
-
getLocoAddress
Parse a given string and return the LocoAddress value that is presumed stored within it based on this object's protocol. The Class Block implementation defers to its associated Reporter, if it exists.- Specified by:
getLocoAddressin interfacePhysicalLocationReporter- Parameters:
rep- String to be parsed- Returns:
- LocoAddress address parsed from string, or null if this Block isn't associated with a Reporter, or is associated with a Reporter that is not also a PhysicalLocationReporter
-
getDirection
Parses out a (possibly old) LnReporter-generated report string to extract the direction from within it based on this object's protocol. The Class Block implementation defers to its associated Reporter, if it exists.- Specified by:
getDirectionin interfacePhysicalLocationReporter- Parameters:
rep- String to be parsed- Returns:
- PhysicalLocationReporter.Direction direction parsed from string, or null if this Block isn't associated with a Reporter, or is associated with a Reporter that is not also a PhysicalLocationReporter
-
getPhysicalLocation
Return this Block's physical location, if it exists. Defers actual work to the helper methods in class PhysicalLocation.- Specified by:
getPhysicalLocationin interfacePhysicalLocationReporter- Returns:
- PhysicalLocation : this Block's location.
-
getPhysicalLocation
Return this Block's physical location, if it exists. Does not use the parameter s. Defers actual work to the helper methods in class PhysicalLocation- Specified by:
getPhysicalLocationin interfacePhysicalLocationReporter- Parameters:
s- (this parameter is ignored)- Returns:
- PhysicalLocation : this Block's location.
-
vetoableChange
Description copied from class:AbstractNamedBean- Specified by:
vetoableChangein interfaceNamedBean- Overrides:
vetoableChangein classAbstractNamedBean- Throws:
PropertyVetoException
-
getUsageReport
Description copied from interface:NamedBeanGet a list of references for the specified bean.- Specified by:
getUsageReportin interfaceNamedBean- Parameters:
bean- The bean to be checked.- Returns:
- a list of NamedBeanUsageReports or an empty ArrayList.
-
getBeanType
Description copied from interface:NamedBeanFor instances in the code where we are dealing with just a bean and a message needs to be passed to the user or in a log.- Specified by:
getBeanTypein interfaceNamedBean- Returns:
- a string of the bean type, eg Turnout, Sensor etc
-
describeState
Provide human-readable, localized version of state value.This method is intended for use when presenting to a human operator.
- Specified by:
describeStatein interfaceNamedBean- Overrides:
describeStatein classAbstractNamedBean- Parameters:
state- the state to describe- Returns:
- the state in localized form
-
