/// <summary> /// Creates a delegate that will execute this script when invoked. /// </summary> public ScriptRunner CreateDelegate(CancellationToken cancellationToken = default(CancellationToken)) { var executor = this.GetAggregateScriptExecutor(cancellationToken); return((globals) => { var executionState = ScriptExecutionState.Create(globals); return executor(executionState); }); }
/// <summary> /// Runs this script. /// </summary> /// <param name="globals">An object instance whose members can be accessed by the script as global variables, /// or a <see cref="ScriptState"/> instance that was the output from a previously run script.</param> /// <returns>A <see cref="ScriptState"/> that represents the state after running the script, including all declared variables and return value.</returns> public ScriptState Run(object globals = null) { var state = globals as ScriptState; if (state != null) { if (state.Script == this) { // this state is already the output of running this script. return(state); } else if (this.Previous == null) { // if this script is unbound (no previous script) then run this script bound to the state's script return(this.WithPrevious(state.Script).Run(state)); } else { // attempt to run script forward from the point after the specified state was computed. ScriptExecutionState executionState; object value; if (this.TryRunFrom(state, out executionState, out value)) { return(new ScriptState(executionState, value, this)); } else { throw new InvalidOperationException(ScriptingResources.StartingStateIncompatible); } } } else { if (_globalsType != null && globals == null) { throw new ArgumentNullException("globals"); } else if (globals != null && _globalsType != null) { var runtimeType = globals.GetType(); if (!_globalsType.IsAssignableFrom(runtimeType)) { throw new ArgumentException(string.Format(ScriptingResources.GlobalsNotAssignable, runtimeType, _globalsType)); } } // make sure we are running from a script with matching globals type if (globals != null && _globalsType == null) { return(this.WithGlobalsType(globals.GetType()).Run(globals)); } // run this script from the start with the specified globals var executionState = ScriptExecutionState.Create(globals); if (this.Previous == null) { // only single submission, so just execute it directly. var executor = this.GetExecutor(CancellationToken.None); var value = executionState.RunSubmission(executor); return(new ScriptState(executionState, value, this)); } else { // otherwise run the aggregate script. var executor = this.GetAggregateScriptExecutor(CancellationToken.None); var value = executor(executionState); return(new ScriptState(executionState, value, this)); } } }