private void AdjustEnumerationVariableValue(Gum.DataTypes.Variables.VariableSave variableSave, ElementSave element, ref string variableValue, ref string variableType) { if (variableSave.Type == "Gum.Managers.PositionUnitType" || variableSave.Type == "PositionUnitType") { string rootName = variableSave.GetRootName(); // convert from PositionUnitType to GeneralUnitType GeneralUnitType convertedValue = UnitConverter.ConvertToGeneralUnit((PositionUnitType)variableSave.Value); variableValue = convertedValue.ToString(); variableType = "Gum.Converters.GeneralUnitType"; } string prefix = variableType; if (mTypeToQualifiedTypes.ContainsKey(prefix)) { prefix = mTypeToQualifiedTypes[prefix]; } else { ModifyVariableTypeForProperty(ref prefix, variableSave, element); } variableValue = prefix + "." + variableValue; }
private void GenerateVariable(ICodeBlock currentBlock, string propertyName, Gum.DataTypes.Variables.VariableSave variable, ElementSave elementSave) { #region Get Variable Type string variableType = variable.Type; string unmodifiedVariableType = variableType; if (GueDerivingClassCodeGenerator.Self.TypeToQualifiedTypes.ContainsKey(variableType)) { variableType = GueDerivingClassCodeGenerator.Self.TypeToQualifiedTypes[variableType]; } if (variable.IsFile && variable.GetRootName() == "SourceFile") { variableType = "Microsoft.Xna.Framework.Graphics.Texture2D"; } #endregion ICodeBlock property = currentBlock.Property("public " + variableType, variable.Name.Replace(" ", "")); string variableName = variable.Name; if (mStandardVariableNameAliases.ContainsKey(variableName.Replace(" ", ""))) { variableName = mStandardVariableNameAliases[variableName.Replace(" ", "")]; } string whatToGetOrSet = propertyName + "." + variableName.Replace(" ", ""); GenerateGetter(propertyName, variable, property, variableName, whatToGetOrSet, elementSave); GenerateSetter(propertyName, variable, property, variableName, whatToGetOrSet, elementSave); }
private bool GetIfShouldGenerateProperty(Gum.DataTypes.Variables.VariableSave variable, ElementSave standardElementSave) { string variableName = variable.GetRootName(); if (mVariableNamesToSkipForProperties.Contains(variableName)) { return(false); } return(true); }
private bool GetIfShouldGenerateProperty(Gum.DataTypes.Variables.VariableSave variable, ElementSave standardElementSave) { string variableName = variable.GetRootName(); if (mVariableNamesToSkipForProperties.Contains(variableName)) { return(false); } // Core Gum objets don't have states, so if it's a state then don't create a property for it - it'll be handled // by the code that handles states if (variable.IsState(standardElementSave)) { return(false); } return(true); }
private bool GetIfShouldGenerateStateVariable(Gum.DataTypes.Variables.VariableSave variable, ElementSave container) { bool toReturn = true; string variableName = variable.GetRootName(); if (variable.Value == null || !variable.SetsValue) { toReturn = false; } // states can't set states on this if (variable.IsState(container) && string.IsNullOrEmpty(variable.SourceObject)) { toReturn = false; } if (toReturn && mVariableNamesToSkipForStates.Contains(variableName)) { toReturn = false; } bool hasSourceObject = !string.IsNullOrEmpty(variable.SourceObject); if (toReturn && hasSourceObject) { InstanceSave instanceSave = container.GetInstance(variable.SourceObject); if (instanceSave == null) { toReturn = false; } else { var baseElement = Gum.Managers.ObjectFinder.Self.GetElementSave(instanceSave.BaseType); if (baseElement == null) { toReturn = false; } if (toReturn) { // Gum (just like Glue) keeps variables that aren't needed around. This allows users to rename things and not lose // important information accidentally. But because of that we have to make sure that the variable we're working with is // valid for the type of object we're dealing with. var defaultState = baseElement.DefaultState; // October 26, 2018 // Bernardo reported // a crash caused by the // RecursiveVariableFinder // being given a state without // a ParentContainer. This is a // sign that the element hasn't // been initialized yet. Elements // should be initialized, but if they're // not, we could just catch it here and initialize // it on the spot. Not sure if I like this solution // or not. It allows code to behave a little unpredictably, // but at the same time, we could simply solve the problem by // initializing here, so I'm going to do that: if (defaultState.ParentContainer == null) { baseElement.Initialize(null); } RecursiveVariableFinder rvf = new RecursiveVariableFinder(defaultState); var foundVariable = rvf.GetVariable(variable.GetRootName()); if (foundVariable == null) { // This doesn't exist anywhere in the inheritance chain, so we don't want to generate it: toReturn = false; } } } } if (toReturn && !hasSourceObject) { // If a variable is part of a component, it better be defined in the base type or else we won't generate it. // For example, consider a component that used to inherit from Text. It will have variables for fonts. If that // component switches to inheriting from Sprite, those variables will still exist in the XML for that component, // but we shouldn't generate any state variables for those variables. So we'll go to the base type and see if those // variables exist bool isComponent = container is ComponentSave; var rootStandardElementSave = Gum.Managers.ObjectFinder.Self.GetRootStandardElementSave(container); // If the Container is a Screen, then rootComponent will be null, so we don't need to do anything if (rootStandardElementSave == null) { toReturn = false; } else { IEnumerable <VariableSave> variablesToCheck; // This code used to get the default state from the rootStandardElementSave, // but the standard element save can have variables missing from the Gum XML, // but it should still support them based on the definition in the StandardElementsManager, // especially if new variables have been added in the future. Therefore, use the StandardElementsManager // rather than the DefaultState: //var rootStandardElementVariables = rootStandardElementSave.DefaultState.Variables; var rootStandardElementVariables = StandardElementsManager.Self .DefaultStates[rootStandardElementSave.Name].Variables; if (isComponent) { var component = Gum.Managers.ObjectFinder.Self.GetStandardElement("Component"); variablesToCheck = rootStandardElementVariables.Concat(component.DefaultState.Variables).ToList(); } else { variablesToCheck = rootStandardElementVariables.ToList(); } bool wasMatchFound = variablesToCheck.Any(item => item.Name == variable.GetRootName()); toReturn = wasMatchFound; } } return(toReturn); }
/// <summary> /// Returns the first instance of an existing VariableSave recursively. /// </summary> /// <param name="stateSave">The possible state that contains the variable. If it doesn't, then the code will recursively go to base types.</param> /// <param name="variableName"></param> /// <returns></returns> public static VariableSave GetVariableRecursive(this StateSave stateSave, string variableName) { VariableSave variableSave = stateSave.GetVariableSave(variableName); if (variableSave == null) { // 1. Go to the default state if it's not a default bool shouldGoToDefaultState = false; // 2. Go to the base type if the variable is on the container itself, or if the instance is DefinedByBase bool shouldGoToBaseType = false; // 3. Go to the instance if it's on an instance and we're not going to the default state or base type bool shouldGoToInstanceComponent = false; // Is this thing the default? ElementSave elementContainingState = stateSave.ParentContainer; if (elementContainingState != null) { if (elementContainingState != null && stateSave != elementContainingState.DefaultState) { shouldGoToDefaultState = true; } var isVariableOnInstance = variableName.Contains('.'); InstanceSave instance = null; bool canGoToBase = false; var hasBaseType = !string.IsNullOrEmpty(elementContainingState.BaseType); var isVariableDefinedOnThisInheritanceLevel = false; var instanceName = VariableSave.GetSourceObject(variableName); instance = elementContainingState.Instances.FirstOrDefault(item => item.Name == instanceName); if (isVariableOnInstance && hasBaseType) { if (instance != null && instance.DefinedByBase == false) { isVariableDefinedOnThisInheritanceLevel = true; } } else if (!hasBaseType) { isVariableDefinedOnThisInheritanceLevel = true; } canGoToBase = isVariableOnInstance == false || isVariableDefinedOnThisInheritanceLevel == false; if (!shouldGoToDefaultState) { shouldGoToBaseType = canGoToBase; } if (!shouldGoToDefaultState && !shouldGoToBaseType) { shouldGoToInstanceComponent = isVariableOnInstance; } if (shouldGoToDefaultState) { variableSave = elementContainingState.DefaultState.GetVariableSave(variableName); if (variableSave == null) { shouldGoToBaseType = canGoToBase; } } if (shouldGoToBaseType) { var baseElement = ObjectFinder.Self.GetElementSave(elementContainingState.BaseType); if (baseElement != null) { variableSave = baseElement.DefaultState.GetVariableRecursive(variableName); } } else if (shouldGoToInstanceComponent) { ElementSave instanceElement = null; if (instance != null) { instanceElement = ObjectFinder.Self.GetElementSave(instance); } if (instanceElement != null) { variableSave = instanceElement.DefaultState.GetVariableRecursive(VariableSave.GetRootName(variableName)); } } } } return(variableSave); }
/// <summary> /// Adjusts a variable value to be code which can execute properly. For example, converts a file string to a load call. /// </summary> /// <param name="variableSave">The variable</param> /// <param name="container">The container of the variable</param> /// <param name="variableValue">The variable value to modify</param> /// <param name="isEntireAssignment">Whether the modified value is an entire assignment - meaning no assignment is necessary. This is used for file loading.</param> public void AdjustVariableValueIfNecessary(Gum.DataTypes.Variables.VariableSave variableSave, ElementSave container, ref string variableValue, out bool isEntireAssignment) { isEntireAssignment = false; ElementSave categoryContainer; Gum.DataTypes.Variables.StateSaveCategory stateSaveCategory; string variableType = variableSave.Type; if (variableSave.IsState(container, out categoryContainer, out stateSaveCategory)) { string categoryName = "Category"; if (stateSaveCategory != null) { categoryName = stateSaveCategory.Name; } else { categoryName = "VariableState"; } variableValue = GetQualifiedRuntimeTypeFor(categoryContainer) + "." + categoryName + "." + variableSave.Value; } else if (variableSave.IsEnumeration()) { AdjustEnumerationVariableValue(variableSave, container, ref variableValue, ref variableType); } else if (variableSave.GetRootName() == "Parent") { if (container is ComponentSave) { variableValue = $"this.ContainedElements.FirstOrDefault(item =>item.Name == \"{variableValue}\") ?? this"; } else { variableValue = $"this.ContainedElements.FirstOrDefault(item =>item.Name == \"{variableValue}\")"; } } else if (variableSave.IsFile) { isEntireAssignment = true; string fileName = "\"" + variableValue.Replace("\\", "\\\\") + "\""; variableValue = "SetProperty(\"" + variableSave.Name + "\", " + fileName + ");"; ////RenderingLibrary.Content.LoaderManager.Self.Load("fileName", managers); //variableValue = "RenderingLibrary.Content.LoaderManager.Self.Load(\"" + variableValue.Replace("\\", "\\\\") + "\", RenderingLibrary.SystemManagers.Default)"; } else if (variableSave.Type == "string") { variableValue = variableValue.Replace("\\", "\\\\"); variableValue = variableValue.Replace("\"", "\\\""); // do this after replacing the backslashes up above variableValue = variableValue.Replace("\n", "\\n"); variableValue = "\"" + variableValue + "\""; } else if (variableSave.Type == "float") { //variableValue = variableValue + "f"; // convert this using the current language: var value = Convert.ToSingle(variableValue, System.Globalization.CultureInfo.CurrentCulture); variableValue = value.ToString(System.Globalization.CultureInfo.InvariantCulture) + "f"; } else if (variableSave.Type == "bool") { variableValue = variableValue.ToLower(); } }
private bool GetIfShouldGenerateStateVariable(Gum.DataTypes.Variables.VariableSave variable, ElementSave container) { bool toReturn = true; string variableName = variable.GetRootName(); if (variable.Value == null || !variable.SetsValue) { toReturn = false; } // states can't set states on this if (variable.IsState(container) && string.IsNullOrEmpty(variable.SourceObject)) { toReturn = false; } if (toReturn && mVariableNamesToSkipForStates.Contains(variableName)) { toReturn = false; } bool hasSourceObject = !string.IsNullOrEmpty(variable.SourceObject); if (toReturn && hasSourceObject) { InstanceSave instanceSave = container.GetInstance(variable.SourceObject); if (instanceSave == null) { toReturn = false; } else { var baseElement = Gum.Managers.ObjectFinder.Self.GetElementSave(instanceSave.BaseType); if (baseElement == null) { toReturn = false; } if (toReturn) { // Gum (just like Glue) keeps variables that aren't needed around. This allows users to rename things and not lose // important information accidentally. But because of that we have to make sure that the variable we're working with is // valid for the type of object we're dealing with. var defaultState = baseElement.DefaultState; RecursiveVariableFinder rvf = new RecursiveVariableFinder(defaultState); var foundVariable = rvf.GetVariable(variable.GetRootName()); if (foundVariable == null) { // This doesn't exist anywhere in the inheritance chain, so we don't want to generate it: toReturn = false; } } } } if (toReturn && !hasSourceObject) { // If a variable is part of a component, it better be defined in the base type or else we won't generate it. // For example, consider a component that used to inherit from Text. It will have variables for fonts. If that // component switches to inheriting from Sprite, those variables will still exist in the XML for that component, // but we shouldn't generate any state variables for those variables. So we'll go to the base type and see if those // variables exist bool isComponent = container is ComponentSave; var rootComponent = Gum.Managers.ObjectFinder.Self.GetRootStandardElementSave(container); // If the Container is a Screen, then rootComponent will be null, so we don't need to do anything if (rootComponent == null) { toReturn = false; } else { IEnumerable <VariableSave> variablesToCheck; if (isComponent) { var component = Gum.Managers.ObjectFinder.Self.GetStandardElement("Component"); variablesToCheck = rootComponent.DefaultState.Variables.Concat(component.DefaultState.Variables); } else { var defaultState = rootComponent.DefaultState; variablesToCheck = defaultState.Variables; } bool wasMatchFound = variablesToCheck.Any(item => item.Name == variable.GetRootName()); toReturn = wasMatchFound; } } return(toReturn); }