Example #1
0
        public override object ReturningInvokeHappened(object[] parameterValues)
        {
            // This is only allowed if the returning method gets a IActorCompoment

            // TODO Use a CIIH or something to run the getter method asynchronously in the root actor's thread
            //CreatorInterfaceInvocationHandler creatorInvocationHandler = new CreatorInterfaceInvocationHandler(
            //    () => (IActorComponent)m_MethodBeingProxied.Invoke(m_Wrapped, parameterValues), m_Root, m_ProxyFactory);

            object subInterfaceObject = base.ReturningInvokeHappened(parameterValues);

            // Find the object's interface which implements IActor (it might have others, but this is the important one
            Type interfaceType = null;

            foreach (Type eachInterface in subInterfaceObject.GetType().GetInterfaces())
            {
                if (typeof(IActorComponent).IsAssignableFrom(eachInterface))
                {
                    interfaceType = eachInterface;
                    break;
                }
            }

            ActorInterfaceInvocationHandler invocationHandler = new ActorInterfaceInvocationHandler(subInterfaceObject, m_Root, m_ProxyFactory);

            return(m_ProxyFactory.CreateInterfaceProxy(invocationHandler, interfaceType, true));
        }
        /// <summary>
        /// Checks an object for being a callback, and proxies it to move to the right thread if it is
        /// </summary>
        /// <param name="original">The original object that might be a callback</param>
        /// <returns>The object that should now be the parameter, either just original, or a proxy for it if it was a callback</returns>
        private object ConvertParameter(object original)
        {
            // See if this parameter is, or is in, an actor
            IActor rootForObject = RootForObject(original);

            if (rootForObject != null)
            {
                Delegate originalAsDelegate = original as Delegate;
                if (originalAsDelegate != null)
                {
                    // Special case for delegates: make a new delegate that calls the existing one in the right thread
                    Type returnType = originalAsDelegate.Method.ReturnType;
                    if (returnType != typeof(void))
                    {
                        // The method has a return type, fail fast
                        throw new InvalidOperationException("The delegate " + originalAsDelegate.GetType() +
                                                            " has a non-void return type. Actors may only be given callbacks with void return types.");
                    }
                    MethodCaller delegateMethodCaller = m_ProxyFactory.CreateDelegateCaller(originalAsDelegate.GetType(), originalAsDelegate.Method);
                    ActorMethodInvocationHandler methodInvocationHandler = new ActorMethodInvocationHandler(rootForObject, originalAsDelegate, delegateMethodCaller, m_ProxyFactory, returnType, originalAsDelegate.Method);
                    return(m_ProxyFactory.CreateDelegateProxy(methodInvocationHandler, originalAsDelegate.Method, original.GetType()));
                }
                else
                {
                    // Yep, this object needs to be wrapped to move back to its actor's logical thread when it's used
                    ActorInterfaceInvocationHandler callbackInterceptor = new ActorInterfaceInvocationHandler(original, rootForObject, m_ProxyFactory);

                    // Find the object's interface which implements IActor (it might have others, but this is the important one)
                    Type interfaceType = null;
                    foreach (Type eachInterface in original.GetType().GetInterfaces())
                    {
                        if (typeof(IActor).IsAssignableFrom(eachInterface) && !eachInterface.Equals(typeof(IActor)))
                        {
                            interfaceType = eachInterface;
                            break;
                        }
                    }

                    if (interfaceType == null)
                    {
                        throw new ApplicationException("NAct encountered an internal inconsistency and will eat your cake.");
                    }

                    return(m_ProxyFactory.CreateInterfaceProxy(callbackInterceptor, interfaceType, true));
                }
            }

            return(original);
        }
Example #3
0
        /// <summary>
        /// Creates a proxy for an actor component object and places it in an existing actor
        /// </summary>
        internal CreatorInterfaceInvocationHandler(ObjectCreator <IActorComponent> creator, IActor rootObject, ProxyFactory proxyFactory)
        {
            // We need to lock on the root when using an existing actor
            ThreadPool.QueueUserWorkItem(
                delegate
            {
                Hooking.ActorCallWrapper(() =>
                {
                    IActorComponent newObject            = creator();
                    ActorInterfaceInvocationHandler temp = new ActorInterfaceInvocationHandler(newObject, rootObject, proxyFactory);

                    m_RealInvocationHandler = temp;
                    m_FinishedEvent.Set();
                });
            });
        }
