A workaround for the state change problem described best here http://opensimulator.org/mantis/view.php?id=6960 which should make state changes behave more like is described here http://wiki.secondlife.com/wiki/State

inv-download
Bob Shaffer II 2015-02-18 15:01:13 +01:00 committed by Justin Clark-Casey (justincc)
parent 80936fb4c5
commit b4b13510e8
1 changed files with 22 additions and 1 deletions

View File

@ -82,6 +82,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
private int m_ControlEventsInQueue; private int m_ControlEventsInQueue;
private int m_LastControlLevel; private int m_LastControlLevel;
private bool m_CollisionInQueue; private bool m_CollisionInQueue;
private bool m_StateChangeInProgress;
// The following is for setting a minimum delay between events // The following is for setting a minimum delay between events
private double m_minEventDelay; private double m_minEventDelay;
@ -210,6 +211,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public void ClearQueue() public void ClearQueue()
{ {
m_TimerQueued = false; m_TimerQueued = false;
m_StateChangeInProgress = false;
EventQueue.Clear(); EventQueue.Clear();
} }
@ -617,12 +619,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
if (state == State) if (state == State)
return; return;
// Remove all queued events, remembering the last timer event
EventParams lastTimerEv = null;
while (EventQueue.Count > 0)
{
EventParams tempv = (EventParams)EventQueue.Dequeue();
if (tempv.EventName == "timer") lastTimerEv = tempv;
}
// Post events
PostEvent(new EventParams("state_exit", new Object[0], PostEvent(new EventParams("state_exit", new Object[0],
new DetectParams[0])); new DetectParams[0]));
PostEvent(new EventParams("state", new Object[] { state }, PostEvent(new EventParams("state", new Object[] { state },
new DetectParams[0])); new DetectParams[0]));
PostEvent(new EventParams("state_entry", new Object[0], PostEvent(new EventParams("state_entry", new Object[0],
new DetectParams[0])); new DetectParams[0]));
// Requeue the timer event after the state changing events
if (lastTimerEv != null) EventQueue.Enqueue(lastTimerEv);
// This will stop events from being queued and processed
// until the new state is started
m_StateChangeInProgress = true;
throw new EventAbortException(); throw new EventAbortException();
} }
@ -698,6 +713,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
m_CollisionInQueue = true; m_CollisionInQueue = true;
} }
// The only events that persist across state changes are timers
if (m_StateChangeInProgress && data.EventName != "timer") return;
EventQueue.Enqueue(data); EventQueue.Enqueue(data);
if (m_CurrentWorkItem == null) if (m_CurrentWorkItem == null)
@ -785,6 +803,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
AsyncCommandManager.StateChange(Engine, AsyncCommandManager.StateChange(Engine,
LocalID, ItemID); LocalID, ItemID);
// we are effectively in the new state now, so we can resume queueing
// and processing other non-timer events
m_StateChangeInProgress = false;
Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State));
} }