예제 #1
0
        public static unsafe void RegisterTypeDef(JsContext context, JsTypeDefinition jsTypeDefinition)
        {
            INativeRef proxObject = jsTypeDefinition._nativeProxy;

            byte[] finalBuffer = null;
            using (MemoryStream ms = new MemoryStream())
            {
                //serialize with our custom protocol
                //plan change to json ?

                //utf16
                BinaryWriter binWriter = new BinaryWriter(ms, System.Text.Encoding.Unicode);
                //binay format
                //1. typename
                //2. fields
                //3. method
                //4. indexer get/set
                binWriter.Write((short)1);//start marker
                context.CollectionTypeMembers(jsTypeDefinition);
                jsTypeDefinition.WriteDefinitionToStream(binWriter);
                //------------------------------------------------
                finalBuffer = ms.ToArray();

                fixed(byte *tt = &finalBuffer[0])
                {
                    proxObject.SetUnmanagedPtr(
                        ContextRegisterTypeDefinition(
                            context.NativeContextHandle.Handle,
                            0, tt, finalBuffer.Length));
                }
            }
        }
예제 #2
0
 public static void UnRegisterNativePart(INativeRef proxyObj)
 {
     if (proxyObj.HasNativeSide)
     {
         ReleaseWrapper(proxyObj.UnmanagedPtr);
         proxyObj.SetUnmanagedPtr(IntPtr.Zero);
     }
 }
예제 #3
0
        public unsafe void AnyToJsValuePtr(object obj, JsValue *output)
        {
            if (obj == null)
            {
                output->Type = JsValueType.Null;
                return;
            }
            //-----

            if (obj is INativeRef)
            {
                //extension
                INativeRef prox = (INativeRef)obj;
                output->I32  = _context.KeepAliveAdd(obj);
                output->Type = JsValueType.JsTypeWrap;
                output->Ptr  = prox.UnmanagedPtr;
                return;
            }
            //-----
            Type type = obj.GetType();
            // Check for nullable types (we will cast the value out of the box later).
            Type innerTypeOfNullable = type.ExtGetInnerTypeIfNullableValue();

            if (innerTypeOfNullable != null)
            {
                type = innerTypeOfNullable;
            }


            if (type == typeof(Boolean))
            {
                output->Type = JsValueType.Boolean;
                output->I32  = (bool)obj ? 1 : 0;
                return;
            }

            if (type == typeof(String) || type == typeof(Char))
            {
                // We need to allocate some memory on the other side;
                // will be free'd by unmanaged code.
                string strdata = obj.ToString();
                unsafe
                {
                    fixed(char *b = strdata)
                    {
                        JsContext.jsvalue_alloc_string2(b, strdata.Length, output);
                    }
                }
                output->Type = JsValueType.String;
                return;
            }
            //-----------------------------------------------------------
            if (type == typeof(Byte))
            {
                output->Type = JsValueType.Integer;
                output->I32  = (int)(byte)obj;
                return;
            }
            if (type == typeof(Int16))
            {
                output->Type = JsValueType.Integer;
                output->I32  = (int)(Int16)obj;
                return;
            }
            if (type == typeof(UInt16))
            {
                output->Type = JsValueType.Integer;
                output->I32  = (int)(UInt16)obj;
                return;
            }
            if (type == typeof(Int32))
            {
                output->Type = JsValueType.Integer;
                output->I32  = (int)obj;
                return;
            }

            if (type == typeof(UInt32))
            {
                //TODO: review Type here when send to native side
                output->Type = JsValueType.Integer;
                output->I32  = (int)(uint)obj;
                return;
            }

            if (type == typeof(Int64))
            {
                output->Type = JsValueType.Number;
                output->Num  = (double)(Int64)obj;
                return;
            }

            if (type == typeof(UInt64))
            {
                output->Type = JsValueType.Number;
                output->Num  = (double)(UInt64)obj;
                return;
            }


            if (type == typeof(Single))
            {
                output->Type = JsValueType.Number;
                output->Num  = (double)(Single)obj;
                return;
            }


            if (type == typeof(Double))
            {
                output->Type = JsValueType.Number;
                output->Num  = (double)obj;
                return;
            }

            if (type == typeof(Decimal))
            {
                //TODO: review here
                //.net decimal is larger than double?
                output->Type = JsValueType.Number;
                output->Num  = (double)(Decimal)obj;
                return;
            }

            if (type == typeof(DateTime))
            {
                output->Type = JsValueType.Date;
                output->Num  = Convert.ToInt64(((DateTime)obj).Subtract(EPOCH).TotalMilliseconds); /*(((DateTime)obj).Ticks - 621355968000000000.0 + 26748000000000.0)/10000.0*/
                return;
            }
            // Arrays of anything that can be cast to object[] are recursively convertef after
            // allocating an appropriate jsvalue on the unmanaged side.

            var array = obj as object[];

            if (array != null)
            {
                //alloc space for array
                int arrLen = array.Length;
                JsContext.jsvalue_alloc_array(arrLen, output);

                if (output->I32 != arrLen)
                {
                    throw new JsInteropException("can't allocate memory on the unmanaged side");
                }
                //

                output->Type = JsValueType.Array;
                unsafe
                {
                    JsValue *arr = (JsValue *)output->Ptr;
                    for (int i = 0; i < arrLen; i++)
                    {
                        AnyToJsValuePtr(array[i], arr + i);
                    }
                }

                return;
            }

            // Every object explicitly converted to a value becomes an entry of the
            // _keepalives list, to make sure the GC won't collect it while still in
            // use by the unmanaged Javascript engine. We don't try to track duplicates
            // because adding the same object more than one time acts more or less as
            // reference counting.
            //check

            JsTypeDefinition jsTypeDefinition = _context.GetJsTypeDefinition(type);
            INativeRef       prox2            = _context.CreateWrapper(obj, jsTypeDefinition);

            //
            output->Type = JsValueType.JsTypeWrap;
            output->Ptr  = prox2.UnmanagedPtr;
            output->I32  = prox2.ManagedIndex;
        }
