예제 #1
0
        public void CallRef(int refIndex, byte[] argsSerialized, out IntPtr retvalSerialized, out int retvalSize)
        {
            var retvalData = FunctionReference.Invoke(refIndex, argsSerialized);

            if (retvalData != null)
            {
                if (m_retvalBuffer == IntPtr.Zero)
                {
                    m_retvalBuffer     = Marshal.AllocHGlobal(32768);
                    m_retvalBufferSize = 32768;
                }

                if (m_retvalBufferSize < retvalData.Length)
                {
                    m_retvalBuffer = Marshal.ReAllocHGlobal(m_retvalBuffer, new IntPtr(retvalData.Length));
                }

                Marshal.Copy(retvalData, 0, m_retvalBuffer, retvalData.Length);

                retvalSerialized = m_retvalBuffer;
                retvalSize       = retvalData.Length;
            }
            else
            {
                retvalSerialized = IntPtr.Zero;
                retvalSize       = 0;
            }
        }
예제 #2
0
        protected override void PackToCore(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.");
                }

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

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

                packer.PackExtendedTypeValue(10, Encoding.UTF8.GetBytes(refType));
            }
        }
예제 #3
0
        public static FunctionReference Create(Delegate method)
        {
            var reference   = new FunctionReference(method);
            var referenceId = Register(reference);

            reference.Identifier = referenceId;

            return(reference);
        }
예제 #4
0
        private static int Register(FunctionReference reference)
        {
            var thisRefId = ms_referenceId;

            ms_references[thisRefId] = reference;

            unchecked { ms_referenceId++; }

            return(thisRefId);
        }
예제 #5
0
        public static byte[] CallRef(uint reference, byte[] argsSerialized)
        {
            try
            {
                return(FunctionReference.Invoke(reference, argsSerialized));
            }
            catch (Exception e)
            {
                Debug.WriteLine("Exception while calling native reference: {0}", e.ToString());

                return(new byte[] { 0xC0 });
            }
        }
예제 #6
0
        public void CallRef(int refIndex, byte[] argsSerialized, out IntPtr retvalSerialized, out int retvalSize)
        {
            // not using using statements here as old Mono on Linux build doesn't know of these
#if IS_FXSERVER
            using (var syncContext = new SyncContextScope())
#endif
            {
                if (GameInterface.SnapshotStackBoundary(out var b))
                {
                    ScriptHost.SubmitBoundaryStart(b, b.Length);
                }

                try
                {
                    var retvalData = FunctionReference.Invoke(refIndex, argsSerialized);

                    if (retvalData != null)
                    {
                        if (m_retvalBuffer == IntPtr.Zero)
                        {
                            m_retvalBuffer     = Marshal.AllocHGlobal(32768);
                            m_retvalBufferSize = 32768;
                        }

                        if (m_retvalBufferSize < retvalData.Length)
                        {
                            m_retvalBuffer     = Marshal.ReAllocHGlobal(m_retvalBuffer, new IntPtr(retvalData.Length));
                            m_retvalBufferSize = retvalData.Length;
                        }

                        Marshal.Copy(retvalData, 0, m_retvalBuffer, retvalData.Length);

                        retvalSerialized = m_retvalBuffer;
                        retvalSize       = retvalData.Length;
                    }
                    else
                    {
                        retvalSerialized = IntPtr.Zero;
                        retvalSize       = 0;
                    }
                }
                catch (Exception e)
                {
                    retvalSerialized = IntPtr.Zero;
                    retvalSize       = 0;

                    PrintError($"reference call", e.InnerException ?? e);
                }
            }
        }
예제 #7
0
        protected override void PackToCore(MsgPack.Packer packer, Delegate objectTree)
        {
            if (objectTree is CallbackDelegate)
            {
                throw new InvalidOperationException("Resending callback delegates is currently not supported.");
            }

            var funcRefDetails = FunctionReference.Create(objectTree);

            var resourceNameBytes = Encoding.UTF8.GetBytes(funcRefDetails.Resource);
            var delegateData      = new byte[8 + resourceNameBytes.Length];

            Array.Copy(BitConverter.GetBytes(funcRefDetails.Identifier).Reverse().ToArray(), 0, delegateData, 0, 4);
            Array.Copy(BitConverter.GetBytes(funcRefDetails.Instance).Reverse().ToArray(), 0, delegateData, 4, 4);
            Array.Copy(resourceNameBytes, 0, delegateData, 8, resourceNameBytes.Length);

            packer.PackExtendedTypeValue(1, delegateData);
        }
예제 #8
0
        public void CallRef(int refIndex, byte[] argsSerialized, out IntPtr retvalSerialized, out int retvalSize)
        {
            if (GameInterface.SnapshotStackBoundary(out var b))
            {
                ScriptHost.SubmitBoundaryStart(b, b.Length);
            }

            try
            {
                var retvalData = FunctionReference.Invoke(refIndex, argsSerialized);

                if (retvalData != null)
                {
                    if (m_retvalBuffer == IntPtr.Zero)
                    {
                        m_retvalBuffer     = Marshal.AllocHGlobal(32768);
                        m_retvalBufferSize = 32768;
                    }

                    if (m_retvalBufferSize < retvalData.Length)
                    {
                        m_retvalBuffer     = Marshal.ReAllocHGlobal(m_retvalBuffer, new IntPtr(retvalData.Length));
                        m_retvalBufferSize = retvalData.Length;
                    }

                    Marshal.Copy(retvalData, 0, m_retvalBuffer, retvalData.Length);

                    retvalSerialized = m_retvalBuffer;
                    retvalSize       = retvalData.Length;
                }
                else
                {
                    retvalSerialized = IntPtr.Zero;
                    retvalSize       = 0;
                }
            }
            catch (Exception e)
            {
                retvalSerialized = IntPtr.Zero;
                retvalSize       = 0;

                PrintError($"reference call", e.InnerException ?? e);
            }
        }
예제 #9
0
 public void RemoveRef(int refIndex)
 {
     FunctionReference.Remove(refIndex);
 }
예제 #10
0
 public int DuplicateRef(int refIndex)
 {
     return(FunctionReference.Duplicate(refIndex));
 }
예제 #11
0
 public static void RemoveRef(uint reference)
 {
     FunctionReference.Remove(reference);
 }