/// <summary> /// Generates the code for all state variables. /// </summary> /// <param name="service">The service containing the state variables.</param> /// <param name="testStateVars"> /// True to test each state variable to ensure it is /// usuable for accessing as property, false to include /// all state variables as properties.</param> /// <param name="consts">The string constants created.</param> /// <param name="stateVarProps">A StringBuilder to contain property definitions.</param> /// <param name="stateVarConversion">A StringBuilder to contain the conversion method definitions.</param> /// <param name="stateVarEnums">A StringBuilder to contain the enumerations for the state variables.</param> /// <param name="eventHandlers">A StringBuilder to contain event handler declarations for the state variable changes.</param> /// <param name="eventCallers">A StringBuilder to contain event caller methods for the state variable changes.</param> /// <param name="stateVarEventIntercept">A StringBuilder to contain case statement code for each event state variable.</param> /// <param name="enumStateVars">A HashSet containing the names of all enumerated state variables.</param> /// <param name="stateVarTypes">A Dictionary to contain each state variaible name and its code data type.</param> /// <param name="desc">The service description to create the state variable code from.</param> private void GenerateStateVarCode( Service service, bool testStateVars, StringConstants consts, StringBuilder stateVarProps, StringBuilder stateVarConversion, StringBuilder stateVarEnums, StringBuilder eventHandlers, StringBuilder eventCallers, StringBuilder stateVarEventIntercept, HashSet <string> enumStateVars, Dictionary <string, string> stateVarTypes, ServiceDescription desc) { // For each state variaible description foreach (StateVariableDescription lsdStateVarDesc in desc.StateVariables.Values) { string lsFriendlyName = CodeGenProvider.CodeFriendlyIdentifier(lsdStateVarDesc.Name, false); // Determine if we actually want the property accessor for the state variable bool lbAddProp = IsStateVarQueryable(service, testStateVars, lsdStateVarDesc); // If the state variable is a string and has an allowed value list if (lsdStateVarDesc.DataTypeValue == StateVariableDataType.tstring && lsdStateVarDesc.AllowedValues.Count > 0) { // Generate it using an enumeration GenerateEnumStateVarCode( consts, stateVarProps, stateVarConversion, stateVarEnums, eventHandlers, eventCallers, stateVarEventIntercept, enumStateVars, stateVarTypes, lsdStateVarDesc, lsFriendlyName, lbAddProp); } else { // Otherwise generate it using simple properties GenerateStateVarCode( consts, stateVarProps, eventHandlers, eventCallers, stateVarEventIntercept, stateVarTypes, lsdStateVarDesc, lsFriendlyName, lbAddProp); } } }
private void GenerateStateVarEventCode( string type, string stateVarFriendlyName, string conversionCode, StringConstants consts, StringBuilder eventHandlers, StringBuilder eventCallers, StringBuilder stateVarEventIntercept, StateVariableDescription stateVarDesc) { string lsConstName = consts[ CodeGenProvider.StateVarNameGroup, stateVarDesc.Name, string.Format(CodeGenProvider.StateVarNameComment, stateVarDesc.Name) ]; eventHandlers.Append( string.Format( CodeGenProvider.StateVariableEventHandler, type, stateVarFriendlyName)); eventCallers.Append( string.Format( CodeGenProvider.StateVariableEventCaller, type, stateVarFriendlyName)); stateVarEventIntercept.Append( string.Format( CodeGenProvider.StateVarChangedEventHandlerCaseStatement, lsConstName, stateVarFriendlyName, type, conversionCode)); }
/// <summary> /// Generates the case statements for the conversion functions /// for an enumerated state variaible. /// </summary> /// <param name="consts">The string constants created.</param> /// <param name="stateVarDesc">The state variable description.</param> /// <param name="friendlyName">The code friendly name of the state variaible.</param> /// <param name="stateVarEnumValues">A StringBuilder to contain the list of enumeration values.</param> /// <param name="enumStateVarParse">A StringBuilder to contain the list of state variable parse case statements.</param> /// <param name="enumStateVarToString">A StringBuilder to contain the list of state variable to string case statements.</param> private void GenerateEnumAllowedValuesCode( StringConstants consts, StateVariableDescription stateVarDesc, string friendlyName, StringBuilder stateVarEnumValues, StringBuilder enumStateVarParse, StringBuilder enumStateVarToString) { // For each allowed value foreach (string lsAllowedValue in stateVarDesc.AllowedValues) { // Get the code friendly name string lsFriendlyValue = CodeGenProvider.CodeFriendlyIdentifier(lsAllowedValue, false); // Create the constant for the allowed value string lsAllowedValueConst = consts[ string.Format(CodeGenProvider.AllowedValueGroup, CodeGenProvider.CodeFriendlyIdentifier(stateVarDesc.Name, false)), lsAllowedValue, string.Format(CodeGenProvider.AllowedValueComment, lsAllowedValue, stateVarDesc.Name) ]; // Generate the enumeration values stateVarEnumValues.Append(string.Format(CodeGenProvider.EnumStateVarValue, lsFriendlyValue, friendlyName)); // Generate the parse case statement enumStateVarParse.Append(string.Format(CodeGenProvider.EnumParseCaseStatement, lsAllowedValueConst, friendlyName, lsFriendlyValue)); // Generate the to string case statment enumStateVarToString.Append(string.Format(CodeGenProvider.EnumToStringCaseStatement, friendlyName, lsFriendlyValue, lsAllowedValueConst)); } }
/// <summary> /// Generates the code for an enumerated state variable. /// </summary> /// <param name="consts">The string constants created.</param> /// <param name="stateVarProps">A StringBuilder to contain property definitions.</param> /// <param name="stateVarConversion">A StringBuilder to contain the conversion method definitions.</param> /// <param name="stateVarEnums">A StringBuilder to contain the enumerations for the state variables.</param> /// <param name="eventHandlers">A StringBuilder to contain event handler declarations for the state variable changes.</param> /// <param name="eventCallers">A StringBuilder to contain event caller methods for the state variable changes.</param> /// <param name="stateVarEventIntercept">A StringBUilder to contain the case statements for the state variable changed event.</param> /// <param name="enumStateVars">A HashSet containing the names of all enumerated state variables.</param> /// <param name="stateVarTypes">A Dictionary to contain each state variaible name and its code data type.</param> /// <param name="stateVarDesc">The state variable description.</param> /// <param name="friendlyName">The code friendly name of the state variaible.</param> /// <param name="addProp">True to add the actual property accessor.</param> private void GenerateEnumStateVarCode( StringConstants consts, StringBuilder stateVarProps, StringBuilder stateVarConversion, StringBuilder stateVarEnums, StringBuilder eventHandlers, StringBuilder eventCallers, StringBuilder stateVarEventIntercept, HashSet <string> enumStateVars, Dictionary <string, string> stateVarTypes, StateVariableDescription stateVarDesc, string friendlyName, bool addProp) { StringBuilder lsbStateVarEnumValues = new StringBuilder(); StringBuilder lsbEnumStateVarParse = new StringBuilder(); StringBuilder lsbEnumStateVarToString = new StringBuilder(); // Add the state var to the enum list enumStateVars.Add(stateVarDesc.Name); // Generate allowed values code GenerateEnumAllowedValuesCode( consts, stateVarDesc, friendlyName, lsbStateVarEnumValues, lsbEnumStateVarParse, lsbEnumStateVarToString); // Generate enumeration stateVarEnums.Append(string.Format(CodeGenProvider.StateVarEnum, friendlyName, lsbStateVarEnumValues)); // Generate conversion functions stateVarConversion.Append(string.Format(CodeGenProvider.EnumStateVarConversion, friendlyName, lsbEnumStateVarParse, lsbEnumStateVarToString)); // Generate property accessor if required if (addProp) { stateVarProps.Append( string.Format( CodeGenProvider.EnumStateVar, friendlyName, consts[ CodeGenProvider.StateVarNameGroup, stateVarDesc.Name, string.Format(CodeGenProvider.StateVarNameComment, stateVarDesc.Name) ], GenerateStateVarComment(stateVarDesc))); } string lsEnumTypeName = string.Format(CodeGenProvider.EnumStateVarName, friendlyName); // Add the type to the list for the actions stateVarTypes[stateVarDesc.Name] = lsEnumTypeName; // If the state variable is evented if (stateVarDesc.SendEvents) { GenerateStateVarEventCode( lsEnumTypeName, friendlyName, String.Format(CodeGenProvider.EnumStateVarEventConversion, friendlyName), consts, eventHandlers, eventCallers, stateVarEventIntercept, stateVarDesc); } }
/// <summary> /// Generates the code for the device properties. /// </summary> /// <param name="device">The device to generate for.</param> /// <param name="specificDevices">True if specific device classes are being used, false if using the Device class.</param> /// <param name="consts">The string constants list.</param> /// <param name="specificDeviceClasses">The dictionary of UDNs, ClassNames for the devices or null for default.</param> /// <param name="properties">A StringBuilder to append the properties code to.</param> private void GenerateDevicePropertyCode( Device device, bool specificDevices, StringConstants consts, StringBuilder properties, Dictionary <string, string> specificDeviceClasses) { if (device.HasChildren) { // For each service foreach (Device ldDevice in device.Children) { string lsDeviceName = DefaultCodeGenClassName(ldDevice, CodeGenProvider); bool lbSpecificDevice = specificDevices; string lsSpecificClass = string.Empty; // If using specific device names if (lbSpecificDevice) { // And the devices dictionary is null if (specificDeviceClasses == null) { // Then use the device name for its name lsSpecificClass = lsDeviceName; } else // Otherwise reference the specific device classes if (!specificDeviceClasses.TryGetValue(ldDevice.UniqueDeviceName, out lsSpecificClass)) { // If its not found then dont use specific device name for this device lbSpecificDevice = false; } } // Get the device class if specific, otherwise use generic device class string lsDeviceClass = (lbSpecificDevice ? lsSpecificClass : CodeGenProvider.Device); // Build the property for the service and append properties.Append( string.Format( CodeGenProvider.Property, lsDeviceClass, (lbSpecificDevice ? lsDeviceClass : lsDeviceName), CodeGenProvider.Device, string.Format( (lbSpecificDevice ? CodeGenProvider.SpecificDeviceRet : CodeGenProvider.GenericDeviceRet), lsDeviceClass, consts[CodeGenProvider.DeviceGroup, lsDeviceName + CodeGenProvider.DeviceType, ldDevice.Type, string.Format(CodeGenProvider.DeviceTypeConstComment, lsDeviceName)] ), lsDeviceName, ldDevice.Type, CodeGenProvider.Device ) ); } } }
/// <summary> /// Generates the code for the service properties. /// </summary> /// <param name="device">The device to generate for.</param> /// <param name="specificServices">True if specific service classes are being used, false if using the Service class.</param> /// <param name="consts">The string constants list.</param> /// <param name="specificServiceClasses">The dictionary of IDs, ClassNames for the services or null for default.</param> /// <param name="properties">A StringBuilder to append the properties code to.</param> private void GenerateServicePropertyCode( Device device, bool specificServices, StringConstants consts, StringBuilder properties, Dictionary<string, string> specificServiceClasses) { // For each service foreach (Service lsService in device.Services) { string lsServiceName = ServiceGen.DefaultCodeGenClassName(lsService, CodeGenProvider); bool lbSpecificService = specificServices; string lsSpecificClass = string.Empty; // If using specific service names if (lbSpecificService) { // And the services dictionary is null if (specificServiceClasses == null) // Then use the service name for its name lsSpecificClass = lsServiceName; else // Otherwise reference the specific service classes if (!specificServiceClasses.TryGetValue(lsService.Id, out lsSpecificClass)) // If its not found then dont use specific service name for this service lbSpecificService = false; } // Get the service class if specific, otherwise use generic service class string lsServiceClass = (lbSpecificService ? lsSpecificClass : CodeGenProvider.Service); // Build the property for the service and append properties.Append( string.Format( CodeGenProvider.Property, lsServiceClass, (lbSpecificService ? lsServiceClass : lsServiceName), CodeGenProvider.Service, string.Format( (lbSpecificService ? CodeGenProvider.SpecificServiceRet : CodeGenProvider.GenericServiceRet), lsServiceClass, consts[CodeGenProvider.ServiceGroup, lsServiceName + CodeGenProvider.ServiceID, lsService.Id, string.Format(CodeGenProvider.ServiceIdConstComment,lsServiceName)]), lsServiceName, lsService.ServiceTypeIdentifier, CodeGenProvider.Service ) ); } }
/// <summary> /// Generates the code for a NON enumerated state variable. /// </summary> /// <param name="consts">The string constants created.</param> /// <param name="stateVarProps">A StringBuilder to contain property definitions.</param> /// <param name="eventHandlers">A StringBuilder to contain event handler declarations for the state variable changes.</param> /// <param name="eventCallers">A StringBuilder to contain event caller methods for the state variable changes.</param> /// <param name="stateVarEventIntercept">A StringBUilder to contain the case statements for the state variable changed event.</param> /// <param name="stateVarTypes">A Dictionary to contain each state variaible name and its code data type.</param> /// <param name="stateVarDesc">The state variable description.</param> /// <param name="friendlyName">The code friendly name of the state variaible.</param> /// <param name="addProp">True to add the actual property accessor.</param> private void GenerateStateVarCode( StringConstants consts, StringBuilder stateVarProps, StringBuilder eventHandlers, StringBuilder eventCallers, StringBuilder stateVarEventIntercept, Dictionary <string, string> stateVarTypes, StateVariableDescription stateVarDesc, string friendlyName, bool addProp) { // Get the data type string lsType = stateVarDesc.DataTypeValue.BaseType().Name; // Append the accessor for the state variaible if (addProp) { stateVarProps.Append( string.Format( CodeGenProvider.NonEnumStateVar, lsType, friendlyName, consts[ CodeGenProvider.StateVarNameGroup, stateVarDesc.Name, string.Format(CodeGenProvider.StateVarNameComment, stateVarDesc.Name) ], GenerateStateVarComment(stateVarDesc))); } // Add the type to the list for the actions stateVarTypes[stateVarDesc.Name] = lsType; // If the state variable is evented if (stateVarDesc.SendEvents) { GenerateStateVarEventCode( lsType, friendlyName, String.Format(CodeGenProvider.NonEnumStateVarEventConversion, lsType), consts, eventHandlers, eventCallers, stateVarEventIntercept, stateVarDesc); } }
/// <summary> /// Generates the code for all actions. /// </summary> /// <param name="consts">The stirng constants created.</param> /// <param name="actionMethods">The StringBuilder to contain the action call methods.</param> /// <param name="enumStateVars">A HashSet of the state variables which are enumerations.</param> /// <param name="stateVarTypes">A Dictionary containing the state variables and their data types.</param> /// <param name="desc">The service description to generate the action code for.</param> private void GenerateActionCode( StringConstants consts, StringBuilder actionMethods, HashSet <string> enumStateVars, Dictionary <string, string> stateVarTypes, ServiceDescription desc) { // For each action foreach (ActionDescription ladDesc in desc.Actions.Values) { string lsFriendlyName = CodeGenProvider.CodeFriendlyIdentifier(ladDesc.Name, false); int liInArgumentCount = 0; int liInArgumentIndex = 0; int liOutArgumentIndex = 0; StringBuilder lsbInArguments = new StringBuilder(); StringBuilder lsbOutArguments = new StringBuilder(); StringBuilder lsbInSetValues = new StringBuilder(); StringBuilder lsbOutSetValues = new StringBuilder(); StringBuilder lsbInParamComments = new StringBuilder(); StringBuilder lsbOutParamComments = new StringBuilder(); StringBuilder lsbReturnsComments = new StringBuilder(); int liOutArguments = ladDesc.Arguments.OutArgCount; string lsLastOutType = CodeGenProvider.UnknownType; // For each argument foreach (ArgumentDescription ladArgDesc in ladDesc.Arguments.Values) { bool lbEnumStateVar = enumStateVars.Contains(ladArgDesc.RelatedStateVariable); string lsArgFriendlyName = CodeGenProvider.CodeFriendlyIdentifier(ladArgDesc.Name, true); string lsRelatedStateVarFriendlyName = CodeGenProvider.CodeFriendlyIdentifier(ladArgDesc.RelatedStateVariable, false); string lsType; // Get the type of the related state variable, or use unknown type if state variable cannot be found if (!stateVarTypes.TryGetValue(ladArgDesc.RelatedStateVariable, out lsType)) { lsType = CodeGenProvider.UnknownType; } // Determine direction if (ladArgDesc.DirectionValue == ArgumentDirection.Out) { lsLastOutType = lsType; // If there is more than 1 out argument then use out parameters if (liOutArguments > 1) { GenerateOutArgumentCode( ladArgDesc, liOutArgumentIndex, lsbOutArguments, lsbOutSetValues, lbEnumStateVar, lsArgFriendlyName, lsRelatedStateVarFriendlyName, lsType, lsbOutParamComments); } else { // Otherwise use a returning function GenerateOutArgumentReturnCode( ladArgDesc, liOutArgumentIndex, lsbOutSetValues, lbEnumStateVar, lsRelatedStateVarFriendlyName, lsType, lsbReturnsComments); } // Increment the out argument index liOutArgumentIndex++; } else { // Generate the in argument code GenerateInArgumentCode( ladArgDesc, liInArgumentIndex, lsbInArguments, lsbInSetValues, lbEnumStateVar, lsArgFriendlyName, lsRelatedStateVarFriendlyName, lsType, lsbInParamComments); // Increment in argument count and index liInArgumentCount++; liInArgumentIndex++; } } // Generate the method code actionMethods.Append( string.Format( (liOutArguments == 1 ? CodeGenProvider.ReturnAction : CodeGenProvider.Action), lsFriendlyName, lsbInArguments, lsbOutArguments, CodeGenProvider.ArraySizeForCount(liInArgumentCount), lsbInSetValues, consts[CodeGenProvider.ActionNameGroup, ladDesc.Name, string.Format(CodeGenProvider.ActionNameComment, ladDesc.Name)], lsbOutSetValues, (lsbInArguments.Length > 0 && lsbOutArguments.Length > 0 ? CodeGenProvider.ParameterSeperator : String.Empty), lsLastOutType, lsbInParamComments, lsbOutParamComments, lsbReturnsComments, (liOutArguments > 0 ? CodeGenProvider.OutVar : string.Empty) ) ); } }
/// <summary> /// Generates the class code for a service. /// </summary> /// <param name="service">The service to generate for.</param> /// <param name="className">The class name of the service or null to use the service type.</param> /// <param name="namespaceName">The namespace for the class.</param> /// <param name="classScope">The scope for the class.</param> /// <param name="partial">True to make the class partial, false otherwise.</param> /// <param name="testStateVars"> /// True to test each state variable to ensure it is /// usuable for accessing as property, false to include /// all state variables as properties.</param> /// <returns>The string representing the code for the class.</returns> public string GenerateClassFor( Service service, string className, string namespaceName, ClassScope classScope, bool partial, bool testStateVars) { // If classname is not specified then default to service information if (className == null) className = DefaultCodeGenClassName(service, CodeGenProvider); else // Otherwise ensure classname is Identifier compatible className = CodeGenProvider.CodeFriendlyIdentifier(className, false); StringBuilder lsbStateVarProps = new StringBuilder(); StringBuilder lsbStateVarConversion = new StringBuilder(); StringBuilder lsbStateVarEnums = new StringBuilder(); StringBuilder lsbActionMethods = new StringBuilder(); StringBuilder lsbEventHandlers = new StringBuilder(); StringBuilder lsbEventCallers = new StringBuilder(); StringBuilder lsbStateVarEventIntercept = new StringBuilder(); HashSet<string> lhsEnumStateVars = new HashSet<string>(); StringConstants lscConsts = new StringConstants(CodeGenProvider); Dictionary<string, string> ldStateVarTypes = new Dictionary<string,string>(); // Get the service description ServiceDescription lsdDesc = service.Description(); if (lsdDesc != null) { // Generate the state variable property declarations GenerateStateVarCode( service, testStateVars, lscConsts, lsbStateVarProps, lsbStateVarConversion, lsbStateVarEnums, lsbEventHandlers, lsbEventCallers, lsbStateVarEventIntercept, lhsEnumStateVars, ldStateVarTypes, lsdDesc); // Generate the action methods GenerateActionCode( lscConsts, lsbActionMethods, lhsEnumStateVars, ldStateVarTypes, lsdDesc); } if (lsbStateVarEventIntercept.Length > 0) lsbEventCallers.Append( String.Format(CodeGenProvider.StateVarChangedEventHandler, lsbStateVarEventIntercept) ); return String.Format( CodeGenProvider.ServiceBase, namespaceName, className, service.ServiceTypeIdentifier, CodeGenProvider.GenerateRegion(CodeGenProvider.PublicEnumerations, lsbStateVarEnums.ToString()), (partial ? CodeGenProvider.PartialClass : String.Empty), CodeGenProvider.GenerateRegion(CodeGenProvider.ProtectedMethods, lsbStateVarConversion.ToString()), lsbActionMethods, CodeGenProvider.GenerateRegion(CodeGenProvider.PublicProperties, lsbStateVarProps.ToString()), CodeGenProvider.GenerateRegion(CodeGenProvider.ProtectedConstants, lscConsts.Definitions().ToString(), false, false), CodeGenProvider.GetClassScope(classScope, CodeGenProvider.Space.ToString()), CodeGenProvider.GenerateRegion(CodeGenProvider.EventHandlers, lsbEventHandlers.ToString(), true), CodeGenProvider.GenerateRegion(CodeGenProvider.EventCallers, lsbEventCallers.ToString()), string.Format( CodeGenProvider.ServiceClassHeaderComment, (service.Device != null && service.Device.RootDevice != null ? service.Device.RootDevice.FriendlyName : CodeGenProvider.Null), (service.Device != null && service.Device.RootDevice != null ? service.Device.RootDevice.Type : CodeGenProvider.Null), (service.Device != null && service.Device.RootDevice != null ? service.Device.RootDevice.SerialNumber : CodeGenProvider.Null), (service.Device != null ? service.Device.FriendlyName : CodeGenProvider.Null), (service.Device != null ? service.Device.Type : CodeGenProvider.Null), service.Id, service.ServiceTypeIdentifier, DateTime.Now.ToString(), className, namespaceName, classScope.ToString(), (partial ? CodeGenProvider.PartialClass : string.Empty), testStateVars, CodeGenProvider.ToString() ) ); }
/// <summary> /// Generates the class code for a device. /// </summary> /// <param name="device">The device to generate code for.</param> /// <param name="className">The class name of the device class or null to use friendly name.</param> /// <param name="namespaceName">The namespace for the class.</param> /// <param name="classScope">The scope of the class.</param> /// <param name="partial">True to make the class partial, false otherwise.</param> /// <param name="specificDevices">True if generating properties for device specific class types, false to use device non-specific class types.</param> /// <param name="specificServiceNamespace">The name of the service namespace if using specific service class types, null to use service non-specific class types.</param> /// <param name="specificDeviceClasses">The dictionary of UDNs, ClassNames for the devices or null for default / none.</param> /// <param name="specificServiceClasses">The dictionary of IDs, ClassNames for the services or null for default / none.</param> /// <returns>The string representing the code for the class.</returns> public string GenerateClassFor( Device device, string className, string namespaceName, ClassScope classScope, bool partial, bool specificDevices, string specificServiceNamespace, Dictionary <string, string> specificDeviceClasses = null, Dictionary <string, string> specificServiceClasses = null) { if (className == null) { className = DefaultCodeGenClassName(device, CodeGenProvider); } else { className = CodeGenProvider.CodeFriendlyIdentifier(className, false); } // No namespace specified then set it not use one if (string.IsNullOrEmpty(specificServiceNamespace)) { specificServiceNamespace = string.Empty; } // Set the specific services bool mbSpecificServices = specificServiceNamespace.Length > 0; string lsUsing; // If service namespace is different to device namespace if (specificServiceNamespace != namespaceName) { // Add the services namespace to the using clause lsUsing = (mbSpecificServices ? string.Format(CodeGenProvider.UsingClause, specificServiceNamespace) : string.Empty); } else { // Otherwise dont add anything to the uses clause lsUsing = string.Empty; } StringConstants lscConstants = new StringConstants(CodeGenProvider); StringBuilder lsbProperties = new StringBuilder(); // Build the child devices properties GenerateDevicePropertyCode(device, specificDevices, lscConstants, lsbProperties, specificDeviceClasses); // Build the child services properties GenerateServicePropertyCode(device, mbSpecificServices, lscConstants, lsbProperties, specificServiceClasses); // Build the code for the device class return (string.Format( CodeGenProvider.DeviceBase, lsUsing, namespaceName, CodeGenProvider.GetClassScope(classScope, CodeGenProvider.Space.ToString()), (partial ? CodeGenProvider.PartialClass : string.Empty), className, CodeGenProvider.GenerateRegion(CodeGenProvider.ProtectedConstants, lscConstants.Definitions().ToString(), false, false), device.Type, CodeGenProvider.GenerateRegion(CodeGenProvider.PublicProperties, lsbProperties.ToString()), device.ModelName, string.Format( CodeGenProvider.DeviceClassHeaderComment, (device.RootDevice != null ? device.RootDevice.FriendlyName : CodeGenProvider.Null), (device.RootDevice != null ? device.RootDevice.Type : CodeGenProvider.Null), (device.RootDevice != null ? device.RootDevice.SerialNumber : CodeGenProvider.Null), device.FriendlyName, device.Type, DateTime.Now.ToString(), className, namespaceName, classScope.ToString(), (partial ? CodeGenProvider.PartialClass : string.Empty), CodeGenProvider.ToString() ) )); }
/// <summary> /// Generates the code for a NON enumerated state variable. /// </summary> /// <param name="consts">The string constants created.</param> /// <param name="stateVarProps">A StringBuilder to contain property definitions.</param> /// <param name="eventHandlers">A StringBuilder to contain event handler declarations for the state variable changes.</param> /// <param name="eventCallers">A StringBuilder to contain event caller methods for the state variable changes.</param> /// <param name="stateVarEventIntercept">A StringBUilder to contain the case statements for the state variable changed event.</param> /// <param name="stateVarTypes">A Dictionary to contain each state variaible name and its code data type.</param> /// <param name="stateVarDesc">The state variable description.</param> /// <param name="friendlyName">The code friendly name of the state variaible.</param> /// <param name="addProp">True to add the actual property accessor.</param> private void GenerateStateVarCode( StringConstants consts, StringBuilder stateVarProps, StringBuilder eventHandlers, StringBuilder eventCallers, StringBuilder stateVarEventIntercept, Dictionary<string, string> stateVarTypes, StateVariableDescription stateVarDesc, string friendlyName, bool addProp) { // Get the data type string lsType = stateVarDesc.DataTypeValue.BaseType().Name; // Append the accessor for the state variaible if (addProp) stateVarProps.Append( string.Format( CodeGenProvider.NonEnumStateVar, lsType, friendlyName, consts[ CodeGenProvider.StateVarNameGroup, stateVarDesc.Name, string.Format(CodeGenProvider.StateVarNameComment, stateVarDesc.Name) ], GenerateStateVarComment(stateVarDesc))); // Add the type to the list for the actions stateVarTypes[stateVarDesc.Name] = lsType; // If the state variable is evented if (stateVarDesc.SendEvents) GenerateStateVarEventCode( lsType, friendlyName, String.Format(CodeGenProvider.NonEnumStateVarEventConversion, lsType), consts, eventHandlers, eventCallers, stateVarEventIntercept, stateVarDesc); }
/// <summary> /// Generates the code for all state variables. /// </summary> /// <param name="service">The service containing the state variables.</param> /// <param name="testStateVars"> /// True to test each state variable to ensure it is /// usuable for accessing as property, false to include /// all state variables as properties.</param> /// <param name="consts">The string constants created.</param> /// <param name="stateVarProps">A StringBuilder to contain property definitions.</param> /// <param name="stateVarConversion">A StringBuilder to contain the conversion method definitions.</param> /// <param name="stateVarEnums">A StringBuilder to contain the enumerations for the state variables.</param> /// <param name="eventHandlers">A StringBuilder to contain event handler declarations for the state variable changes.</param> /// <param name="eventCallers">A StringBuilder to contain event caller methods for the state variable changes.</param> /// <param name="stateVarEventIntercept">A StringBuilder to contain case statement code for each event state variable.</param> /// <param name="enumStateVars">A HashSet containing the names of all enumerated state variables.</param> /// <param name="stateVarTypes">A Dictionary to contain each state variaible name and its code data type.</param> /// <param name="desc">The service description to create the state variable code from.</param> private void GenerateStateVarCode( Service service, bool testStateVars, StringConstants consts, StringBuilder stateVarProps, StringBuilder stateVarConversion, StringBuilder stateVarEnums, StringBuilder eventHandlers, StringBuilder eventCallers, StringBuilder stateVarEventIntercept, HashSet<string> enumStateVars, Dictionary<string, string> stateVarTypes, ServiceDescription desc) { // For each state variaible description foreach (StateVariableDescription lsdStateVarDesc in desc.StateVariables.Values) { string lsFriendlyName = CodeGenProvider.CodeFriendlyIdentifier(lsdStateVarDesc.Name, false); // Determine if we actually want the property accessor for the state variable bool lbAddProp = IsStateVarQueryable(service, testStateVars, lsdStateVarDesc); // If the state variable is a string and has an allowed value list if (lsdStateVarDesc.DataTypeValue == StateVariableDataType.tstring && lsdStateVarDesc.AllowedValues.Count > 0) // Generate it using an enumeration GenerateEnumStateVarCode( consts, stateVarProps, stateVarConversion, stateVarEnums, eventHandlers, eventCallers, stateVarEventIntercept, enumStateVars, stateVarTypes, lsdStateVarDesc, lsFriendlyName, lbAddProp); else // Otherwise generate it using simple properties GenerateStateVarCode( consts, stateVarProps, eventHandlers, eventCallers, stateVarEventIntercept, stateVarTypes, lsdStateVarDesc, lsFriendlyName, lbAddProp); } }
/// <summary> /// Generates the code for an enumerated state variable. /// </summary> /// <param name="consts">The string constants created.</param> /// <param name="stateVarProps">A StringBuilder to contain property definitions.</param> /// <param name="stateVarConversion">A StringBuilder to contain the conversion method definitions.</param> /// <param name="stateVarEnums">A StringBuilder to contain the enumerations for the state variables.</param> /// <param name="eventHandlers">A StringBuilder to contain event handler declarations for the state variable changes.</param> /// <param name="eventCallers">A StringBuilder to contain event caller methods for the state variable changes.</param> /// <param name="stateVarEventIntercept">A StringBUilder to contain the case statements for the state variable changed event.</param> /// <param name="enumStateVars">A HashSet containing the names of all enumerated state variables.</param> /// <param name="stateVarTypes">A Dictionary to contain each state variaible name and its code data type.</param> /// <param name="stateVarDesc">The state variable description.</param> /// <param name="friendlyName">The code friendly name of the state variaible.</param> /// <param name="addProp">True to add the actual property accessor.</param> private void GenerateEnumStateVarCode( StringConstants consts, StringBuilder stateVarProps, StringBuilder stateVarConversion, StringBuilder stateVarEnums, StringBuilder eventHandlers, StringBuilder eventCallers, StringBuilder stateVarEventIntercept, HashSet<string> enumStateVars, Dictionary<string, string> stateVarTypes, StateVariableDescription stateVarDesc, string friendlyName, bool addProp) { StringBuilder lsbStateVarEnumValues = new StringBuilder(); StringBuilder lsbEnumStateVarParse = new StringBuilder(); StringBuilder lsbEnumStateVarToString = new StringBuilder(); // Add the state var to the enum list enumStateVars.Add(stateVarDesc.Name); // Generate allowed values code GenerateEnumAllowedValuesCode( consts, stateVarDesc, friendlyName, lsbStateVarEnumValues, lsbEnumStateVarParse, lsbEnumStateVarToString); // Generate enumeration stateVarEnums.Append(string.Format(CodeGenProvider.StateVarEnum, friendlyName, lsbStateVarEnumValues)); // Generate conversion functions stateVarConversion.Append(string.Format(CodeGenProvider.EnumStateVarConversion, friendlyName, lsbEnumStateVarParse, lsbEnumStateVarToString)); // Generate property accessor if required if (addProp) stateVarProps.Append( string.Format( CodeGenProvider.EnumStateVar, friendlyName, consts[ CodeGenProvider.StateVarNameGroup, stateVarDesc.Name, string.Format(CodeGenProvider.StateVarNameComment, stateVarDesc.Name) ], GenerateStateVarComment(stateVarDesc))); string lsEnumTypeName = string.Format(CodeGenProvider.EnumStateVarName, friendlyName); // Add the type to the list for the actions stateVarTypes[stateVarDesc.Name] = lsEnumTypeName; // If the state variable is evented if (stateVarDesc.SendEvents) GenerateStateVarEventCode( lsEnumTypeName, friendlyName, String.Format(CodeGenProvider.EnumStateVarEventConversion, friendlyName), consts, eventHandlers, eventCallers, stateVarEventIntercept, stateVarDesc); }
/// <summary> /// Generates the code for all actions. /// </summary> /// <param name="consts">The stirng constants created.</param> /// <param name="actionMethods">The StringBuilder to contain the action call methods.</param> /// <param name="enumStateVars">A HashSet of the state variables which are enumerations.</param> /// <param name="stateVarTypes">A Dictionary containing the state variables and their data types.</param> /// <param name="desc">The service description to generate the action code for.</param> private void GenerateActionCode( StringConstants consts, StringBuilder actionMethods, HashSet<string> enumStateVars, Dictionary<string, string> stateVarTypes, ServiceDescription desc) { // For each action foreach (ActionDescription ladDesc in desc.Actions.Values) { string lsFriendlyName = CodeGenProvider.CodeFriendlyIdentifier(ladDesc.Name, false); int liInArgumentCount = 0; int liInArgumentIndex = 0; int liOutArgumentIndex = 0; StringBuilder lsbInArguments = new StringBuilder(); StringBuilder lsbOutArguments = new StringBuilder(); StringBuilder lsbInSetValues = new StringBuilder(); StringBuilder lsbOutSetValues = new StringBuilder(); StringBuilder lsbInParamComments = new StringBuilder(); StringBuilder lsbOutParamComments = new StringBuilder(); StringBuilder lsbReturnsComments = new StringBuilder(); int liOutArguments = ladDesc.Arguments.OutArgCount; string lsLastOutType = CodeGenProvider.UnknownType; // For each argument foreach (ArgumentDescription ladArgDesc in ladDesc.Arguments.Values) { bool lbEnumStateVar = enumStateVars.Contains(ladArgDesc.RelatedStateVariable); string lsArgFriendlyName = CodeGenProvider.CodeFriendlyIdentifier(ladArgDesc.Name, true); string lsRelatedStateVarFriendlyName = CodeGenProvider.CodeFriendlyIdentifier(ladArgDesc.RelatedStateVariable, false); string lsType; // Get the type of the related state variable, or use unknown type if state variable cannot be found if (!stateVarTypes.TryGetValue(ladArgDesc.RelatedStateVariable, out lsType)) lsType = CodeGenProvider.UnknownType; // Determine direction if (ladArgDesc.DirectionValue == ArgumentDirection.Out) { lsLastOutType = lsType; // If there is more than 1 out argument then use out parameters if (liOutArguments > 1) GenerateOutArgumentCode( ladArgDesc, liOutArgumentIndex, lsbOutArguments, lsbOutSetValues, lbEnumStateVar, lsArgFriendlyName, lsRelatedStateVarFriendlyName, lsType, lsbOutParamComments); else // Otherwise use a returning function GenerateOutArgumentReturnCode( ladArgDesc, liOutArgumentIndex, lsbOutSetValues, lbEnumStateVar, lsRelatedStateVarFriendlyName, lsType, lsbReturnsComments); // Increment the out argument index liOutArgumentIndex++; } else { // Generate the in argument code GenerateInArgumentCode( ladArgDesc, liInArgumentIndex, lsbInArguments, lsbInSetValues, lbEnumStateVar, lsArgFriendlyName, lsRelatedStateVarFriendlyName, lsType, lsbInParamComments); // Increment in argument count and index liInArgumentCount++; liInArgumentIndex++; } } // Generate the method code actionMethods.Append( string.Format( (liOutArguments == 1 ? CodeGenProvider.ReturnAction : CodeGenProvider.Action), lsFriendlyName, lsbInArguments, lsbOutArguments, CodeGenProvider.ArraySizeForCount(liInArgumentCount), lsbInSetValues, consts[CodeGenProvider.ActionNameGroup, ladDesc.Name, string.Format(CodeGenProvider.ActionNameComment, ladDesc.Name)], lsbOutSetValues, (lsbInArguments.Length > 0 && lsbOutArguments.Length > 0 ? CodeGenProvider.ParameterSeperator : String.Empty), lsLastOutType, lsbInParamComments, lsbOutParamComments, lsbReturnsComments, (liOutArguments > 0 ? CodeGenProvider.OutVar : string.Empty) ) ); } }
/// <summary> /// Generates the class code for a device. /// </summary> /// <param name="device">The device to generate code for.</param> /// <param name="className">The class name of the device class or null to use friendly name.</param> /// <param name="namespaceName">The namespace for the class.</param> /// <param name="classScope">The scope of the class.</param> /// <param name="partial">True to make the class partial, false otherwise.</param> /// <param name="specificDevices">True if generating properties for device specific class types, false to use device non-specific class types.</param> /// <param name="specificServiceNamespace">The name of the service namespace if using specific service class types, null to use service non-specific class types.</param> /// <param name="specificDeviceClasses">The dictionary of UDNs, ClassNames for the devices or null for default / none.</param> /// <param name="specificServiceClasses">The dictionary of IDs, ClassNames for the services or null for default / none.</param> /// <returns>The string representing the code for the class.</returns> public string GenerateClassFor( Device device, string className, string namespaceName, ClassScope classScope, bool partial, bool specificDevices, string specificServiceNamespace, Dictionary<string, string> specificDeviceClasses = null, Dictionary<string, string> specificServiceClasses = null) { if (className == null) className = DefaultCodeGenClassName(device, CodeGenProvider); else className = CodeGenProvider.CodeFriendlyIdentifier(className, false); // No namespace specified then set it not use one if (string.IsNullOrEmpty(specificServiceNamespace)) specificServiceNamespace = string.Empty; // Set the specific services bool mbSpecificServices = specificServiceNamespace.Length > 0; string lsUsing; // If service namespace is different to device namespace if (specificServiceNamespace != namespaceName) // Add the services namespace to the using clause lsUsing = (mbSpecificServices ? string.Format(CodeGenProvider.UsingClause, specificServiceNamespace) : string.Empty); else // Otherwise dont add anything to the uses clause lsUsing = string.Empty; StringConstants lscConstants = new StringConstants(CodeGenProvider); StringBuilder lsbProperties = new StringBuilder(); // Build the child devices properties GenerateDevicePropertyCode(device, specificDevices, lscConstants, lsbProperties, specificDeviceClasses); // Build the child services properties GenerateServicePropertyCode(device, mbSpecificServices, lscConstants, lsbProperties, specificServiceClasses); // Build the code for the device class return string.Format( CodeGenProvider.DeviceBase, lsUsing, namespaceName, CodeGenProvider.GetClassScope(classScope, CodeGenProvider.Space.ToString()), (partial ? CodeGenProvider.PartialClass : string.Empty), className, CodeGenProvider.GenerateRegion(CodeGenProvider.ProtectedConstants, lscConstants.Definitions().ToString(), false, false), device.Type, CodeGenProvider.GenerateRegion(CodeGenProvider.PublicProperties, lsbProperties.ToString()), device.ModelName, string.Format( CodeGenProvider.DeviceClassHeaderComment, (device.RootDevice != null ? device.RootDevice.FriendlyName : CodeGenProvider.Null), (device.RootDevice != null ? device.RootDevice.Type : CodeGenProvider.Null), (device.RootDevice != null ? device.RootDevice.SerialNumber : CodeGenProvider.Null), device.FriendlyName, device.Type, DateTime.Now.ToString(), className, namespaceName, classScope.ToString(), (partial ? CodeGenProvider.PartialClass : string.Empty), CodeGenProvider.ToString() ) ); }
/// <summary> /// Generates the class code for a service. /// </summary> /// <param name="service">The service to generate for.</param> /// <param name="className">The class name of the service or null to use the service type.</param> /// <param name="namespaceName">The namespace for the class.</param> /// <param name="classScope">The scope for the class.</param> /// <param name="partial">True to make the class partial, false otherwise.</param> /// <param name="testStateVars"> /// True to test each state variable to ensure it is /// usuable for accessing as property, false to include /// all state variables as properties.</param> /// <returns>The string representing the code for the class.</returns> public string GenerateClassFor( Service service, string className, string namespaceName, ClassScope classScope, bool partial, bool testStateVars) { // If classname is not specified then default to service information if (className == null) { className = DefaultCodeGenClassName(service, CodeGenProvider); } else { // Otherwise ensure classname is Identifier compatible className = CodeGenProvider.CodeFriendlyIdentifier(className, false); } StringBuilder lsbStateVarProps = new StringBuilder(); StringBuilder lsbStateVarConversion = new StringBuilder(); StringBuilder lsbStateVarEnums = new StringBuilder(); StringBuilder lsbActionMethods = new StringBuilder(); StringBuilder lsbEventHandlers = new StringBuilder(); StringBuilder lsbEventCallers = new StringBuilder(); StringBuilder lsbStateVarEventIntercept = new StringBuilder(); HashSet <string> lhsEnumStateVars = new HashSet <string>(); StringConstants lscConsts = new StringConstants(CodeGenProvider); Dictionary <string, string> ldStateVarTypes = new Dictionary <string, string>(); // Get the service description ServiceDescription lsdDesc = service.Description(); if (lsdDesc != null) { // Generate the state variable property declarations GenerateStateVarCode( service, testStateVars, lscConsts, lsbStateVarProps, lsbStateVarConversion, lsbStateVarEnums, lsbEventHandlers, lsbEventCallers, lsbStateVarEventIntercept, lhsEnumStateVars, ldStateVarTypes, lsdDesc); // Generate the action methods GenerateActionCode( lscConsts, lsbActionMethods, lhsEnumStateVars, ldStateVarTypes, lsdDesc); } if (lsbStateVarEventIntercept.Length > 0) { lsbEventCallers.Append( String.Format(CodeGenProvider.StateVarChangedEventHandler, lsbStateVarEventIntercept) ); } return (String.Format( CodeGenProvider.ServiceBase, namespaceName, className, service.ServiceTypeIdentifier, CodeGenProvider.GenerateRegion(CodeGenProvider.PublicEnumerations, lsbStateVarEnums.ToString()), (partial ? CodeGenProvider.PartialClass : String.Empty), CodeGenProvider.GenerateRegion(CodeGenProvider.ProtectedMethods, lsbStateVarConversion.ToString()), lsbActionMethods, CodeGenProvider.GenerateRegion(CodeGenProvider.PublicProperties, lsbStateVarProps.ToString()), CodeGenProvider.GenerateRegion(CodeGenProvider.ProtectedConstants, lscConsts.Definitions().ToString(), false, false), CodeGenProvider.GetClassScope(classScope, CodeGenProvider.Space.ToString()), CodeGenProvider.GenerateRegion(CodeGenProvider.EventHandlers, lsbEventHandlers.ToString(), true), CodeGenProvider.GenerateRegion(CodeGenProvider.EventCallers, lsbEventCallers.ToString()), string.Format( CodeGenProvider.ServiceClassHeaderComment, (service.Device != null && service.Device.RootDevice != null ? service.Device.RootDevice.FriendlyName : CodeGenProvider.Null), (service.Device != null && service.Device.RootDevice != null ? service.Device.RootDevice.Type : CodeGenProvider.Null), (service.Device != null && service.Device.RootDevice != null ? service.Device.RootDevice.SerialNumber : CodeGenProvider.Null), (service.Device != null ? service.Device.FriendlyName : CodeGenProvider.Null), (service.Device != null ? service.Device.Type : CodeGenProvider.Null), service.Id, service.ServiceTypeIdentifier, DateTime.Now.ToString(), className, namespaceName, classScope.ToString(), (partial ? CodeGenProvider.PartialClass : string.Empty), testStateVars, CodeGenProvider.ToString() ) )); }