diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs | 124 |
1 files changed, 97 insertions, 27 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs index d0cab49..24d81d9 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs | |||
@@ -51,8 +51,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
51 | /// This is a state machine. | 51 | /// This is a state machine. |
52 | /// | 52 | /// |
53 | /// [Entry] => Preparing | 53 | /// [Entry] => Preparing |
54 | /// Preparing => { Transferring || CleaningUp || [Exit] } | 54 | /// Preparing => { Transferring || Cancelling || CleaningUp || [Exit] } |
55 | /// Transferring => { ReceivedAtDestination || CleaningUp } | 55 | /// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp } |
56 | /// Cancelling => CleaningUp | ||
56 | /// ReceivedAtDestination => CleaningUp | 57 | /// ReceivedAtDestination => CleaningUp |
57 | /// CleaningUp => [Exit] | 58 | /// CleaningUp => [Exit] |
58 | /// | 59 | /// |
@@ -64,7 +65,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
64 | Preparing, // The agent is being prepared for transfer | 65 | Preparing, // The agent is being prepared for transfer |
65 | Transferring, // The agent is in the process of being transferred to a destination | 66 | Transferring, // The agent is in the process of being transferred to a destination |
66 | ReceivedAtDestination, // The destination has notified us that the agent has been successfully received | 67 | ReceivedAtDestination, // The destination has notified us that the agent has been successfully received |
67 | CleaningUp // The agent is being changed to child/removed after a transfer | 68 | CleaningUp, // The agent is being changed to child/removed after a transfer |
69 | Cancelling // The user has cancelled the teleport but we have yet to act upon this. | ||
68 | } | 70 | } |
69 | 71 | ||
70 | /// <summary> | 72 | /// <summary> |
@@ -115,42 +117,110 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
115 | /// <param name='newState'></param> | 117 | /// <param name='newState'></param> |
116 | /// <returns></returns> | 118 | /// <returns></returns> |
117 | /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception> | 119 | /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception> |
118 | internal void UpdateInTransit(UUID id, AgentTransferState newState) | 120 | internal bool UpdateInTransit(UUID id, AgentTransferState newState) |
119 | { | 121 | { |
122 | bool transitionOkay = false; | ||
123 | |||
124 | // We don't want to throw an exception on cancel since this can come it at any time. | ||
125 | bool failIfNotOkay = true; | ||
126 | |||
127 | // Should be a failure message if failure is not okay. | ||
128 | string failureMessage = null; | ||
129 | |||
130 | AgentTransferState? oldState = null; | ||
131 | |||
120 | lock (m_agentsInTransit) | 132 | lock (m_agentsInTransit) |
121 | { | 133 | { |
122 | // Illegal to try and update an agent that's not actually in transit. | 134 | // Illegal to try and update an agent that's not actually in transit. |
123 | if (!m_agentsInTransit.ContainsKey(id)) | 135 | if (!m_agentsInTransit.ContainsKey(id)) |
124 | throw new Exception( | 136 | { |
125 | string.Format( | 137 | if (newState != AgentTransferState.Cancelling) |
126 | "Agent with ID {0} is not registered as in transit in {1}", | 138 | failureMessage = string.Format( |
127 | id, m_mod.Scene.RegionInfo.RegionName)); | 139 | "Agent with ID {0} is not registered as in transit in {1}", |
128 | 140 | id, m_mod.Scene.RegionInfo.RegionName); | |
129 | AgentTransferState oldState = m_agentsInTransit[id]; | 141 | else |
142 | failIfNotOkay = false; | ||
143 | } | ||
144 | else | ||
145 | { | ||
146 | oldState = m_agentsInTransit[id]; | ||
130 | 147 | ||
131 | bool transitionOkay = false; | 148 | if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) |
149 | { | ||
150 | transitionOkay = true; | ||
151 | } | ||
152 | else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing) | ||
153 | { | ||
154 | transitionOkay = true; | ||
155 | } | ||
156 | else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring) | ||
157 | { | ||
158 | transitionOkay = true; | ||
159 | } | ||
160 | else | ||
161 | { | ||
162 | if (newState == AgentTransferState.Cancelling | ||
163 | && (oldState == AgentTransferState.Preparing || oldState == AgentTransferState.Transferring)) | ||
164 | { | ||
165 | transitionOkay = true; | ||
166 | } | ||
167 | else | ||
168 | { | ||
169 | failIfNotOkay = false; | ||
170 | } | ||
171 | } | ||
132 | 172 | ||
133 | if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) | 173 | if (!transitionOkay) |
134 | transitionOkay = true; | 174 | failureMessage |
135 | else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing) | 175 | = string.Format( |
136 | transitionOkay = true; | 176 | "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}", |
137 | else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring) | 177 | id, oldState, newState, m_mod.Scene.RegionInfo.RegionName); |
138 | transitionOkay = true; | 178 | } |
139 | 179 | ||
140 | if (transitionOkay) | 180 | if (transitionOkay) |
181 | { | ||
141 | m_agentsInTransit[id] = newState; | 182 | m_agentsInTransit[id] = newState; |
142 | else | 183 | |
143 | throw new Exception( | 184 | // m_log.DebugFormat( |
144 | string.Format( | 185 | // "[ENTITY TRANSFER STATE MACHINE]: Changed agent with id {0} from state {1} to {2} in {3}", |
145 | "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}", | 186 | // id, oldState, newState, m_mod.Scene.Name); |
146 | id, oldState, newState, m_mod.Scene.RegionInfo.RegionName)); | 187 | } |
188 | else if (failIfNotOkay) | ||
189 | { | ||
190 | throw new Exception(failureMessage); | ||
191 | } | ||
192 | // else | ||
193 | // { | ||
194 | // if (oldState != null) | ||
195 | // m_log.DebugFormat( | ||
196 | // "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} from state {1} to {2} in {3}", | ||
197 | // id, oldState, newState, m_mod.Scene.Name); | ||
198 | // else | ||
199 | // m_log.DebugFormat( | ||
200 | // "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} to state {1} in {2} since agent not in transit", | ||
201 | // id, newState, m_mod.Scene.Name); | ||
202 | // } | ||
147 | } | 203 | } |
204 | |||
205 | return transitionOkay; | ||
148 | } | 206 | } |
149 | 207 | ||
150 | internal bool IsInTransit(UUID id) | 208 | /// <summary> |
209 | /// Gets the current agent transfer state. | ||
210 | /// </summary> | ||
211 | /// <returns>Null if the agent is not in transit</returns> | ||
212 | /// <param name='id'> | ||
213 | /// Identifier. | ||
214 | /// </param> | ||
215 | internal AgentTransferState? GetAgentTransferState(UUID id) | ||
151 | { | 216 | { |
152 | lock (m_agentsInTransit) | 217 | lock (m_agentsInTransit) |
153 | return m_agentsInTransit.ContainsKey(id); | 218 | { |
219 | if (!m_agentsInTransit.ContainsKey(id)) | ||
220 | return null; | ||
221 | else | ||
222 | return m_agentsInTransit[id]; | ||
223 | } | ||
154 | } | 224 | } |
155 | 225 | ||
156 | /// <summary> | 226 | /// <summary> |
@@ -203,14 +273,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
203 | 273 | ||
204 | lock (m_agentsInTransit) | 274 | lock (m_agentsInTransit) |
205 | { | 275 | { |
206 | if (!IsInTransit(id)) | 276 | AgentTransferState? currentState = GetAgentTransferState(id); |
277 | |||
278 | if (currentState == null) | ||
207 | throw new Exception( | 279 | throw new Exception( |
208 | string.Format( | 280 | string.Format( |
209 | "Asked to wait for destination callback for agent with ID {0} in {1} but agent is not in transit", | 281 | "Asked to wait for destination callback for agent with ID {0} in {1} but agent is not in transit", |
210 | id, m_mod.Scene.RegionInfo.RegionName)); | 282 | id, m_mod.Scene.RegionInfo.RegionName)); |
211 | 283 | ||
212 | AgentTransferState currentState = m_agentsInTransit[id]; | ||
213 | |||
214 | if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination) | 284 | if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination) |
215 | throw new Exception( | 285 | throw new Exception( |
216 | string.Format( | 286 | string.Format( |