static object UnpackExt8(byte a, BinaryReader reader)
        {
            var length  = reader.ReadByte();
            var extType = reader.ReadByte();

            if (extType != 10)
            {
                throw new InvalidOperationException("Only extension type 10 (Citizen funcref) is handled by this class.");
            }

            var funcRefData             = reader.ReadBytes(length);
            var remoteFunctionReference = new RemoteFunctionReference(funcRefData);

            return(new CallbackDelegate(delegate(object[] args)
            {
                var byteData = MsgPackSerializer.Serialize(args);

                var returnByteData = remoteFunctionReference.InvokeNative(byteData);

                var returnData = Deserialize(returnByteData) as List <object>;

                if (returnData == null || returnData.Count == 0)
                {
                    return null;
                }

                return (returnData)[0];
            }));
        }
示例#2
0
        protected override void PackToCore(MsgPack.Packer packer, Delegate objectTree)
        {
            if (objectTree is CallbackDelegate)
            {
                var funcRef = objectTree.Method.DeclaringType?.GetFields(BindingFlags.NonPublic |
                                                                         BindingFlags.Instance |
                                                                         BindingFlags.Public |
                                                                         BindingFlags.Static).FirstOrDefault(a => a.FieldType == typeof(RemoteFunctionReference));

                if (funcRef == null)
                {
                    throw new ArgumentException("The CallbackDelegate does not contain a RemoteFunctionReference capture.");
                }

                RemoteFunctionReference fr = (RemoteFunctionReference)funcRef.GetValue(objectTree.Target);

                packer.PackExtendedTypeValue(10, fr.Duplicate());
            }
            else
            {
                var    funcRefDetails = FunctionReference.Create(objectTree);
                string refType        = InternalManager.CanonicalizeRef(funcRefDetails.Identifier);

                packer.PackExtendedTypeValue(10, Encoding.UTF8.GetBytes(refType));
            }
        }
示例#3
0
        static object CreateRemoteFunctionReference(byte[] funcRefData)
        {
            var remoteFunctionReference = new RemoteFunctionReference(funcRefData);

            return(new CallbackDelegate(delegate(object[] args)
            {
                var byteData = MsgPackSerializer.Serialize(args);

                var returnByteData = remoteFunctionReference.InvokeNative(byteData);

                var returnData = Deserialize(returnByteData) as List <object>;

                if (returnData == null || returnData.Count == 0)
                {
                    return null;
                }

                if (returnData[0] is IDictionary <string, object> obj)
                {
                    if (obj.TryGetValue("__cfx_async_retval", out dynamic asyncRef))
                    {
                        var tcs = new TaskCompletionSource <object>();

                        asyncRef(new Action <dynamic, dynamic>((res, err) =>
                        {
                            if (err != null && err != false)
                            {
                                tcs.SetException(new Exception(err.ToString()));
                            }
                            else
                            {
                                tcs.SetResult(res[0]);
                            }
                        }));

                        return tcs.Task;
                    }
                }

                return (returnData)[0];
            }));
        }
        static object UnpackExt8(byte a, BinaryReader reader)
        {
            var length  = reader.ReadByte();
            var extType = reader.ReadByte();

            if (extType != 1)
            {
                throw new InvalidOperationException("Only extension type 1 (Citizen callback) is handled by this class.");
            }

            // read the local reference ID
            var tmpBytes  = reader.ReadBytes(4);
            var reference = BitConverter.ToUInt32(new byte[] { tmpBytes[3], tmpBytes[2], tmpBytes[1], tmpBytes[0] }, 0);

            // read the environment instance ID
            tmpBytes = reader.ReadBytes(4);
            var instance = BitConverter.ToUInt32(new byte[] { tmpBytes[3], tmpBytes[2], tmpBytes[1], tmpBytes[0] }, 0);

            // read the resource name
            tmpBytes = reader.ReadBytes(length - 8);

            var resource = Encoding.UTF8.GetString(tmpBytes, 0, tmpBytes.Length);

            var remoteFunctionReference = new RemoteFunctionReference(resource, instance, reference);

            return(new CallbackDelegate(delegate(object[] args)
            {
                var byteData = MsgPackSerializer.Serialize(args);

                var returnByteData = remoteFunctionReference.InvokeNative(byteData);

                var returnData = Deserialize(returnByteData) as List <object>;

                if (returnData == null || returnData.Count == 0)
                {
                    return null;
                }

                return (returnData)[0];
            }));
        }