// I wrote this for animation but it turns out it isn't going to work how I expected //public static StateSave CombineBaseValuesAndClone(this StateSave stateSave) //{ // StateSave cloned = new StateSave(); // if (stateSave.ParentContainer == null) // { // // This thing doesn't have a parent container so we have no idea how to get the default and follow inheritance // cloned = stateSave.Clone(); // } // else // { // ElementSave parent = stateSave.ParentContainer; // if (parent.DefaultState == stateSave) // { // if (string.IsNullOrEmpty(parent.BaseType)) // { // cloned = stateSave.Clone(); // } // else // { // ElementSave baseOfParent = ObjectFinder.Self.GetElementSave(parent.BaseType); // if (baseOfParent == null) // { // cloned = stateSave.Clone(); // } // else // { // cloned = baseOfParent.DefaultState.CombineBaseValuesAndClone(); // cloned.MergeIntoThis(stateSave); // } // } // } // else // { // cloned = parent.DefaultState.CombineBaseValuesAndClone(); // cloned.MergeIntoThis(stateSave); // } // } // return cloned; //} public static void Merge(StateSave firstState, StateSave secondState, float otherRatio, List <VariableSaveValues> mergedValues) { #if DEBUG if (firstState == null || secondState == null) { throw new ArgumentNullException("States must not be null"); } #endif foreach (var secondVariable in secondState.Variables) { object secondValue = secondVariable.Value; VariableSave firstVariable = firstState.GetVariableSave(secondVariable.Name); // If this variable doesn't have a value, or if the variable doesn't set the variable // then we need to go recursive to see what the value is: bool needsValueFromBase = firstVariable == null || firstVariable.SetsValue == false; bool setsValue = secondVariable.SetsValue; object firstValue = null; if (firstVariable == null) { firstValue = secondVariable.Value; // Get the value recursively before adding it to the list if (needsValueFromBase) { var variableOnThis = firstState.GetVariableSave(secondVariable.Name); if (variableOnThis != null) { setsValue |= variableOnThis.SetsValue; } firstValue = firstState.GetValueRecursive(secondVariable.Name); } } else { firstValue = firstVariable.Value; } if (setsValue) { object interpolated = GetValueConsideringInterpolation(firstValue, secondValue, otherRatio); VariableSaveValues value = new VariableSaveValues(); value.Name = secondVariable.Name; value.Value = interpolated; mergedValues.Add(value); } } // todo: Handle lists? }
public static void MergeIntoThis(this StateSave thisState, StateSave other, float otherRatio = 1) { #if DEBUG if (other == null) { throw new ArgumentNullException("other Statesave is null and it shouldn't be"); } #endif foreach (var variableSave in other.Variables) { // The first will use its default if one doesn't exist VariableSave whatToSet = thisState.GetVariableSave(variableSave.Name); // If this variable doesn't have a value, or if the variable doesn't set the variable // then we need to go recursive to see what the value is: bool needsValueFromBase = whatToSet == null || whatToSet.SetsValue == false; bool setsValue = variableSave.SetsValue; if (whatToSet == null) { whatToSet = variableSave.Clone(); // Get the value recursively before adding it to the list if (needsValueFromBase) { var variableOnThis = thisState.GetVariableSave(variableSave.Name); if (variableOnThis != null) { setsValue |= variableOnThis.SetsValue; } whatToSet.Value = thisState.GetValueRecursive(variableSave.Name); } thisState.Variables.Add(whatToSet); } whatToSet.SetsValue = setsValue; whatToSet.Value = GetValueConsideringInterpolation(whatToSet.Value, variableSave.Value, otherRatio); } // todo: Handle lists? }
public static object GetValueRecursive(this StateSave stateSave, string variableName) { object value = stateSave.GetValue(variableName); if (value == null) { // Is this thing the default? ElementSave parent = stateSave.ParentContainer; // I don't know if we need this code // because if we got in here, then the non-default failed to find a value // Update July 12, 2013 // Not sure why I commented this code out. This code lets us check a non-default // state, and if it doesn't contain a value, then we look at the default state in this // element. Then if that fails, we can climb up the inheritance tree. // Let's see if we can get something from the non-default first bool wasFound = false; if (parent != null && stateSave != parent.DefaultState) { // try to get it from the stateSave var foundVariable = stateSave.GetVariableRecursive(variableName); if (foundVariable != null && foundVariable.SetsValue) { // Why do we early out here? //return foundVariable.Value; value = foundVariable.Value; wasFound = true; } } if (!wasFound && parent != null) { if (!string.IsNullOrEmpty(parent.BaseType)) { // eventually pass the state, but for now use default value = TryToGetValueFromInheritance(variableName, parent.BaseType); } if (value == null) { ElementSave baseElement = GetBaseElementFromVariable(variableName, parent); if (baseElement != null) { string nameInBase = variableName; if (StringFunctions.ContainsNoAlloc(variableName, '.')) { // this variable is set on an instance, but we're going into the // base type, so we want to get the raw variable and not the variable // as tied to an instance. nameInBase = variableName.Substring(nameInBase.IndexOf('.') + 1); } value = baseElement.DefaultState.GetValueRecursive(nameInBase); } } if (value == null && parent is ComponentSave) { StateSave defaultStateForComponent = StandardElementsManager.Self.GetDefaultStateFor("Component"); if (defaultStateForComponent != null) { value = defaultStateForComponent.GetValueRecursive(variableName); } } } } return(value); }