public static bool GetIsVariableState(this CustomVariable customVariable, IElement containingElement = null) { bool returnValue = false; if (customVariable != null && customVariable.DefinedByBase) { // If this is DefinedByBase, it may represent a variable that is tunneling, but it // doesn't know it - we have to get the variable from the base to know for sure. if (containingElement == null) { containingElement = ObjectFinder.Self.GetElementContaining(customVariable); } if (containingElement != null && !string.IsNullOrEmpty(containingElement.BaseElement)) { IElement baseElement = ObjectFinder.Self.GetIElement(containingElement.BaseElement); if (baseElement != null) { CustomVariable customVariableInBase = baseElement.GetCustomVariableRecursively(customVariable.Name); if (customVariableInBase != null) { returnValue = customVariableInBase.GetIsVariableState(); } } } } else { bool isTunneled = !string.IsNullOrEmpty(customVariable.SourceObject) && !string.IsNullOrEmpty(customVariable.SourceObjectProperty); bool isOnThis = string.IsNullOrEmpty(customVariable.SourceObject) && string.IsNullOrEmpty(customVariable.SourceObjectProperty); if (isTunneled) { string property = customVariable.SourceObjectProperty; return(!string.IsNullOrEmpty(property) && property.StartsWith("Current") && property.EndsWith("State")); } else { if (containingElement == null) { containingElement = ObjectFinder.Self.GetElementContaining(customVariable); } if (containingElement != null) { returnValue = customVariable.Type == "VariableState" || containingElement.GetStateCategory(customVariable.Type) != null; } } } return(returnValue); }
public static Type GetRuntimeType(this CustomVariable customVariable) { if (customVariable.GetIsVariableState()) { return(null); } else if (string.IsNullOrEmpty(customVariable.OverridingPropertyType)) { var type = TypeManager.GetTypeFromString(customVariable.Type); return(type); } else { return(TypeManager.GetTypeFromString(customVariable.OverridingPropertyType)); } }
private static void ReactToChangedCustomVariableName(string oldName, CustomVariable customVariable) { string whyItIsntValid = ""; bool isNameValid = NameVerifier.IsCustomVariableNameValid(customVariable.Name, customVariable, GlueState.Self.CurrentElement, ref whyItIsntValid); string newName = EditorLogic.CurrentCustomVariable.Name; if (customVariable.GetIsVariableState() && oldName != newName) { whyItIsntValid += "\nState variables cannot be renamed - they require specific names to function properly."; } if (!string.IsNullOrEmpty(whyItIsntValid)) { MessageBox.Show(whyItIsntValid); customVariable.Name = oldName; // handle invalid names here } else { IElement element = EditorLogic.CurrentElement; List<IElement> elementsToGenerate = new List<IElement>(); List<IElement> elementsToSearchForTunneledVariablesIn = new List<IElement>(); #region Change any states that use this variable foreach (StateSave stateSave in element.AllStates) { foreach (InstructionSave instructionSave in stateSave.InstructionSaves) { if (instructionSave.Member == oldName) { instructionSave.Member = newName; } } } #endregion #region Change any NOS that uses this as its source List<NamedObjectSave> nosList = ObjectFinder.Self.GetAllNamedObjectsThatUseElement(element); foreach (NamedObjectSave nos in nosList) { IElement container = ObjectFinder.Self.GetElementContaining(nos); if (!elementsToSearchForTunneledVariablesIn.Contains(container)) { elementsToSearchForTunneledVariablesIn.Add(container); } if (nos.RenameVariable(oldName, newName)) { if (!elementsToGenerate.Contains(container)) { elementsToGenerate.Add(container); } } } #endregion #region Change any CustomVaribles that tunnel in to this variable foreach (IElement elementToCheck in elementsToSearchForTunneledVariablesIn) { foreach (CustomVariable variableToCheck in elementToCheck.CustomVariables) { if (!string.IsNullOrEmpty(variableToCheck.SourceObject) && !string.IsNullOrEmpty(variableToCheck.SourceObjectProperty) && variableToCheck.SourceObjectProperty == oldName) { NamedObjectSave nos = elementToCheck.GetNamedObjectRecursively(variableToCheck.SourceObject); // just to be safe if (nos != null && nosList.Contains(nos)) { variableToCheck.SourceObjectProperty = newName; if (!elementsToGenerate.Contains(elementToCheck)) { elementsToGenerate.Add(elementToCheck); } } } } } #endregion #region Change all events that reference this variable foreach (var eventResponse in element.Events) { if (eventResponse.SourceVariable == oldName) { eventResponse.SourceVariable = newName; Plugins.PluginManager.ReceiveOutput("Changing event " + eventResponse.EventName + " to use variable " + newName); } } #endregion foreach (IElement toRegenerate in elementsToGenerate) { CodeWriter.GenerateCode(toRegenerate); } } }
private bool GetIfCanBeRenamed(CustomVariable customVariable) { if (customVariable.GetIsVariableState()) { return false; } return true; }
//public abstract void GenerateCode(); public static IElement GetElementIfCustomVariableIsVariableState(CustomVariable customVariable, IElement saveObject) { if (customVariable.GetIsVariableState() && string.IsNullOrEmpty(customVariable.SourceObject)) { return saveObject; } else { NamedObjectSave sourceNamedObjectSave = saveObject.GetNamedObjectRecursively(customVariable.SourceObject); if (sourceNamedObjectSave != null) { EntitySave sourceEntitySave = ObjectFinder.Self.GetEntitySave(sourceNamedObjectSave.SourceClassType); if (sourceEntitySave != null && ((sourceEntitySave.States.Count != 0 && customVariable.SourceObjectProperty == "CurrentState") || sourceEntitySave.StateCategoryList.ContainsCategoryName(customVariable.Type)) ) { return sourceEntitySave; } else if (sourceEntitySave == null) { ScreenSave sourceScreenSave = ObjectFinder.Self.GetScreenSave(sourceNamedObjectSave.SourceClassType); if (sourceScreenSave != null && sourceScreenSave.States.Count != 0 && customVariable.SourceObjectProperty == "CurrentState") { return sourceScreenSave; } } } return null; } }
public static bool GetIsVariableState(this CustomVariable customVariable, IElement containingElement = null) { bool returnValue = false; if (customVariable != null && customVariable.DefinedByBase) { // If this is DefinedByBase, it may represent a variable that is tunneling, but it // doesn't know it - we have to get the variable from the base to know for sure. if (containingElement == null) { containingElement = ObjectFinder.Self.GetElementContaining(customVariable); } if (containingElement != null && !string.IsNullOrEmpty(containingElement.BaseElement)) { IElement baseElement = GlueState.CurrentGlueProject.GetElement(containingElement.BaseElement); if (baseElement != null) { CustomVariable customVariableInBase = baseElement.GetCustomVariableRecursively(customVariable.Name); if (customVariableInBase != null) { returnValue = customVariableInBase.GetIsVariableState(); } } } } else { bool isTunneled = !string.IsNullOrEmpty(customVariable.SourceObject) && !string.IsNullOrEmpty(customVariable.SourceObjectProperty); bool isOnThis = string.IsNullOrEmpty(customVariable.SourceObject) && string.IsNullOrEmpty(customVariable.SourceObjectProperty); if (isTunneled) { string property = customVariable.SourceObjectProperty; return(!string.IsNullOrEmpty(property) && property.StartsWith("Current") && property.EndsWith("State")); } else { if (containingElement == null) { containingElement = ObjectFinder.Self.GetElementContaining(customVariable); } if (containingElement != null) { returnValue = customVariable.Type == "VariableState" || containingElement.GetStateCategory(customVariable.Type) != null; } } } if (!returnValue && customVariable.Type.StartsWith("Entities.")) { // It may still be a state, so let's see the entity: var entityName = customVariable.GetEntityNameDefiningThisTypeCategory(); var entity = ObjectFinder.Self.GetEntitySave(entityName); if (entity != null) { var lastPeriod = customVariable.Type.LastIndexOf('.'); var startIndex = lastPeriod + 1; var stateCategory = customVariable.Type.Substring(startIndex); var category = entity.GetStateCategory(stateCategory); if (category != null) { returnValue = true; } } } return(returnValue); }
// made public for testing public void SetCustomVariable(CustomVariable cv, IElement container, object valueToSetTo, bool attachAndUnattach, VariableSettingOptions settingOptions = VariableSettingOptions.TreatAbsoluteAsRelativeIfAttached) { //////////////////////////////////Early out///////////////////////////////////// if (valueToSetTo == null || // May 28, 2012 - I hesitate to write this at first because I thought - what if the user wants to set something like // a texture to null. GView should understand this. However, it seems like if we want to do that we should instead have // a specific value for it like <NONE> or <NULL>. (valueToSetTo is string && string.IsNullOrEmpty((string)valueToSetTo) && cv.Type != "String" && cv.Type != "string") ) { // I need to // fix this - // maybe this method // should never be called // when this is null? Or maybe // this method should tolerate a // null value and do nothing? Need // to see what calls this. // Update - I think we should do nothing return; } //////////////////////////////////End early out///////////////////////////////////// // This converts the value if the user is overriding the type (like converting a string to an int for a score Text object) valueToSetTo = ConvertIfOverriding(cv, valueToSetTo); object untranslated = valueToSetTo; valueToSetTo = CastAndTranslateValueToSet(cv, valueToSetTo); ElementRuntime sourceElement; string variableName; GetSourceElementAndVariableName(cv, out sourceElement, out variableName); if (sourceElement != null) { object objectToSetOn; PositionedObject parent; GetObjectToSetOnAndParent(sourceElement, out objectToSetOn, out parent); if (objectToSetOn is PositionedObject && ((PositionedObject)objectToSetOn).Parent != null && settingOptions == VariableSettingOptions.TreatAbsoluteAsRelativeIfAttached) { variableName = ConvertAbsoluteToRelative(variableName); } PropertyInfo property; FieldInfo field; bool hasFieldOrProperty; GetHasFieldOrProperty(variableName, objectToSetOn, out property, out field, out hasFieldOrProperty); if (hasFieldOrProperty) { parent = SetFieldOrPropertyCustomVariable(cv, valueToSetTo, attachAndUnattach, container, sourceElement, objectToSetOn, parent, property, field); } else if (cv.SourceObject != null && cv.SourceObjectProperty != null) // It's tunneled! { SetTunneledVariable(valueToSetTo, attachAndUnattach, untranslated, variableName, objectToSetOn, container, container.GetNamedObjectRecursively(cv.SourceObject)); } else if ( cv.DefaultValue is StateSave || (cv.GetIsVariableState(this.AssociatedIElement) && valueToSetTo is string)) { SetStateFromCustomVariable(cv, container, valueToSetTo); } else { SetCustomVariableWithNoSourceObject(cv, valueToSetTo); } } else { SetCustomVariableWithNoSourceObject(cv, valueToSetTo); } }
/// <summary> /// This method populates the mCustomVariables list with default valued variables. These can later get set in SetCustomVariable, but they need to exist so that /// plugins like the script parser know whether something is a custom variable or not. /// </summary> /// <param name="cv">The variable to evaluate and add if it is a custom variable.</param> private void CreateCustomVariableContainer(CustomVariable cv) { bool isCustomVariable = true; if(!string.IsNullOrEmpty(cv.SourceObject)) { isCustomVariable = false; } if (isCustomVariable) { Type positionedObjectType = typeof(PositionedObject); PropertyInfo property = positionedObjectType.GetProperty(cv.Name); FieldInfo field = positionedObjectType.GetField(cv.Name); if (property != null || field != null) { isCustomVariable = false; } } if (isCustomVariable) { EntitySave baseEntitySave = ObjectFinder.Self.GetEntitySave(this.AssociatedIElement.BaseElement); if (baseEntitySave != null && baseEntitySave.GetCustomVariable(cv.Name) != null) { isCustomVariable = false; } } if (isCustomVariable) { object defaultValue = null; if (cv.GetIsFile()) { defaultValue = null; } else if (cv.GetIsCsv()) { defaultValue = null; } else if (cv.GetIsVariableState()) { defaultValue = null; } else { try { defaultValue = TypeManager.GetDefaultForTypeAsType(cv.Type); } catch { throw new Exception("Could not get the default value for variable " + cv); } } mCustomVariables.Add(new PropertyValuePair(cv.Name, defaultValue)); } }
public static TypeConverter GetTypeConverter(this CustomVariable customVariable, IElement containingElement, StateSave stateSave, FlatRedBall.Glue.Plugins.ExportedInterfaces.IGlueState glueState) { TypeConverter typeConverter = null; if (customVariable.GetIsVariableState()) { typeConverter = new AvailableStates( FacadeContainer.Self.GlueState.CurrentNamedObjectSave, FacadeContainer.Self.GlueState.CurrentElement, FacadeContainer.Self.GlueState.CurrentCustomVariable, FacadeContainer.Self.GlueState.CurrentStateSave ); } else { Type runtimeType = customVariable.GetRuntimeType(); if (runtimeType != null) { if (runtimeType.IsEnum) { typeConverter = new EnumConverter(runtimeType); } else if (runtimeType == typeof(Color)) { return(new AvailableColorTypeConverter()); } else if ((runtimeType == typeof(string) || runtimeType == typeof(AnimationChainList)) && customVariable.SourceObjectProperty == "CurrentChainName") { typeConverter = new AvailableAnimationChainsStringConverter(customVariable, stateSave); } else if (customVariable.GetIsFile()) { AvailableFileStringConverter converter = new AvailableFileStringConverter(containingElement); converter.QualifiedRuntimeTypeName = runtimeType.FullName; converter.ShowNewFileOption = false; converter.RemovePathAndExtension = true; typeConverter = converter; } } else if (customVariable.GetIsCsv()) { if (FacadeContainer.Self.ProjectValues == null) { throw new NullReferenceException("The ProjectValues property in FAcadeContainer.Self.ProjectValues must be set before trying to get the CSV type converter for the variable " + customVariable.ToString()); } ReferencedFileSave rfs = ObjectFinder.Self.GetAllReferencedFiles().FirstOrDefault(item => item.IsCsvOrTreatedAsCsv && item.GetTypeForCsvFile() == customVariable.Type); AvailableSpreadsheetValueTypeConverter converter = null; if (rfs != null) { converter = new AvailableSpreadsheetValueTypeConverter( FacadeContainer.Self.ProjectValues.ContentDirectory + rfs.Name, containingElement); } else { converter = new AvailableSpreadsheetValueTypeConverter( FacadeContainer.Self.ProjectValues.ContentDirectory + customVariable.Type, containingElement); } converter.ShouldAppendFileName = true; typeConverter = converter; } else if (customVariable.GetIsFile()) { // If we got here, that means that the // CustomVariable is a file, but it doesn't // have a System.Type, so it only knows its runtime // type; AvailableFileStringConverter converter = new AvailableFileStringConverter(containingElement); converter.UnqualifiedRuntimeTypeName = customVariable.Type; converter.ShowNewFileOption = false; converter.RemovePathAndExtension = true; typeConverter = converter; } } return(typeConverter); }
private static void GenerateInterpolateForIndividualStateWithSource(ref ICodeBlock codeBlock, IElement element, ref ICodeBlock otherBlock, CustomVariable customVariable, string valueAsString, NamedObjectSave sourceNamedObjectSave, string timeCastString) { if (customVariable.GetIsVariableState()) { GenerateInterpolateForIndividualStateWithSourceStateVariable(codeBlock, customVariable, element, valueAsString.Replace("\"", "")); } else { string velocityMember = FlatRedBall.Instructions.InstructionManager.GetVelocityForState(customVariable.SourceObjectProperty); bool generatedVelocity = false; if (velocityMember == null && customVariable.HasAccompanyingVelocityProperty) { velocityMember = customVariable.Name + "Velocity"; generatedVelocity = true; } bool velocityComesFromTunnel = false; if (velocityMember == null && // Only want to go 1 deep. The reason is if the tunneled variable has a // velocity value, we can use that. However, if it's tunneled multiple times // into a variable that ultimately has a velocity variable we may not be able to // get to it, so we shouldn't just assume we can add "Velocity" to the variable name. customVariable.HasAccompanyingVelocityConsideringTunneling(element, 1)) { velocityMember = customVariable.SourceObjectProperty + "Velocity"; generatedVelocity = true; velocityComesFromTunnel = true; } if (!string.IsNullOrEmpty(velocityMember)) { string sourceDot = customVariable.SourceObject + "."; IEnumerable<string> exposableVariables = FlatRedBall.Glue.Reflection.ExposedVariableManager.GetExposableMembersFor(sourceNamedObjectSave).Select(item=>item.Member); // We will generate this if the variable is contained in exposable variables, // if the user explicitly said to generate a velocity variable, or if // this is a FRB type. The reason we check if it's a FRB Type is because FRB // types have velocity variables which may not be exposable. We don't want Glue // to mess with temporary values like Velocity, so they are removed from the exposab // variable list: bool shouldGenerate = exposableVariables.Contains(velocityMember) || generatedVelocity || sourceNamedObjectSave.SourceType == SourceType.FlatRedBallType; if (shouldGenerate) { string relativeVelocity = InstructionManager.GetRelativeForAbsolute(velocityMember); string leftHandPlusEquals = null; if (!string.IsNullOrEmpty(relativeVelocity)) { codeBlock = codeBlock .If(customVariable.SourceObject + ".Parent != null"); otherBlock = otherBlock .If(customVariable.SourceObject + ".Parent != null"); string sourceObjectPropertyRelative = InstructionManager.GetRelativeForAbsolute(customVariable.SourceObjectProperty); leftHandPlusEquals = sourceDot + relativeVelocity + " = "; codeBlock.Line(leftHandPlusEquals + "(" + valueAsString + " - " + sourceDot + sourceObjectPropertyRelative + ") / " + timeCastString + "secondsToTake;"); otherBlock.Line(leftHandPlusEquals + " 0;"); codeBlock = codeBlock .End() .Else(); otherBlock = otherBlock .End() .Else(); } // If we're using a custom velocity value, we don't want to // use the sourceDot. We just want to use the velocity value if (generatedVelocity && !velocityComesFromTunnel) { leftHandPlusEquals = velocityMember + " = "; } else { leftHandPlusEquals = sourceDot + velocityMember + " = "; } codeBlock.Line(leftHandPlusEquals + "(" + valueAsString + " - " + sourceDot + customVariable.SourceObjectProperty + ") / " + timeCastString + "secondsToTake;"); otherBlock.Line(leftHandPlusEquals + " 0;"); if (!string.IsNullOrEmpty(relativeVelocity)) { codeBlock = codeBlock.End(); otherBlock = otherBlock.End(); } } } } }
private static void AddAssignmentForInterpolationForVariable(ICodeBlock curBlock, CustomVariable variable, string prepend, string variableToAssign) { if (variable.GetIsVariableState() && ! string.IsNullOrEmpty(variable.SourceObject )) { string line = string.Format("{0}.InterpolateBetween({2}FirstValue, {2}SecondValue, interpolationValue);", variable.SourceObject, variable.SourceObjectProperty, prepend); curBlock.Line(line); } else { switch (variable.Type) { case "int": curBlock.Line(string.Format("{0} = FlatRedBall.Math.MathFunctions.RoundToInt({1}FirstValue* (1 - interpolationValue) + {1}SecondValue * interpolationValue);", variableToAssign, prepend)); break; case "float": case "double": curBlock.Line(string.Format("{0} = {1}FirstValue * (1 - interpolationValue) + {1}SecondValue * interpolationValue;", variableToAssign, prepend)); break; } } }
public static string GetMemberTypeFor(CustomVariable customVariable, IElement element) { NamedObjectSave referencedNos = element.GetNamedObjectRecursively(customVariable.SourceObject); string customVariableType; bool isTypeFromCsv = false; if (IsTypeFromCsv(customVariable)) { // This is a type defined in a CSV ReferencedFileSave rfsForCsv = ObjectFinder.Self.GetAllReferencedFiles().FirstOrDefault(item => item.IsCsvOrTreatedAsCsv && item.GetTypeForCsvFile() == customVariable.Type); if (rfsForCsv != null) { customVariableType = rfsForCsv.GetTypeForCsvFile(); } else { string unqualifiedType = null; unqualifiedType = FileManager.RemovePath(FileManager.RemoveExtension(customVariable.Type)); if (unqualifiedType.EndsWith("File")) { unqualifiedType = unqualifiedType.Substring(0, unqualifiedType.Length - "File".Length); } customVariableType = ProjectManager.ProjectNamespace + ".DataTypes." + unqualifiedType; } isTypeFromCsv = true; } else { customVariableType = customVariable.Type; } // CSVs may happen to be named the same as base types - like "Resources", // so we only want to use the TypeManager if we didn't first find a CSV. if (!isTypeFromCsv) { Type type = null; if (!string.IsNullOrEmpty(customVariableType)) { type = TypeManager.GetTypeFromString(customVariableType); } if (type != null) { // If it's a common type we don't want to make things confusing // by using "System.Single", but we do want to fully-qualify things // like FlatRedBall types to make sure we don't get any kind of naming // conflicts // If a value is defined inside a class (like the Borders enum in SpriteFrame) // then its type will come out with a +. We need to replace that with a dot. customVariableType = TypeManager.ConvertToCommonType(type.FullName).Replace("+", "."); } } if (customVariable.GetIsVariableState()) { // handle old tunneled variables: tunneled state variables used to set their type // as "string" instead of the variable state type. // We now set the type to be the variable type (the enum type) but we want existing projects to continue to work if (customVariableType == "string") { customVariableType = "VariableState"; } if (customVariable.IsTunneling) { IElement namedObjectElement = ObjectFinder.Self.GetIElement(referencedNos.SourceClassType); if (namedObjectElement != null) { customVariableType = namedObjectElement.Name.Replace("\\", ".") + "." + customVariableType; } } else { customVariableType = element.Name.Replace("\\", ".") + "." + customVariableType; } } return customVariableType; }
private static void CreateNewVariableMember(ICodeBlock codeBlock, CustomVariable customVariable, bool isExposing, IElement element) { string variableAssignment = ""; if (customVariable.DefaultValue != null) { if (!IsTypeFromCsv(customVariable)) { variableAssignment = CodeParser.ParseObjectValue(customVariable.DefaultValue); // If this is a file, we don't want to assign it here if (customVariable.GetIsFile()) { variableAssignment = null; } if (customVariable.Type == "Color") { variableAssignment = "Color." + variableAssignment.Replace("\"", ""); } else if (customVariable.Type != "string" && variableAssignment == "\"\"") { variableAssignment = null; } if (variableAssignment != null) { variableAssignment = " = " + variableAssignment; } } else if(!string.IsNullOrEmpty(customVariable.DefaultValue as string) && (string)customVariable.DefaultValue != "<NULL>") { // If the variable IsShared (ie static) then we // don't want to assign the value because the CSV // may not yet be loaded. This may create behavior // the user doesn't expect, but the alternative is either // to load the file before the user wants to (which maybe we // will end up doing) or to get a crash // Update June 2, 2013 // If the customVariable // is not "IsShared" (it's // not static), we don't want // to assign the value where we // create the variable as a field // because this means the value will // attempt to assign before LoadStaticContent. // This can cause a crash, and has in the GlueTestProject. // Update June 2, 2013 // Used to set it to null // if it's static, but we should // allow statics to set their values // if they come from global content files. if ( ReferencesCsvFromGlobalContent(customVariable) && ShouldAssignToCsv(customVariable, customVariable.DefaultValue as string)) { variableAssignment = " = " + GetAssignmentToCsvItem(customVariable, element, (string)customVariable.DefaultValue); } else { variableAssignment = null; } } } string formatString = null; bool needsToBeProperty = (customVariable.SetByDerived && !customVariable.IsShared) || customVariable.CreatesProperty || customVariable.CreatesEvent || IsVariableWholeNumberWithVelocity(customVariable); needsToBeProperty = needsToBeProperty & !customVariable.GetIsVariableState(); EventCodeGenerator.TryGenerateEventsForVariable(codeBlock, customVariable, element); string memberType = GetMemberTypeFor(customVariable, element); if (needsToBeProperty) { // If the variable // creates an event // then it needs to have // custom code (it can't be // an automatic property). bool isWholeNumberWithVelocity = IsVariableWholeNumberWithVelocity(customVariable); if (customVariable.CreatesEvent || isWholeNumberWithVelocity || customVariable.DefaultValue != null ) { string variableToAssignInProperty = "base." + customVariable.Name; // create a field for this, unless it's defined by base - then the base creates a field for it if (!isExposing && !customVariable.DefinedByBase) { variableToAssignInProperty = "m" + customVariable.Name; // First we make the field that will get set here: codeBlock.Line(StringHelper.Modifiers(Public: false, Static: customVariable.IsShared, Type: memberType, Name: variableToAssignInProperty) + variableAssignment + ";"); } string propertyHeader = null; if (isExposing) { propertyHeader = "public new " + memberType + " " + customVariable.Name; } else if (customVariable.DefinedByBase) { propertyHeader = "public override " + memberType + " " + customVariable.Name; } else if (customVariable.SetByDerived) { propertyHeader = "public virtual " + memberType + " " + customVariable.Name; } else { propertyHeader = "public " + memberType + " " + customVariable.Name; } ICodeBlock set = codeBlock.Property(propertyHeader, Static:customVariable.IsShared) .Set(); if (EventCodeGenerator.ShouldGenerateEventsForVariable(customVariable, element)) { EventCodeGenerator.GenerateEventRaisingCode(set, BeforeOrAfter.Before, customVariable.Name, element); } set.Line(variableToAssignInProperty + " = value;"); if (IsVariableWholeNumberWithVelocity(customVariable)) { set.Line(customVariable.Name + "ModifiedByVelocity = value;"); } if (EventCodeGenerator.ShouldGenerateEventsForVariable(customVariable, element)) { EventCodeGenerator.GenerateEventRaisingCode(set, BeforeOrAfter.After, customVariable.Name, element); } ICodeBlock get = set.End().Get(); codeBlock = get.Line("return " + variableToAssignInProperty + ";") .End().End(); // end the getter, end the property } else { // Static vars can't be virtual bool isVirtual = !customVariable.IsShared; codeBlock.AutoProperty(customVariable.Name, Public: true, Virtual: isVirtual, Static: customVariable.IsShared, Type: memberType); } } else { if (!customVariable.GetIsVariableState()) { codeBlock.Line(StringHelper.Modifiers(Public: true, Static: customVariable.IsShared, Type: memberType, Name: customVariable.Name) + variableAssignment + ";"); } else { if (IsVariableTunnelingToDisabledObject(customVariable, element)) { // If it's a varaible // that is exposing a // state variable for a // disabled object, we still // want to generate something: codeBlock.Line(StringHelper.Modifiers(Public: true, Static: customVariable.IsShared, Type: memberType, Name: customVariable.Name) // No assignment for now. Do we eventually want this? The reason // this even exists is to satisfy a variable that may be needed by other // code which would point to a disabled object. //+ variableAssignment + ";"); } } } }