Beispiel #1
0
        /// <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);
            });
        }
Beispiel #2
0
        /// <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));
                }
            }
        }