PageRenderTime 46ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/Aurora/AuroraDotNetEngine/ScriptBase/ScriptBase.cs

https://bitbucket.org/VirtualReality/async-sim-testing
C# | 630 lines | 526 code | 57 blank | 47 comment | 175 complexity | 8372738a1e4768331fbd9e79df2c8c60 MD5 | raw file
  1. /*
  2. * Copyright (c) Contributors, http://aurora-sim.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 Aurora-Sim 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 Aurora.Framework;
  28. using System;
  29. using System.Collections;
  30. using System.Collections.Generic;
  31. using System.Linq;
  32. using System.Reflection;
  33. using System.Runtime.Remoting.Lifetime;
  34. using Aurora.Framework.SceneInfo;
  35. namespace Aurora.ScriptEngine.AuroraDotNetEngine.Runtime
  36. {
  37. [Serializable]
  38. public partial class ScriptBaseClass : MarshalByRefObject, IScript, IDisposable
  39. {
  40. private readonly ScriptSponsor m_sponser;
  41. public ISponsor Sponsor
  42. {
  43. get { return m_sponser; }
  44. }
  45. private bool m_stateSaveRequired;
  46. public bool NeedsStateSaved
  47. {
  48. get
  49. {
  50. if (m_stateSaveRequired)
  51. return true;
  52. if (!m_useStateSaves)
  53. return false;
  54. if (m_lastStateSaveValues == null)
  55. m_lastStateSaveValues = m_InitialValues;
  56. Dictionary<string, object> vars = GetVars();
  57. return vars.Any(kvp => m_lastStateSaveValues[kvp.Key].ToString() != kvp.Value.ToString());
  58. }
  59. set
  60. {
  61. m_stateSaveRequired = value;
  62. if (!m_useStateSaves)
  63. return;
  64. //Besides setting the value, if we don't need one, save the vars we have for the last state save as well
  65. if (!value)
  66. m_lastStateSaveValues = GetVars();
  67. }
  68. }
  69. private Dictionary<string, object> m_lastStateSaveValues;
  70. public IScene Scene;
  71. public ISceneChildEntity Object;
  72. public bool m_useStateSaves = true;
  73. public void SetSceneRefs(IScene scene, ISceneChildEntity child, bool useStateSaves)
  74. {
  75. Scene = scene;
  76. Object = child;
  77. m_useStateSaves = useStateSaves;
  78. }
  79. public override Object InitializeLifetimeService()
  80. {
  81. try
  82. {
  83. ILease lease = (ILease) base.InitializeLifetimeService();
  84. if (lease.CurrentState == LeaseState.Initial)
  85. {
  86. // Infinite : lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
  87. lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
  88. //lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
  89. //lease.RenewOnCallTime = TimeSpan.FromMinutes(10.0);
  90. //lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
  91. }
  92. return lease;
  93. }
  94. catch (Exception)
  95. {
  96. return null;
  97. }
  98. }
  99. #if DEBUG
  100. // For tracing GC while debugging
  101. public static bool GCDummy;
  102. ~ScriptBaseClass()
  103. {
  104. GCDummy = true;
  105. }
  106. #endif
  107. public ScriptBaseClass()
  108. {
  109. m_Executor = new Executor(this);
  110. m_sponser = new ScriptSponsor();
  111. }
  112. public Executor m_Executor;
  113. public virtual long GetStateEventFlags(string state)
  114. {
  115. return (long) m_Executor.GetStateEventFlags(state);
  116. }
  117. public EnumeratorInfo ExecuteEvent(string state, string FunctionName, object[] args, EnumeratorInfo Start,
  118. out Exception ex)
  119. {
  120. return m_Executor.ExecuteEvent(state, FunctionName, args, Start, out ex);
  121. }
  122. public bool CheckSlice()
  123. {
  124. return m_Executor.CheckSlice();
  125. }
  126. private Dictionary<string, object> m_InitialValues =
  127. new Dictionary<string, object>();
  128. public Dictionary<string, IScriptApi> m_apis = new Dictionary<string, IScriptApi>();
  129. public void InitApi(IScriptApi data)
  130. {
  131. /*ILease lease = (ILease)RemotingServices.GetLifetimeService(data as MarshalByRefObject);
  132. if (lease != null)
  133. lease.Register(m_sponser);*/
  134. m_apis.Add(data.Name, data);
  135. }
  136. public void UpdateInitialValues()
  137. {
  138. m_InitialValues = GetVars();
  139. }
  140. public virtual void StateChange(string newState)
  141. {
  142. }
  143. public void Close()
  144. {
  145. m_sponser.Close();
  146. }
  147. public Dictionary<string, object> GetVars()
  148. {
  149. Dictionary<string, object> vars = new Dictionary<string, object>();
  150. Type t = GetType();
  151. FieldInfo[] fields = t.GetFields(BindingFlags.NonPublic |
  152. BindingFlags.Public |
  153. BindingFlags.Instance |
  154. BindingFlags.DeclaredOnly);
  155. foreach (FieldInfo field in fields)
  156. {
  157. if (field.FieldType == typeof (LSL_Types.list)) // ref type, copy
  158. {
  159. LSL_Types.list v = (LSL_Types.list) field.GetValue(this);
  160. if (((object) v) == null)
  161. continue; //Broken... :/
  162. Object[] data = new Object[v.Data.Length];
  163. Array.Copy(v.Data, 0, data, 0, v.Data.Length);
  164. LSL_Types.list c = new LSL_Types.list {Data = data};
  165. vars[field.Name] = c;
  166. }
  167. else if (field.FieldType == typeof (LSL_Types.LSLInteger) ||
  168. field.FieldType == typeof (LSL_Types.LSLString) ||
  169. field.FieldType == typeof (LSL_Types.LSLFloat) ||
  170. field.FieldType == typeof (Int32) ||
  171. field.FieldType == typeof (Double) ||
  172. field.FieldType == typeof (Single) ||
  173. field.FieldType == typeof (String) ||
  174. field.FieldType == typeof (Byte) ||
  175. field.FieldType == typeof (short) ||
  176. field.FieldType == typeof (LSL_Types.Vector3) ||
  177. field.FieldType == typeof (LSL_Types.Quaternion))
  178. {
  179. vars[field.Name] = field.GetValue(this);
  180. }
  181. }
  182. fields = null;
  183. t = null;
  184. return vars;
  185. }
  186. /// <summary>
  187. /// Note: this is just used for reset
  188. /// </summary>
  189. /// <param name="vars"></param>
  190. public void SetVars(Dictionary<string, object> vars)
  191. {
  192. if (!m_useStateSaves)
  193. return;
  194. Type t = GetType();
  195. FieldInfo[] fields = t.GetFields(BindingFlags.NonPublic |
  196. BindingFlags.Public |
  197. BindingFlags.Instance |
  198. BindingFlags.DeclaredOnly);
  199. foreach (FieldInfo field in fields)
  200. {
  201. if (vars.ContainsKey(field.Name))
  202. {
  203. object newVal = vars[field.Name];
  204. if (field.FieldType == typeof (LSL_Types.list))
  205. {
  206. LSL_Types.list v = (LSL_Types.list) field.GetValue(this);
  207. Object[] data = ((LSL_Types.list) (newVal)).Data;
  208. v.Data = new Object[data.Length];
  209. Array.Copy(data, 0, v.Data, 0, data.Length);
  210. field.SetValue(this, v);
  211. }
  212. else if (field.FieldType == typeof (LSL_Types.LSLInteger) ||
  213. field.FieldType == typeof (LSL_Types.LSLString) ||
  214. field.FieldType == typeof (LSL_Types.LSLFloat) ||
  215. field.FieldType == typeof (Int32) ||
  216. field.FieldType == typeof (Double) ||
  217. field.FieldType == typeof (Single) ||
  218. field.FieldType == typeof (String) ||
  219. field.FieldType == typeof (Byte) ||
  220. field.FieldType == typeof (short) ||
  221. field.FieldType == typeof (LSL_Types.Vector3) ||
  222. field.FieldType == typeof (LSL_Types.Quaternion)
  223. )
  224. {
  225. field.SetValue(this, newVal);
  226. }
  227. }
  228. }
  229. fields = null;
  230. t = null;
  231. }
  232. public string GetShortType(object o)
  233. {
  234. string tmp = o.GetType().ToString();
  235. int i = tmp.LastIndexOf('+');
  236. string type = tmp.Substring(i + 1);
  237. return type;
  238. }
  239. #region String Escaping for Save/Load States
  240. public string EscapeString(string str)
  241. {
  242. // Must escape string for lists
  243. // This escapes double quotes first, then backslashes
  244. return str.Replace("\"", "\\\"").Replace("\\", "\\\\");
  245. }
  246. public string UnEscapeString(string str)
  247. {
  248. // Must do the opposite of EscapeString
  249. // This unescapes backslashes first, then quotes
  250. return str.Replace("\\\\", "\\").Replace("\\\"", "\"");
  251. }
  252. #endregion
  253. public string ListToString(object o)
  254. {
  255. string tmp = "";
  256. string cur = "";
  257. LSL_Types.list v = (LSL_Types.list) o;
  258. foreach (object ob in v.Data)
  259. {
  260. if (ob.GetType() == typeof (LSL_Types.LSLInteger))
  261. cur = "i" + ob;
  262. else if (ob.GetType() == typeof (LSL_Types.LSLFloat))
  263. cur = "f" + ob;
  264. else if (ob.GetType() == typeof (LSL_Types.Vector3))
  265. cur = "v" + ob;
  266. else if (ob.GetType() == typeof (LSL_Types.Quaternion))
  267. cur = "q" + ob;
  268. else if (ob.GetType() == typeof (LSL_Types.LSLString))
  269. cur = "\"" + EscapeString(ob.ToString()) + "\"";
  270. else if (ob.GetType() == typeof (LSL_Types.key))
  271. cur = "k\"" + ob + "\"";
  272. else if (o.GetType() == typeof (LSL_Types.list))
  273. cur = "{" + ListToString(ob) + "}";
  274. if (tmp == "")
  275. tmp = cur;
  276. else
  277. tmp += ", " + cur;
  278. }
  279. return tmp;
  280. }
  281. public Dictionary<string, object> GetStoreVars()
  282. {
  283. Dictionary<string, object> vars = new Dictionary<string, object>();
  284. if (!m_useStateSaves)
  285. return vars;
  286. Type t = GetType();
  287. FieldInfo[] fields = t.GetFields(BindingFlags.NonPublic |
  288. BindingFlags.Public |
  289. BindingFlags.Instance |
  290. BindingFlags.DeclaredOnly);
  291. foreach (FieldInfo field in fields)
  292. {
  293. if (field.FieldType == typeof (LSL_Types.list)) // ref type, copy
  294. {
  295. string tmp = "";
  296. string cur = "";
  297. LSL_Types.list v = (LSL_Types.list) field.GetValue(this);
  298. foreach (object o in v.Data)
  299. {
  300. if (o.GetType() == typeof (LSL_Types.LSLInteger))
  301. cur = "i" + o;
  302. else if (o.GetType() == typeof (LSL_Types.LSLFloat))
  303. cur = "f" + o;
  304. else if (o.GetType() == typeof (LSL_Types.Vector3))
  305. cur = "v" + o;
  306. else if (o.GetType() == typeof (LSL_Types.Quaternion))
  307. cur = "q" + o;
  308. else if (o.GetType() == typeof (LSL_Types.LSLString))
  309. cur = "\"" + EscapeString(o.ToString()) + "\"";
  310. else if (o.GetType() == typeof (LSL_Types.key))
  311. cur = "k\"" + o + "\"";
  312. else if (o.GetType() == typeof (LSL_Types.list))
  313. cur = "{" + ListToString(o) + "}";
  314. if (tmp == "")
  315. tmp = cur;
  316. else
  317. tmp += ", " + cur;
  318. }
  319. vars[field.Name] = tmp;
  320. }
  321. else if (field.FieldType == typeof (LSL_Types.LSLInteger) ||
  322. field.FieldType == typeof (LSL_Types.LSLString) ||
  323. field.FieldType == typeof (LSL_Types.LSLFloat) ||
  324. field.FieldType == typeof (Int32) ||
  325. field.FieldType == typeof (Double) ||
  326. field.FieldType == typeof (Single) ||
  327. field.FieldType == typeof (String) ||
  328. field.FieldType == typeof (Byte) ||
  329. field.FieldType == typeof (short) ||
  330. field.FieldType == typeof (LSL_Types.Vector3) ||
  331. field.FieldType == typeof (LSL_Types.Quaternion))
  332. {
  333. vars[field.Name] = field.GetValue(this).ToString();
  334. }
  335. }
  336. fields = null;
  337. t = null;
  338. return vars;
  339. }
  340. public LSL_Types.list ParseValueToList(string inval, int start, out int end)
  341. {
  342. LSL_Types.list v = new LSL_Types.list();
  343. end = -1;
  344. char c;
  345. string tr = ",}";
  346. char[] charany = tr.ToCharArray();
  347. string param = "";
  348. int totlen = inval.Length;
  349. int len;
  350. DateTime time_limit = DateTime.Now.AddSeconds(5.0);
  351. while (true)
  352. {
  353. try
  354. {
  355. if (inval.Length == 0)
  356. v.Add(new LSL_Types.LSLString(""));
  357. else
  358. {
  359. c = inval[start++];
  360. switch (c)
  361. {
  362. case 'i':
  363. end = inval.IndexOfAny(charany, start);
  364. if (end > 0)
  365. len = end - start;
  366. else
  367. len = totlen - start;
  368. param = inval.Substring(start, len);
  369. v.Add(new LSL_Types.LSLInteger(param));
  370. break;
  371. case 'f':
  372. end = inval.IndexOfAny(charany, start);
  373. if (end > 0)
  374. len = end - start;
  375. else
  376. len = totlen - start;
  377. param = inval.Substring(start, len);
  378. v.Add(new LSL_Types.LSLFloat(param));
  379. break;
  380. case 'v':
  381. end = inval.IndexOf('>', start);
  382. if (end > 0)
  383. len = end - start;
  384. else
  385. len = totlen - start;
  386. param = inval.Substring(start, len);
  387. v.Add(new LSL_Types.Vector3(param));
  388. end++;
  389. break;
  390. case 'q':
  391. end = inval.IndexOf('>', start);
  392. if (end > 0)
  393. len = end - start;
  394. else
  395. len = totlen - start;
  396. param = inval.Substring(start, len);
  397. v.Add(new LSL_Types.Quaternion(param));
  398. end++;
  399. break;
  400. case '"':
  401. end = inval.IndexOf('"', start);
  402. while (inval[end - 1] == '\\')
  403. {
  404. int slashes = 2;
  405. while (end - slashes > 0 && inval[end - slashes] == '\\')
  406. slashes++;
  407. if ((slashes - 1)%2 == 0)
  408. end = inval.IndexOf('"', end + 1);
  409. else
  410. break;
  411. }
  412. if (end > 0)
  413. len = end - start;
  414. else
  415. len = totlen - start;
  416. param = UnEscapeString(inval.Substring(start, len));
  417. v.Add(new LSL_Types.LSLString(param));
  418. end++;
  419. break;
  420. case 'k':
  421. start++;
  422. end = inval.IndexOf('"', start);
  423. if (end > 0)
  424. len = end - start;
  425. else
  426. len = totlen - start;
  427. param = inval.Substring(start, len);
  428. v.Add(new LSL_Types.key(param));
  429. end++;
  430. break;
  431. case '{':
  432. v.Add(ParseValueToList(inval, start, out end));
  433. end++;
  434. break;
  435. default:
  436. break;
  437. }
  438. }
  439. start = end;
  440. if (start == -1 || start >= totlen || (inval[start] == '}'))
  441. break;
  442. else
  443. while ((inval[start] == ',' || inval[start] == ' ') && DateTime.Now.CompareTo(time_limit) < 0)
  444. start++;
  445. if (DateTime.Now.CompareTo(time_limit) > 0)
  446. break;
  447. }
  448. catch
  449. {
  450. }
  451. }
  452. return v;
  453. }
  454. public void SetStoreVars(Dictionary<string, object> vars)
  455. {
  456. if (!m_useStateSaves)
  457. return;
  458. m_lastStateSaveValues = vars;
  459. m_stateSaveRequired = false;
  460. //If something is setting the vars, we don't need to do a state save, as this came from a state save
  461. Type t = GetType();
  462. FieldInfo[] fields = t.GetFields(BindingFlags.NonPublic |
  463. BindingFlags.Public |
  464. BindingFlags.Instance |
  465. BindingFlags.DeclaredOnly);
  466. foreach (FieldInfo field in fields)
  467. {
  468. if (vars.ContainsKey(field.Name))
  469. {
  470. object var = vars[field.Name];
  471. if (field.FieldType == typeof (LSL_Types.list))
  472. {
  473. string val = var.ToString();
  474. int end;
  475. LSL_Types.list v = ParseValueToList(val, 0, out end);
  476. field.SetValue(this, v);
  477. }
  478. else if (field.FieldType == typeof (LSL_Types.LSLInteger))
  479. {
  480. int val = int.Parse(var.ToString());
  481. field.SetValue(this, new LSL_Types.LSLInteger(val));
  482. }
  483. else if (field.FieldType == typeof (LSL_Types.LSLString))
  484. {
  485. string val = var.ToString();
  486. field.SetValue(this, new LSL_Types.LSLString(val));
  487. }
  488. else if (field.FieldType == typeof (LSL_Types.LSLFloat))
  489. {
  490. float val = float.Parse(var.ToString());
  491. field.SetValue(this, new LSL_Types.LSLFloat(val));
  492. }
  493. else if (field.FieldType == typeof (Int32))
  494. {
  495. Int32 val = Int32.Parse(var.ToString());
  496. field.SetValue(this, val);
  497. }
  498. else if (field.FieldType == typeof (Double))
  499. {
  500. Double val = Double.Parse(var.ToString());
  501. field.SetValue(this, val);
  502. }
  503. else if (field.FieldType == typeof (Single))
  504. {
  505. Single val = Single.Parse(var.ToString());
  506. field.SetValue(this, val);
  507. }
  508. else if (field.FieldType == typeof (String))
  509. {
  510. String val = var.ToString();
  511. field.SetValue(this, val);
  512. }
  513. else if (field.FieldType == typeof (Byte))
  514. {
  515. Byte val = Byte.Parse(var.ToString());
  516. field.SetValue(this, val);
  517. }
  518. else if (field.FieldType == typeof (short))
  519. {
  520. short val = short.Parse(var.ToString());
  521. field.SetValue(this, val);
  522. }
  523. else if (field.FieldType == typeof (LSL_Types.Quaternion))
  524. {
  525. LSL_Types.Quaternion val = new LSL_Types.Quaternion(var.ToString());
  526. field.SetValue(this, val);
  527. }
  528. else if (field.FieldType == typeof (LSL_Types.Vector3))
  529. {
  530. LSL_Types.Vector3 val = new LSL_Types.Vector3(var.ToString());
  531. field.SetValue(this, val);
  532. }
  533. }
  534. }
  535. fields = null;
  536. t = null;
  537. }
  538. public void ResetVars()
  539. {
  540. if (!m_useStateSaves)
  541. return;
  542. m_Executor.ResetStateEventFlags();
  543. m_stateSaveRequired = true;
  544. SetVars(m_InitialValues);
  545. }
  546. public void NoOp()
  547. {
  548. // Does what is says on the packet. Nowt, nada, nothing.
  549. // Required for insertion after a jump label to do what it says on the packet!
  550. // With a bit of luck the compiler may even optimize it out.
  551. }
  552. public string Name
  553. {
  554. get { return "ScriptBase"; }
  555. }
  556. public void Dispose()
  557. {
  558. }
  559. private Type m_typeCache; //This shouldn't normally be used
  560. public virtual IEnumerator FireEvent(string evName, object[] parameters)
  561. {
  562. if (m_typeCache == null)
  563. m_typeCache = GetType();
  564. MethodInfo ev = m_typeCache.GetMethod(evName);
  565. if (ev != null)
  566. if (ev.ReturnType == typeof (IEnumerator))
  567. return (IEnumerator) ev.Invoke(this, parameters);
  568. else
  569. ev.Invoke(this, parameters);
  570. return null;
  571. }
  572. }
  573. }