Beispiel #1
0
 /// <summary>
 /// Enumerates all scripts in the the container, and execute the
 /// scripts that have the highest reference count first.
 /// </summary>
 protected void ExecuteScripts()
 {
     foreach (JistScript script in scriptContainer.Scripts.OrderByDescending(i => i.ReferenceCount))
     {
         try {
             ExecuteScript(script);
             RaisePercentChangedEvent("Execute");
         } catch (Exception ex) {
             ScriptLog.ErrorFormat(script.FilePathOrUri, "Execution error: " + ex.Message);
         }
     }
 }
Beispiel #2
0
        /// <summary>
        /// Executes a script, and returns it's completion value.
        /// </summary>
        public JsValue ExecuteScript(JistScript script)
        {
            if (script == null || string.IsNullOrEmpty(script.Script) == true)
            {
                return(JsValue.Undefined);
            }

            try {
                return(jsEngine.Execute(script.Script).GetCompletionValue());
            } catch (Exception ex) {
                ScriptLog.ErrorFormat(script.FilePathOrUri, "Execution error: " + ex.Message);
                return(JsValue.Undefined);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Loads a script from file into a reference-counted object, and inserts it into
        /// the script container.
        ///
        /// Scripts are /not/ executed by the javascript engine at this point.
        /// </summary>
        public JistScript LoadScript(string ScriptPath, bool IncreaseRefCount = true)
        {
            JistScript content;

            /*
             * if this script has already been called for, return the called object
             * with an incremented ref count
             */
            if (scriptContainer.Scripts.Count(i =>
                                              i.FilePathOrUri.Equals(ScriptPath, StringComparison.InvariantCultureIgnoreCase)) > 0)
            {
                content = scriptContainer.Scripts.FirstOrDefault(i =>
                                                                 i.FilePathOrUri.Equals(ScriptPath, StringComparison.InvariantCultureIgnoreCase));
                if (IncreaseRefCount)
                {
                    content.ReferenceCount++;
                }
                return(null);
            }

            content = new JistScript();
            content.FilePathOrUri  = ScriptPath;
            content.ReferenceCount = 1;

            try
            {
                content.Script = File.ReadAllText(Path.Combine(scriptsDir, content.FilePathOrUri));
            }
            catch (Exception ex)
            {
                ScriptLog.ErrorFormat("engine", "Cannot load {0}: {1}", ScriptPath, ex.Message);
                return(null);
            }

            /*
             * Script must be added to the content list before preprocessing
             * this is to prevent cyclic references between @imports, used as an include guard
             */
            scriptContainer.PreprocessScript(content);
            scriptContainer.Scripts.Add(content);

            return(content);
        }
Beispiel #4
0
        /// <summary>
        /// Creates Javascript function delegates for the type specified, and
        /// optionally by the object instance.
        ///
        /// Instance may be null, however only static methods will be regarded
        /// in this manner, since there is no 'this' pointer.
        /// </summary>
        public void CreateScriptFunctions(Type type, object instance)
        {
            Delegate functionDelegate  = null;
            Type     delegateSignature = null;
            string   functionName      = null;
            JavascriptFunctionAttribute jsAttribute = null;

            /*
             * If the class provides functionality for scripts,
             * add it into the providedpackages array.
             */
            foreach (JavascriptProvidesAttribute attrib in type.GetCustomAttributes(true).OfType <JavascriptProvidesAttribute>())
            {
                if (!providedPackages.Contains(attrib.PackageName))
                {
                    providedPackages.Add(attrib.PackageName);
                }
            }

            /*
             * look for JS methods in the type
             */
            foreach (var jsFunction in type.GetMethods().Where(i => i.GetCustomAttributes(true).OfType <JavascriptFunctionAttribute>().Any()))
            {
                if (instance == null && jsFunction.IsStatic == false ||
                    (jsAttribute = jsFunction.GetCustomAttributes(true).OfType <JavascriptFunctionAttribute>().FirstOrDefault()) == null)
                {
                    continue;
                }

                foreach (string func in jsAttribute.FunctionNames)
                {
                    functionName = func ?? jsFunction.Name;

                    try
                    {
                        /*
                         * A delegate signature type matching every single parameter type,
                         * and the return type must be appended as the very last item
                         * in the array.
                         */
                        delegateSignature = Expression.GetDelegateType(jsFunction.GetParameters().Select(i => i.ParameterType)
                                                                       .Concat(new[] { jsFunction.ReturnType }).ToArray());

                        if (instance != null)
                        {
                            functionDelegate = Delegate.CreateDelegate(delegateSignature, instance, jsFunction);
                        }
                        else
                        {
                            functionDelegate = Delegate.CreateDelegate(delegateSignature, jsFunction);
                        }

                        lock (syncRoot)
                            jsEngine.SetValue(functionName, functionDelegate);
                    }
                    catch (Exception ex)
                    {
                        ScriptLog.ErrorFormat("engine", "Error whilst creating javascript function for {0}: {1}",
                                              functionName, ex.ToString());
                        continue;
                    }
                }
            }
        }