Example #4
0
        /// <summary>
        /// Creates an interceptor for an object that doesn't exist yet.
        ///
        /// This will trigger its asynchronous construction.
        /// </summary>
        public CreatorInterfaceInvocationHandler(ObjectCreator <IActor> creator, ProxyFactory proxyFactory)
        {
            ThreadPool.QueueUserWorkItem(
                delegate
            {
                Hooking.ActorCallWrapper(
                    () =>
                {
                    IActor newObject = creator();
                    ActorInterfaceInvocationHandler temp = new ActorInterfaceInvocationHandler(newObject, newObject, proxyFactory);

                    m_RealInvocationHandler = temp;
                    m_FinishedEvent.Set();
                });
            });
        }
        /// <summary>
        /// Creates a proxy for an actor component object and places it in an existing actor
        /// </summary>
        internal CreatorInterfaceInvocationHandler(ObjectCreator<IActorComponent> creator, IActor rootObject, ProxyFactory proxyFactory)
        {
            // We need to lock on the root when using an existing actor
            ThreadPool.QueueUserWorkItem(
                delegate
                {
                    Hooking.ActorCallWrapper(() =>
                    {
                        IActorComponent newObject = creator();
                        ActorInterfaceInvocationHandler temp = new ActorInterfaceInvocationHandler(newObject, rootObject, proxyFactory);

                        m_RealInvocationHandler = temp;
                        m_FinishedEvent.Set();
                    });
                });
        }
        /// <summary>
        /// Creates an interceptor for an object that doesn't exist yet.
        /// 
        /// This will trigger its asynchronous construction.
        /// </summary>
        public CreatorInterfaceInvocationHandler(ObjectCreator<IActor> creator, ProxyFactory proxyFactory)
        {
            ThreadPool.QueueUserWorkItem(
                delegate
                {
                    Hooking.ActorCallWrapper(
                        () =>
                        {
                            IActor newObject = creator();
                            ActorInterfaceInvocationHandler temp = new ActorInterfaceInvocationHandler(newObject, newObject, proxyFactory);

                            m_RealInvocationHandler = temp;
                            m_FinishedEvent.Set();
                        });
                });
        }
        /// <summary>
        /// Checks an object for being a callback, and proxies it to move to the right thread if it is
        /// </summary>
        /// <param name="original">The original object that might be a callback</param>
        /// <returns>The object that should now be the parameter, either just original, or a proxy for it if it was a callback</returns>
        private object ConvertParameter(object original)
        {
            // See if this parameter is, or is in, an actor
            IActor rootForObject = RootForObject(original);

            if (rootForObject != null)
            {
                Delegate originalAsDelegate = original as Delegate;
                if (originalAsDelegate != null)
                {
                    // Special case for delegates: make a new delegate that calls the existing one in the right thread
                    Type returnType = originalAsDelegate.Method.ReturnType;
                    if (returnType != typeof(void))
                    {
                        // The method has a return type, fail fast
                        throw new InvalidOperationException("The delegate " + originalAsDelegate.GetType() +
                                                            " has a non-void return type. Actors may only be given callbacks with void return types.");
                    }
                    MethodCaller delegateMethodCaller = m_ProxyFactory.CreateDelegateCaller(originalAsDelegate.GetType(), originalAsDelegate.Method);
                    ActorMethodInvocationHandler methodInvocationHandler = new ActorMethodInvocationHandler(rootForObject, originalAsDelegate, delegateMethodCaller, m_ProxyFactory, returnType, originalAsDelegate.Method);
                    return m_ProxyFactory.CreateDelegateProxy(methodInvocationHandler, originalAsDelegate.Method, original.GetType());
                }
                else
                {
                    // Yep, this object needs to be wrapped to move back to its actor's logical thread when it's used
                    ActorInterfaceInvocationHandler callbackInterceptor = new ActorInterfaceInvocationHandler(original, rootForObject, m_ProxyFactory);

                    // Find the object's interface which implements IActor (it might have others, but this is the important one)
                    Type interfaceType = null;
                    foreach (Type eachInterface in original.GetType().GetInterfaces())
                    {
                        if (typeof(IActor).IsAssignableFrom(eachInterface) && !eachInterface.Equals(typeof(IActor)))
                        {
                            interfaceType = eachInterface;
                            break;
                        }
                    }

                    if (interfaceType == null)
                    {
                        throw new ApplicationException("NAct encountered an internal inconsistency and will eat your cake.");
                    }

                    return m_ProxyFactory.CreateInterfaceProxy(callbackInterceptor, interfaceType, true);
                }
            }

            return original;
        }
        public override object ReturningInvokeHappened(object[] parameterValues)
        {
            // This is only allowed if the returning method gets a IActorCompoment

            // TODO Use a CIIH or something to run the getter method asynchronously in the root actor's thread
            //CreatorInterfaceInvocationHandler creatorInvocationHandler = new CreatorInterfaceInvocationHandler(
            //    () => (IActorComponent)m_MethodBeingProxied.Invoke(m_Wrapped, parameterValues), m_Root, m_ProxyFactory);

            object subInterfaceObject = base.ReturningInvokeHappened(parameterValues);

            // Find the object's interface which implements IActor (it might have others, but this is the important one
            Type interfaceType = null;
            foreach (Type eachInterface in subInterfaceObject.GetType().GetInterfaces())
            {
                if (typeof(IActorComponent).IsAssignableFrom(eachInterface))
                {
                    interfaceType = eachInterface;
                    break;
                }
            }

            ActorInterfaceInvocationHandler invocationHandler = new ActorInterfaceInvocationHandler(subInterfaceObject, m_Root, m_ProxyFactory);

            return m_ProxyFactory.CreateInterfaceProxy(invocationHandler, interfaceType, true);
        }