Changeset 10731 for trunk/sources/HeuristicLab.Scripting/3.3/Script.cs
- Timestamp:
- 04/08/14 23:28:40 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Scripting/3.3/Script.cs
r10727 r10731 29 29 using System.Reflection; 30 30 using System.Text; 31 using System.Text.RegularExpressions;32 using System.Threading;33 31 using HeuristicLab.Common; 34 32 using HeuristicLab.Common.Resources; … … 38 36 39 37 namespace HeuristicLab.Scripting { 40 [Item("C# Script", "An empty C# script.")]41 [Creatable("Scripts")]42 38 [StorableClass] 43 public sealed class Script : NamedItem, IStorableContent { 44 #region Constants 45 private const string ExecuteMethodName = "Execute"; 46 private const string CodeTemplate = 47 @"// use 'vars' to access variables in the script's variable store (e.g. vars.x = 5) 48 // use 'vars.Contains(string)' to check if a variable exists 49 // use 'vars.Clear()' to remove all variables 50 // use 'foreach (KeyValuePair<string, object> v in vars) { ... }' to iterate over all variables 51 52 using System; 53 using System.Linq; 54 using System.Collections.Generic; 55 using HeuristicLab.Common; 56 using HeuristicLab.Core; 57 using HeuristicLab.Data; 58 59 public class UserScript : HeuristicLab.Scripting.UserScriptBase { 60 public override void Main() { 61 // type your code here 62 } 63 64 // implement further classes and methods 65 66 }"; 67 #endregion 39 public class Script : NamedItem { 40 protected virtual string CodeTemplate { 41 get { return string.Empty; } 42 } 68 43 69 44 #region Fields & Properties 70 private UserScriptBase compiledScript;71 72 public string Filename { get; set; }73 74 45 public static new Image StaticItemImage { 75 46 get { return VSImageLibrary.Script; } … … 77 48 78 49 [Storable] 79 private VariableStore variableStore;80 public VariableStore VariableStore {81 get { return variableStore; }82 }83 84 [Storable]85 50 private string code; 86 public string Code {51 public virtual string Code { 87 52 get { return code; } 88 53 set { 89 54 if (value == code) return; 90 55 code = value; 91 compiledScript = null;92 56 OnCodeChanged(); 93 57 } … … 95 59 96 60 private string compilationUnitCode; 97 public string CompilationUnitCode {61 public virtual string CompilationUnitCode { 98 62 get { return compilationUnitCode; } 99 63 } 100 64 101 65 private CompilerErrorCollection compileErrors; 102 public CompilerErrorCollection CompileErrors {66 public virtual CompilerErrorCollection CompileErrors { 103 67 get { return compileErrors; } 104 68 private set { … … 111 75 #region Construction & Initialization 112 76 [StorableConstructor] 113 pr ivateScript(bool deserializing) : base(deserializing) { }114 pr ivateScript(Script original, Cloner cloner)77 protected Script(bool deserializing) : base(deserializing) { } 78 protected Script(Script original, Cloner cloner) 115 79 : base(original, cloner) { 116 80 code = original.code; 117 variableStore = new VariableStore();118 81 compilationUnitCode = original.compilationUnitCode; 119 82 if (original.compileErrors != null) … … 124 87 description = ItemDescription; 125 88 code = CodeTemplate; 126 variableStore = new VariableStore();127 89 } 128 90 public Script(string code) … … 136 98 #endregion 137 99 138 private void RegisterScriptEvents() { 139 if (compiledScript == null) return; 140 compiledScript.ConsoleOutputChanged += compiledScript_ConsoleOutputChanged; 100 #region Compilation 101 protected virtual CSharpCodeProvider CodeProvider { 102 get { 103 return new CSharpCodeProvider( 104 new Dictionary<string, string> { 105 {"CompilerVersion", "v4.0"}, // support C# 4.0 syntax 106 }); 107 } 141 108 } 142 109 143 private void DeregisterScriptEvents() { 144 if (compiledScript == null) return; 145 compiledScript.ConsoleOutputChanged -= compiledScript_ConsoleOutputChanged; 146 } 147 148 #region Compilation 149 private CSharpCodeProvider codeProvider = 150 new CSharpCodeProvider( 151 new Dictionary<string, string> { 152 { "CompilerVersion", "v4.0" }, // support C# 4.0 syntax 153 }); 154 155 private CompilerResults DoCompile() { 110 protected virtual CompilerResults DoCompile() { 156 111 var parameters = new CompilerParameters { 157 112 GenerateExecutable = false, … … 166 121 var unit = CreateCompilationUnit(); 167 122 var writer = new StringWriter(); 168 codeProvider.GenerateCodeFromCompileUnit(123 CodeProvider.GenerateCodeFromCompileUnit( 169 124 unit, 170 125 writer, … … 174 129 }); 175 130 compilationUnitCode = writer.ToString(); 176 return codeProvider.CompileAssemblyFromDom(parameters, unit);131 return CodeProvider.CompileAssemblyFromDom(parameters, unit); 177 132 } 178 133 179 public v oidCompile() {134 public virtual Assembly Compile() { 180 135 var results = DoCompile(); 181 compiledScript = null;182 136 CompileErrors = results.Errors; 183 137 if (results.Errors.HasErrors) { … … 188 142 .AppendLine(error.ErrorText); 189 143 } 190 throw new Exception(string.Format( 191 "Compilation of \"{0}\" failed:{1}{2}", 192 Name, Environment.NewLine, 193 sb.ToString())); 144 throw new Exception(string.Format("Compilation of \"{0}\" failed:{1}{2}", 145 Name, Environment.NewLine, sb.ToString())); 194 146 } else { 195 var assembly = results.CompiledAssembly; 196 var types = assembly.GetTypes(); 197 DeregisterScriptEvents(); 198 compiledScript = (UserScriptBase)Activator.CreateInstance(types[0]); 199 RegisterScriptEvents(); 147 return results.CompiledAssembly; 200 148 } 201 149 } 202 150 203 public IEnumerable<Assembly> GetAssemblies() {151 public virtual IEnumerable<Assembly> GetAssemblies() { 204 152 var assemblies = new List<Assembly>(); 205 153 foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) { … … 217 165 } 218 166 219 private readonly Regex SafeTypeNameCharRegex = new Regex("[_a-zA-Z0-9]+"); 220 private readonly Regex SafeTypeNameRegex = new Regex("[_a-zA-Z][_a-zA-Z0-9]*"); 221 222 private CodeCompileUnit CreateCompilationUnit() { 167 protected virtual CodeCompileUnit CreateCompilationUnit() { 223 168 var unit = new CodeSnippetCompileUnit(code); 224 169 return unit; 225 170 } 226 227 public string CompiledTypeName {228 get {229 var sb = new StringBuilder();230 var strings = SafeTypeNameCharRegex.Matches(Name)231 .Cast<Match>()232 .Select(m => m.Value);233 foreach (string s in strings)234 sb.Append(s);235 return SafeTypeNameRegex.Match(sb.ToString()).Value;236 }237 }238 171 #endregion 239 172 240 private Thread scriptThread;241 public void Execute() {242 if (compiledScript == null) return;243 var executeMethod = typeof(UserScriptBase).GetMethod(ExecuteMethodName, BindingFlags.NonPublic | BindingFlags.Instance);244 if (executeMethod != null) {245 scriptThread = new Thread(() => {246 Exception ex = null;247 try {248 OnScriptExecutionStarted();249 executeMethod.Invoke(compiledScript, new[] { VariableStore });250 } catch (ThreadAbortException) {251 // the execution was cancelled by the user252 } catch (TargetInvocationException e) {253 ex = e.InnerException;254 } finally {255 OnScriptExecutionFinished(ex);256 }257 });258 scriptThread.Start();259 }260 }261 262 public void Kill() {263 if (scriptThread.IsAlive)264 scriptThread.Abort();265 }266 267 private void compiledScript_ConsoleOutputChanged(object sender, EventArgs<string> e) {268 OnConsoleOutputChanged(e.Value);269 }270 271 173 public event EventHandler CodeChanged; 272 pr ivatevoid OnCodeChanged() {174 protected virtual void OnCodeChanged() { 273 175 var handler = CodeChanged; 274 176 if (handler != null) handler(this, EventArgs.Empty); … … 276 178 277 179 public event EventHandler CompileErrorsChanged; 278 pr ivatevoid OnCompileErrorsChanged() {180 protected virtual void OnCompileErrorsChanged() { 279 181 var handler = CompileErrorsChanged; 280 182 if (handler != null) handler(this, EventArgs.Empty); 281 183 } 282 283 public event EventHandler ScriptExecutionStarted;284 private void OnScriptExecutionStarted() {285 var handler = ScriptExecutionStarted;286 if (handler != null) handler(this, EventArgs.Empty);287 }288 289 public event EventHandler<EventArgs<Exception>> ScriptExecutionFinished;290 private void OnScriptExecutionFinished(Exception e) {291 var handler = ScriptExecutionFinished;292 if (handler != null) handler(this, new EventArgs<Exception>(e));293 }294 295 public event EventHandler<EventArgs<string>> ConsoleOutputChanged;296 private void OnConsoleOutputChanged(string args) {297 var handler = ConsoleOutputChanged;298 if (handler != null) handler(this, new EventArgs<string>(args));299 }300 184 } 301 185 }
Note: See TracChangeset
for help on using the changeset viewer.