예제 #4
0
 public static void UnRegisterNativePart(INativeRef proxyObj)
 {
     if (proxyObj.HasNativeSide)
     {
         ReleaseWrapper(proxyObj.UnmanagedPtr);
         proxyObj.SetUnmanagedPtr(IntPtr.Zero);
     }
 }
예제 #5
0
        public JsValue AnyToJsValue(object obj)
        {
            if (obj == null)
            {
                return new JsValue {
                           Type = JsValueType.Null
                }
            }
            ;

            if (obj is INativeRef)
            {
                //extension
                INativeRef prox = (INativeRef)obj;

                int keepAliveId = _context.KeepAliveAdd(obj);
                return(new JsValue {
                    Type = JsValueType.JsTypeWrap, Ptr = prox.UnmanagedPtr, Index = keepAliveId
                });
            }

            Type type = obj.GetType();

            // Check for nullable types (we will cast the value out of the box later).
            //if (type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
            if (type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                type = type.GenericTypeArguments[0]; //type = type.GetGenericArguments()[0];
            }
            if (type == typeof(Boolean))
            {
                return new JsValue {
                           Type = JsValueType.Boolean, I32 = (bool)obj ? 1 : 0
                }
            }
            ;

            if (type == typeof(String) || type == typeof(Char))
            {
                // We need to allocate some memory on the other side; will be free'd by unmanaged code.
                return(JsContext.jsvalue_alloc_string(obj.ToString()));
            }

            if (type == typeof(Byte))
            {
                return new JsValue {
                           Type = JsValueType.Integer, I32 = (int)(Byte)obj
                }
            }
            ;
            if (type == typeof(Int16))
            {
                return new JsValue {
                           Type = JsValueType.Integer, I32 = (int)(Int16)obj
                }
            }
            ;
            if (type == typeof(UInt16))
            {
                return new JsValue {
                           Type = JsValueType.Integer, I32 = (int)(UInt16)obj
                }
            }
            ;
            if (type == typeof(Int32))
            {
                return new JsValue {
                           Type = JsValueType.Integer, I32 = (int)obj
                }
            }
            ;
            if (type == typeof(UInt32))
            {
                return new JsValue {
                           Type = JsValueType.Integer, I32 = (int)(UInt32)obj
                }
            }
            ;

            if (type == typeof(Int64))
            {
                return new JsValue {
                           Type = JsValueType.Number, Num = (double)(Int64)obj
                }
            }
            ;
            if (type == typeof(UInt64))
            {
                return new JsValue {
                           Type = JsValueType.Number, Num = (double)(UInt64)obj
                }
            }
            ;
            if (type == typeof(Single))
            {
                return new JsValue {
                           Type = JsValueType.Number, Num = (double)(Single)obj
                }
            }
            ;
            if (type == typeof(Double))
            {
                return new JsValue {
                           Type = JsValueType.Number, Num = (double)obj
                }
            }
            ;
            if (type == typeof(Decimal))
            {
                return new JsValue {
                           Type = JsValueType.Number, Num = (double)(Decimal)obj
                }
            }
            ;

            if (type == typeof(DateTime))
            {
                return new JsValue
                       {
                           Type = JsValueType.Date,
                           Num  = Convert.ToInt64(((DateTime)obj).Subtract(EPOCH).TotalMilliseconds) /*(((DateTime)obj).Ticks - 621355968000000000.0 + 26748000000000.0)/10000.0*/
                       }
            }
            ;

            // Arrays of anything that can be cast to object[] are recursively convertef after
            // allocating an appropriate jsvalue on the unmanaged side.

            var array = obj as object[];

            if (array != null)
            {
                JsValue v = JsContext.jsvalue_alloc_array(array.Length);

                if (v.Length != array.Length)
                {
                    throw new JsInteropException("can't allocate memory on the unmanaged side");
                }
                for (int i = 0; i < array.Length; i++)
                {
                    Marshal.StructureToPtr(AnyToJsValue(array[i]), new IntPtr(v.Ptr.ToInt64() + (16 * i)), false);
                }
                return(v);
            }

            // Every object explicitly converted to a value becomes an entry of the
            // _keepalives list, to make sure the GC won't collect it while still in
            // use by the unmanaged Javascript engine. We don't try to track duplicates
            // because adding the same object more than one time acts more or less as
            // reference counting.
            //check

            var        jsTypeDefinition = _context.GetJsTypeDefinition2(type);
            INativeRef prox2            = _context.CreateWrapper(obj, jsTypeDefinition);

            //int keepAliveId2 = _context.KeepAliveAdd(prox2);
            return(new JsValue {
                Type = JsValueType.JsTypeWrap, Ptr = prox2.UnmanagedPtr, Index = prox2.ManagedIndex
            });
            //return new JsValue { Type = JsValueType.JsTypeWrap, Ptr = prox2.UnmanagedPtr, Index = keepAliveId2 };

            //return new JsValue { Type = JsValueType.Managed, Index = _context.KeepAliveAdd(obj) };
        }
#endif
    }
}