public CreatorMethodInvocationHandler(CreatorInterfaceInvocationHandler creatorInterfaceInvocationHandler, MethodCaller methodCaller, Type returnType, MethodInfo targetMethod)
 {
     m_CreatorInterfaceInvocationHandler = creatorInterfaceInvocationHandler;
     m_MethodCaller = methodCaller;
     m_ReturnType = returnType;
     m_TargetMethod = targetMethod;
 }
 public ActorMethodInvocationHandler(IActor root, object wrapped, MethodCaller methodCaller, ProxyFactory proxyFactory, Type returnType, MethodInfo targetMethod)
     : base(proxyFactory, methodCaller, wrapped)
 {
     m_Root = root;
     m_MethodCaller = methodCaller;
     m_ProxyFactory = proxyFactory;
     m_TargetMethod = targetMethod;
 }
Example #3
0
 public ActorMethodInvocationHandler(IActor root, object wrapped, MethodCaller methodCaller, ProxyFactory proxyFactory, Type returnType, MethodInfo targetMethod)
     : base(proxyFactory, methodCaller, wrapped)
 {
     m_Root         = root;
     m_MethodCaller = methodCaller;
     m_ProxyFactory = proxyFactory;
     m_TargetMethod = targetMethod;
 }
Example #4
0
 public IMethodInvocationHandler GetInvocationHandlerFor(MethodCaller methodCaller, Type returnType, MethodInfo targetMethod)
 {
     if (m_FinishedEvent.WaitOne(0))
     {
         // m_RealInvocationHandler is already finished, forward to it
         return(m_RealInvocationHandler.GetInvocationHandlerFor(methodCaller, returnType, targetMethod));
     }
     else
     {
         // It's taking a while to construct, use something that will forward to it once it's finished
         return(new CreatorMethodInvocationHandler(this, methodCaller, returnType, targetMethod));
     }
 }
 public IMethodInvocationHandler GetInvocationHandlerFor(MethodCaller methodCaller, Type returnType, MethodInfo targetMethod)
 {
     if (m_FinishedEvent.WaitOne(0))
     {
         // m_RealInvocationHandler is already finished, forward to it
         return m_RealInvocationHandler.GetInvocationHandlerFor(methodCaller, returnType, targetMethod);
     }
     else
     {
         // It's taking a while to construct, use something that will forward to it once it's finished
         return new CreatorMethodInvocationHandler(this, methodCaller, returnType, targetMethod);
     }
 }
        /// <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 #7
0
        /// <summary>
        /// Creates something that takes a target and a parameters array, and will call the given method, having unpacked its arguments from the array.
        /// </summary>
        public MethodCaller CreateMethodCaller(MethodInfo methodToCall)
        {
            lock (m_Sync)
            {
                MethodCaller cachedCaller;
                if (m_MethodCallerCache.TryGetValue(methodToCall, out cachedCaller))
                {
                    return(cachedCaller);
                }
            }

            Action <object, object[]>       caller          = (Action <object, object[]>)CreateCallerDelegate(methodToCall, typeof(Action <object, object[]>), typeof(void));
            Func <object, object[], object> returningCaller = (Func <object, object[], object>)CreateCallerDelegate(methodToCall, typeof(Func <object, object[], object>), typeof(object));

            MethodCaller methodCaller = new MethodCaller(caller, returningCaller);

            lock (m_Sync)
            {
                m_MethodCallerCache[methodToCall] = methodCaller;
            }

            return(methodCaller);
        }
Example #8
0
        /// <summary>
        /// Creates something that, when given a delegate (compatible with the signature given here) and some parameters, will run it.
        /// </summary>
        public MethodCaller CreateDelegateCaller(Type delegateType, MethodInfo delegateSignature)
        {
            // Check the cache
            lock (m_Sync)
            {
                MethodCaller cachedCaller;
                if (m_DelegateCallerCache.TryGetValue(delegateType, out cachedCaller))
                {
                    return(cachedCaller);
                }
            }

            Action <object, object[]>       caller          = (Action <object, object[]>)CreateDelegateCallerDelegate(delegateType, delegateSignature, typeof(Action <object, object[]>), typeof(void));
            Func <object, object[], object> returningCaller = (Func <object, object[], object>)CreateDelegateCallerDelegate(delegateType, delegateSignature, typeof(Func <object, object[], object>), typeof(object));

            MethodCaller methodCaller = new MethodCaller(caller, returningCaller);

            lock (m_Sync)
            {
                m_DelegateCallerCache[delegateType] = methodCaller;
            }

            return(methodCaller);
        }
