Ejemplo n.º 1
0
        internal static CodeMemberProperty CreateSignalEventProperty(IDLSignal idlSignal)
        {
            CodeTypeReference typerefEvent = new CodeTypeReference(typeof(System.EventHandler <>));

            typerefEvent.TypeArguments.Add(new CodeTypeReference(CodeBuilderCommon.GetSignalEventTypeName(idlSignal.Name)));
            CodeMemberProperty propEventSignal = new CodeMemberProperty();

            propEventSignal.Name = CodeBuilderCommon.GetSignalEventPropertyName(idlSignal.Name);
            propEventSignal.Type = typerefEvent;
            return(propEventSignal);
        }
Ejemplo n.º 2
0
        private void GenerateSignals(IDLInterface idlIntf, string nsName
                                     , CodeTypeReference typerefDbusInterface
                                     , CodeTypeReference typerefDbusMarshal
                                     , CodeTypeReference typerefWCFCallbackInterface
                                     , CodeTypeDeclaration typeProxy)
        {
            #region list of callbacks
            // Callbacks field.
            // * LinkedList<I<interface>Callback> callbacks = null;
            CodeTypeReference typerefCallbacksLinkedList = new CodeTypeReference(typeof(LinkedList <>));
            typerefCallbacksLinkedList.TypeArguments.Add(typerefWCFCallbackInterface);
            CodeMemberField fieldCallbacks = new CodeMemberField(typerefCallbacksLinkedList, callbacks);
            fieldCallbacks.InitExpression = new CodePrimitiveExpression(null);
            typeProxy.Members.Add(fieldCallbacks);
            #endregion

            #region Method: OnCallBackClosing
            // Write:
            //   private void OnCallbackClosing(object sender, System.EventArgs e)
            //   {
            //        RemoveCallback(sender, this.callbacks);
            //   }
            CodeMemberMethod methodOnCallbackClosing = new CodeMemberMethod();
            methodOnCallbackClosing.Attributes = MemberAttributes.Private;
            methodOnCallbackClosing.Name       = "OnCallbackClosing";
            CodeParameterDeclarationExpression paramdeclSender    = new CodeParameterDeclarationExpression(typerefObject, "sender");
            CodeArgumentReferenceExpression    argrefSender       = new CodeArgumentReferenceExpression(paramdeclSender.Name);
            CodeParameterDeclarationExpression paramdeclEventArgs = new CodeParameterDeclarationExpression(typeof(System.EventArgs), "e");
            CodeArgumentReferenceExpression    argrefEventArgs    = new CodeArgumentReferenceExpression(paramdeclEventArgs.Name);
            methodOnCallbackClosing.Parameters.Add(paramdeclSender);
            methodOnCallbackClosing.Parameters.Add(paramdeclEventArgs);
            methodOnCallbackClosing.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(null, RemoveCallback, argrefSender, fieldrefCallbacks)));
            typeProxy.Members.Add(methodOnCallbackClosing);
            #endregion

            #region Method: AddCallBack
            // AddCallback().
            // * private void AddCallback(I<interface>Callback callback)
            CodeParameterDeclarationExpression paramdeclCallback = new CodeParameterDeclarationExpression(typerefWCFCallbackInterface, CodeBuilderCommon.callback);
            CodeArgumentReferenceExpression    argrefCallback    = new CodeArgumentReferenceExpression(paramdeclCallback.Name);
            CodeMemberMethod methodAddCallback = new CodeMemberMethod();
            methodAddCallback.Attributes = MemberAttributes.Private;
            methodAddCallback.Name       = AddCallback;
            methodAddCallback.Parameters.Add(paramdeclCallback);
            CodeArrayCreateExpression arraycreatexprCallbacks = new CodeArrayCreateExpression(typerefWCFCallbackInterface);
            arraycreatexprCallbacks.Initializers.Add(argrefCallback);
            CodeVariableReferenceExpression varrefRegisterComms = new CodeVariableReferenceExpression("registerComms");
            // * bool registerComms = true;
            methodAddCallback.Statements.Add(new CodeVariableDeclarationStatement(typeof(bool)
                                                                                  , varrefRegisterComms.VariableName
                                                                                  , new CodePrimitiveExpression(true)));

            CodeTypeReference typerefCallbackEnumerator = new CodeTypeReference(typeof(System.Collections.Generic.IEnumerator <>));
            typerefCallbackEnumerator.TypeArguments.Add(typerefWCFCallbackInterface);
            CodeVariableReferenceExpression  varrefCallbackEnumerator  = new CodeVariableReferenceExpression(callbackEnumerator);
            CodeVariableDeclarationStatement vardeclCallbackEnumerator = new CodeVariableDeclarationStatement(typerefCallbackEnumerator, varrefCallbackEnumerator.VariableName,
                                                                                                              new CodeMethodInvokeExpression(fieldrefCallbacks, "GetEnumerator"));
            CodePropertyReferenceExpression  proprefCallbackEnumeratorCurrent  = new CodePropertyReferenceExpression(varrefCallbackEnumerator, "Current");
            CodeMethodInvokeExpression       invokeCallbackEnumeratorMoveNext  = new CodeMethodInvokeExpression(varrefCallbackEnumerator, "MoveNext");
            CodeVariableDeclarationStatement vardeclCallbackEnumeratorMoveNext = new CodeVariableDeclarationStatement(typeof(bool), callbackEnumeratorMoveNext, invokeCallbackEnumeratorMoveNext);
            CodeVariableReferenceExpression  varrefCallbackEnumeratorMoveNext  = new CodeVariableReferenceExpression(vardeclCallbackEnumeratorMoveNext.Name);
            CodeAssignStatement assignCallbackEnumeratorMoveNext = new CodeAssignStatement(varrefCallbackEnumeratorMoveNext, invokeCallbackEnumeratorMoveNext);

            methodAddCallback.Statements.Add(
                // * if (this.callbacks == null)
                new CodeConditionStatement(new CodeBinaryOperatorExpression(fieldrefCallbacks
                                                                            , CodeBinaryOperatorType.IdentityEquality
                                                                            , new CodePrimitiveExpression(null))
                                           , new CodeStatement[]
            {
                // * this.callbacks = new LinkedList<I<interface>Callback>(new I<interface>Callback[] { callback });
                new CodeAssignStatement(fieldrefCallbacks
                                        , new CodeObjectCreateExpression(typerefCallbacksLinkedList
                                                                         , arraycreatexprCallbacks)
                                        )
            }
                                           // * else
                                           , new CodeStatement[]
            {
                // * IEnumerator<[callback_interface]> callbacksEnumerator = this.callbacks.GetEnumerator();
                vardeclCallbackEnumerator
                // * for (bool callbackEnumeratorMoveNext = callbackEnumerator.MoveNext(); callbackEnumeratorMoveNext; callbackEnumeratorMoveNext = callbackEnumerator.MoveNext())
                // * {
                , new CodeIterationStatement(vardeclCallbackEnumeratorMoveNext
                                             , new CodeBinaryOperatorExpression(varrefCallbackEnumeratorMoveNext
                                                                                , CodeBinaryOperatorType.BooleanAnd
                                                                                , varrefRegisterComms)
                                             , assignCallbackEnumeratorMoveNext
                                             // * if (callbacksEnumerator.Current.Equals(callback))
                                             // * {
                                             , new CodeConditionStatement(new CodeMethodInvokeExpression(proprefCallbackEnumeratorCurrent
                                                                                                         , "Equals"
                                                                                                         , argrefCallback)
                                                                          , new CodeStatement[]       // True
                {
                    // * registerComms = false;
                    new CodeAssignStatement(varrefRegisterComms, new CodePrimitiveExpression(false))
                }
                                                                          )
                                             )
                // * if (registerComms)
                , new CodeConditionStatement(varrefRegisterComms
                                             // * this.callbacks.AddLast(callback);
                                             , new CodeExpressionStatement(new CodeMethodInvokeExpression(fieldrefCallbacks
                                                                                                          , "AddLast"
                                                                                                          , argrefCallback))
                                             )
            }
                                           ));

            // * System.ServiceModel.ICommunicationObject commsCallback = callback as System.ServiceModel.ICommunicationObject;

            // * if (registerComms && (typeof(System.ServiceModel.ICommunicationObject).IsInstanceOfType(callback) != false))
            // * {
            // * commsCallback.Closing += this.OnCallbackClosing;
            // * }
            CodeTypeReference typerefICommunicationObject           = new CodeTypeReference(typeof(System.ServiceModel.ICommunicationObject));
            CodeVariableDeclarationStatement vardeclCallbackAsComms = new CodeVariableDeclarationStatement(typerefICommunicationObject
                                                                                                           , "commsCallback"
                                                                                                           , new CodeCastExpression(typerefICommunicationObject, argrefCallback)
                                                                                                           );
            CodeVariableReferenceExpression varrefCallbackAsComms = new CodeVariableReferenceExpression(vardeclCallbackAsComms.Name);
            methodAddCallback.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(
                                                                            varrefRegisterComms
                                                                            , CodeBinaryOperatorType.BooleanAnd
                                                                            , new CodeBinaryOperatorExpression(
                                                                                new CodeMethodInvokeExpression(new CodeTypeOfExpression(typerefICommunicationObject), "IsInstanceOfType", argrefCallback)
                                                                                , CodeBinaryOperatorType.IdentityInequality
                                                                                , new CodePrimitiveExpression(false)
                                                                                )
                                                                            )
                                                                        , vardeclCallbackAsComms
                                                                        , new CodeAttachEventStatement(varrefCallbackAsComms, "Closing", new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), methodOnCallbackClosing.Name))
                                                                        ));
            typeProxy.Members.Add(methodAddCallback);
            #endregion

            #region Method: RemoveCallBack
            // RemoveCallback().
            /// * static private void RemoveCallback<T>(object callback, LinkedList<T> callbacks)
            /// *     where T: class
            /// * {
            CodeMemberMethod methodRemoveCallback = new CodeMemberMethod();
            methodRemoveCallback.Attributes = MemberAttributes.Static | MemberAttributes.Private;
            methodRemoveCallback.Name       = RemoveCallback;
            CodeTypeParameter typeparamCallback    = new CodeTypeParameter("TCallback");
            CodeTypeReference typerefCallbackParam = new CodeTypeReference(typeparamCallback.Name);
            CodeParameterDeclarationExpression paramdeclRemoveCallback = new CodeParameterDeclarationExpression(typerefObject, CodeBuilderCommon.callback);
            CodeTypeReference typerefLinkedListRemoveCallback          = new CodeTypeReference(typeof(System.Collections.Generic.LinkedList <>));
            typerefLinkedListRemoveCallback.TypeArguments.Add(typerefCallbackParam);
            CodeTypeReference typerefLinkedListNodeRemoveCallback = new CodeTypeReference(typeof(System.Collections.Generic.LinkedListNode <>));
            typerefLinkedListNodeRemoveCallback.TypeArguments.Add(typerefCallbackParam);

            CodeParameterDeclarationExpression paramdeclRemoveCallbacks = new CodeParameterDeclarationExpression(typerefLinkedListRemoveCallback, callbacks);
            CodeArgumentReferenceExpression    argrefCallbacks          = new CodeArgumentReferenceExpression(paramdeclRemoveCallbacks.Name);
            typeparamCallback.Constraints.Add(new CodeTypeReference(" class")); // Space before "class" bloody important, stupid CodeDOM and CSharp.
            methodRemoveCallback.TypeParameters.Add(typeparamCallback);
            methodRemoveCallback.Parameters.Add(paramdeclRemoveCallback);
            methodRemoveCallback.Parameters.Add(paramdeclRemoveCallbacks);

            CodeVariableDeclarationStatement vardeclIteratorNode = new CodeVariableDeclarationStatement(
                typerefLinkedListNodeRemoveCallback, "iteratorNode"
                , new CodePropertyReferenceExpression(argrefCallbacks, "First")
                );
            CodeVariableReferenceExpression  varrefIteratorNode = new CodeVariableReferenceExpression(vardeclIteratorNode.Name);
            CodeVariableDeclarationStatement vardeclRemoveNode  = new CodeVariableDeclarationStatement(
                typerefLinkedListNodeRemoveCallback, "removeNode"
                , varrefIteratorNode
                );
            CodeVariableReferenceExpression varrefRemoveNode   = new CodeVariableReferenceExpression(vardeclRemoveNode.Name);
            CodeAssignStatement             assignIteratorNode = new CodeAssignStatement(varrefIteratorNode, new CodePropertyReferenceExpression(varrefIteratorNode, "Next"));

            // * for (LinkedListNode<string> n = l.First; n != null; )
            // * {
            methodRemoveCallback.Statements.Add(new CodeIterationStatement(vardeclIteratorNode
                                                                           , new CodeBinaryOperatorExpression(varrefIteratorNode
                                                                                                              , CodeBinaryOperatorType.IdentityInequality
                                                                                                              , new CodePrimitiveExpression(null))
                                                                           , new CodeSnippetStatement(string.Empty) // Don't increment
                                                                                                                    // * if (iteratorNode.Value == callback)
                                                                                                                    // * {
                                                                           , new CodeConditionStatement(
                                                                               new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(varrefIteratorNode, "Value")
                                                                                                                , CodeBinaryOperatorType.IdentityEquality
                                                                                                                , argrefCallback)
                                                                               , new CodeStatement[] // True
            {
                // * LinkedListNode<string> removeNode = iteratorNode;
                vardeclRemoveNode
                // * iteratorNode = iteratorNode.Next;
                , assignIteratorNode
                // * l.Remove(removeNode);
                , new CodeExpressionStatement(new CodeMethodInvokeExpression(argrefCallbacks, "Remove", varrefRemoveNode))
                // * }
            }
                                                                               // * else
                                                                               // * {
                                                                               , new CodeStatement[] // False
            {
                // * iteratorNode = iteratorNode.Next;
                assignIteratorNode
                // * }
            }
                                                                               // * }
                                                                               // * }
                                                                               )));
            typeProxy.Members.Add(methodRemoveCallback);
            #endregion

            foreach (IDLSignal idlSignal in idlIntf.Signals)
            {
                #region Write method which will call every registered
                // Add private event handler function which delegates to callback interfaces.
                // * private void On<signal>(object sender, <signal_interface_ns>.<signal>Args e)
                string            signalArgsName         = CodeBuilderCommon.GetSignalEventTypeName(idlSignal.Name);
                string            scopedSignalArgsName   = CodeBuilderCommon.GetScopedName(nsName, signalArgsName);
                string            signalEventMethodName  = CodeBuilderCommon.GetSignalCallbackMethodName(idlSignal.Name);
                CodeTypeReference typerefSignalEventArgs = new CodeTypeReference(scopedSignalArgsName);
                CodeParameterDeclarationExpression paramdeclSignalEventArgs = new CodeParameterDeclarationExpression(typerefSignalEventArgs, eventArgsParamName);
                CodeArgumentReferenceExpression    argrefSignalEventArgs    = new CodeArgumentReferenceExpression(paramdeclSignalEventArgs.Name);
                CodeMemberMethod methodOnSignal = new CodeMemberMethod();

                methodOnSignal.Attributes = MemberAttributes.Private;
                methodOnSignal.Name       = signalEventMethodName;
                methodOnSignal.Parameters.Add(paramdeclSender);
                methodOnSignal.Parameters.Add(paramdeclSignalEventArgs);
                methodOnSignal.Statements.Add(new CodeConditionStatement(
                                                  // * if (this.callbacks != null)
                                                  new CodeBinaryOperatorExpression(fieldrefCallbacks, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null))
                                                  // * IEnumerator< <interface>Callback > callbackEnumerator = this.callbacks.GetEnumerator();
                                                  , vardeclCallbackEnumerator
                                                  // * for (bool callbackEnumeratorMoveNext = callbackEnumerator.MoveNext(); callbackEnumeratorMoveNext; callbackEnumeratorMoveNext = callbackEnumerator.MoveNext())
                                                  , new CodeIterationStatement(vardeclCallbackEnumeratorMoveNext, varrefCallbackEnumeratorMoveNext, assignCallbackEnumeratorMoveNext
                                                                               , new CodeExpressionStatement(new CodeMethodInvokeExpression(proprefCallbackEnumeratorCurrent, signalEventMethodName, argrefSignalEventArgs))
                                                                               //// * callbackEnumerator.Current.On<signal>(e);
                                                                               //, new CodeExpressionStatement(new CodeMethodInvokeExpression(arrayindexCallbacks, signalEventMethodName, argrefSignalEventArgs))
                                                                               )));
                typeProxy.Members.Add(methodOnSignal);
                #endregion

                #region Write method to register for a signal
                // * public void RegisterFor<signal>()
                CodeMethodReferenceExpression methodrefGetCallbackChannel = new CodeMethodReferenceExpression(proprefOperationContextCurrent, "GetCallbackChannel", typerefWCFCallbackInterface);
                CodeMethodReferenceExpression methodrefOnSignal           = new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), methodOnSignal.Name);
                CodeMemberMethod methodRegisterForSignal = new CodeMemberMethod();
                methodRegisterForSignal.Attributes = MemberAttributes.Public;
                methodRegisterForSignal.Name       = CodeBuilderCommon.GetSignalRegisterFunction(idlSignal.Name);
                // * <interface> target = this.GetWCFMethodTarget();
                methodRegisterForSignal.Statements.Add(this.DeclareTargetVariable(typerefDbusInterface, typerefDbusMarshal));
                // * AddCallback(System.ServiceModel.OperationContext.Current.GetCallbackChannel<I<interface>Callback>());
                methodRegisterForSignal.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), methodAddCallback.Name
                                                                                                                  , new CodeMethodInvokeExpression(methodrefGetCallbackChannel))
                                                                                   ));
                CodePropertyReferenceExpression proprefDbusServiceSignal = new CodePropertyReferenceExpression(fieldrefDbusServices, CodeBuilderCommon.GetSignalEventPropertyName(idlSignal.Name));
                CodeAttachEventStatement        attacheventSignal        = new CodeAttachEventStatement(new CodeEventReferenceExpression(varrefTarget, CodeBuilderCommon.GetSignalEventPropertyName(idlSignal.Name)), methodrefOnSignal);
                methodRegisterForSignal.Statements.Add(attacheventSignal);

                typeProxy.Members.Add(methodRegisterForSignal);
                #endregion
            } // Ends loop over signals
        }