ScriptManager.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Diagnostics;
  30. using System.Reflection;
  31. using System.Text;
  32. using System.Threading;
  33. using log4net;
  34. using OpenMetaverse;
  35. using OpenSim.Region.ScriptEngine.Shared;
  36. using OpenSim.ScriptEngine.Shared;
  37. using EventParams=OpenSim.ScriptEngine.Shared.EventParams;
  38. namespace OpenSim.ScriptEngine.Components.DotNetEngine.Scheduler
  39. {
  40. public partial class ScriptManager: IScriptExecutor
  41. {
  42. private const int NoWorkSleepMs = 50;
  43. private const int NoWorkSleepMsInc = 1; // How much time to increase wait with on every iteration
  44. private const int NoWorkSleepMsIncMax = 300; // Max time to wait
  45. internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  46. public string Name { get { return "SECS.DotNetEngine.ScriptManager"; } }
  47. private static Thread ScriptLoadUnloadThread;
  48. public Dictionary<uint, Dictionary<UUID, ScriptStructure>> Scripts = new Dictionary<uint, Dictionary<UUID, ScriptStructure>>();
  49. private RegionInfoStructure CurrentRegion;
  50. public void Initialize(RegionInfoStructure currentRegion)
  51. {
  52. CurrentRegion = currentRegion;
  53. }
  54. public ScriptManager()
  55. {
  56. ScriptLoadUnloadThread = new Thread(LoadUnloadLoop);
  57. ScriptLoadUnloadThread.Name = "ScriptLoadUnloadThread";
  58. ScriptLoadUnloadThread.IsBackground = true;
  59. ScriptLoadUnloadThread.Start();
  60. }
  61. public void Close() { }
  62. private void LoadUnloadLoop ()
  63. {
  64. int _NoWorkSleepMsInc = 0;
  65. while (true)
  66. {
  67. if (DoScriptLoadUnload())
  68. {
  69. // We found work, reset counter
  70. _NoWorkSleepMsInc = NoWorkSleepMs;
  71. } else
  72. {
  73. // We didn't find work
  74. // Sleep
  75. Thread.Sleep(NoWorkSleepMs + NoWorkSleepMsInc);
  76. // Increase sleep delay
  77. _NoWorkSleepMsInc += NoWorkSleepMsInc;
  78. // Make sure we don't exceed max
  79. if (_NoWorkSleepMsInc > NoWorkSleepMsIncMax)
  80. _NoWorkSleepMsInc = NoWorkSleepMsIncMax;
  81. }
  82. }
  83. }
  84. #region Add/Remove/Find script functions for our Script memory structure
  85. private void MemAddScript(ScriptStructure script)
  86. {
  87. lock (scriptLock)
  88. {
  89. // Create object if it doesn't exist
  90. if (!Scripts.ContainsKey(script.LocalID))
  91. Scripts.Add(script.LocalID, new Dictionary<UUID, ScriptStructure>());
  92. // Delete script if it exists
  93. Dictionary<UUID, ScriptStructure> Obj;
  94. if (Scripts.TryGetValue(script.LocalID, out Obj))
  95. if (Obj.ContainsKey(script.ItemID) == true)
  96. Obj.Remove(script.ItemID);
  97. // Add to object
  98. Obj.Add(script.ItemID, script);
  99. }
  100. }
  101. private void MemRemoveScript(uint LocalID, UUID ItemID)
  102. {
  103. // TODO: Also clean up command queue and async commands for object
  104. lock (scriptLock)
  105. {
  106. // Create object if it doesn't exist
  107. if (!Scripts.ContainsKey(LocalID))
  108. return;
  109. // Delete script if it exists
  110. Dictionary<UUID, ScriptStructure> Obj;
  111. if (Scripts.TryGetValue(LocalID, out Obj))
  112. if (Obj.ContainsKey(ItemID) == true)
  113. Obj.Remove(ItemID);
  114. // Empty?
  115. if (Obj.Count == 0)
  116. Scripts.Remove(LocalID);
  117. }
  118. }
  119. public bool TryGetScript(uint localID, UUID itemID, ref ScriptStructure script)
  120. {
  121. lock (scriptLock)
  122. {
  123. if (Scripts.ContainsKey(localID) == false)
  124. return false;
  125. Dictionary<UUID, ScriptStructure> Obj;
  126. if (Scripts.TryGetValue(localID, out Obj))
  127. if (Obj.ContainsKey(itemID) == false)
  128. return false;
  129. // Get script
  130. return Obj.TryGetValue(itemID, out script);
  131. }
  132. }
  133. public ScriptStructure GetScript(uint localID, UUID itemID)
  134. {
  135. lock (scriptLock)
  136. {
  137. if (Scripts.ContainsKey(localID) == false)
  138. throw new Exception("No script with LocalID " + localID + " was found.");
  139. Dictionary<UUID, ScriptStructure> Obj;
  140. if (Scripts.TryGetValue(localID, out Obj))
  141. if (Obj.ContainsKey(itemID) == false)
  142. throw new Exception("No script with ItemID " + itemID + " was found.");
  143. // Get script
  144. return Obj[itemID];
  145. }
  146. }
  147. public bool TryGetScripts(uint localID, ref Dictionary<UUID, ScriptStructure> returnList)
  148. {
  149. Dictionary<UUID, ScriptStructure> getList = GetScripts(localID);
  150. if (getList != null)
  151. {
  152. returnList = getList;
  153. return true;
  154. }
  155. return false;
  156. }
  157. public Dictionary<UUID, ScriptStructure> GetScripts(uint localID)
  158. {
  159. lock (scriptLock)
  160. {
  161. if (Scripts.ContainsKey(localID) == false)
  162. return null;
  163. return Scripts[localID];
  164. }
  165. }
  166. #endregion
  167. public void ExecuteCommand(EventParams p)
  168. {
  169. ScriptStructure ss = new ScriptStructure();
  170. if (TryGetScript(p.LocalID, p.ItemID, ref ss))
  171. ExecuteCommand(ref ss, p);
  172. }
  173. public void ExecuteCommand(ref ScriptStructure scriptContainer, EventParams p)
  174. {
  175. m_log.DebugFormat("[{0}] ######################################################", Name);
  176. m_log.DebugFormat("[{0}] Command execution ItemID {1}: \"{2}\".", Name, scriptContainer.ItemID, p.EventName);
  177. scriptContainer.ExecuteEvent(p);
  178. m_log.DebugFormat("[{0}] ######################################################", Name);
  179. }
  180. }
  181. }