001package jmri;
002
003import java.util.EventListener;
004
005/**
006 * A listener interface for a class requesting a DccThrottle from the
007 * ThrottleManager.
008 * <p>
009 * Implementing classes used the methods here as part of the throttle request and initialization process as described shown in
010 * <img src="doc-files/ThrottleListener-Sequence.png" alt="Throttle initialization sequence UML diagram">
011 *
012 * <hr>
013 * This file is part of JMRI.
014 * <p>
015 * JMRI is free software; you can redistribute it and/or modify it under the
016 * terms of version 2 of the GNU General Public License as published by the Free
017 * Software Foundation. See the "COPYING" file for a copy of this license.
018 * <p>
019 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
020 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
021 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
022 *
023 * @author Bob Jacobsen Copyright (C) 2007
024 */
025public interface ThrottleListener extends EventListener {
026    
027    /**
028     * A decision type requested from ThrottleManager to ThrottleListener,
029     * or decision made from ThrottleListener to ThrottleManager
030     *
031     * @since 4.15.7
032     */
033    enum DecisionType {
034        /**
035         * Notification for decision needed, Steal OR Cancel, or wish to Steal
036         */
037        STEAL,
038        /**
039         * Notification for decision needed, Share OR Cancel, or wish to Share
040         */
041        SHARE,
042        /**
043         * Notification for decision needed, Steal OR Share OR Cancel
044         */
045        STEAL_OR_SHARE
046    }
047    
048    /**
049     * Get notification that a throttle has been found as requested.
050     *
051     * @param t the throttle with the requested address
052     */
053    public void notifyThrottleFound(DccThrottle t);
054
055    /**
056     * Get notification that an attempt to request a throttle has failed.
057     *
058     * @param address address of the failed request
059     * @param reason  failure cause
060     */
061    void notifyFailedThrottleRequest(LocoAddress address, String reason);
062    
063    /**
064     * Get notification that a throttle request is in use by another
065     * device, and a "steal", "share", or "steal/share" decision may be required.
066     *
067     * @param address The LocoAddress that needs the decision.
068     * @param question The question being asked, steal / cancel, share / cancel, steal / share / cancel
069     */
070    void notifyDecisionRequired(LocoAddress address, DecisionType question);
071
072}
073
074/*
075 * @startuml jmri/doc-files/ThrottleListener-Sequence.png
076 *  participant ThrottleListener
077 *  participant ThrottleManager
078 *  participant Throttle
079 * 
080 *  == Scenario 1: Quick Failure ==
081 *  ThrottleListener --> ThrottleManager : requestThrottle(address,ThrottleListener,*)
082 *  group If Throttle Request Cannot Continue
083 *      ThrottleListener <-- ThrottleManager : return false
084 *      note over ThrottleListener : Request ends here
085 *  end
086 *  == Scenario 2: Steal/Share not supported by the manager ==
087 *  ThrottleListener --> ThrottleManager : requestThrottle(address,ThrottleListener,*)
088 *  ThrottleListener <-- ThrottleManager : return true 
089 *  note over ThrottleListener: Wait for callback, see Common Process Completion
090 *
091 *  == Scenario 3: ThrottleListener asks ThrottleManager to handle steal/share decision. == 
092 *  
093 *     ThrottleListener --> ThrottleManager : requestThrottle(address,ThrottleListener,<b>false</b>)
094 *     ThrottleListener <-- ThrottleManager : return true 
095 *     note over ThrottleListener: Wait for callback, see Common Process Completion
096 *  == Scenario 4: ThrottleListener wants to make steal/share decision ==
097 *     ThrottleListener --> ThrottleManager : requestThrottle(address,ThrottleListener,<b>true</b>)
098 *     ThrottleListener <-- ThrottleManager : return true 
099 *     group Manager determines steal/share is required
100 *        group Case 1: Only steal is an option
101 *     
102 *           ThrottleListener <-- ThrottleManager : notifyDecisionRequired(LocoAddress, ThrottleListener.DecisionType.STEAL)
103 *        
104 *           group If the Listener chooses to steal
105 *               ThrottleListener --> ThrottleManager : responseThrottleDecision(LocoAddress, ThrottleListener, ThrottleListener.DecisionType.STEAL)
106 *           end
107 *        
108 *           group If the Listener chooses to cancel
109 *               ThrottleListener --> ThrottleManager : cancelThrottleRequest(LocoAddress, ThrottleListener)
110 *               note over ThrottleListener : Request ends here
111 *           end
112 *       end
113 *        
114 *       group Case 2: Only share is an option
115 *            ThrottleListener <-- ThrottleManager : notifyDecisionRequired(LocoAddress, ThrottleListener.DecisionType.SHARE)
116 *        
117 *            group If the Listener chooses to share
118 *               ThrottleListener --> ThrottleManager : responseThrottleDecision(LocoAddress, ThrottleListener, ThrottleListener.DecisionType.SHARE)
119 *            end
120 *        
121 *            group If the Listener chooses to cancel
122 *               ThrottleListener --> ThrottleManager : cancelThrottleRequest(LocoAddress, ThrottleListener)
123 *               note over ThrottleListener : Request ends here
124 *            end        
125         end
126
127 *       group Case 3: steal and share are options
128 *            ThrottleListener <-- ThrottleManager : notifyDecisionRequired(LocoAddress, ThrottleListener.DecisionType.STEAL_OR_SHARE)
129 *        
130 *            group If the Listener chooses to steal
131 *               ThrottleListener --> ThrottleManager : responseThrottleDecision(LocoAddress, ThrottleListener, ThrottleListener.DecisionType.STEAL)
132 *            end
133 *        
134 *            group If the Listener chooses to share
135 *               ThrottleListener --> ThrottleManager : responseThrottleDecision(LocoAddress, ThrottleListener, ThrottleListener.DecisionType.SHARE)
136 *            end
137 *        
138 *            group If the Listener chooses to cancel
139 *               ThrottleListener --> ThrottleManager : cancelThrottleRequest(LocoAddress, ThrottleListener)
140 *               note over ThrottleListener : Request ends here
141 *            end
142        end
143 *  end
144 *  note over ThrottleListener: Wait for callback, see Common Process Completion
145 *    == Common Process Completion ==
146 *    group If Throttle Does Not Exist 
147 *    == Throttle Creation  ==
148 *       ThrottleManager --> Throttle: new Throttle(address)
149 *       group If the Throttle creation fails
150 *          ThrottleListener <-- ThrottleManager: notifyFailedThrottleReqest(address)
151 *          note over ThrottleListener : Request ends here
152 *       end                    
153 *       group If the Throttle creation succeeds
154 *         ThrottleManager <-- Throttle: return Throttle        
155 *       end
156 *    end
157 *    ThrottleListener <-- ThrottleManager: notifyThrottleFound(Throttle)
158 *    note over ThrottleListener : Throttle can now be controlled by ThrottleListener or a delegate.
159 *  
160 * @enduml
161 */