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