Class SprogCommandStation
- java.lang.Object
-
- jmri.jmrix.sprog.SprogCommandStation
-
- All Implemented Interfaces:
java.beans.PropertyChangeListener
,java.lang.Runnable
,java.util.EventListener
,CommandStation
,SprogListener
public class SprogCommandStation extends java.lang.Object implements CommandStation, SprogListener, java.lang.Runnable, java.beans.PropertyChangeListener
Control a collection of slots, acting as a soft command station for SPROGA SlotListener can register to hear changes. By registering here, the SlotListener is saying that it wants to be notified of a change in any slot. Alternately, the SlotListener can register with some specific slot, done via the SprogSlot object itself.
This Programmer implementation is single-user only. It's not clear whether the command stations can have multiple programming requests outstanding (e.g. service mode and ops mode, or two ops mode) at the same time, but this code definitely can't.
Updated by Andrew Berridge, January 2010 - state management code now safer, uses enum, etc. Amalgamated with Sprog Slot Manager into a single class - reduces code duplication.
Updated by Andrew Crosland February 2012 to allow slots to hold 28 step speed packets
Re-written by Andrew Crosland to send the next packet as soon as a reply is notified. This removes a race between the old state machine running before the traffic controller despatches a reply, missing the opportunity to send a new packet to the layout until the next JVM time slot, which can be 15ms on Windows platforms.
May-17 Moved status reply handling to the slot monitor. Monitor messages from other sources and suppress messages from here to prevent queueing messages in the traffic controller.
Jan-18 Re-written again due to threading issues. Previous changes removed activity from the slot thread, which could result in loading the swing thread to the extent that the gui becomes very slow to respond. Moved status message generation to the slot monitor. Interact with power control as a way to allow the user to recover after a timeout error due to loss of communication with the hardware.
-
-
Field Summary
Fields Modifier and Type Field Description (package private) SprogSystemConnectionMemo
adaptermemo
protected int
currentSlot
protected int
currentSprogAddress
(package private) java.lang.Object
lock
protected int
numSlots
(package private) boolean
powerChanged
(package private) PowerManager
powerMgr
(package private) int
powerState
protected java.util.Queue<SprogSlot>
sendNow
protected java.util.LinkedList<SprogSlot>
slots
-
Constructor Summary
Constructors Constructor Description SprogCommandStation(SprogTrafficController controller)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
addSlotListener(SprogSlotListener l)
void
estopAll()
Send emergency stop to all slots.protected void
eStopSlot(SprogSlot s)
Send emergency stop to a slot.protected SprogSlot
findFree()
Find a free slot entry.void
forwardCommandChangeToLayout(int address, boolean closed)
void
function0Through4Packet(DccLocoAddress address, boolean f0, boolean f0Momentary, boolean f1, boolean f1Momentary, boolean f2, boolean f2Momentary, boolean f3, boolean f3Momentary, boolean f4, boolean f4Momentary)
void
function13Through20Packet(DccLocoAddress address, boolean f13, boolean f13Momentary, boolean f14, boolean f14Momentary, boolean f15, boolean f15Momentary, boolean f16, boolean f16Momentary, boolean f17, boolean f17Momentary, boolean f18, boolean f18Momentary, boolean f19, boolean f19Momentary, boolean f20, boolean f20Momentary)
void
function21Through28Packet(DccLocoAddress address, boolean f21, boolean f21Momentary, boolean f22, boolean f22Momentary, boolean f23, boolean f23Momentary, boolean f24, boolean f24Momentary, boolean f25, boolean f25Momentary, boolean f26, boolean f26Momentary, boolean f27, boolean f27Momentary, boolean f28, boolean f28Momentary)
void
function29Through36Packet(DccLocoAddress address, boolean a, boolean am, boolean b, boolean bm, boolean c, boolean cm, boolean d, boolean dm, boolean e, boolean em, boolean f, boolean fm, boolean g, boolean gm, boolean h, boolean hm)
void
function37Through44Packet(DccLocoAddress address, boolean a, boolean am, boolean b, boolean bm, boolean c, boolean cm, boolean d, boolean dm, boolean e, boolean em, boolean f, boolean fm, boolean g, boolean gm, boolean h, boolean hm)
void
function45Through52Packet(DccLocoAddress address, boolean a, boolean am, boolean b, boolean bm, boolean c, boolean cm, boolean d, boolean dm, boolean e, boolean em, boolean f, boolean fm, boolean g, boolean gm, boolean h, boolean hm)
void
function53Through60Packet(DccLocoAddress address, boolean a, boolean am, boolean b, boolean bm, boolean c, boolean cm, boolean d, boolean dm, boolean e, boolean em, boolean f, boolean fm, boolean g, boolean gm, boolean h, boolean hm)
void
function5Through8Packet(DccLocoAddress address, boolean f5, boolean f5Momentary, boolean f6, boolean f6Momentary, boolean f7, boolean f7Momentary, boolean f8, boolean f8Momentary)
void
function61Through68Packet(DccLocoAddress address, boolean a, boolean am, boolean b, boolean bm, boolean c, boolean cm, boolean d, boolean dm, boolean e, boolean em, boolean f, boolean fm, boolean g, boolean gm, boolean h, boolean hm)
void
function9Through12Packet(DccLocoAddress address, boolean f9, boolean f9Momentary, boolean f10, boolean f10Momentary, boolean f11, boolean f11Momentary, boolean f12, boolean f12Momentary)
int
getInUseCount()
Provide a count of the slots in use.java.lang.String
getSystemPrefix()
Get system prefix.java.lang.String
getUserName()
Get user name.boolean
isBusy()
void
notifyMessage(SprogMessage m)
void
notifyReply(SprogReply m)
Handle replies.SprogSlot
opsModepacket(int address, boolean longAddr, int cv, int val)
void
propertyChange(java.beans.PropertyChangeEvent evt)
implement a property change listener for powervoid
release(DccLocoAddress address)
void
removeSlotListener(SprogSlotListener l)
void
run()
protected void
sendMessage(SprogMessage m)
Send the SprogMessage to the hardware.boolean
sendPacket(byte[] packet, int repeats)
Send a specific packet as a SprogMessage.void
setPowerState(boolean powerOption)
Set initial power state If connection option is set for track power on the property change is sent before we are registered with the power manager so force a change in the slot threadvoid
setSpeed(SpeedStepMode mode, DccLocoAddress address, int spd, boolean isForward)
Handle speed changes from throttle.void
setSystemConnectionMemo(SprogSystemConnectionMemo memo)
SprogSlot
slot(int i)
Return contents of Queue slot i.-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface jmri.CommandStation
sendAccSignalDecoderPkt, sendAltAccSignalDecoderPkt
-
-
-
-
Field Detail
-
currentSlot
protected int currentSlot
-
currentSprogAddress
protected int currentSprogAddress
-
numSlots
protected int numSlots
-
lock
final java.lang.Object lock
-
powerMgr
PowerManager powerMgr
-
powerState
int powerState
-
powerChanged
boolean powerChanged
-
adaptermemo
SprogSystemConnectionMemo adaptermemo
-
-
Constructor Detail
-
SprogCommandStation
public SprogCommandStation(SprogTrafficController controller)
-
-
Method Detail
-
sendPacket
public boolean sendPacket(byte[] packet, int repeats)
Send a specific packet as a SprogMessage.- Specified by:
sendPacket
in interfaceCommandStation
- Parameters:
packet
- Byte array representing the packet, including the error-correction byte. Must not be null.repeats
- number of times to repeat the packet- Returns:
true
if the operation succeeds,false
otherwise.
-
sendMessage
protected void sendMessage(SprogMessage m)
Send the SprogMessage to the hardware.sendSprogMessage will block until the message can be sent. When it returns we set the reply status for the message just sent.
- Parameters:
m
- The message to be sent
-
slot
public SprogSlot slot(int i)
Return contents of Queue slot i.- Parameters:
i
- int of slot requested- Returns:
- SprogSlot slot i
-
findFree
protected SprogSlot findFree()
Find a free slot entry.- Returns:
- SprogSlot the next free Slot or null if all slots are full
-
forwardCommandChangeToLayout
public void forwardCommandChangeToLayout(int address, boolean closed)
-
function0Through4Packet
public void function0Through4Packet(DccLocoAddress address, boolean f0, boolean f0Momentary, boolean f1, boolean f1Momentary, boolean f2, boolean f2Momentary, boolean f3, boolean f3Momentary, boolean f4, boolean f4Momentary)
-
function5Through8Packet
public void function5Through8Packet(DccLocoAddress address, boolean f5, boolean f5Momentary, boolean f6, boolean f6Momentary, boolean f7, boolean f7Momentary, boolean f8, boolean f8Momentary)
-
function9Through12Packet
public void function9Through12Packet(DccLocoAddress address, boolean f9, boolean f9Momentary, boolean f10, boolean f10Momentary, boolean f11, boolean f11Momentary, boolean f12, boolean f12Momentary)
-
function13Through20Packet
public void function13Through20Packet(DccLocoAddress address, boolean f13, boolean f13Momentary, boolean f14, boolean f14Momentary, boolean f15, boolean f15Momentary, boolean f16, boolean f16Momentary, boolean f17, boolean f17Momentary, boolean f18, boolean f18Momentary, boolean f19, boolean f19Momentary, boolean f20, boolean f20Momentary)
-
function21Through28Packet
public void function21Through28Packet(DccLocoAddress address, boolean f21, boolean f21Momentary, boolean f22, boolean f22Momentary, boolean f23, boolean f23Momentary, boolean f24, boolean f24Momentary, boolean f25, boolean f25Momentary, boolean f26, boolean f26Momentary, boolean f27, boolean f27Momentary, boolean f28, boolean f28Momentary)
-
function29Through36Packet
public void function29Through36Packet(DccLocoAddress address, boolean a, boolean am, boolean b, boolean bm, boolean c, boolean cm, boolean d, boolean dm, boolean e, boolean em, boolean f, boolean fm, boolean g, boolean gm, boolean h, boolean hm)
-
function37Through44Packet
public void function37Through44Packet(DccLocoAddress address, boolean a, boolean am, boolean b, boolean bm, boolean c, boolean cm, boolean d, boolean dm, boolean e, boolean em, boolean f, boolean fm, boolean g, boolean gm, boolean h, boolean hm)
-
function45Through52Packet
public void function45Through52Packet(DccLocoAddress address, boolean a, boolean am, boolean b, boolean bm, boolean c, boolean cm, boolean d, boolean dm, boolean e, boolean em, boolean f, boolean fm, boolean g, boolean gm, boolean h, boolean hm)
-
function53Through60Packet
public void function53Through60Packet(DccLocoAddress address, boolean a, boolean am, boolean b, boolean bm, boolean c, boolean cm, boolean d, boolean dm, boolean e, boolean em, boolean f, boolean fm, boolean g, boolean gm, boolean h, boolean hm)
-
function61Through68Packet
public void function61Through68Packet(DccLocoAddress address, boolean a, boolean am, boolean b, boolean bm, boolean c, boolean cm, boolean d, boolean dm, boolean e, boolean em, boolean f, boolean fm, boolean g, boolean gm, boolean h, boolean hm)
-
setSpeed
public void setSpeed(SpeedStepMode mode, DccLocoAddress address, int spd, boolean isForward)
Handle speed changes from throttle.As well as updating an existing slot, or creating a new on where necessary, the speed command is added to the queue of packets to be sent immediately.This ensures minimum latency between the user adjusting the throttle and a loco responding, rather than possibly waiting for a complete traversal of all slots before the new speed is actually sent to the hardware.
- Parameters:
mode
- speed step mode.address
- loco address.spd
- speed to send.isForward
- true if forward, else false.
-
opsModepacket
public SprogSlot opsModepacket(int address, boolean longAddr, int cv, int val)
-
release
public void release(DccLocoAddress address)
-
estopAll
public void estopAll()
Send emergency stop to all slots.
-
eStopSlot
protected void eStopSlot(SprogSlot s)
Send emergency stop to a slot.- Parameters:
s
- SprogSlot to eStop
-
addSlotListener
public void addSlotListener(SprogSlotListener l)
-
removeSlotListener
public void removeSlotListener(SprogSlotListener l)
-
setPowerState
public void setPowerState(boolean powerOption)
Set initial power state If connection option is set for track power on the property change is sent before we are registered with the power manager so force a change in the slot thread- Parameters:
powerOption
- true if power on at startup
-
run
public void run()
- Specified by:
run
in interfacejava.lang.Runnable
-
notifyMessage
public void notifyMessage(SprogMessage m)
- Specified by:
notifyMessage
in interfaceSprogListener
-
notifyReply
public void notifyReply(SprogReply m)
Handle replies.Handle replies from the hardware, ignoring those that were not sent from the command station.
- Specified by:
notifyReply
in interfaceSprogListener
- Parameters:
m
- The SprogReply to be handled
-
propertyChange
public void propertyChange(java.beans.PropertyChangeEvent evt)
implement a property change listener for power- Specified by:
propertyChange
in interfacejava.beans.PropertyChangeListener
-
getInUseCount
public int getInUseCount()
Provide a count of the slots in use.- Returns:
- the number of slots in use
-
isBusy
public boolean isBusy()
- Returns:
- a boolean if the command station is busy - i.e. it has at least one occupied slot
-
setSystemConnectionMemo
public void setSystemConnectionMemo(SprogSystemConnectionMemo memo)
-
getUserName
public java.lang.String getUserName()
Get user name.- Specified by:
getUserName
in interfaceCommandStation
- Returns:
- the user name
-
getSystemPrefix
public java.lang.String getSystemPrefix()
Get system prefix.- Specified by:
getSystemPrefix
in interfaceCommandStation
- Returns:
- the system prefix
-
-