Ejemplo n.º 1
0
        /// <summary>
        /// Handle event subscription (Proxy.Event.Subscribe)
        /// </summary>
        protected override void ProcessReceiveEventSubscription(int methodId, Delegate delegateInstance, bool isAdd)
        {
            SuperPoolProxyCall pendingCall = null;

            if (_pendingThreadsCalls.TryGetValue(Thread.CurrentThread.ManagedThreadId, out pendingCall) == false)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find corresponding thread proxy call information.");
#endif
                return;
            }

            EventSubscriptionRequest subscriptionRequest = pendingCall.SubscriptionRequest;
            if (subscriptionRequest == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find corresponding subscription requests, event subscription failed.");
#endif
                return;
            }

            if (pendingCall.Sender == null || pendingCall.Sender.Id == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to establish subscription sender information, subscription failed.");
#endif
                return;
            }

            if (delegateInstance.Target != pendingCall.Sender.Source)
            {
#if Matrix_Diagnostics
                InstanceMonitor.Error("Only a message super pool client source can subscribe to events.");
#endif
                return;
            }

            ProxyTypeBuilder builder = ProxyTypeBuilder;
            if (builder == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find proxy type builder, event subscription failed.");
#endif
                return;
            }

            GeneratedMethodInfo generatedMethodInfo = builder.GetMethodInfoById(methodId);
            if (generatedMethodInfo == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find method [id, " + methodId + "] info, event subscription failed.");
#endif
                return;
            }

            if (string.IsNullOrEmpty(generatedMethodInfo.EventName))
            {
                generatedMethodInfo.EventName = GeneralHelper.GetEventExtendedNameByMethod(generatedMethodInfo.GetMethodInfo(), false, true);
            }

            // generatedMethodInfo.GetMethodInfo() >> I2.add_AEVent
            string     extendedEventName  = generatedMethodInfo.EventName;
            MethodInfo eventAddMethodInfo = generatedMethodInfo.GetMethodInfo();

            // *IMPORTANT* the Call<> will cause the currently used pendingCall to be repopulated with information,
            // so we ned to extract the *sender id* BEFORE calling the actual Call(), since it will change the
            // pendingCall instance immediately.
            subscriptionRequest.SenderId          = pendingCall.Sender.Id;
            subscriptionRequest.ExtendedEventName = extendedEventName;
            subscriptionRequest.IsAdd             = isAdd;
            //subscriptionRequest.EventAddMethodInfo = eventAddMethodInfo;
            subscriptionRequest.DelegateInstanceMethodInfo = delegateInstance.Method;

            // Process locally.
            ((ISuperPoolIntercom)this).ProcessSubscriptionUpdate(subscriptionRequest);

            SuperPoolClient mainClient = IntercomClient;
            if (mainClient == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.Error("Failed to obtain super pool main intercom client, so new client handling has failed.");
#endif
            }
            else
            {
                // Notify other connected super pools of this subcription,
                // since the subscribee(s) may be attached on them.
                // *pendingCall swap done here, make sure to not use it on or after this line*
                mainClient.CallAll <ISuperPoolIntercom>().ProcessSubscriptionUpdate(subscriptionRequest);
            }
        }
Ejemplo n.º 2
0
        protected void AssignClientSource(object source)
        {
            SuperPoolClient client = _client;

            if (client == null)
            {
#if Matrix_Diagnostics
                SystemMonitor.Error("Failed to add client source, since client not available (possible Dispose).");
#endif
                return;
            }

            SuperPoolSubscription owner = _owner;
            if (owner == null)
            {
#if Matrix_Diagnostics
                SystemMonitor.Error("Failed to add client source, since no owner is available (possible Dispose).");
#endif
                return;
            }

            ReleaseCurrentClientSource();

            _clientSource = source;

            if (_clientSource == null)
            {
#if Matrix_Diagnostics
                SystemMonitor.OperationWarning("Starting a client with no source attached.");
#endif
                return;
            }

            foreach (Type interfaceType in ReflectionHelper.GatherTypeAttributeMarkedInterfaces(source.GetType(), typeof(SuperPoolInterfaceAttribute)))
            {// Gather all events, from interfaces marked with [SuperPoolInterfaceAttribute].
                // Make sure to have created the corresponding proxy instance for this interface type.
                owner.ProxyTypeManager.ObtainInterfaceProxy(interfaceType);

                foreach (EventInfo eventInfo in interfaceType.GetEvents())
                {
                    Type delegateType = eventInfo.EventHandlerType;
                    GeneratedMethodInfo methodInfo = owner.ProxyTypeManager.Builder.GenerateDynamicMethodProxyDelegate(delegateType);

                    // Create delegate can operate in 2 modes:
                    // - create a static delegate like this (requires instnace upon call): info.Method.CreateDelegate(delegateType);
                    // - create an instance delegate like this (can be direct called): info.Method.CreateDelegate(delegateType, instance);

                    Delegate delegateInstance = methodInfo.StandaloneDynamicMethod.CreateDelegate(delegateType, this);
                    eventInfo.AddEventHandler(source, delegateInstance);

                    EventHandlingInformation subscriptionInfo = new EventHandlingInformation()
                    {
                        DelegateInstance    = delegateInstance,
                        EventInfo           = eventInfo,
                        GeneratedMethodInfo = methodInfo
                    };

                    lock (this)
                    {
                        _eventsMethods.Add(methodInfo.Id, subscriptionInfo);
                    }
                }
            }
        }