PageRenderTime 97ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/Runtime/Dreaming/Script.cs

#
C# | 257 lines | 237 code | 8 blank | 12 comment | 10 complexity | b708169951514cb32b56b3764c769d3b MD5 | raw file
  1. using System;
  2. using System.Reflection;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using LuaInterface;
  7. using IronPython.Hosting;
  8. using IronPython.Runtime;
  9. using Microsoft.Scripting;
  10. using IronRuby.Hosting;
  11. using IronRuby.Runtime;
  12. using IronRuby;
  13. using Refl.Extensions;
  14. using Microsoft.Scripting.Hosting;
  15. using System.Diagnostics;
  16. using System.IO;
  17. using Jint;
  18. namespace Refl.Dreaming
  19. {
  20. public class Script : Codex , IDream
  21. {
  22. //---------------------------------------------------------------------
  23. // This class was designed using a delegate approach combined with
  24. // an object of type dynamic for the engine. The delegate approach
  25. // is very usefull, because it prevents the code from checking
  26. // the language every time the methods Invoke, InsertObject and
  27. // RetrieveObject are called.
  28. //---------------------------------------------------------------------
  29. #region 'Properties'
  30. internal dynamic _Engine;
  31. internal ScriptScope _Scope = null;
  32. internal ScriptInfo Info;
  33. public string Name
  34. {
  35. get { if (Info._RequireNameUpdate) { this.UpdateName(); } return Info._Name; }
  36. }
  37. internal List<DreamError> _Errors;
  38. public List<DreamError> Errors
  39. {
  40. get { return _Errors; }
  41. }
  42. internal bool _HasErrors = false;
  43. public bool HasErrors
  44. {
  45. get { return _HasErrors; }
  46. }
  47. //bool-returning action
  48. internal Func<bool> _Invoker;
  49. internal Action<string, object> _Setter;
  50. internal Func<string, dynamic> _Getter;
  51. #endregion
  52. public Script(string code, ScriptLanguage language) : base(code, (Language)language)
  53. {
  54. Info = new ScriptInfo();
  55. Info.Language = language;
  56. UpdateName();
  57. switch (language)
  58. {
  59. case ScriptLanguage.Brainfuck:
  60. break;
  61. case ScriptLanguage.IronPython:
  62. _Engine = Python.CreateEngine();
  63. _Scope = _Engine.CreateScope();
  64. _Invoker = ipy_invoke;
  65. _Getter = ipy_get;
  66. _Setter = ipy_set;
  67. break;
  68. case ScriptLanguage.IronRuby:
  69. _Engine = Ruby.CreateEngine();
  70. _Scope = _Engine.CreateScope();
  71. _Invoker = iru_invoke;
  72. _Getter = iru_get;
  73. _Setter = iru_set;
  74. break;
  75. case ScriptLanguage.JavaScript:
  76. _Engine = new JintEngine();
  77. _Engine.DisableSecurity();
  78. _Scope = null;
  79. _Invoker = jint_invoke;
  80. _Getter = jint_get;
  81. _Setter = jint_set;
  82. break;
  83. case ScriptLanguage.Lua:
  84. _Engine = new Lua();
  85. _Scope = null; //The scope is integrated in the engine
  86. _Invoker = lua_invoke;
  87. _Getter = lua_get;
  88. _Setter = lua_set;
  89. break;
  90. }
  91. }
  92. internal void UpdateName()
  93. {
  94. //the dream name is a MD5 hash of its characteristics.
  95. //TODO: Implement Json and generate a object for this.
  96. string assembled = (string.Format("[{0}][{1}][{2}]", _Str_Code, Info.Language.ToString(), Info.Threaded.ToString()));
  97. Info._Name = assembled.GetMD5Hash();
  98. }
  99. public bool Invoke()
  100. {
  101. return _Invoker();
  102. }
  103. public void InsertObject(string name, object obj)
  104. {
  105. _Setter(name, obj);
  106. }
  107. public dynamic RetrieveObject(string name)
  108. {
  109. return _Getter(name);
  110. }
  111. public T RetrieveObject<T>(string name)
  112. {
  113. object o = _Getter(name);
  114. if (o.GetType() != typeof(T))
  115. {
  116. return default(T);
  117. }
  118. else
  119. {
  120. return (T)o;
  121. }
  122. }
  123. //----------------------------------------------------------------------
  124. //Private delegate methods
  125. #region IronPython
  126. internal void ipy_set(string name, object obj)
  127. {
  128. _Scope.SetVariable(name, obj);
  129. }
  130. internal dynamic ipy_get(string name)
  131. {
  132. return _Scope.GetVariable(name);
  133. }
  134. internal bool ipy_invoke()
  135. {
  136. try
  137. {
  138. ScriptSource source = _Engine.CreateScriptSourceFromString(_Str_Code, SourceCodeKind.AutoDetect);
  139. source.Execute(_Scope);
  140. }
  141. catch (Exception ex)
  142. {
  143. #if DEBUG
  144. Console.WriteLine();
  145. #endif
  146. if (_Errors == null) { _Errors = new List<DreamError>(); }
  147. _Errors.Add(new DreamError("Script:Invoke.IronPython/Exception", ex.Message, null, null, true));
  148. _HasErrors = true;
  149. return false;
  150. }
  151. return true;
  152. }
  153. #endregion
  154. #region Lua
  155. internal void lua_set(string name, object obj)
  156. {
  157. _Engine[name] = obj;
  158. }
  159. internal dynamic lua_get(string name)
  160. {
  161. return _Engine[name];
  162. }
  163. internal bool lua_invoke()
  164. {
  165. try
  166. {
  167. _Engine.DoString(_Str_Code);
  168. }
  169. catch (LuaException lex)
  170. {
  171. if (_Errors == null) { _Errors = new List<DreamError>(); }
  172. _Errors.Add(new DreamError("Script:Invoke.Lua/LuaException", lex.Message, null, null, true));
  173. _HasErrors = true;
  174. return false;
  175. }
  176. catch (Exception ex)
  177. {
  178. #if DEBUG
  179. Console.WriteLine();
  180. #endif
  181. if (_Errors == null) { _Errors = new List<DreamError>(); }
  182. _Errors.Add(new DreamError("Script:Invoke.Lua/Exception", ex.Message, null, null, true));
  183. _HasErrors = true;
  184. return false;
  185. }
  186. return true;
  187. }
  188. #endregion
  189. #region IronRuby
  190. internal void iru_set(string name, object obj)
  191. {
  192. _Scope.SetVariable(name, obj);
  193. }
  194. internal dynamic iru_get(string name)
  195. {
  196. return _Scope.GetVariable(name);
  197. }
  198. internal bool iru_invoke()
  199. {
  200. try
  201. {
  202. List<string> sp = new List<string>(); sp.Add("..\\..\\..\\Dreams\\IronRuby\\Lib\\ironruby\\");
  203. _Engine.SetSearchPaths(sp);
  204. ScriptSource source = _Engine.CreateScriptSourceFromString(_Str_Code, SourceCodeKind.AutoDetect);
  205. source.Execute(_Scope);
  206. }
  207. catch (Exception ex)
  208. {
  209. #if DEBUG
  210. Console.WriteLine();
  211. #endif
  212. if (_Errors == null) { _Errors = new List<DreamError>(); }
  213. _Errors.Add(new DreamError("Script:Invoke.IronRuby/Exception", ex.Message, null, null, true));
  214. _HasErrors = true;
  215. return false;
  216. }
  217. return true;
  218. }
  219. #endregion
  220. #region JavaScript
  221. internal void jint_set(string name, object obj)
  222. {
  223. _Engine.SetParameter(name, obj);
  224. }
  225. internal dynamic jint_get(string name)
  226. {
  227. return _Engine.Run("return " + name + ";");
  228. }
  229. internal bool jint_invoke()
  230. {
  231. try
  232. {
  233. _Engine.Run(_Str_Code);
  234. }
  235. catch (Exception ex)
  236. {
  237. #if DEBUG
  238. Console.WriteLine();
  239. #endif
  240. if (_Errors == null) { _Errors = new List<DreamError>(); }
  241. _Errors.Add(new DreamError("Script:Invoke.JavaScript/Exception", ex.Message, null, null, true));
  242. _HasErrors = true;
  243. return false;
  244. }
  245. return true;
  246. }
  247. #endregion
  248. }
  249. }