/// <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); } }
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); } } } }