Example #9
0
 public IMethodInvocationHandler GetInvocationHandlerFor(MethodCaller methodCaller, Type returnType, MethodInfo targetMethod)
 {
     return new MyInvocationHandler(m_Parent);
 }
 public IMethodInvocationHandler GetInvocationHandlerFor(MethodCaller methodCaller, Type returnType, MethodInfo targetMethod)
 {
     return(new ActorMethodInvocationHandler(m_RootForObject, m_Original, methodCaller, m_ProxyFactory, returnType, targetMethod));
 }
 public AudienceMethodInvocationHandler(object wrapped, MethodCaller methodCaller, ProxyFactory proxyFactory)
     : base(proxyFactory, methodCaller, wrapped)
 {
 }
 protected MethodInvocationHandler(ProxyFactory proxyFactory, MethodCaller methodCaller, object wrapped)
 {
     m_ProxyFactory = proxyFactory;
     m_MethodCaller = methodCaller;
     m_Wrapped      = wrapped;
 }
Example #13
0
 public AudienceMethodInvocationHandler(object wrapped, MethodCaller methodCaller, ProxyFactory proxyFactory)
     : base(proxyFactory, methodCaller, wrapped)
 {
 }
Example #14
0
        /// <summary>
        /// Creates something that implements the given interface, and forwards all calls to the invocationHandler
        /// </summary>
        public object CreateInterfaceProxy(IInterfaceInvocationHandler invocationHandler, Type interfaceType, bool throwOnNonActorMethod)
        {
            if (!interfaceType.IsInterface)
            {
                // Only allowing interfaces for the moment, fail fast
                throw new InvalidOperationException("The type " + interfaceType +
                                                    " is not an interface, so an NAct proxy cannot be created for it.");
            }

            if (interfaceType.IsNotPublic)
            {
                throw new InvalidOperationException("The interface " + interfaceType +
                                                    " is not public, so an NAct proxy cannot be created for it.");
            }

            Type proxyType;

            lock (m_Sync)
            {
                m_InterfaceProxyCache.TryGetValue(interfaceType, out proxyType);
            }

            if (proxyType == null)
            {
                TypeBuilder typeBuilder = GetFreshType();

                ForEveryMethodIncludingSuperInterfaces(
                    interfaceType,
                    delegate(MethodInfo eachMethod)
                {
                    if (throwOnNonActorMethod && eachMethod.ReturnType != typeof(void) &&
                        !typeof(IActorComponent).IsAssignableFrom(eachMethod.ReturnType))
                    {
                        // The method has a return type, fail fast
                        throw new InvalidOperationException("The interface " + interfaceType +
                                                            " contains the method " +
                                                            eachMethod +
                                                            " which has a non-void return type. Actors may only have methods with void return types.");
                    }

                    Type[] parameterTypes       = GetParameterTypes(eachMethod);
                    MethodBuilder methodBuilder = typeBuilder.DefineMethod(eachMethod.Name,
                                                                           eachMethod.Attributes &
                                                                           ~MethodAttributes.Abstract,
                                                                           eachMethod.ReturnType, parameterTypes);

                    if (eachMethod.ReturnType == typeof(void))
                    {
                        // This is an asynchronous call, use the appropriate IMethodInvocationHandler to move it to the right thread
                        // Create a field in which to put the IMethodInvocationHandler
                        FieldBuilder invocationHandlerField =
                            typeBuilder.DefineField(InvocationHandlerNameForMethod(eachMethod),
                                                    typeof(IMethodInvocationHandler),
                                                    FieldAttributes.Private);
                        BuildForwarderMethod(methodBuilder, parameterTypes, m_InvokeHappenedMethod,
                                             invocationHandlerField);
                    }
                    else
                    {
                        // This is a request for a subinterface - create a method that will return a proxied version of it
                        FieldBuilder invocationHandlerField =
                            typeBuilder.DefineField(InvocationHandlerNameForMethod(eachMethod),
                                                    typeof(IMethodInvocationHandler),
                                                    FieldAttributes.Private);
                        BuildForwarderMethod(methodBuilder, parameterTypes, m_ReturningInvokeHappenedMethod,
                                             invocationHandlerField);
                    }
                });

                typeBuilder.AddInterfaceImplementation(interfaceType);

                // Finalise the type
                proxyType = typeBuilder.CreateType();

                // Save it in the cache (this may have raced with another thread, worst that can happen is an unused extra type is created)
                lock (m_Sync)
                {
                    m_InterfaceProxyCache[interfaceType] = proxyType;
                }
            }

            object proxyInstance = Activator.CreateInstance(proxyType);

            // Now we can write all the invocation handlers
            ForEveryMethodIncludingSuperInterfaces(
                interfaceType,
                delegate(MethodInfo eachMethod)
            {
                FieldInfo writeableInvocationHandlerField =
                    proxyType.GetField(InvocationHandlerNameForMethod(eachMethod), BindingFlags.NonPublic | BindingFlags.Instance);

                MethodCaller methodCaller = CreateMethodCaller(eachMethod);

                writeableInvocationHandlerField.SetValue(proxyInstance,
                                                         invocationHandler.GetInvocationHandlerFor(
                                                             methodCaller, eachMethod.ReturnType, eachMethod));
            });

            return(proxyInstance);
        }
