private static string GetExceptionString(JavaScriptValue exception)
        {
            var code = JavaScriptPropertyId.FromString("Code");

            if (exception.ValueType == JavaScriptValueType.Error)
            {
                JavaScriptPropertyId messageName  = JavaScriptPropertyId.FromString("message");
                JavaScriptValue      messageValue = exception.GetProperty(messageName);
                string message = messageValue.ToString();

                double column = -1, line = -1;
                var    lineProp = JavaScriptPropertyId.FromString("line");
                var    colProp  = JavaScriptPropertyId.FromString("column");
                if (exception.HasProperty(lineProp))
                {
                    line = exception.GetProperty(lineProp).ConvertToNumber().ToDouble();
                }

                if (exception.HasProperty(colProp))
                {
                    column = exception.GetProperty(lineProp).ConvertToNumber().ToDouble();
                }

                return(string.Format("{0}, at {1}:{2}", message, (int)line, (int)column));
            }

            if (exception.ValueType == JavaScriptValueType.Object && exception.HasProperty(code))
            {
                return(exception.GetProperty(code).ConvertToString().ToString());
            }

            return(string.Format("{0}", exception.ConvertToString().ToString()));
        }
示例#2
0
        private Property VisitProperty(JavaScriptValue value)
        {
            Enum.TryParse <ValueType>(value.GetProperty("valueType".ToJavaScriptPropertyId()).ToNative() + "", out var valueType);
            var name          = value.GetProperty("name".ToJavaScriptPropertyId()).ToNative <string>();
            var propertyValue = value.GetProperty("value".ToJavaScriptPropertyId());

            switch (valueType)
            {
            case ValueType.Extension:
                var target     = propertyValue.GetProperty("target".ToJavaScriptPropertyId()).ToNative <string>();
                var type       = propertyValue.GetProperty("type".ToJavaScriptPropertyId()).ToNative <string>();
                var scriptName = string.Empty;
                if (propertyValue.HasProperty("scriptName".ToJavaScriptPropertyId()))
                {
                    scriptName = propertyValue.GetProperty("scriptName".ToJavaScriptPropertyId()).ToNative <string>();
                }
                return(new Property(name, new ShibaExtension(type, target, scriptName)));

            case ValueType.Custom:
                return(new Property(name, Singleton <ValueVisitor> .Instance.DynamicVisit(propertyValue, null)));

            case ValueType.Boolean:
            case ValueType.Number:
            case ValueType.String:
            case ValueType.Null:
                return(new Property(name, propertyValue.ToNative()));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
示例#3
0
文件: JSUrl.cs 项目: zaaack/electrino
        private static JavaScriptValue Format(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData)
        {
            JavaScriptValue obj      = arguments[1];
            string          pathName = JSValToString(obj.GetProperty(JavaScriptPropertyId.FromString("pathname"))).Replace("\\", "/");
            string          protocol = JSValToString(obj.GetProperty(JavaScriptPropertyId.FromString("protocol")));

            return(JavaScriptValue.FromString(protocol + "//" + pathName));
        }
 private JToken VisitError(JavaScriptValue value)
 {
     return new JObject
     {
         { "message", Visit(value.GetProperty(JavaScriptPropertyId.FromString("message"))) },
         { "description", Visit(value.GetProperty(JavaScriptPropertyId.FromString("description"))) },
         { "stack", Visit(value.GetProperty(JavaScriptPropertyId.FromString("stack"))) },
     };
 }
 private JToken VisitError(JavaScriptValue value)
 {
     return(new JObject
     {
         { "message", Visit(value.GetProperty(JavaScriptPropertyId.FromString("message"))) },
         { "description", Visit(value.GetProperty(JavaScriptPropertyId.FromString("description"))) },
         { "stack", Visit(value.GetProperty(JavaScriptPropertyId.FromString("stack"))) },
     });
 }
        private static bool IsNotFatalJsException(JavaScriptValue exception)
        {
            var code = JavaScriptPropertyId.FromString("Code");

            return(exception.ValueType == JavaScriptValueType.Object && exception.HasProperty(code) &&
                   exception.GetProperty(code).ConvertToString().ToString().Equals("ArmLanguageFunction"));
        }
示例#7
0
        /// <summary>
        /// For object constructed in JS, we need to create a C# representation and bind it to that
        /// object. For this, we'll use a <see cref="Dictionary{TKey,TValue}"/>. Possibly a later addition
        /// could use a custom serialization process and allow the user to control.
        /// </summary>
        private Dictionary <string, object> NewHostObject(JavaScriptValue arg)
        {
            // Create new Dictionary mapping to hold the properties, Create a new bindable JS object to replace
            // the existing one. Note: This could cause issues if these objects are used as keys.
            var d           = new Dictionary <string, object>();
            var replacement = _binder.BindObject(d);

            var propNames = (string[])ToHostArray(arg.GetOwnPropertyNames(), typeof(string[]));

            for (var i = 0; i < propNames.Length; ++i)
            {
                var propName = propNames[i];
                var propId   = JavaScriptPropertyId.FromString(propName);
                var jsProp   = arg.GetProperty(propId);

                // Copy Properties into Replacement
                replacement.SetProperty(propId, jsProp, true);

                Type propType;
                if (!TryInferType(jsProp, out propType))
                {
                    throw new Exception($"Failed to create Host representation of JS object. Property: {propName}");
                }

                d[propName] = ToHostObject(jsProp, propType);
            }

            return(d);
        }
示例#8
0
        private static bool IsPromise(JavaScriptValue value)
        {
            var id = JavaScriptPropertyId.FromString("then");

            return(value.HasProperty(id) &&
                   value.GetProperty(id).ValueType == JavaScriptValueType.Function);
        }
示例#9
0
        public static void Register(JavaScriptContext context)
        {
            JavaScriptValue symbolGlobal = JavaScriptValue.GlobalObject.GetProperty("Symbol");

            modulesSymbol = symbolGlobal.GetProperty("for").CallFunction(symbolGlobal, JavaScriptValue.FromString("typescript-for-unity.importedRootModules"));
            modulesSymbol.AddRef();
            JavaScriptValue.GlobalObject.SetProperty(modulesSymbol, JavaScriptValue.CreateObject());
        }
示例#10
0
        private View VisitView(JavaScriptValue value)
        {
            var name       = value.GetProperty("name".ToJavaScriptPropertyId()).ToNative <string>();
            var properties = value.GetProperty("properties".ToJavaScriptPropertyId());
            var children   = value.GetProperty("children".ToJavaScriptPropertyId());
            var view       = new View(name, string.Empty);

            if (properties.ValueType != JavaScriptValueType.Array)
            {
                throw new ArgumentException();
            }

            if (children.ValueType != JavaScriptValueType.Array)
            {
                throw new ArgumentException();
            }

            {
                var currentIndex = 0;
                while (properties.HasIndexedProperty(currentIndex.ToJavaScriptValue()))
                {
                    view.Properties.Add(VisitProperty(properties.GetIndexedProperty(currentIndex.ToJavaScriptValue())));
                    currentIndex++;
                }
            }

            {
                var currentIndex = 0;
                while (children.HasIndexedProperty(currentIndex.ToJavaScriptValue()))
                {
                    var child = Visit(children.GetIndexedProperty(currentIndex.ToJavaScriptValue()));
                    if (child is View childView)
                    {
                        childView.Parent = view;
                        view.Children.Add(childView);
                    }
                    else
                    {
                        view.DefaultValue = child;
                    }
                    currentIndex++;
                }
            }

            return(view);
        }
        private static string GetMessage(JavaScriptValue error)
        {
            var messageProperty = JavaScriptPropertyId.FromString("message");
            var message         = error.HasProperty(messageProperty)
                ? error.GetProperty(messageProperty).ConvertToString().ToString()
                : "Promise rejected.";

            return(message);
        }
        private void PrintScriptException(JavaScriptValue exception)
        {
            // Get message.
            JavaScriptPropertyId messageName  = JavaScriptPropertyId.FromString("message");
            JavaScriptValue      messageValue = exception.GetProperty(messageName);
            string message = messageValue.ToString();

            Log(string.Format("chakrahost: exception: {0}", message));
        }
示例#13
0
        private static void PrintScriptException(JavaScriptValue exception)
        {
            //
            // Get message.
            //

            JavaScriptPropertyId messageName  = JavaScriptPropertyId.FromString("message");
            JavaScriptValue      messageValue = exception.GetProperty(messageName);
            string message = messageValue.ToString();

            Console.Error.WriteLine("chakrahost: exception: {0}", message);
        }
示例#14
0
        private ShibaObject VisitJavascriptObject(JavaScriptValue value)
        {
            var propers = VisitJavascriptArray(value.GetOwnPropertyNames()).Cast <string>().ToList();
            var obj     = new ShibaObject();

            foreach (var name in propers)
            {
                obj.TryAdd(name, Visit(value.GetProperty(name.ToJavaScriptPropertyId()), null));
            }

            return(obj);
        }
示例#15
0
        public static string CompileTypescript(string code)
        {
            JavaScriptValue ts = JavaScriptValue.GlobalObject
                                 .GetProperty("ts");

            JavaScriptValue compileOptions = JavaScriptValue.CreateObject();

            compileOptions.SetProperty(
                "target",
                ts.GetProperty("ScriptTarget").GetProperty("ES2017") // http://kangax.github.io/compat-table/es2016plus/
                );

            string compiledCode = ts
                                  .GetProperty("transpile")
                                  .CallFunction(
                JavaScriptValue.Undefined,
                JavaScriptValue.FromString(code),
                compileOptions
                ).ToString();

            return(compiledCode);
        }
        public static int?Length(this JavaScriptValue v)
        {
            switch (v.ValueType)
            {
            case JavaScriptValueType.Array:
            case JavaScriptValueType.ArrayBuffer:
            case JavaScriptValueType.TypedArray:
                return(v.GetProperty(JavaScriptPropertyId.FromString("length")).ConvertToNumber().ToInt32());

            default:
                return(null);
            }
        }
        private JToken VisitObject(JavaScriptValue value)
        {
            var jsonObject = new JObject();
            var properties = Visit(value.GetOwnPropertyNames()).ToObject <string[]>();

            foreach (var property in properties)
            {
                var propertyId    = JavaScriptPropertyId.FromString(property);
                var propertyValue = value.GetProperty(propertyId);
                jsonObject.Add(property, Visit(propertyValue));
            }

            return(jsonObject);
        }
        private JToken VisitArray(JavaScriptValue value)
        {
            var array = new JArray();
            var propertyId = JavaScriptPropertyId.FromString("length");
            var length = (int)value.GetProperty(propertyId).ToDouble();
            for (var i = 0; i < length; ++i)
            {
                var index = JavaScriptValue.FromInt32(i);
                var element = value.GetIndexedProperty(index);
                array.Add(Visit(element));
            }

            return array;
        }
        private JToken VisitArray(JavaScriptValue value)
        {
            var array      = new JArray();
            var propertyId = JavaScriptPropertyId.FromString("length");
            var length     = (int)value.GetProperty(propertyId).ToDouble();

            for (var i = 0; i < length; ++i)
            {
                var index   = JavaScriptValue.FromInt32(i);
                var element = value.GetIndexedProperty(index);
                array.Add(Visit(element));
            }

            return(array);
        }
示例#20
0
        public static void Add(JavaScriptValue objectContext, int a, int b)
        {
            var jsArgs = new[]
            {
                objectContext,
                JavaScriptValue.FromInt32(a),
                JavaScriptValue.FromInt32(b)
            };

            Native.JsCallFunction(
                objectContext.GetProperty(JavaScriptPropertyId.FromString("add")), jsArgs,
                (ushort)jsArgs.Length, out var functionValue);

            Console.WriteLine(JsValueAsString(functionValue));
        }
示例#21
0
        public bool CanConvert(JavaScriptValue value)
        {
            if (!value.HasProperty(JavaScriptPropertyId.FromString("constructor")))
            {
                return(false);
            }
            var constructor = value.GetProperty(JavaScriptPropertyId.FromString("constructor"));

            if (!constructor.HasProperty(JavaScriptPropertyId.FromString("name")))
            {
                return(false);
            }

            var name = constructor.GetProperty(JavaScriptPropertyId.FromString("name"));

            return(name.ValueType == JavaScriptValueType.String && name.ToString() == "Promise");
        }
示例#22
0
        public object Visit(JavaScriptValue value)
        {
            const string className = "className";

            if (value.ValueType != JavaScriptValueType.Object || !value.HasProperty(className.ToJavaScriptPropertyId()))
            {
                return(value.ToNative());
            }
            var type = value.GetProperty(className.ToJavaScriptPropertyId()).ToNative <string>();

            switch (type)
            {
            case ViewType:
                return(VisitView(value));

            default: throw new ArgumentOutOfRangeException();
            }
        }
示例#23
0
        private static JavaScriptValue InternalCreateConstructor(
            Type type,
            Func <JavaScriptValue[], JavaScriptValue> func,
            out JavaScriptValue prototype,
            JavaScriptValue?extends = null
            )
        {
            JavaScriptValue constructor = FunctionAllocation.CreateFunction(func);

            prototype = constructor.GetProperty("prototype");
            if (extends.HasValue)
            {
                prototype.Prototype = extends.Value;
            }

            WireUp(constructor, type, prototype);

            return(constructor);
        }
示例#24
0
        private Task <JavaScriptValue> ConvertPromiseToTask(JavaScriptValue promise)
        {
            // Get the 'then' function from the promise.
            var thenFunction = promise.GetProperty(JavaScriptPropertyId.FromString("then"));

            // Create resolve & reject callbacks and wire them to a TaskCompletionSource
            JavaScriptNativeFunction[]             state      = new JavaScriptNativeFunction[2];
            TaskCompletionSource <JavaScriptValue> completion = new TaskCompletionSource <JavaScriptValue>(state);
            var resolveFunc = JavaScriptValue.CreateFunction(
                state[0] = (callee, call, arguments, count, data) =>
            {
                if (count > 1)
                {
                    completion.TrySetResult(arguments[1]);
                }
                else
                {
                    completion.TrySetResult(JavaScriptValue.Undefined);
                }

                return(JavaScriptValue.Invalid);
            });
            var rejectFunc = JavaScriptValue.CreateFunction(
                state[1] = (callee, call, arguments, count, data) =>
            {
                if (count > 1)
                {
                    completion.TrySetException(new JavaScriptException(arguments[1]));
                }
                else
                {
                    completion.TrySetException(
                        new JavaScriptException(JavaScriptValue.FromString("Unknown exception in JavaScript promise rejection.")));
                }
                return(JavaScriptValue.Invalid);
            });

            // Register the callbacks with the promise using the 'then' function.
            thenFunction.CallFunction(promise, resolveFunc, rejectFunc);

            // Return a task which will complete when the promise completes.
            return(completion.Task);
        }
示例#25
0
        /// <summary>
        /// Converts a <see cref="JavaScriptValue"/> array into a host array.
        /// </summary>
        public object ToHostArray(JavaScriptValue arg, Type toType)
        {
            if (!toType.IsArray)
            {
                throw new Exception($"Cannot convert javascript array to type: {toType}");
            }

            var elementType = toType.GetElementType();
            var length      = arg.GetProperty(JavaScriptPropertyId.FromString("length")).ToInt32();
            var resultArray = Array.CreateInstance(elementType, length);

            for (int i = 0; i < length; ++i)
            {
                var atIndex = arg.GetIndexedProperty(JavaScriptValue.FromInt32(i));
                resultArray.SetValue(ToHostObject(atIndex, elementType), i);
            }

            return(resultArray);
        }
示例#26
0
        /// <summary>
        /// Determines whether or not the <see cref="Type"/> is a valid JS type for array conversions.
        /// </summary>
        private static bool IsArrayType(JavaScriptValue value, JsBinder bindingData, Type type)
        {
            if (!type.IsArray)
            {
                return(false);
            }

            // Check length, if empty, we can assume it matches any of the array types
            var length = value.GetProperty(JavaScriptPropertyId.FromString("length")).ToInt32();

            if (length <= 0)
            {
                return(true);
            }

            // Look at the first element, type check against the host array element type
            var firstElement = value.GetIndexedProperty(JavaScriptValue.FromInt32(0));
            var elementType  = type.GetElementType();

            return(IsAssignable(firstElement, bindingData, elementType));
        }
示例#27
0
        public static void GetObjectProperty(JavaScriptValue objectContext, string jsonText, string property)
        {
            var jsonObject = JavaScriptValue.GlobalObject.GetProperty(
                JavaScriptPropertyId.FromString("JSON"));
            var parse = jsonObject.GetProperty(
                JavaScriptPropertyId.FromString("parse"));

            var stringInput = JavaScriptValue.FromString(jsonText);
            var parsedInput = parse.CallFunction(JavaScriptValue.GlobalObject, stringInput);

            var jsArgs = new[]
            {
                objectContext,
                parsedInput,
                JavaScriptValue.FromString(property)
            };

            Native.JsCallFunction(
                objectContext.GetProperty(JavaScriptPropertyId.FromString("getProperty")), jsArgs,
                (ushort)jsArgs.Length, out var functionValue);

            Console.WriteLine(JsValueAsString(functionValue));
        }
        private JToken VisitObject(JavaScriptValue value)
        {
            var jsonObject = new JObject();
            var properties = Visit(value.GetOwnPropertyNames()).ToObject<string[]>();
            foreach (var property in properties)
            {
                var propertyId = JavaScriptPropertyId.FromString(property);
                var propertyValue = value.GetProperty(propertyId);
                jsonObject.Add(property, Visit(propertyValue));
            }

            return jsonObject;
        }
示例#29
0
        /// <summary>
        /// Attempts to infer the host type based on the javscript type.
        /// </summary>
        public bool TryInferType(JavaScriptValue arg, out Type type)
        {
            // TODO: This method should be used as a last line of effort to try and build a host
            // TODO: type of method call from JS objects. Would love to get rid of it altogether.
            type = null;
            switch (arg.ValueType)
            {
            case JavaScriptValueType.Undefined: return(true);

            case JavaScriptValueType.Null: return(true);

            case JavaScriptValueType.Array:
            case JavaScriptValueType.TypedArray:
            {
                var length = arg.GetProperty(JavaScriptPropertyId.FromString("length")).ToInt32();
                if (length <= 0)
                {
                    type = typeof(object[]);
                    return(true);
                }

                Type innerType;
                var  firstElement = arg.GetIndexedProperty(JavaScriptValue.FromInt32(0));
                if (TryInferType(firstElement, out innerType))
                {
                    type = innerType.MakeArrayType();
                    return(true);
                }

                type = typeof(object[]);
                return(true);
            }

            case JavaScriptValueType.Boolean:
            {
                type = typeof(bool);
                return(true);
            }

            case JavaScriptValueType.Number:
            {
                type = typeof(double);
                return(true);
            }

            case JavaScriptValueType.String:
            {
                type = typeof(string);
                return(true);
            }

            case JavaScriptValueType.Function:
            {
                type = typeof(IJsCallback);
                return(true);
            }

            case JavaScriptValueType.Object:
            {
                try
                {
                    var hostObject = ToHostBoundObject(arg, typeof(void));
                    type = hostObject.GetType();
                    return(true);
                }
                catch
                {
                    type = typeof(object);
                    return(true);
                }
            }
            }

            return(false);
        }
示例#30
0
        /// <summary>
        /// Creates and caches a multicast delegate wrapper which forwards parameters into the JS
        /// callback.
        /// </summary>
        /// <remarks>
        /// This currently handles well defined delegates (with Invoke). For instance:
        /// <see cref="Action{T}"/> and <see cref="Func{TResult}"/> work appropriately.
        /// Some of the parameter handling may need some work (ie: <c>params T[] rest</c>).
        ///
        /// This conversion occurs when executing javascript code needs to pass a callback to
        /// C#. Instead of forcing implementers to use <see cref="JavaScriptNativeFunction"/>,
        /// we dynamically build the callback methods using the <see cref="Expression"/> utility
        /// class. Assuming a callback of type <see cref="Func{int, string, float}"/>, the following
        /// will build an expression tree similar to the following:
        /// <example>
        /// <code>
        /// .Block(JavaScriptValue $returnValue)
        /// {
        ///   .Try
        ///   {
        ///     .Block()
        ///     {
        ///       $returnValue = .Call .Constant[JavaScriptValue](JavaScriptValue).CallFunction(
        ///         .NewArray JavaScriptValue[]
        ///         {
        ///           .Constant[JavaScriptValue](JavaScriptValue),
        ///           .Call .JsInterop.ToJsObject((object)$arg1_0, .Constant[Type](int)),
        ///           .Call .JsInterop.ToJsObject($arg2_1, .Constant[Type](string))
        ///         });
        ///       (float) .Call JsInterop.ToJsObject($returnValue, .Constant[Type](float))
        ///     }
        ///   }
        ///   .Catch (Exception $e)
        ///   {
        ///     .Block()
        ///     {
        ///       .Call JavaScriptContext.SetException(.Call JavaScriptValue.CreateError(.Call JavaScriptValue.FromString($e.Message)));
        ///       .Default(float)
        ///     }
        ///   }
        ///   .Finally
        ///   {
        ///     .Call .Constant[.JavaScriptValue](.JavaScriptValue).Release()
        ///   }
        /// }
        /// </code>
        /// </example>
        /// </remarks>
        private object ToMulticastDelegate(JavaScriptValue arg, Type toType)
        {
            // Get the JS function reference pointer, and determine if we've adapted this function to a host delegate before.
            // If so, return the cached expression. This also ensures that the delegate passed out stays consistent.
            var fnReference = arg.Reference;

            if (_delegateCache.ContainsKey(fnReference))
            {
                return(_delegateCache[fnReference]);
            }

            var method = toType.GetMethod("Invoke");

            if (null == method)
            {
                throw new Exception($"Delegate/Function type must contain an Invoke method.");
            }

            var parameters = method.GetParameters();
            var funcLength = arg.GetProperty(JavaScriptPropertyId.FromString("length")).ToInt32();

            if (parameters.Length != funcLength)
            {
                throw new Exception($"Host function parameters: {parameters.Length} does not match JS parameters: {funcLength}");
            }

            // Target Return Type
            var returnType = method.ReturnType;

            // Increase reference count to ensure function doesn't get GC'd
            // Expression Body will Release() the reference after calling.
            arg.AddRef();

            // Create Parameter Expressions for Invoke Parameters, then wrap in conversion expressions
            var parameterExpressions = ExpressionHelper.ToParameterExpressions(parameters);
            var convertedParameters  = ParametersToJsValueParameters(parameterExpressions);

            // Define the constant expression for the JS Func argument
            var jsFunc      = Expression.Constant(arg, typeof(JavaScriptValue));
            var paramsArray = Expression.NewArrayInit(typeof(JavaScriptValue), convertedParameters);

            // Define a JavaScriptValue return value and assign it to the result of calling the JS Function
            var jsReturn       = Expression.Variable(typeof(JavaScriptValue), "returnValue");
            var assignJsReturn = Expression.Assign(jsReturn, Expression.Call(jsFunc, JsValueCallFunctionInfo, paramsArray));

            // Call the ToHostObject() method passing in the return value and return type
            // Then, cast the resulting object to the return type
            var convertCall = Expression.Call(Expression.Constant(this),
                                              ConvertMethodInfo,
                                              jsReturn,
                                              Expression.Constant(returnType));
            var conversionExpr = ExpressionHelper.ConvertExpression(convertCall, returnType);

            // Block Expression setting JavaScriptValue variable, then converting to correct host type
            var callAndConvert = Expression.Block(assignJsReturn, conversionExpr);

            // -------------------------------------------------------------------------------

            // Wrap the entire call in a try/catch/finally where we execute the callAndConvert
            // in the try, the function release in the finally, and handle Js Exceptions in Catch

            // Setup Exception.Message extraction
            var exceptionParam = Expression.Parameter(typeof(Exception), "e");
            var messageProp    = Expression.Call(JsExtractErrorInfo, exceptionParam);

            // JavaScriptContext.SetException(JavaScriptValue.FromString(e.Message));
            var message        = Expression.Call(JsValueFromString, messageProp);
            var fromString     = Expression.Call(JsValueCreateError, message);
            var setJsException = Expression.Call(JsContextSetException, fromString);

            var assignAndBody = Expression.Block(new[] { jsReturn },
                                                 Expression.TryCatch(callAndConvert,
                                                                     ExpressionHelper.CatchBlock(exceptionParam, setJsException, returnType)));

            var hostFn = Expression.Lambda(toType, assignAndBody, parameterExpressions).Compile();

            // Add to Delegate Cache for the reference
            // TODO: Look into hooking this into the GC management in JsBinder
            _delegateCache[arg.Reference] = hostFn;

            return(hostFn);
        }
示例#31
0
 private static JavaScriptValue GetFunctionByName(string name,
                                                  JavaScriptValue objectContext)
 {
     return(objectContext.GetProperty(JavaScriptPropertyId.FromString(name)));
 }
 public static JavaScriptValue GetProperty(this JavaScriptValue This, String propertyName)
 {
     return(This.GetProperty(JavaScriptPropertyId.FromString(propertyName)));
 }
示例#33
0
        public static void Register(JavaScriptContext context)
        {
            JavaScriptValue GameObjectPrototype;
            JavaScriptValue GameObjectConstructor = Bridge.CreateConstructor(
                typeof(UnityEngine.GameObject),
                (args) => {
                GameObject obj;

                if (args.Length > 1 && args[1].ValueType == JavaScriptValueType.String)
                {
                    obj = new GameObject(args[1].ToString());
                }
                else
                {
                    obj = new GameObject();
                }

                return(Bridge.CreateExternalWithPrototype(obj));
            },
                out GameObjectPrototype
                );

            JavaScriptValue
            .GlobalObject
            .GetProperty("UnityEngine")
            .SetProperty("GameObject", GameObjectConstructor);


            // Static Fields


            // Static Property Accessors


            // Static Methods

            GameObjectConstructor.SetProperty(
                "CreatePrimitive",
                Bridge.CreateFunction(
                    "CreatePrimitive",
                    (args) => {
                PrimitiveType type;
                switch (args[1].ToString().ToLower()) // TODO lowercase? can these collide?
                {
                case "capsule":
                    type = PrimitiveType.Capsule;
                    break;

                case "cube":
                    type = PrimitiveType.Cube;
                    break;

                case "cylinder":
                    type = PrimitiveType.Cylinder;
                    break;

                case "plane":
                    type = PrimitiveType.Plane;
                    break;

                case "quad":
                    type = PrimitiveType.Quad;
                    break;

                case "sphere":
                    type = PrimitiveType.Sphere;
                    break;

                default:
                    throw new System.Exception("invalid type");
                }
                return(Bridge.CreateExternalWithPrototype(GameObject.CreatePrimitive(type), GameObjectPrototype));
            }
                    )
                );


            GameObjectConstructor.SetProperty(
                "FindWithTag",
                Bridge.CreateFunction(
                    "FindWithTag",
                    (args) => Bridge.CreateExternalWithPrototype(UnityEngine.GameObject.FindWithTag(args[1].ToString()))
                    )
                );


            GameObjectConstructor.SetProperty(
                "FindGameObjectWithTag",
                Bridge.CreateFunction(
                    "FindGameObjectWithTag",
                    (args) => Bridge.CreateExternalWithPrototype(UnityEngine.GameObject.FindGameObjectWithTag(args[1].ToString()))
                    )
                );


            GameObjectConstructor.SetProperty(
                "FindGameObjectsWithTag",
                Bridge.CreateFunction(
                    "FindGameObjectsWithTag",
                    (args) => { // TODO make an array creator helper
                GameObject[] foundObjects = UnityEngine.GameObject.FindGameObjectsWithTag(args[1].ToString());
                JavaScriptValue jsArray   = JavaScriptValue.CreateArray(0);

                for (int i = 0; i < foundObjects.Length; i++)
                {
                    jsArray.SetIndexedProperty(i, Bridge.CreateExternalWithPrototype(foundObjects[i]));
                }

                return(jsArray);
            }
                    )
                );


            GameObjectConstructor.SetProperty(
                "Find",
                Bridge.CreateFunction(
                    "Find",
                    (args) => Bridge.CreateExternalWithPrototype(UnityEngine.GameObject.Find(args[1].ToString()))
                    )
                );


            // Instance Fields


            // Instance Property Accessors

            Bridge.DefineGetter(
                GameObjectPrototype,
                "transform",
                Bridge.WithExternal <UnityEngine.GameObject>((o, args) => Bridge.CreateExternalWithPrototype(o.transform))
                );


            Bridge.DefineGetterSetter(
                GameObjectPrototype,
                "layer",
                Bridge.WithExternal <UnityEngine.GameObject>((o, args) => JavaScriptValue.FromInt32(o.layer)),
                Bridge.WithExternal <UnityEngine.GameObject>((o, args) => { o.layer = args[1].ToInt32(); })
                );


            Bridge.DefineGetter(
                GameObjectPrototype,
                "activeSelf",
                Bridge.WithExternal <UnityEngine.GameObject>((o, args) => JavaScriptValue.FromBoolean(o.activeSelf))
                );


            Bridge.DefineGetter(
                GameObjectPrototype,
                "activeInHierarchy",
                Bridge.WithExternal <UnityEngine.GameObject>((o, args) => JavaScriptValue.FromBoolean(o.activeInHierarchy))
                );


            Bridge.DefineGetterSetter(
                GameObjectPrototype,
                "isStatic",
                Bridge.WithExternal <UnityEngine.GameObject>((o, args) => JavaScriptValue.FromBoolean(o.isStatic)),
                Bridge.WithExternal <UnityEngine.GameObject>((o, args) => { o.isStatic = args[1].ToBoolean(); })
                );


            Bridge.DefineGetterSetter(
                GameObjectPrototype,
                "tag",
                Bridge.WithExternal <UnityEngine.GameObject>((o, args) => JavaScriptValue.FromString(o.tag)),
                Bridge.WithExternal <UnityEngine.GameObject>((o, args) => { o.tag = args[1].ToString(); })
                );


            Bridge.DefineGetter(
                GameObjectPrototype,
                "scene",
                Bridge.WithExternal <UnityEngine.GameObject>((o, args) => Bridge.CreateExternalWithPrototype(o.scene))
                );


            Bridge.DefineGetter(
                GameObjectPrototype,
                "gameObject",
                Bridge.WithExternal <UnityEngine.GameObject>((o, args) => Bridge.CreateExternalWithPrototype(o.gameObject))
                );


            // Instance Methods

            GameObjectPrototype.SetProperty("GetComponent", Bridge.CreateFunction(Bridge.WithExternal <UnityEngine.GameObject>((o, args) => {
                string typeName;
                if (args[1].ValueType == JavaScriptValueType.Function)
                {
                    typeName = args[1].GetProperty("name").ToString();
                }
                else if (args[1].ValueType == JavaScriptValueType.String)
                {
                    typeName = args[1].ToString();
                }
                else
                {
                    throw new System.Exception("Argument passed to GetComponent must be a class or string");
                }

                System.Type type          = Bridge.GetType(typeName);
                JavaScriptValue prototype = Bridge.GetPrototype(typeName);

                return(Bridge.CreateExternalWithPrototype(
                           o.GetComponent(type),
                           prototype
                           ));
            })));


            GameObjectPrototype.SetProperty(
                "GetComponentInChildren",
                Bridge.CreateFunction(
                    "GetComponentInChildren",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => {
                string typeName = args[1].GetProperty("name").ToString();

                System.Type type          = Bridge.GetType(typeName);
                JavaScriptValue prototype = Bridge.GetPrototype(typeName);

                if (args.Length == 2)
                {
                    return(Bridge.CreateExternalWithPrototype(
                               o.GetComponentInChildren(type),
                               prototype
                               ));
                }
                else
                {
                    return(Bridge.CreateExternalWithPrototype(
                               o.GetComponentInChildren(type, args[2].ToBoolean()),
                               prototype
                               ));
                }
            })
                    )
                );

            GameObjectPrototype.SetProperty(
                "GetComponentInParent",
                Bridge.CreateFunction(
                    "GetComponentInParent",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => {
                string typeName = args[1].GetProperty("name").ToString();

                System.Type type          = Bridge.GetType(typeName);
                JavaScriptValue prototype = Bridge.GetPrototype(typeName);

                return(Bridge.CreateExternalWithPrototype(
                           o.GetComponentInParent(type),
                           prototype
                           ));
            })
                    )
                );


            GameObjectPrototype.SetProperty(
                "GetComponents",
                Bridge.CreateFunction(
                    "GetComponents",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => {
                string typeName = args[1].GetProperty("name").ToString();

                System.Type type          = Bridge.GetType(typeName);
                JavaScriptValue prototype = Bridge.GetPrototype(typeName);


                JavaScriptValue array = JavaScriptValue.CreateArray(0);

                foreach (var component in o.GetComponents(type))
                {
                    array.GetProperty("push").CallFunction(array, Bridge.CreateExternalWithPrototype(
                                                               component,
                                                               prototype
                                                               ));
                }

                return(array);
            })
                    )
                );


            GameObjectPrototype.SetProperty(
                "GetComponentsInChildren",
                Bridge.CreateFunction(
                    "GetComponentsInChildren",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => {
                string typeName = args[1].GetProperty("name").ToString();

                System.Type type          = Bridge.GetType(typeName);
                JavaScriptValue prototype = Bridge.GetPrototype(typeName);
                bool includeInactive      = args.Length == 3 ? args[2].ToBoolean() : false;

                JavaScriptValue array = JavaScriptValue.CreateArray(0);

                foreach (var component in o.GetComponentsInChildren(type, includeInactive))
                {
                    array.GetProperty("push").CallFunction(array, Bridge.CreateExternalWithPrototype(
                                                               component,
                                                               prototype
                                                               ));
                }

                return(array);
            })
                    )
                );


            GameObjectPrototype.SetProperty(
                "GetComponentsInParent",
                Bridge.CreateFunction(
                    "GetComponentsInParent",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => {
                string typeName = args[1].GetProperty("name").ToString();

                System.Type type          = Bridge.GetType(typeName);
                JavaScriptValue prototype = Bridge.GetPrototype(typeName);
                bool includeInactive      = args.Length == 3 ? args[2].ToBoolean() : false;

                JavaScriptValue array = JavaScriptValue.CreateArray(0);

                foreach (var component in o.GetComponentsInParent(type, includeInactive))
                {
                    array.GetProperty("push").CallFunction(array, Bridge.CreateExternalWithPrototype(
                                                               component,
                                                               prototype
                                                               ));
                }

                return(array);
            })
                    )
                );


            GameObjectPrototype.SetProperty(
                "SendMessageUpwards",
                Bridge.CreateFunction(
                    "SendMessageUpwards",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => o.SendMessageUpwards(args[1].ToString(), Bridge.GetExternal <UnityEngine.SendMessageOptions>(args[2])))
                    )
                );


            GameObjectPrototype.SetProperty(
                "SendMessage",
                Bridge.CreateFunction(
                    "SendMessage",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => o.SendMessage(args[1].ToString(), Bridge.GetExternal <UnityEngine.SendMessageOptions>(args[2])))
                    )
                );


            GameObjectPrototype.SetProperty(
                "BroadcastMessage",
                Bridge.CreateFunction(
                    "BroadcastMessage",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => o.BroadcastMessage(args[1].ToString(), Bridge.GetExternal <UnityEngine.SendMessageOptions>(args[2])))
                    )
                );


            GameObjectPrototype.SetProperty(
                "AddComponent",
                Bridge.CreateFunction(
                    "AddComponent",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => {
                string typeName = args[1].GetProperty("name").ToString();

                System.Type type          = Bridge.GetType(typeName);
                JavaScriptValue prototype = Bridge.GetPrototype(typeName);

                return(Bridge.CreateExternalWithPrototype(o.AddComponent(type), prototype));
            })
                    )
                );


            /*
             * GameObject AddComponent
             * method has generics
             */


            GameObjectPrototype.SetProperty(
                "SetActive",
                Bridge.CreateFunction(
                    "SetActive",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => o.SetActive(args[1].ToBoolean()))
                    )
                );


            GameObjectPrototype.SetProperty(
                "CompareTag",
                Bridge.CreateFunction(
                    "CompareTag",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => JavaScriptValue.FromBoolean(o.CompareTag(args[1].ToString())))
                    )
                );


            GameObjectPrototype.SetProperty(
                "SendMessageUpwards",
                Bridge.CreateFunction(
                    "SendMessageUpwards",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => o.SendMessageUpwards(args[1].ToString(), Bridge.GetExternal <System.Object>(args[2]), Bridge.GetExternal <UnityEngine.SendMessageOptions>(args[3])))
                    )
                );


            GameObjectPrototype.SetProperty(
                "SendMessageUpwards",
                Bridge.CreateFunction(
                    "SendMessageUpwards",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => o.SendMessageUpwards(args[1].ToString(), Bridge.GetExternal <System.Object>(args[2])))
                    )
                );


            GameObjectPrototype.SetProperty(
                "SendMessageUpwards",
                Bridge.CreateFunction(
                    "SendMessageUpwards",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => o.SendMessageUpwards(args[1].ToString()))
                    )
                );


            GameObjectPrototype.SetProperty(
                "SendMessage",
                Bridge.CreateFunction(
                    "SendMessage",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => o.SendMessage(args[1].ToString(), Bridge.GetExternal <System.Object>(args[2]), Bridge.GetExternal <UnityEngine.SendMessageOptions>(args[3])))
                    )
                );


            GameObjectPrototype.SetProperty(
                "SendMessage",
                Bridge.CreateFunction(
                    "SendMessage",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => o.SendMessage(args[1].ToString(), Bridge.GetExternal <System.Object>(args[2])))
                    )
                );


            GameObjectPrototype.SetProperty(
                "SendMessage",
                Bridge.CreateFunction(
                    "SendMessage",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => o.SendMessage(args[1].ToString()))
                    )
                );


            GameObjectPrototype.SetProperty(
                "BroadcastMessage",
                Bridge.CreateFunction(
                    "BroadcastMessage",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => o.BroadcastMessage(args[1].ToString(), Bridge.GetExternal <System.Object>(args[2]), Bridge.GetExternal <UnityEngine.SendMessageOptions>(args[3])))
                    )
                );


            GameObjectPrototype.SetProperty(
                "BroadcastMessage",
                Bridge.CreateFunction(
                    "BroadcastMessage",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => o.BroadcastMessage(args[1].ToString(), Bridge.GetExternal <System.Object>(args[2])))
                    )
                );


            GameObjectPrototype.SetProperty(
                "BroadcastMessage",
                Bridge.CreateFunction(
                    "BroadcastMessage",
                    Bridge.WithExternal <UnityEngine.GameObject>((o, args) => o.BroadcastMessage(args[1].ToString()))
                    )
                );
        }