public AnimationSave ToSave() { AnimationSave toReturn = new AnimationSave(); toReturn.Name = this.Name; toReturn.Loops = this.mLoops; foreach (var state in this.Keyframes) { if (!string.IsNullOrEmpty(state.StateName)) { toReturn.States.Add(state.ToAnimatedStateSave()); } else if (!string.IsNullOrEmpty(state.AnimationName)) { toReturn.Animations.Add(state.ToAnimationReferenceSave()); } else { toReturn.Events.Add(state.ToEventSave()); } } return(toReturn); }
public static string PropertyNameInCode(this AnimationSave animation) { string propertyName = animation.Name + "Animation"; var firstChar = propertyName.Substring(0, 1).ToUpperInvariant(); return(firstChar + propertyName.Substring(1)); }
public static float GetLength(this AnimationSave animation, ElementSave elementSave, ElementAnimationsSave allAnimationSaves) { float lastState = animation.States.Max(item => item.Time); float endOfLastSubAnimation = 0; if (animation.Animations != null) { foreach (var subAnimation in animation.Animations) { AnimationSave subAnimationSave = null; ElementSave subAnimationElement = null; ElementAnimationsSave subAnimationSiblings = null; if (subAnimation.SourceObject == null) { subAnimationSave = allAnimationSaves.Animations.FirstOrDefault(item => item.Name == subAnimation.Name); subAnimationElement = elementSave; subAnimationSiblings = allAnimationSaves; } else { var instance = elementSave.Instances.FirstOrDefault(item => item.Name == subAnimation.SourceObject); if (instance != null) { ElementSave instanceElement = Gum.Managers.ObjectFinder.Self.GetElementSave(instance); if (instanceElement != null) { var instanceAnimations = AnimationCollectionViewModelManager.Self.GetElementAnimationsSave(instanceElement); subAnimationSave = instanceAnimations.Animations.FirstOrDefault(item => item.Name == subAnimation.RootName); subAnimationElement = instanceElement; subAnimationSiblings = instanceAnimations; } } } if (subAnimationSave != null) { endOfLastSubAnimation = System.Math.Max(endOfLastSubAnimation, subAnimation.Time + subAnimationSave.GetLength(subAnimationElement, subAnimationSiblings)); } } } return(System.Math.Max(lastState, endOfLastSubAnimation)); }
private float GetAnimationLength(ElementSave element, AnimationSave animation) { float max = 0; if (animation.States.Count != 0) { max = animation.States.Max(item => item.Time); } if (animation.Events.Count != 0) { max = System.Math.Max( max, animation.Events.Max(item => item.Time)); } foreach (var item in animation.Animations) { AnimationSave subAnimation = null; ElementSave subElement = null; if (!string.IsNullOrEmpty(item.SourceObject)) { var instance = element.GetInstance(item.SourceObject); // This may refer to an instance that was deleted at some point: if (instance != null) { subElement = Gum.Managers.ObjectFinder.Self.GetElementSave(instance); } if (subElement != null) { subAnimation = GetAnimationsFor(subElement).Animations.FirstOrDefault(candidate => candidate.Name == item.RootName); } } else { subElement = element; subAnimation = GetAnimationsFor(element).Animations.FirstOrDefault(candidate => candidate.Name == item.RootName); } if (subElement != null && subAnimation != null) { max = Math.Max(max, item.Time + GetAnimationLength(subElement, subAnimation)); } } return(max); }
private void GenerateAnimationMember(StateCodeGeneratorContext context, ICodeBlock currentBlock, AnimationSave animation, AbsoluteOrRelative absoluteOrRelative) { string propertyName = animation.PropertyNameInCode(); if (absoluteOrRelative == AbsoluteOrRelative.Relative) { propertyName += "Relative"; } string referencedInstructionProperty = propertyName + "Instructions"; // Force the property to be upper-case, since the field is lower-case: // We want to generate something like: //private FlatRedBall.Gum.Animation.GumAnimation uncategorizedAnimation; //public FlatRedBall.Gum.Animation.GumAnimation UncategorizedAnimation //{ // get // { // if (uncategorizedAnimation == null) // { // uncategorizedAnimation = new FlatRedBall.Gum.Animation.GumAnimation(1, () => UncategorizedAnimationInstructions); // uncategorizedAnimation.AddEvent("Event1", 3.0f); // } // return uncategorizedAnimation; // } //} var firstCharacterLower = propertyName.Substring(0, 1).ToLowerInvariant(); var fieldName = firstCharacterLower + propertyName.Substring(1); currentBlock.Line($"private FlatRedBall.Gum.Animation.GumAnimation {fieldName};"); currentBlock = currentBlock.Property("public FlatRedBall.Gum.Animation.GumAnimation", propertyName).Get(); float length = GetAnimationLength(context.Element, animation); string lengthAsString = ToFloatString(length); var ifBlock = currentBlock.If($"{fieldName} == null"); { ifBlock.Line( $"{fieldName} = new FlatRedBall.Gum.Animation.GumAnimation({lengthAsString}, {referencedInstructionProperty});"); foreach (var namedEvent in animation.Events) { string timeAsString = ToFloatString(namedEvent.Time); ifBlock.Line( $"{fieldName}.AddEvent(\"{namedEvent.Name}\", {timeAsString});"); } foreach (var subAnimation in animation.Animations) { if (string.IsNullOrEmpty(subAnimation.SourceObject) == false) { var isMissingInstance = context.Element.GetInstance(subAnimation.SourceObject) == null; if (isMissingInstance) { ifBlock.Line($"//Missing object {subAnimation.SourceObject}"); } else { ifBlock.Line($"{fieldName}.SubAnimations.Add({subAnimation.PropertyNameInCode()});"); } } } } currentBlock.Line($"return {fieldName};"); }
private static void CreateInstructionForSubAnimation(ICodeBlock currentBlock, AnimationReferenceSave animationReferenceSave, AbsoluteOrRelative absoluteOrRelative, AnimationSave parentAnimation, StateCodeGeneratorContext context) { currentBlock = currentBlock.Block(); //var instruction = new FlatRedBall.Instructions.DelegateInstruction(() => //FlatRedBall.Instructions.InstructionManager.Instructions.AddRange(ClickableBushInstance.GrowAnimation)); //instruction.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + asdf; //yield return instruction; var isReferencingMissingInstance = !string.IsNullOrEmpty(animationReferenceSave.SourceObject) && context.Element.GetInstance(animationReferenceSave.SourceObject) == null; ////////////////Early Out/////////////// if (isReferencingMissingInstance) { currentBlock.Line($"// This animation references a missing instance named {animationReferenceSave.SourceObject}"); return; } /////////////End Early Out///////////// string animationName = animationReferenceSave.PropertyNameInCode(); //animationReferenceSave. FlatRedBall.IO.FileManager.RemovePath(animationReferenceSave.Name) + "Animation"; if (absoluteOrRelative == AbsoluteOrRelative.Relative) { animationName += "Relative"; } currentBlock.Line($"var instruction = new FlatRedBall.Instructions.DelegateInstruction(()=>{animationName}.Play({parentAnimation.PropertyNameInCode()}));"); currentBlock.Line("instruction.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + " + ToFloatString(animationReferenceSave.Time) + ";"); currentBlock.Line("yield return instruction;"); currentBlock = currentBlock.End(); }
private void GenerateOrderedStateAndSubAnimationCode(StateCodeGeneratorContext context, ICodeBlock currentBlock, AnimationSave animation, string animationType, AbsoluteOrRelative absoluteOrRelative) { List <AnimatedStateSave> remainingStates = new List <AnimatedStateSave>(); remainingStates.AddRange(animation.States); List <AnimationReferenceSave> remainingSubAnimations = new List <AnimationReferenceSave>(); remainingSubAnimations.AddRange(animation.Animations); double nextStateTime; double nextAnimationTime; AnimatedStateSave previousState = null; AnimatedStateSave currentState = null; while (remainingStates.Count > 0 || remainingSubAnimations.Count > 0) { if (remainingStates.Count > 0) { nextStateTime = remainingStates[0].Time; } else { nextStateTime = double.PositiveInfinity; } if (remainingSubAnimations.Count > 0) { nextAnimationTime = remainingSubAnimations[0].Time; } else { nextAnimationTime = double.PositiveInfinity; } if (nextAnimationTime < nextStateTime) { CreateInstructionForSubAnimation(currentBlock, remainingSubAnimations[0], absoluteOrRelative, animation, context); remainingSubAnimations.RemoveAt(0); } else { currentState = remainingStates[0]; CreateInstructionForInterpolation(context, currentBlock, animationType, previousState, currentState, absoluteOrRelative, animation.PropertyNameInCode()); previousState = currentState; remainingStates.RemoveAt(0); } } }
private void GenerateGetEnumerableFor(StateCodeGeneratorContext context, ICodeBlock currentBlock, AnimationSave animation, AbsoluteOrRelative absoluteOrRelative) { string animationType = "VariableState"; string animationName = animation.PropertyNameInCode(); if (absoluteOrRelative == AbsoluteOrRelative.Relative) { animationName += "Relative"; } string propertyName = animationName + "Instructions"; // Instructions used to be public - the user would grab them and add them to the InstructionManager, // but now everything is encased in an Animation object which handles stopping itself and provides a simple // Play method. const string signature = "private System.Collections.Generic.IEnumerable<FlatRedBall.Instructions.Instruction>"; if (animation.States.Count == 0 && animation.Animations.Count == 0) { currentBlock = currentBlock.Function(signature, propertyName, "object target"); currentBlock.Line("yield break;"); } else if (absoluteOrRelative == AbsoluteOrRelative.Relative && animation.States.Count < 2 && animation.Animations.Count == 0) { currentBlock = currentBlock.Function(signature, propertyName, "object target"); currentBlock.Line("yield break;"); } else { if (animation.States.Count != 0) { var firstState = context.Element.AllStates.FirstOrDefault(item => item.Name == animation.States.First().StateName); var category = context.Element.Categories.FirstOrDefault(item => item.States.Contains(firstState)); if (category != null) { animationType = category.Name; } } currentBlock = currentBlock.Function(signature, propertyName, "object target"); GenerateOrderedStateAndSubAnimationCode(context, currentBlock, animation, animationType, absoluteOrRelative); if (animation.Loops) { currentBlock = currentBlock.Block(); currentBlock.Line("var toReturn = new FlatRedBall.Instructions.DelegateInstruction( " + "() => FlatRedBall.Instructions.InstructionManager.Instructions.AddRange(this." + propertyName + "(target)));"); string executionTime = "0.0f"; if (animation.States.Count != 0) { executionTime = ToFloatString(animation.States.Last().Time); } currentBlock.Line("toReturn.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + " + executionTime + ";"); currentBlock.Line("toReturn.Target = target;"); currentBlock.Line("yield return toReturn;"); currentBlock = currentBlock.End(); } } }
public static AnimationViewModel FromSave(AnimationSave save, ElementSave element, ElementAnimationsSave allAnimationSaves = null) { AnimationViewModel toReturn = new AnimationViewModel(); toReturn.Name = save.Name; toReturn.mLoops = save.Loops; foreach (var stateSave in save.States) { var foundState = element.AllStates.FirstOrDefault(item => item.Name == stateSave.StateName); var newAnimatedStateViewModel = AnimatedKeyframeViewModel.FromSave(stateSave); newAnimatedStateViewModel.HasValidState = foundState != null; toReturn.Keyframes.Add(newAnimatedStateViewModel); } foreach (var animationReference in save.Animations) { AnimationSave animationSave = null; ElementSave subAnimationElement = null; ElementAnimationsSave subAnimationSiblings = null; if (string.IsNullOrEmpty(animationReference.SourceObject)) { if (allAnimationSaves == null) { allAnimationSaves = AnimationCollectionViewModelManager.Self.GetElementAnimationsSave(element); } animationSave = allAnimationSaves.Animations.FirstOrDefault(item => item.Name == animationReference.RootName); subAnimationElement = element; subAnimationSiblings = allAnimationSaves; } else { var instance = element.Instances.FirstOrDefault(item => item.Name == animationReference.SourceObject); if (instance != null) { ElementSave instanceElement = Gum.Managers.ObjectFinder.Self.GetElementSave(instance); subAnimationElement = instanceElement; if (instanceElement != null) { var allAnimations = AnimationCollectionViewModelManager.Self.GetElementAnimationsSave(instanceElement); animationSave = allAnimations.Animations.FirstOrDefault(item => item.Name == animationReference.RootName); subAnimationElement = instanceElement; subAnimationSiblings = allAnimations; } } } var newVm = AnimatedKeyframeViewModel.FromSave(animationReference); if (animationSave != null) { newVm.SubAnimationViewModel = AnimationViewModel.FromSave(animationSave, subAnimationElement, subAnimationSiblings); } newVm.HasValidState = animationReference != null; toReturn.Keyframes.Add(newVm); } toReturn.SortList(); return(toReturn); }
private void GenerateAnimationMember(StateCodeGeneratorContext context, ICodeBlock currentBlock, AnimationSave animation, AbsoluteOrRelative absoluteOrRelative) { string propertyName = animation.PropertyNameInCode(); if (absoluteOrRelative == AbsoluteOrRelative.Relative) { propertyName += "Relative"; } string referencedInstructionProperty = propertyName + "Instructions"; // Force the property to be upper-case, since the field is lower-case: // We want to generate something like: //private FlatRedBall.Gum.Animation.GumAnimation uncategorizedAnimation; //public FlatRedBall.Gum.Animation.GumAnimation UncategorizedAnimation //{ // get // { // if (uncategorizedAnimation == null) // { // uncategorizedAnimation = new FlatRedBall.Gum.Animation.GumAnimation(1, () => UncategorizedAnimationInstructions); // uncategorizedAnimation.AddEvent("Event1", 3.0f); // } // return uncategorizedAnimation; // } //} var firstCharacterLower = propertyName.Substring(0, 1).ToLowerInvariant(); var fieldName = firstCharacterLower + propertyName.Substring(1); currentBlock.Line($"private FlatRedBall.Gum.Animation.GumAnimation {fieldName};"); currentBlock = currentBlock.Property("public FlatRedBall.Gum.Animation.GumAnimation", propertyName).Get(); float length = GetAnimationLength(context.Element, animation); string lengthAsString = ToFloatString(length); var ifBlock = currentBlock.If($"{fieldName} == null"); { ifBlock.Line( $"{fieldName} = new FlatRedBall.Gum.Animation.GumAnimation({lengthAsString}, () => {referencedInstructionProperty});"); foreach(var namedEvent in animation.Events) { string timeAsString = ToFloatString(namedEvent.Time); ifBlock.Line( $"{fieldName}.AddEvent(\"{namedEvent.Name}\", {timeAsString});"); } foreach(var subAnimation in animation.Animations) { if(string.IsNullOrEmpty(subAnimation.SourceObject) == false) { ifBlock.Line($"{fieldName}.SubAnimations.Add({subAnimation.PropertyNameInCode()});"); } } } currentBlock.Line($"return {fieldName};"); }
private static void CreateInstructionForSubAnimation(ICodeBlock currentBlock, AnimationReferenceSave animationReferenceSave, AbsoluteOrRelative absoluteOrRelative, AnimationSave parentAnimation) { currentBlock = currentBlock.Block(); //var instruction = new FlatRedBall.Instructions.DelegateInstruction(() => //FlatRedBall.Instructions.InstructionManager.Instructions.AddRange(ClickableBushInstance.GrowAnimation)); //instruction.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + asdf; //yield return instruction; string animationName = animationReferenceSave.PropertyNameInCode(); //animationReferenceSave. FlatRedBall.IO.FileManager.RemovePath(animationReferenceSave.Name) + "Animation"; if(absoluteOrRelative == AbsoluteOrRelative.Relative) { animationName += "Relative"; } currentBlock.Line($"var instruction = new FlatRedBall.Instructions.DelegateInstruction(()=>{animationName}.Play({parentAnimation.PropertyNameInCode()}));"); currentBlock.Line("instruction.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + " + ToFloatString(animationReferenceSave.Time) + ";"); currentBlock.Line("yield return instruction;"); currentBlock = currentBlock.End(); }
private void GenerateOrderedStateAndSubAnimationCode(StateCodeGeneratorContext context, ICodeBlock currentBlock, AnimationSave animation, string animationType, AbsoluteOrRelative absoluteOrRelative) { List<AnimatedStateSave> remainingStates = new List<AnimatedStateSave>(); remainingStates.AddRange(animation.States); List<AnimationReferenceSave> remainingSubAnimations = new List<AnimationReferenceSave>(); remainingSubAnimations.AddRange(animation.Animations); double nextStateTime; double nextAnimationTime; AnimatedStateSave previousState = null; AnimatedStateSave currentState = null; while (remainingStates.Count > 0 || remainingSubAnimations.Count > 0) { if (remainingStates.Count > 0) { nextStateTime = remainingStates[0].Time; } else { nextStateTime = double.PositiveInfinity; } if (remainingSubAnimations.Count > 0) { nextAnimationTime = remainingSubAnimations[0].Time; } else { nextAnimationTime = double.PositiveInfinity; } if (nextAnimationTime < nextStateTime) { CreateInstructionForSubAnimation(currentBlock, remainingSubAnimations[0], absoluteOrRelative, animation); remainingSubAnimations.RemoveAt(0); } else { currentState = remainingStates[0]; CreateInstructionForInterpolation(context, currentBlock, animationType, previousState, currentState, absoluteOrRelative, animation.PropertyNameInCode()); previousState = currentState; remainingStates.RemoveAt(0); } } }
private void GenerateEnumerableFor(StateCodeGeneratorContext context, ICodeBlock currentBlock, AnimationSave animation, AbsoluteOrRelative absoluteOrRelative) { string animationType = "VariableState"; string animationName = animation.PropertyNameInCode(); if(absoluteOrRelative == AbsoluteOrRelative.Relative) { animationName += "Relative"; } string propertyName = animationName + "Instructions"; // Instructions used to be public - the user would grab them and add them to the InstructionManager, // but now everything is encased in an Animation object which handles stopping itself and provides a simple // Play method. if (animation.States.Count == 0 && animation.Animations.Count == 0) { currentBlock = currentBlock.Property("private System.Collections.Generic.IEnumerable<FlatRedBall.Instructions.Instruction>", propertyName).Get(); currentBlock.Line("yield break;"); } else if(absoluteOrRelative == AbsoluteOrRelative.Relative && animation.States.Count < 2 && animation.Animations.Count == 0) { currentBlock = currentBlock.Property("private System.Collections.Generic.IEnumerable<FlatRedBall.Instructions.Instruction>", propertyName).Get(); currentBlock.Line("yield break;"); } else { if (animation.States.Count != 0) { var firstState = context.Element.AllStates.FirstOrDefault(item => item.Name == animation.States.First().StateName); var category = context.Element.Categories.FirstOrDefault(item => item.States.Contains(firstState)); if (category != null) { animationType = category.Name; } } currentBlock = currentBlock.Property("private System.Collections.Generic.IEnumerable<FlatRedBall.Instructions.Instruction>", propertyName).Get(); GenerateOrderedStateAndSubAnimationCode(context, currentBlock, animation, animationType, absoluteOrRelative); if(animation.Loops) { currentBlock = currentBlock.Block(); currentBlock.Line("var toReturn = new FlatRedBall.Instructions.DelegateInstruction( " + "() => FlatRedBall.Instructions.InstructionManager.Instructions.AddRange(this." + propertyName + "));"); string executionTime = "0.0f"; if(animation.States.Count != 0) { executionTime = ToFloatString( animation.States.Last().Time); } currentBlock.Line("toReturn.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + " + executionTime + ";"); currentBlock.Line("yield return toReturn;"); currentBlock = currentBlock.End(); } } }
private float GetAnimationLength(ElementSave element, AnimationSave animation) { float max = 0; if (animation.States.Count != 0) { max = animation.States.Max(item => item.Time); } if(animation.Events.Count != 0) { max = System.Math.Max( max, animation.Events.Max(item => item.Time)); } foreach (var item in animation.Animations) { AnimationSave subAnimation = null; ElementSave subElement = null; if(!string.IsNullOrEmpty( item.SourceObject)) { var instance = element.GetInstance(item.SourceObject); // This may refer to an instance that was deleted at some point: if (instance != null) { subElement = Gum.Managers.ObjectFinder.Self.GetElementSave(instance); } if (subElement != null) { subAnimation = GetAnimationsFor(subElement).Animations.FirstOrDefault(candidate => candidate.Name == item.RootName); } } else { subElement = element; subAnimation = GetAnimationsFor(element).Animations.FirstOrDefault(candidate => candidate.Name == item.RootName); } if (subElement != null && subAnimation != null) { max = Math.Max(max, item.Time + GetAnimationLength(subElement, subAnimation)); } } return max; }
private static void CreateInstructionForSubAnimation(ICodeBlock currentBlock, AnimationReferenceSave animationReferenceSave, AbsoluteOrRelative absoluteOrRelative, AnimationSave parentAnimation) { currentBlock = currentBlock.Block(); //var instruction = new FlatRedBall.Instructions.DelegateInstruction(() => //FlatRedBall.Instructions.InstructionManager.Instructions.AddRange(ClickableBushInstance.GrowAnimation)); //instruction.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + asdf; //yield return instruction; string animationName = animationReferenceSave.PropertyNameInCode(); //animationReferenceSave. FlatRedBall.IO.FileManager.RemovePath(animationReferenceSave.Name) + "Animation"; if (absoluteOrRelative == AbsoluteOrRelative.Relative) { animationName += "Relative"; } currentBlock.Line($"var instruction = new FlatRedBall.Instructions.DelegateInstruction(()=>{animationName}.Play({parentAnimation.PropertyNameInCode()}));"); currentBlock.Line("instruction.TimeToExecute = FlatRedBall.TimeManager.CurrentTime + " + ToFloatString(animationReferenceSave.Time) + ";"); currentBlock.Line("yield return instruction;"); currentBlock = currentBlock.End(); }