Example #15
0
 public CreatorMethodInvocationHandler(CreatorInterfaceInvocationHandler creatorInterfaceInvocationHandler, MethodCaller methodCaller, Type returnType, MethodInfo targetMethod)
 {
     m_CreatorInterfaceInvocationHandler = creatorInterfaceInvocationHandler;
     m_MethodCaller = methodCaller;
     m_ReturnType   = returnType;
     m_TargetMethod = targetMethod;
 }
Example #16
0
 protected MethodInvocationHandler(ProxyFactory proxyFactory, MethodCaller methodCaller, object wrapped)
 {
     m_ProxyFactory = proxyFactory;
     m_MethodCaller = methodCaller;
     m_Wrapped = wrapped;
 }
 public IMethodInvocationHandler GetInvocationHandlerFor(MethodCaller methodCaller, Type returnType, MethodInfo targetMethod)
 {
     return new AudienceMethodInvocationHandler(m_Original, methodCaller, m_ProxyFactory);
 }
Example #18
0
        /// <summary>
        /// Creates something that takes a target and a parameters array, and will call the given method, having unpacked its arguments from the array.
        /// </summary>
        public MethodCaller CreateMethodCaller(MethodInfo methodToCall)
        {
            lock (m_Sync)
            {
                MethodCaller cachedCaller;
                if (m_MethodCallerCache.TryGetValue(methodToCall, out cachedCaller))
                {
                    return cachedCaller;
                }
            }

            Action<object, object[]> caller = (Action<object, object[]>)CreateCallerDelegate(methodToCall, typeof(Action<object, object[]>), typeof(void));
            Func<object, object[], object> returningCaller = (Func<object, object[], object>)CreateCallerDelegate(methodToCall, typeof(Func<object, object[], object>), typeof(object));

            MethodCaller methodCaller = new MethodCaller(caller, returningCaller);

            lock (m_Sync)
            {
                m_MethodCallerCache[methodToCall] = methodCaller;
            }

            return methodCaller;
        }
Example #19
0
        /// <summary>
        /// Creates something that, when given a delegate (compatible with the signature given here) and some parameters, will run it.
        /// </summary>
        public MethodCaller CreateDelegateCaller(Type delegateType, MethodInfo delegateSignature)
        {
            // Check the cache
            lock (m_Sync)
            {
                MethodCaller cachedCaller;
                if (m_DelegateCallerCache.TryGetValue(delegateType, out cachedCaller))
                {
                    return cachedCaller;
                }
            }

            Action<object, object[]> caller = (Action<object, object[]>) CreateDelegateCallerDelegate(delegateType, delegateSignature, typeof(Action<object, object[]>), typeof(void));
            Func<object, object[], object> returningCaller = (Func<object, object[], object>)CreateDelegateCallerDelegate(delegateType, delegateSignature, typeof(Func<object, object[], object>), typeof(object));

            MethodCaller methodCaller = new MethodCaller(caller, returningCaller);

            lock (m_Sync)
            {
                m_DelegateCallerCache[delegateType] = methodCaller;
            }

            return methodCaller;
        }
Example #20
0
 public IMethodInvocationHandler GetInvocationHandlerFor(MethodCaller methodCaller, Type returnType, MethodInfo targetMethod)
 {
     return(new AudienceMethodInvocationHandler(m_Original, methodCaller, m_ProxyFactory));
 }
        public IMethodInvocationHandler GetInvocationHandlerFor(MethodCaller methodCaller, Type returnType, MethodInfo targetMethod)
        {

            return new ActorMethodInvocationHandler(m_RootForObject, m_Original, methodCaller, m_ProxyFactory, returnType, targetMethod);
        }