public bool EventSchProcessQIS(ref QueueItemStruct QIS) { try { Exception ex = null; EnumeratorInfo Running = QIS.ID.Script.ExecuteEvent(QIS.State, QIS.functionName, QIS.param, QIS.CurrentlyAt, out ex); if (ex != null) { //Check exceptions, some are ours to deal with, and others are to be logged if (ex.Message.Contains("SelfDeleteException")) { if (QIS.ID.Part != null && QIS.ID.Part.ParentEntity != null) { IBackupModule backup = QIS.ID.Part.ParentEntity.Scene.RequestModuleInterface <IBackupModule>(); if (backup != null) { backup.DeleteSceneObjects( new ISceneEntity[1] { QIS.ID.Part.ParentEntity }, true, true); } } } else if (ex.Message.Contains("ScriptDeleteException")) { if (QIS.ID.Part != null && QIS.ID.Part.ParentEntity != null) { QIS.ID.Part.Inventory.RemoveInventoryItem(QIS.ID.ItemID); } } //Log it for the user else if (!(ex.Message.Contains("EventAbortException")) && !(ex.Message.Contains("MinEventDelayException"))) { QIS.ID.DisplayUserNotification(ex.ToString(), "executing", false, true); } EventManager.EventComplete(QIS); return(false); } else if (Running != null) { //Did not finish so requeue it QIS.CurrentlyAt = Running; QIS.RunningNumber++; return(true); //Do the return... otherwise we open the queue for this event back up } } catch (Exception ex) { //Error, tell the user QIS.ID.DisplayUserNotification(ex.ToString(), "executing", false, true); } //Tell the event manager about it so that the events will be removed from the queue EventManager.EventComplete(QIS); return(false); }
public EnumeratorInfo ExecuteEvent(string state, string FunctionName, object[] args, EnumeratorInfo Start, out Exception ex) { return m_Executor.ExecuteEvent(state, FunctionName, args, Start, out ex); }
public EnumeratorInfo ExecuteEvent (string state, string FunctionName, object[] args, EnumeratorInfo Start, out System.Exception ex) { ex = null; return null; }
public EnumeratorInfo ExecuteEvent(string state, string FunctionName, object[] args, EnumeratorInfo Start, out Exception ex) { ex = null; // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. // Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead! string EventName = state + "_event_" + FunctionName; if (state == "") EventName = FunctionName; //#if DEBUG //m_log.Debug("ScriptEngine: Script event function name: " + EventName); //#endif #region Find Event // not sure it's need if (InTimeSlice) { //OpenSim.Framework.Console.MainConsole.Instance.Output("ScriptEngine TimeSlice Overlap" + FunctionName); return Start; } MethodInfo ev = null; if (m_scriptType == null) m_scriptType = m_Script.GetType(); if (!Events.TryGetValue(EventName, out ev)) { // Not found, create ev = m_scriptType.GetMethod(EventName); Events.Add(EventName, ev); } if (ev == null) // No event by that event name! { //Attempt to find it just by name if (!Events.TryGetValue(EventName, out ev)) { // Not found, create ev = m_scriptType.GetMethod(FunctionName); Events.Add(FunctionName, ev); } if (ev == null) // No event by that name! { //m_log.Debug("ScriptEngine Can not find any event named:" + EventName); return null; } } #endregion return FireAsEnumerator(Start, ev, args, out ex); }
public EnumeratorInfo FireAsEnumerator(EnumeratorInfo Start, MethodInfo ev, object[] args, out Exception ex) { IEnumerator thread = null; OpenTimeSlice(Start); bool running = true; ex = null; try { if (Start != null) { lock (m_enumerators) { m_enumerators.TryGetValue(Start.Key, out thread); } } else thread = (IEnumerator)ev.Invoke(m_Script, args); if (thread != null) running = thread.MoveNext(); } catch (Exception tie) { // Grab the inner exception and rethrow it, unless the inner // exception is an EventAbortException as this indicates event // invocation termination due to a state change. // DO NOT THROW JUST THE INNER EXCEPTION! // FriendlyErrors depends on getting the whole exception! // if (!(tie is EventAbortException) && !(tie is MinEventDelayException)) ex = tie; if (Start != null) { lock (m_enumerators) { m_enumerators.Remove(Start.Key); } } CloseTimeSlice(); return null; } if (running && thread != null) { if (Start == null) { Start = new EnumeratorInfo(); Start.Key = UUID.Random().Guid; } lock (m_enumerators) { m_enumerators[Start.Key] = thread; } if (thread.Current is DateTime) Start.SleepTo = (DateTime)thread.Current; else if (thread.Current is string) { ex = new Exception((string)thread.Current); running = false; lock (m_enumerators) { m_enumerators.Remove(Start.Key); } } CloseTimeSlice(); return Start; } else { //No enumerator.... errr.... something went really wrong here if (Start != null) { lock (m_enumerators) { m_enumerators.Remove(Start.Key); } } CloseTimeSlice(); return null; } }
/// <summary> /// This closes the scrpit, removes it from any known spots, and disposes of itself. /// </summary> /// <param name="shouldbackup">Should we back up this script and fire state_exit?</param> public void CloseAndDispose(bool shouldbackup) { m_ScriptEngine.MaintenanceThread.RemoveFromEventSchQueue(this, true); if (Script != null) { //Fire the exit event for scripts that support it Exception ex; EnumeratorInfo info = null; while ((info = Script.ExecuteEvent(State, "exit", new object[0], info, out ex)) != null) { } } m_ScriptEngine.MaintenanceThread.SetEventSchSetIgnoreNew(this, false); //Give the user back any controls we took ReleaseControls(); // Tell script not to accept new requests //These are fine to set as the state wont be saved again if (shouldbackup) { Running = false; Disabled = true; } // Remove from internal structure ScriptEngine.ScriptProtection.RemoveScript(this); //Remove any errors that might be sitting around m_ScriptEngine.ScriptErrorReporter.RemoveError(ItemID); #region Clean out script parts //Only if this script changed target omega do we reset it if (TargetOmegaWasSet) { Part.AngularVelocity = Vector3.Zero; // Removed in SL Part.ScheduleUpdate(PrimUpdateFlags.AngularVelocity); // Send changes to client. } #endregion if (Script != null) { // Stop long command on script m_ScriptEngine.RemoveScriptFromPlugins(Part.UUID, ItemID); //Release the script and destroy it ILease lease = (ILease)RemotingServices.GetLifetimeService(Script as MarshalByRefObject); if (lease != null) { lease.Unregister(Script.Sponsor); } Script.Close(); Script = null; } if (InventoryItem != null && Part != null) { MainConsole.Instance.Debug("[" + m_ScriptEngine.ScriptEngineName + "]: Closed Script " + InventoryItem.Name + " in " + Part.Name); } if (AppDomain == null) { return; } // Tell AppDomain that we have stopped script m_ScriptEngine.AppDomainManager.UnloadScriptAppDomain(AppDomain); AppDomain = null; }
public void OpenTimeSlice(EnumeratorInfo Start) { TimeSliceStart = DateTime.Now; if(Start==null) TimeSliceEnd = TimeSliceStart.AddMilliseconds(MaxTimeSlice); else TimeSliceEnd = TimeSliceStart.AddMilliseconds(MaxTimeSlice/2); InTimeSlice = true; }
public EnumeratorInfo ExecuteEvent(string state, string FunctionName, object[] args, EnumeratorInfo Start, out Exception ex) { ex = null; string EventName = state == "" ? FunctionName : state + "_event_" + FunctionName; if (InTimeSlice) //OpenSim.Framework.Console.MainConsole.Instance.Output("ScriptEngine TimeSlice Overlap" + FunctionName); return Start; IEnumerator thread = null; OpenTimeSlice(Start); bool running = true; try { if (Start != null) { lock (m_enumerators) m_enumerators.TryGetValue (Start.Key, out thread); } else thread = m_Script.FireEvent (EventName, args); if (thread != null) running = thread.MoveNext(); } catch (Exception tie) { // Grab the inner exception and rethrow it, unless the inner // exception is an EventAbortException as this indicates event // invocation termination due to a state change. // DO NOT THROW JUST THE INNER EXCEPTION! // FriendlyErrors depends on getting the whole exception! // if (!(tie is EventAbortException) && !(tie is MinEventDelayException) && !(tie.InnerException != null && ((tie.InnerException.Message.Contains("EventAbortException")) || (tie.InnerException.Message.Contains ("MinEventDelayException"))))) ex = tie; if (Start != null) { lock (m_enumerators) { m_enumerators.Remove(Start.Key); } } CloseTimeSlice(); return null; } if (running && thread != null) { if (Start == null) { Start = new EnumeratorInfo(); Start.Key = UUID.Random().Guid; } lock (m_enumerators) { m_enumerators[Start.Key] = thread; } if (thread.Current is DateTime) Start.SleepTo = (DateTime)thread.Current; else if (thread.Current is string) { ex = new Exception((string)thread.Current); running = false; lock (m_enumerators) { m_enumerators.Remove(Start.Key); } } CloseTimeSlice(); return Start; } else { //No enumerator.... errr.... something went really wrong here if (Start != null) { lock (m_enumerators) { m_enumerators.Remove(Start.Key); } } CloseTimeSlice(); return null; } }
public void OpenTimeSlice(EnumeratorInfo Start) { if(Start==null) TimeSliceEnd = Util.EnvironmentTickCountAdd (MaxTimeSlice); else TimeSliceEnd = Util.EnvironmentTickCountAdd (MaxTimeSlice/2); InTimeSlice = true; }
public EnumeratorInfo FireAsEnumerator(EnumeratorInfo Start, MethodInfo ev, object[] args, out Exception ex) { IEnumerator thread = null; bool running = true; ex = null; try { for(int i = 0; i < 5; i++) //We do 5 so that we do not kill the loops/queues above with many repeated event firings { if (Start != null) //Make sure we have some info, otherwise start a new thread { //Open the slice at the beginning of every iteration OpenTimeSlice(); InTimeSlice = true; if (thread == null) //Only do this once { lock (m_enumerators) { m_enumerators.TryGetValue(Start.Key, out thread); } } if (thread != null) //Push the event forward running = thread.MoveNext(); if (!running) //Break out of the loop as we are done break; //Close the time slice at the end of every enumeration CloseTimeSlice(); } else thread = (IEnumerator)ev.Invoke(m_Script, args); } } catch (Exception tie) { // Grab the inner exception and rethrow it, unless the inner // exception is an EventAbortException as this indicates event // invocation termination due to a state change. // DO NOT THROW JUST THE INNER EXCEPTION! // FriendlyErrors depends on getting the whole exception! // if (!(tie is EventAbortException) || !(tie is MinEventDelayException) || !(tie is EventAbortException) || !(tie is EventAbortException)) ex = tie; if (Start != null) { lock (m_enumerators) { m_enumerators.Remove(Start.Key); } } InTimeSlice = false; return null; } if (running && thread != null) { if (Start == null) { Start = new EnumeratorInfo(); Start.Key = System.Guid.NewGuid(); } lock (m_enumerators) { m_enumerators[Start.Key] = thread; } if (thread.Current is DateTime) Start.SleepTo = (DateTime)thread.Current; return Start; } else { //No enumerator.... errr.... something went really wrong here if (Start != null) { lock (m_enumerators) { m_enumerators.Remove(Start.Key); } } CloseTimeSlice(); return null; } }
/// <summary> /// This closes the scrpit, removes it from any known spots, and disposes of itself. /// </summary> /// <param name = "shouldbackup">Should we back up this script and fire state_exit?</param> public void CloseAndDispose(bool shouldbackup) { m_ScriptEngine.MaintenanceThread.RemoveFromEventSchQueue(this, true); if (shouldbackup) { if (Script != null) { /* * //Fire this directly so its not closed before its fired * SetEventParams("state_exit", new DetectParams[0]); * * m_ScriptEngine.MaintenanceThread.ProcessQIS(new QueueItemStruct() * { * ID = this, * CurrentlyAt = null, * functionName = "state_exit", * param = new object[0], * llDetectParams = new DetectParams[0], * VersionID = VersionID * }); */ // dont think we should fire state_exit here // m_ScriptEngine.MaintenanceThread.DoAndWaitEventSch(this, "state_exit", // new DetectParams[0], VersionID, EventPriority.FirstStart, new object[0]); m_ScriptEngine.StateSave.SaveStateTo(this); } } if (Script != null) { //Fire the exit event for scripts that support it Exception ex; EnumeratorInfo info = null; while ((info = Script.ExecuteEvent(State, "exit", new object[0], info, out ex)) != null) { } } m_ScriptEngine.MaintenanceThread.SetEventSchSetIgnoreNew(this, false); //Give the user back any controls we took ReleaseControls(); // Tell script not to accept new requests //These are fine to set as the state wont be saved again if (shouldbackup) { Running = false; Disabled = true; } // Remove from internal structure ScriptEngine.ScriptProtection.RemoveScript(this); // if (!Silent) //Don't remove on a recompile because we'll make it under a different assembly // ScriptEngine.ScriptProtection.RemovePreviouslyCompiled(Source); //Remove any errors that might be sitting around m_ScriptEngine.ScriptErrorReporter.RemoveError(ItemID); #region Clean out script parts //Only if this script changed target omega do we reset it if (TargetOmegaWasSet) { Part.AngularVelocity = Vector3.Zero; // Removed in SL Part.ScheduleUpdate(PrimUpdateFlags.AngularVelocity); // Send changes to client. } #endregion if (Script != null) { // Stop long command on script m_ScriptEngine.RemoveScriptFromPlugins(Part.UUID, ItemID); //Release the script and destroy it ILease lease = (ILease)RemotingServices.GetLifetimeService(Script as MarshalByRefObject); if (lease != null) { lease.Unregister(Script.Sponsor); } Script.Close(); Script = null; } MainConsole.Instance.Debug("[" + m_ScriptEngine.ScriptEngineName + "]: Closed Script " + InventoryItem.Name + " in " + Part.Name); if (AppDomain == null) { return; } // Tell AppDomain that we have stopped script m_ScriptEngine.AppDomainManager.UnloadScriptAppDomain(AppDomain); AppDomain = null; }
public EnumeratorInfo FireAsEnumerator(EnumeratorInfo Start, MethodInfo ev, object[] args, out Exception ex) { IEnumerator thread = null; if (Start != null) lock (m_enumerators) { m_enumerators.TryGetValue(Start.Key, out thread); } else thread = (IEnumerator)ev.Invoke(m_Script, args); int i = 0; bool running = false; if (thread != null) { while (i < i + 10) { i++; try { running = CallAndWait(timeout, thread); //Sleep processing if (running && thread.Current != null) { if (thread.Current is DateTime) { if (Start == null) { Start = new EnumeratorInfo(); Start.Key = System.Guid.NewGuid(); } Start.SleepTo = (DateTime)thread.Current; lock (m_enumerators) { m_enumerators[Start.Key] = thread; } ex = null; return Start; } } if (!running) { lock (m_enumerators) { if(Start != null) m_enumerators.Remove(Start.Key); } ex = null; return null; } } catch (Exception tie) { // Grab the inner exception and rethrow it, unless the inner // exception is an EventAbortException as this indicates event // invocation termination due to a state change. // DO NOT THROW JUST THE INNER EXCEPTION! // FriendlyErrors depends on getting the whole exception! // ex = null; if (!(tie is EventAbortException) || !(tie is MinEventDelayException) || !(tie is EventAbortException) || !(tie is EventAbortException)) ex = tie; return null; } } } else { //No enumerator.... errr.... something went really wrong here ex = null; return Start; } if (Start == null) { Start = new EnumeratorInfo(); Start.Key = System.Guid.NewGuid(); } lock (m_enumerators) { m_enumerators[Start.Key] = thread; } ex = null; return Start; }