public void Start() { lock (EventQueue) { if (Running) { return; } Running = true; TimeStarted = DateTime.Now; MeasurementPeriodTickStart = Util.EnvironmentTickCount(); MeasurementPeriodExecutionTime = 0; if (EventQueue.Count > 0) { if (m_CurrentWorkItem == null) { m_CurrentWorkItem = Engine.QueueEventHandler(this); } // else // m_log.Error("[Script] Tried to start a script that was already queued"); } } }
public bool Stop(int timeout) { IScriptWorkItem result; lock (m_EventQueue) { if (!Running) { return(true); } if (m_CurrentResult == null) { m_RunEvents = false; return(true); } if (m_CurrentResult.Cancel()) { m_CurrentResult = null; m_RunEvents = false; return(true); } result = m_CurrentResult; m_RunEvents = false; } if (result.Wait(new TimeSpan((long)timeout * 100000))) { return(true); } lock (m_EventQueue) { result = m_CurrentResult; } if (result == null) { return(true); } if (!m_InSelfDelete) { result.Abort(); } lock (m_EventQueue) { m_CurrentResult = null; } return(true); }
public void Start() { lock (m_EventQueue) { if (Running) { return; } m_RunEvents = true; if (m_EventQueue.Count > 0) { if (m_CurrentResult == null) { m_CurrentResult = m_Engine.QueueEventHandler(this); } // else // m_log.Error("[Script] Tried to start a script that was already queued"); } } }
public bool Stop(int timeout, bool clearEventQueue = false) { if (DebugLevel >= 1) m_log.DebugFormat( "[SCRIPT INSTANCE]: Stopping script {0} {1} in {2} {3} with timeout {4} {5} {6}", ScriptName, ItemID, PrimName, ObjectID, timeout, m_InSelfDelete, DateTime.Now.Ticks); IScriptWorkItem workItem; lock (EventQueue) { if (clearEventQueue) ClearQueue(); if (!Running) return true; // If we're not running or waiting to run an event then we can safely stop. if (m_CurrentWorkItem == null) { Running = false; return true; } // If we are waiting to run an event then we can try to cancel it. if (m_CurrentWorkItem.Cancel()) { m_CurrentWorkItem = null; Running = false; return true; } workItem = m_CurrentWorkItem; Running = false; } // Wait for the current event to complete. if (!m_InSelfDelete) { if (!m_coopTermination) { // If we're not co-operative terminating then try and wait for the event to complete before stopping if (workItem.Wait(timeout)) return true; } else { if (DebugLevel >= 1) m_log.DebugFormat( "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}", ScriptName, ItemID, PrimName, ObjectID); // This will terminate the event on next handle check by the script. m_coopSleepHandle.Set(); // For now, we will wait forever since the event should always cleanly terminate once LSL loop // checking is implemented. May want to allow a shorter timeout option later. if (workItem.Wait(Timeout.Infinite)) { if (DebugLevel >= 1) m_log.DebugFormat( "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}", ScriptName, ItemID, PrimName, ObjectID); return true; } } } lock (EventQueue) { workItem = m_CurrentWorkItem; } if (workItem == null) return true; // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then // forcibly abort the work item (this aborts the underlying thread). // Co-operative termination should never reach this point. if (!m_InSelfDelete) { m_log.DebugFormat( "[SCRIPT INSTANCE]: Aborting unstopped script {0} {1} in prim {2}, localID {3}, timeout was {4} ms", ScriptName, ItemID, PrimName, LocalID, timeout); workItem.Abort(); } lock (EventQueue) { m_CurrentWorkItem = null; } return true; }
public void Start() { lock (EventQueue) { if (Running) return; Running = true; TimeStarted = DateTime.Now; // Note: we don't reset ExecutionTime. The reason is that runaway scripts are stopped and restarted // automatically, and we *do* want to show that they had high CPU in that case. If we had reset // ExecutionTime here then runaway scripts, paradoxically, would never show up in the "Top Scripts" dialog. if (EventQueue.Count > 0) { if (m_CurrentWorkItem == null) m_CurrentWorkItem = Engine.QueueEventHandler(this); // else // m_log.Error("[Script] Tried to start a script that was already queued"); } } }
/// <summary> /// Process the next event queued for this script /// </summary> /// <returns></returns> public object EventProcessor() { lock (m_Script) { EventParams data = null; lock (m_EventQueue) { data = (EventParams) m_EventQueue.Dequeue(); if (data == null) // Shouldn't happen { if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) { m_CurrentResult = m_Engine.QueueEventHandler(this); } else { m_CurrentResult = null; } return 0; } if (data.EventName == "timer") m_TimerQueued = false; if (data.EventName == "control") { if (m_ControlEventsInQueue > 0) m_ControlEventsInQueue--; } if (data.EventName == "collision") m_CollisionInQueue = false; } //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); m_DetectParams = data.DetectParams; if (data.EventName == "state") // Hardcoded state change { // m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}", // m_PrimName, m_ScriptName, data.Params[0].ToString()); m_State=data.Params[0].ToString(); AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); SceneObjectPart part = m_Engine.World.GetSceneObjectPart( m_LocalID); if (part != null) { part.SetScriptEvents(m_ItemID, (int)m_Script.GetStateEventFlags(State)); } } else { if (m_Engine.World.PipeEventsForScript(m_LocalID) || data.EventName == "control") // Don't freeze avies! { SceneObjectPart part = m_Engine.World.GetSceneObjectPart( m_LocalID); // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", // m_PrimName, m_ScriptName, data.EventName, m_State); try { m_CurrentEvent = data.EventName; m_EventStart = DateTime.Now; m_InEvent = true; m_Script.ExecuteEvent(State, data.EventName, data.Params); m_InEvent = false; m_CurrentEvent = String.Empty; if (m_SaveState) { // This will be the very first event we deliver // (state_entry) in default state // SaveState(m_Assembly); m_SaveState = false; } } catch (Exception e) { // m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message); m_InEvent = false; m_CurrentEvent = String.Empty; if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException)) { try { // DISPLAY ERROR INWORLD string text = FormatException(e); if (text.Length > 1000) text = text.Substring(0, 1000); m_Engine.World.SimChat(Utils.StringToBytes(text), ChatTypeEnum.DebugChannel, 2147483647, part.AbsolutePosition, part.Name, part.UUID, false); } catch (Exception) { } // catch (Exception e2) // LEGIT: User Scripting // { // m_log.Error("[SCRIPT]: "+ // "Error displaying error in-world: " + // e2.ToString()); // m_log.Error("[SCRIPT]: " + // "Errormessage: Error compiling script:\r\n" + // e.ToString()); // } } else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) { m_InSelfDelete = true; if (part != null && part.ParentGroup != null) m_Engine.World.DeleteSceneObject(part.ParentGroup, false); } else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) { m_InSelfDelete = true; if (part != null && part.ParentGroup != null) part.Inventory.RemoveInventoryItem(m_ItemID); } } } } lock (m_EventQueue) { if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) { m_CurrentResult = m_Engine.QueueEventHandler(this); } else { m_CurrentResult = null; } } m_DetectParams = null; return 0; } }
public bool Stop(int timeout) { IScriptWorkItem result; lock (m_EventQueue) { if (!Running) return true; if (m_CurrentResult == null) { m_RunEvents = false; return true; } if (m_CurrentResult.Cancel()) { m_CurrentResult = null; m_RunEvents = false; return true; } result = m_CurrentResult; m_RunEvents = false; } if (result.Wait(new TimeSpan((long)timeout * 100000))) { return true; } lock (m_EventQueue) { result = m_CurrentResult; } if (result == null) return true; if (!m_InSelfDelete) result.Abort(); lock (m_EventQueue) { m_CurrentResult = null; } return true; }
public void Start() { lock (m_EventQueue) { if (Running) return; m_RunEvents = true; if (m_EventQueue.Count > 0) { if (m_CurrentResult == null) m_CurrentResult = m_Engine.QueueEventHandler(this); // else // m_log.Error("[Script] Tried to start a script that was already queued"); } } }
/// <summary> /// Process the next event queued for this script /// </summary> /// <returns></returns> public object EventProcessor() { // We check here as the thread stopping this instance from running may itself hold the m_Script lock. if (!Running) { return(0); } lock (m_Script) { // m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); if (Suspended) { return(0); } EventParams data = null; lock (EventQueue) { data = (EventParams)EventQueue.Dequeue(); if (data == null) // Shouldn't happen { if (EventQueue.Count > 0 && Running && !ShuttingDown) { m_CurrentWorkItem = Engine.QueueEventHandler(this); } else { m_CurrentWorkItem = null; } return(0); } if (data.EventName == "timer") { m_TimerQueued = false; } if (data.EventName == "control") { if (m_ControlEventsInQueue > 0) { m_ControlEventsInQueue--; } } if (data.EventName == "collision") { m_CollisionInQueue = false; } } // m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); m_DetectParams = data.DetectParams; if (data.EventName == "state") // Hardcoded state change { // m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}", // PrimName, ScriptName, data.Params[0].ToString()); State = data.Params[0].ToString(); AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); SceneObjectPart part = Engine.World.GetSceneObjectPart( LocalID); if (part != null) { part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); } } else { if (Engine.World.PipeEventsForScript(LocalID) || data.EventName == "control") // Don't freeze avies! { SceneObjectPart part = Engine.World.GetSceneObjectPart( LocalID); // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", // PrimName, ScriptName, data.EventName, State); try { m_CurrentEvent = data.EventName; m_EventStart = DateTime.Now; m_InEvent = true; int start = Util.EnvironmentTickCount(); // Reset the measurement period when we reach the end of the current one. if (start - MeasurementPeriodTickStart > MaxMeasurementPeriod) { MeasurementPeriodTickStart = start; } m_Script.ExecuteEvent(State, data.EventName, data.Params); MeasurementPeriodExecutionTime += Util.EnvironmentTickCount() - start; m_InEvent = false; m_CurrentEvent = String.Empty; if (m_SaveState) { // This will be the very first event we deliver // (state_entry) in default state // SaveState(m_Assembly); m_SaveState = false; } } catch (Exception e) { // m_log.DebugFormat( // "[SCRIPT] Exception in script {0} {1}: {2}{3}", // ScriptName, ItemID, e.Message, e.StackTrace); m_InEvent = false; m_CurrentEvent = String.Empty; if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException)) { try { // DISPLAY ERROR INWORLD string text = FormatException(e); if (text.Length > 1000) { text = text.Substring(0, 1000); } Engine.World.SimChat(Utils.StringToBytes(text), ChatTypeEnum.DebugChannel, 2147483647, part.AbsolutePosition, part.Name, part.UUID, false); } catch (Exception) { } // catch (Exception e2) // LEGIT: User Scripting // { // m_log.Error("[SCRIPT]: "+ // "Error displaying error in-world: " + // e2.ToString()); // m_log.Error("[SCRIPT]: " + // "Errormessage: Error compiling script:\r\n" + // e.ToString()); // } } else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) { m_InSelfDelete = true; if (part != null) { Engine.World.DeleteSceneObject(part.ParentGroup, false); } } else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) { m_InSelfDelete = true; if (part != null) { part.Inventory.RemoveInventoryItem(ItemID); } } } } } // If there are more events and we are currently running and not shutting down, then ask the // script engine to run the next event. lock (EventQueue) { if (EventQueue.Count > 0 && Running && !ShuttingDown) { m_CurrentWorkItem = Engine.QueueEventHandler(this); } else { m_CurrentWorkItem = null; } } m_DetectParams = null; return(0); } }
public bool Stop(int timeout) { // m_log.DebugFormat( // "[SCRIPT INSTANCE]: Stopping script {0} {1} in {2} {3} with timeout {4} {5} {6}", // ScriptName, ItemID, PrimName, ObjectID, timeout, m_InSelfDelete, DateTime.Now.Ticks); IScriptWorkItem workItem; lock (EventQueue) { if (!Running) { return(true); } // If we're not running or waiting to run an event then we can safely stop. if (m_CurrentWorkItem == null) { Running = false; return(true); } // If we are waiting to run an event then we can try to cancel it. if (m_CurrentWorkItem.Cancel()) { m_CurrentWorkItem = null; Running = false; return(true); } workItem = m_CurrentWorkItem; Running = false; } // Wait for the current event to complete. if (!m_InSelfDelete && workItem.Wait(new TimeSpan((long)timeout * 100000))) { return(true); } lock (EventQueue) { workItem = m_CurrentWorkItem; } if (workItem == null) { return(true); } // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then // forcibly abort the work item (this aborts the underlying thread). if (!m_InSelfDelete) { // m_log.ErrorFormat( // "[SCRIPT INSTANCE]: Aborting script {0} {1} in prim {2} {3} {4} {5}", // ScriptName, ItemID, PrimName, ObjectID, m_InSelfDelete, DateTime.Now.Ticks); workItem.Abort(); } lock (EventQueue) { m_CurrentWorkItem = null; } return(true); }
/// <summary> /// Process the next event queued for this script /// </summary> /// <returns></returns> public object EventProcessor() { // We check here as the thread stopping this instance from running may itself hold the m_Script lock. if (!Running) return 0; lock (m_Script) { // m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); if (Suspended) return 0; EventParams data = null; lock (EventQueue) { data = (EventParams)EventQueue.Dequeue(); if (data == null) // Shouldn't happen { if (EventQueue.Count > 0 && Running && !ShuttingDown) { m_CurrentWorkItem = Engine.QueueEventHandler(this); } else { m_CurrentWorkItem = null; } return 0; } if (data.EventName == "timer") m_TimerQueued = false; if (data.EventName == "control") { if (m_ControlEventsInQueue > 0) m_ControlEventsInQueue--; } if (data.EventName == "collision") m_CollisionInQueue = false; } if (DebugLevel >= 2) m_log.DebugFormat( "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", data.EventName, ScriptName, Part.Name, Part.LocalId, Part.ParentGroup.Name, Part.ParentGroup.UUID, Part.AbsolutePosition, Part.ParentGroup.Scene.Name); m_DetectParams = data.DetectParams; if (data.EventName == "state") // Hardcoded state change { State = data.Params[0].ToString(); if (DebugLevel >= 1) m_log.DebugFormat( "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", State, ScriptName, Part.Name, Part.LocalId, Part.ParentGroup.Name, Part.ParentGroup.UUID, Part.AbsolutePosition, Part.ParentGroup.Scene.Name); AsyncCommandManager.StateChange(Engine, LocalID, ItemID); Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); } else { if (Engine.World.PipeEventsForScript(LocalID) || data.EventName == "control") // Don't freeze avies! { // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", // PrimName, ScriptName, data.EventName, State); try { m_CurrentEvent = data.EventName; m_EventStart = DateTime.Now; m_InEvent = true; int start = Util.EnvironmentTickCount(); // Reset the measurement period when we reach the end of the current one. if (start - MeasurementPeriodTickStart > MaxMeasurementPeriod) MeasurementPeriodTickStart = start; m_Script.ExecuteEvent(State, data.EventName, data.Params); MeasurementPeriodExecutionTime += Util.EnvironmentTickCount() - start; m_InEvent = false; m_CurrentEvent = String.Empty; if (m_SaveState) { // This will be the very first event we deliver // (state_entry) in default state // SaveState(m_Assembly); m_SaveState = false; } } catch (Exception e) { // m_log.DebugFormat( // "[SCRIPT] Exception in script {0} {1}: {2}{3}", // ScriptName, ItemID, e.Message, e.StackTrace); m_InEvent = false; m_CurrentEvent = String.Empty; if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException) && !(e.InnerException is ScriptCoopStopException))) && !(e is ThreadAbortException)) { try { // DISPLAY ERROR INWORLD string text = FormatException(e); if (text.Length > 1000) text = text.Substring(0, 1000); Engine.World.SimChat(Utils.StringToBytes(text), ChatTypeEnum.DebugChannel, 2147483647, Part.AbsolutePosition, Part.Name, Part.UUID, false); m_log.Debug(string.Format( "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4} ", ScriptName, PrimName, Part.UUID, Part.AbsolutePosition, Part.ParentGroup.Scene.Name), e); } catch (Exception) { } // catch (Exception e2) // LEGIT: User Scripting // { // m_log.Error("[SCRIPT]: "+ // "Error displaying error in-world: " + // e2.ToString()); // m_log.Error("[SCRIPT]: " + // "Errormessage: Error compiling script:\r\n" + // e.ToString()); // } } else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) { m_InSelfDelete = true; Engine.World.DeleteSceneObject(Part.ParentGroup, false); } else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) { m_InSelfDelete = true; Part.Inventory.RemoveInventoryItem(ItemID); } else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) { if (DebugLevel >= 1) m_log.DebugFormat( "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.", PrimName, ScriptName, data.EventName, State); } } } } // If there are more events and we are currently running and not shutting down, then ask the // script engine to run the next event. lock (EventQueue) { EventsProcessed++; if (EventQueue.Count > 0 && Running && !ShuttingDown) { m_CurrentWorkItem = Engine.QueueEventHandler(this); } else { m_CurrentWorkItem = null; } } m_DetectParams = null; return 0; } }
public void Start() { lock (EventQueue) { if (Running) return; Running = true; TimeStarted = DateTime.Now; MeasurementPeriodTickStart = Util.EnvironmentTickCount(); MeasurementPeriodExecutionTime = 0; if (EventQueue.Count > 0) { if (m_CurrentWorkItem == null) m_CurrentWorkItem = Engine.QueueEventHandler(this); // else // m_log.Error("[Script] Tried to start a script that was already queued"); } } }
public bool Stop(int timeout) { // m_log.DebugFormat( // "[SCRIPT INSTANCE]: Stopping script {0} {1} in {2} {3} with timeout {4} {5} {6}", // ScriptName, ItemID, PrimName, ObjectID, timeout, m_InSelfDelete, DateTime.Now.Ticks); IScriptWorkItem workItem; lock (EventQueue) { if (!Running) return true; // If we're not running or waiting to run an event then we can safely stop. if (m_CurrentWorkItem == null) { Running = false; return true; } // If we are waiting to run an event then we can try to cancel it. if (m_CurrentWorkItem.Cancel()) { m_CurrentWorkItem = null; Running = false; return true; } workItem = m_CurrentWorkItem; Running = false; } // Wait for the current event to complete. if (!m_InSelfDelete && workItem.Wait(new TimeSpan((long)timeout * 100000))) { return true; } lock (EventQueue) { workItem = m_CurrentWorkItem; } if (workItem == null) return true; // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then // forcibly abort the work item (this aborts the underlying thread). if (!m_InSelfDelete) { m_log.DebugFormat( "[SCRIPT INSTANCE]: Aborting unstopped script {0} {1} in prim {2}, localID {3}, timeout was {4} ms", ScriptName, ItemID, PrimName, LocalID, timeout); workItem.Abort(); } lock (EventQueue) { m_CurrentWorkItem = null; } return true; }
public bool Stop(int timeout) { if (DebugLevel >= 1) { m_log.DebugFormat( "[SCRIPT INSTANCE]: Stopping script {0} {1} in {2} {3} with timeout {4} {5} {6}", ScriptName, ItemID, PrimName, ObjectID, timeout, m_InSelfDelete, DateTime.Now.Ticks); } IScriptWorkItem workItem; lock (EventQueue) { if (!Running) { return(true); } // If we're not running or waiting to run an event then we can safely stop. if (m_CurrentWorkItem == null) { Running = false; return(true); } // If we are waiting to run an event then we can try to cancel it. if (m_CurrentWorkItem.Cancel()) { m_CurrentWorkItem = null; Running = false; return(true); } workItem = m_CurrentWorkItem; Running = false; } // Wait for the current event to complete. if (!m_InSelfDelete) { if (DebugLevel >= 1) { m_log.DebugFormat( "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}", ScriptName, ItemID, PrimName, ObjectID); } // This will terminate the event on next handle check by the script. m_coopSleepHandle.Set(); // For now, we will wait forever since the event should always cleanly terminate once LSL loop // checking is implemented. May want to allow a shorter timeout option later. if (workItem.Wait(Timeout.Infinite)) { if (DebugLevel >= 1) { m_log.DebugFormat( "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}", ScriptName, ItemID, PrimName, ObjectID); } return(true); } } lock (EventQueue) { workItem = m_CurrentWorkItem; } if (workItem == null) { return(true); } // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then // forcibly abort the work item (this aborts the underlying thread). // Co-operative termination should never reach this point. if (!m_InSelfDelete) { m_log.DebugFormat( "[SCRIPT INSTANCE]: Aborting unstopped script {0} {1} in prim {2}, localID {3}, timeout was {4} ms", ScriptName, ItemID, PrimName, LocalID, timeout); workItem.Abort(); } lock (EventQueue) { m_CurrentWorkItem = null; } return(true); }
/// <summary> /// Process the next event queued for this script /// </summary> /// <returns></returns> public object EventProcessor() { if (m_Suspended) { return(0); } lock (m_Script) { EventParams data = null; lock (m_EventQueue) { data = (EventParams)m_EventQueue.Dequeue(); if (data == null) // Shouldn't happen { if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) { m_CurrentResult = m_Engine.QueueEventHandler(this); } else { m_CurrentResult = null; } return(0); } if (data.EventName == "timer") { m_TimerQueued = false; } if (data.EventName == "control") { if (m_ControlEventsInQueue > 0) { m_ControlEventsInQueue--; } } if (data.EventName == "collision") { m_CollisionInQueue = false; } } //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); m_DetectParams = data.DetectParams; if (data.EventName == "state") // Hardcoded state change { // m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}", // m_PrimName, m_ScriptName, data.Params[0].ToString()); m_State = data.Params[0].ToString(); AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); SceneObjectPart part = m_Engine.World.GetSceneObjectPart( m_LocalID); if (part != null) { part.SetScriptEvents(m_ItemID, (int)m_Script.GetStateEventFlags(State)); } } else { if (m_Engine.World.PipeEventsForScript(m_LocalID) || data.EventName == "control") // Don't freeze avies! { SceneObjectPart part = m_Engine.World.GetSceneObjectPart( m_LocalID); // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", // m_PrimName, m_ScriptName, data.EventName, m_State); try { m_CurrentEvent = data.EventName; m_EventStart = DateTime.Now; m_InEvent = true; m_Script.ExecuteEvent(State, data.EventName, data.Params); m_InEvent = false; m_CurrentEvent = String.Empty; if (m_SaveState) { // This will be the very first event we deliver // (state_entry) in default state // SaveState(m_Assembly); m_SaveState = false; } } catch (Exception e) { // m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message); m_InEvent = false; m_CurrentEvent = String.Empty; if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException)) { try { // DISPLAY ERROR INWORLD string text = FormatException(e); if (text.Length > 1000) { text = text.Substring(0, 1000); } m_Engine.World.SimChat(Utils.StringToBytes(text), ChatTypeEnum.DebugChannel, 2147483647, part.AbsolutePosition, part.Name, part.UUID, false); } catch (Exception) { } // catch (Exception e2) // LEGIT: User Scripting // { // m_log.Error("[SCRIPT]: "+ // "Error displaying error in-world: " + // e2.ToString()); // m_log.Error("[SCRIPT]: " + // "Errormessage: Error compiling script:\r\n" + // e.ToString()); // } } else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) { m_InSelfDelete = true; if (part != null && part.ParentGroup != null) { m_Engine.World.DeleteSceneObject(part.ParentGroup, false); } } else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) { m_InSelfDelete = true; if (part != null && part.ParentGroup != null) { part.Inventory.RemoveInventoryItem(m_ItemID); } } } } } lock (m_EventQueue) { if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) { m_CurrentResult = m_Engine.QueueEventHandler(this); } else { m_CurrentResult = null; } } m_DetectParams = null; return(0); } }
/// <summary> /// Post an event to this script instance. /// </summary> /// <remarks> /// The request to run the event is sent /// </remarks> /// <param name="data"></param> public void PostEvent(EventParams data) { // m_log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}", // PrimName, ScriptName, data.EventName, State); if (!Running) return; // If min event delay is set then ignore any events untill the time has expired // This currently only allows 1 event of any type in the given time period. // This may need extending to allow for a time for each individual event type. if (m_eventDelayTicks != 0) { if (DateTime.Now.Ticks < m_nextEventTimeTicks) return; m_nextEventTimeTicks = DateTime.Now.Ticks + m_eventDelayTicks; } lock (EventQueue) { // The only events that persist across state changes are timers if (m_StateChangeInProgress && data.EventName != "timer") return; if (EventQueue.Count >= m_MaxScriptQueue) return; if (data.EventName == "timer") { if (m_TimerQueued) return; m_TimerQueued = true; } if (data.EventName == "control") { int held = ((LSL_Types.LSLInteger)data.Params[1]).value; // int changed = ((LSL_Types.LSLInteger)data.Params[2]).value; // If the last message was a 0 (nothing held) // and this one is also nothing held, drop it // if (m_LastControlLevel == held && held == 0) return; // If there is one or more queued, then queue // only changed ones, else queue unconditionally // if (m_ControlEventsInQueue > 0) { if (m_LastControlLevel == held) return; } m_LastControlLevel = held; m_ControlEventsInQueue++; } if (data.EventName == "collision") { if (m_CollisionInQueue) return; if (data.DetectParams == null) return; m_CollisionInQueue = true; } EventQueue.Enqueue(data); if (m_CurrentWorkItem == null) { m_CurrentWorkItem = Engine.QueueEventHandler(this); } } }
private object EventProcessorInt() { EventParams data = null; lock (EventQueue) { data = (EventParams)EventQueue.Dequeue(); if (data == null) // Shouldn't happen { if (EventQueue.Count > 0 && Running && !ShuttingDown) { m_CurrentWorkItem = Engine.QueueEventHandler(this); } else { m_CurrentWorkItem = null; } return 0; } if (data.EventName == "timer") m_TimerQueued = false; if (data.EventName == "control") { if (m_ControlEventsInQueue > 0) m_ControlEventsInQueue--; } if (data.EventName == "collision") m_CollisionInQueue = false; } if (DebugLevel >= 2) m_log.DebugFormat( "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", data.EventName, ScriptName, Part.Name, Part.LocalId, Part.ParentGroup.Name, Part.ParentGroup.UUID, Part.AbsolutePosition, Part.ParentGroup.Scene.Name); m_DetectParams = data.DetectParams; if (data.EventName == "state") // Hardcoded state change { State = data.Params[0].ToString(); if (DebugLevel >= 1) m_log.DebugFormat( "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", State, ScriptName, Part.Name, Part.LocalId, Part.ParentGroup.Name, Part.ParentGroup.UUID, Part.AbsolutePosition, Part.ParentGroup.Scene.Name); AsyncCommandManager.StateChange(Engine, 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)); } else { if (Engine.World.PipeEventsForScript(LocalID) || data.EventName == "control") // Don't freeze avies! { // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", // PrimName, ScriptName, data.EventName, State); try { m_CurrentEvent = data.EventName; m_EventStart = DateTime.Now; m_InEvent = true; try { m_Script.ExecuteEvent(State, data.EventName, data.Params); } finally { m_InEvent = false; m_CurrentEvent = String.Empty; } if (m_SaveState) { // This will be the very first event we deliver // (state_entry) in default state // SaveState(); m_SaveState = false; } } catch (Exception e) { // m_log.DebugFormat( // "[SCRIPT] Exception in script {0} {1}: {2}{3}", // ScriptName, ItemID, e.Message, e.StackTrace); if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException) && !(e.InnerException is ScriptCoopStopException))) && !(e is ThreadAbortException)) { try { // DISPLAY ERROR INWORLD string text = FormatException(e); if (text.Length > 1000) text = text.Substring(0, 1000); Engine.World.SimChat(Utils.StringToBytes(text), ChatTypeEnum.DebugChannel, 2147483647, Part.AbsolutePosition, Part.Name, Part.UUID, false); m_log.Debug(string.Format( "[SCRIPT INSTANCE]: Runtime error in script {0} (event {1}), part {2} {3} at {4} in {5} ", ScriptName, data.EventName, PrimName, Part.UUID, Part.AbsolutePosition, Part.ParentGroup.Scene.Name), e); } catch (Exception) { } // catch (Exception e2) // LEGIT: User Scripting // { // m_log.Error("[SCRIPT]: "+ // "Error displaying error in-world: " + // e2.ToString()); // m_log.Error("[SCRIPT]: " + // "Errormessage: Error compiling script:\r\n" + // e.ToString()); // } } else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) { m_InSelfDelete = true; Engine.World.DeleteSceneObject(Part.ParentGroup, false); } else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) { m_InSelfDelete = true; Part.Inventory.RemoveInventoryItem(ItemID); } else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) { if (DebugLevel >= 1) m_log.DebugFormat( "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.", PrimName, ScriptName, data.EventName, State); } } } } // If there are more events and we are currently running and not shutting down, then ask the // script engine to run the next event. lock (EventQueue) { // Increase processed events counter and prevent wrap; if (++EventsProcessed == 1000000) EventsProcessed = 100000; if ((EventsProcessed % 100000) == 0 && DebugLevel > 0) { m_log.DebugFormat("[SCRIPT INSTANCE]: Script \"{0}\" (Object \"{1}\" {2} @ {3}.{4}, Item ID {5}, Asset {6}) in event {7}: processed {8:n0} script events", ScriptTask.Name, Part.ParentGroup.Name, Part.ParentGroup.UUID, Part.ParentGroup.AbsolutePosition, Part.ParentGroup.Scene.Name, ScriptTask.ItemID, ScriptTask.AssetID, data.EventName, EventsProcessed); } if (EventQueue.Count > 0 && Running && !ShuttingDown) { m_CurrentWorkItem = Engine.QueueEventHandler(this); } else { m_CurrentWorkItem = null; } } m_DetectParams = null; return 0; }
/// <summary> /// Post an event to this script instance. /// </summary> /// <remarks> /// The request to run the event is sent /// </remarks> /// <param name="data"></param> public void PostEvent(EventParams data) { // m_log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}", // PrimName, ScriptName, data.EventName, State); if (!Running) { return; } // If min event delay is set then ignore any events untill the time has expired // This currently only allows 1 event of any type in the given time period. // This may need extending to allow for a time for each individual event type. if (m_eventDelayTicks != 0) { if (DateTime.Now.Ticks < m_nextEventTimeTicks) { return; } m_nextEventTimeTicks = DateTime.Now.Ticks + m_eventDelayTicks; } lock (EventQueue) { if (EventQueue.Count >= m_MaxScriptQueue) { return; } if (data.EventName == "timer") { if (m_TimerQueued) { return; } m_TimerQueued = true; } if (data.EventName == "control") { int held = ((LSL_Types.LSLInteger)data.Params[1]).value; // int changed = ((LSL_Types.LSLInteger)data.Params[2]).value; // If the last message was a 0 (nothing held) // and this one is also nothing held, drop it // if (m_LastControlLevel == held && held == 0) { return; } // If there is one or more queued, then queue // only changed ones, else queue unconditionally // if (m_ControlEventsInQueue > 0) { if (m_LastControlLevel == held) { return; } } m_LastControlLevel = held; m_ControlEventsInQueue++; } if (data.EventName == "collision") { if (m_CollisionInQueue) { return; } if (data.DetectParams == null) { return; } m_CollisionInQueue = true; } EventQueue.Enqueue(data); if (m_CurrentWorkItem == null) { m_CurrentWorkItem = Engine.QueueEventHandler(this); } } }