public void ShouldReturnNullWhenNameIsNotFound() { var widthProperty = new AnimatableProperty<float>(); var animatable = new AnimatableObject("Object"); animatable.Properties.Add("Width", widthProperty); Assert.IsNull(animatable.GetAnimatableProperty<float>("WrongName")); }
public void ShouldReturnNullWhenTypeDoesNotMatch() { var widthProperty = new AnimatableProperty<float>(); var animatable = new AnimatableObject("Object"); animatable.Properties.Add("Width", widthProperty); Assert.IsNull(animatable.GetAnimatableProperty<string>("Width")); }
public void BlendGroupWithAnimationAndTimelineGroups() { var testObject = new AnimatableObject("TestObject"); var property1 = new AnimatableProperty<float> { Value = 123.45f }; testObject.Properties.Add("Property1", property1); var blendGroup = new BlendGroup { new SingleFromToByAnimation { From = 0, To = 100, TargetProperty = "Property1" }, new TimelineGroup { new SingleFromToByAnimation { From = 100, To = 300, Duration = TimeSpan.FromSeconds(2.0), TargetProperty = "Property1" }, }, }; blendGroup.SynchronizeDurations(); Assert.AreEqual(TimeSpan.FromSeconds(1.5), blendGroup.GetTotalDuration()); var manager = new AnimationManager(); var controller = manager.StartAnimation(blendGroup, testObject); controller.UpdateAndApply(); Assert.AreEqual(50.0f, property1.Value); manager.Update(TimeSpan.FromSeconds(0.75)); // t = 0.75 manager.ApplyAnimations(); Assert.AreEqual(TimeSpan.FromSeconds(1.5), blendGroup.GetTotalDuration()); Assert.AreEqual(0.5f * 50.0f + 0.5f * 200.0f, property1.Value); blendGroup.SetWeight(0, 0); Assert.AreEqual(TimeSpan.FromSeconds(2.0), blendGroup.GetTotalDuration()); manager.Update(TimeSpan.FromSeconds(0.25)); // t = 1.0 manager.ApplyAnimations(); Assert.AreEqual(200.0f, property1.Value); blendGroup.SetWeight(0, 10); blendGroup.SetWeight(1, 0); Assert.AreEqual(TimeSpan.FromSeconds(1.0), blendGroup.GetTotalDuration()); manager.Update(TimeSpan.Zero); // t = 1.0 manager.ApplyAnimations(); Assert.AreEqual(100.0f, property1.Value); blendGroup.SetWeight(0, 10); blendGroup.SetWeight(1, 1); Assert.AreEqual(new TimeSpan((long)((1.0f * 10.0f / 11.0f + 2.0f * 1.0f / 11.0f) * TimeSpan.TicksPerSecond)), blendGroup.GetTotalDuration()); manager.Update(TimeSpan.FromSeconds(0.5)); // t = 1.5 manager.ApplyAnimations(); Assert.AreEqual(AnimationState.Filling, controller.State); Assert.IsTrue(Numeric.AreEqual(100.0f * 10.0f / 11.0f + 300.0f * 1.0f / 11.0f, property1.Value)); controller.Stop(); controller.UpdateAndApply(); Assert.AreEqual(AnimationState.Stopped, controller.State); Assert.AreEqual(123.45f, property1.Value); }
public void ShouldReturnAllAnimatableProperties() { var widthProperty = new AnimatableProperty<float>(); var heightProperty = new AnimatableProperty<float>(); var textProperty = new AnimatableProperty<string>(); var animatable = new AnimatableObject("Object"); animatable.Properties.Add("Width", widthProperty); animatable.Properties.Add("Height", heightProperty); animatable.Properties.Add("Text", textProperty); Assert.That(animatable.GetAnimatedProperties(), Has.Member(widthProperty)); Assert.That(animatable.GetAnimatedProperties(), Has.Member(heightProperty)); Assert.That(animatable.GetAnimatedProperties(), Has.Member(textProperty)); }
public void NameShouldBeSet() { var animatableProperty = new AnimatableObject("Name of object"); Assert.AreEqual("Name of object", animatableProperty.Name); }
public void BlendGroupWithAnimationAndTimelineGroups() { var testObject = new AnimatableObject("TestObject"); var property1 = new AnimatableProperty <float> { Value = 123.45f }; testObject.Properties.Add("Property1", property1); var blendGroup = new BlendGroup { new SingleFromToByAnimation { From = 0, To = 100, TargetProperty = "Property1" }, new TimelineGroup { new SingleFromToByAnimation { From = 100, To = 300, Duration = TimeSpan.FromSeconds(2.0), TargetProperty = "Property1" }, }, }; blendGroup.SynchronizeDurations(); Assert.AreEqual(TimeSpan.FromSeconds(1.5), blendGroup.GetTotalDuration()); var manager = new AnimationManager(); var controller = manager.StartAnimation(blendGroup, testObject); controller.UpdateAndApply(); Assert.AreEqual(50.0f, property1.Value); manager.Update(TimeSpan.FromSeconds(0.75)); // t = 0.75 manager.ApplyAnimations(); Assert.AreEqual(TimeSpan.FromSeconds(1.5), blendGroup.GetTotalDuration()); Assert.AreEqual(0.5f * 50.0f + 0.5f * 200.0f, property1.Value); blendGroup.SetWeight(0, 0); Assert.AreEqual(TimeSpan.FromSeconds(2.0), blendGroup.GetTotalDuration()); manager.Update(TimeSpan.FromSeconds(0.25)); // t = 1.0 manager.ApplyAnimations(); Assert.AreEqual(200.0f, property1.Value); blendGroup.SetWeight(0, 10); blendGroup.SetWeight(1, 0); Assert.AreEqual(TimeSpan.FromSeconds(1.0), blendGroup.GetTotalDuration()); manager.Update(TimeSpan.Zero); // t = 1.0 manager.ApplyAnimations(); Assert.AreEqual(100.0f, property1.Value); blendGroup.SetWeight(0, 10); blendGroup.SetWeight(1, 1); Assert.AreEqual(new TimeSpan((long)((1.0f * 10.0f / 11.0f + 2.0f * 1.0f / 11.0f) * TimeSpan.TicksPerSecond)), blendGroup.GetTotalDuration()); manager.Update(TimeSpan.FromSeconds(0.5)); // t = 1.5 manager.ApplyAnimations(); Assert.AreEqual(AnimationState.Filling, controller.State); Assert.IsTrue(Numeric.AreEqual(100.0f * 10.0f / 11.0f + 300.0f * 1.0f / 11.0f, property1.Value)); controller.Stop(); controller.UpdateAndApply(); Assert.AreEqual(AnimationState.Stopped, controller.State); Assert.AreEqual(123.45f, property1.Value); }
public void AnimateObject() { var obj = new AnimatableObject("TestObject"); var property = new AnimatableProperty<float> { Value = 10.0f }; obj.Properties.Add("Value", property); var property2 = new AnimatableProperty<float> { Value = 20.0f }; obj.Properties.Add("Value2", property2); var animationA = new SingleFromToByAnimation { From = 100.0f, To = 200.0f, TargetObject = "ObjectA", // Should be ignored. TargetProperty = "Value", }; var animationB = new SingleFromToByAnimation { From = 200.0f, To = 300.0f, TargetObject = "ObjectB", // Should be ignored. TargetProperty = "", }; var animationGroup = new TimelineGroup(); animationGroup.Add(animationA); animationGroup.Add(animationB); var manager = new AnimationManager(); // Should assign animationA to 'obj'. var controller = manager.CreateController(animationGroup, obj); Assert.AreEqual(property, ((AnimationInstance<float>)controller.AnimationInstance.Children[0]).Property); Assert.AreEqual(null, ((AnimationInstance<float>)controller.AnimationInstance.Children[1]).Property); Assert.IsFalse(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); Assert.IsFalse(manager.IsAnimated(obj)); // When started then animationA should be active. controller.Start(); controller.UpdateAndApply(); Assert.AreEqual(100.0f, property.Value); Assert.AreEqual(20.0f, property2.Value); Assert.IsTrue(manager.IsAnimated(obj)); Assert.IsTrue(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); controller.Stop(); controller.UpdateAndApply(); Assert.AreEqual(10.0f, property.Value); Assert.AreEqual(20.0f, property2.Value); Assert.IsFalse(manager.IsAnimated(obj)); Assert.IsFalse(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); // Same test for AnimationManager.StartAnimation() controller = manager.StartAnimation(animationGroup, obj); controller.UpdateAndApply(); Assert.AreEqual(property, ((AnimationInstance<float>)controller.AnimationInstance.Children[0]).Property); Assert.AreEqual(null, ((AnimationInstance<float>)controller.AnimationInstance.Children[1]).Property); Assert.AreEqual(100.0f, property.Value); Assert.AreEqual(20.0f, property2.Value); Assert.IsTrue(manager.IsAnimated(obj)); Assert.IsTrue(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); manager.StopAnimation(obj); manager.UpdateAndApplyAnimation(obj); Assert.AreEqual(10.0f, property.Value); Assert.AreEqual(20.0f, property2.Value); Assert.IsFalse(manager.IsAnimated(obj)); Assert.IsFalse(manager.IsAnimated(property)); Assert.IsFalse(manager.IsAnimated(property2)); }
public void ShouldRemoveAnimationsIfTargetsAreGarbageCollected() { var obj = new AnimatableObject("TestObject"); var property = new AnimatableProperty<float>(); obj.Properties.Add("Value", property); var animation = new SingleFromToByAnimation { From = 100.0f, To = 200.0f, TargetProperty = "Value", }; var manager = new AnimationManager(); var controller = manager.StartAnimation(animation, obj); controller.AutoRecycle(); controller.UpdateAndApply(); Assert.AreEqual(100.0f, property.Value); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(150.0f, property.Value); // Garbage-collect target object. obj = null; property = null; GC.Collect(); // Controller should be still valid, because AnimationManager.Update() needs // to be called first. Assert.IsTrue(controller.IsValid); manager.Update(TimeSpan.FromSeconds(0.1)); manager.ApplyAnimations(); // Animation instance should now be recycled. Assert.IsFalse(controller.IsValid); }
public void ShouldRemoveAnimationsIfInactive() { var obj = new AnimatableObject("TestObject"); var property = new AnimatableProperty<float>(); obj.Properties.Add("Value", property); var animation = new SingleFromToByAnimation { From = 100.0f, To = 200.0f, TargetProperty = "Value", }; var manager = new AnimationManager(); var controllerA = manager.StartAnimation(animation, obj); controllerA.AutoRecycle(); controllerA.UpdateAndApply(); Assert.AreEqual(100.0f, property.Value); Assert.IsTrue(controllerA.IsValid); manager.Update(TimeSpan.FromSeconds(0.5)); manager.ApplyAnimations(); Assert.AreEqual(150.0f, property.Value); Assert.IsTrue(controllerA.IsValid); // Replace animation instance with new instance. var controllerB = manager.StartAnimation(animation, obj); controllerB.AutoRecycle(); controllerB.UpdateAndApply(); Assert.AreEqual(100.0f, property.Value); Assert.IsTrue(controllerA.IsValid); Assert.IsTrue(controllerB.IsValid); // controllerA should be removed automatically. // (Note: Cleanup is done incrementally, not every frame. // It is okay if it takes a few updates.) manager.Update(TimeSpan.FromSeconds(0.1)); manager.Update(TimeSpan.FromSeconds(0.1)); manager.Update(TimeSpan.FromSeconds(0.1)); manager.Update(TimeSpan.FromSeconds(0.1)); manager.Update(TimeSpan.FromSeconds(0.1)); manager.ApplyAnimations(); Assert.AreEqual(150.0f, property.Value); Assert.IsFalse(controllerA.IsValid); Assert.IsTrue(controllerB.IsValid); }
public void InvalidParameters() { var objectA = new AnimatableObject("ObjectA"); var objectB = new AnimatableObject("ObjectA"); var property = new AnimatableProperty<float>(); var animation = new SingleFromToByAnimation(); var objects = new[] { objectA, objectB }; var manager = new AnimationManager(); // Should throw exception. Assert.That(() => { manager.IsAnimated((IAnimatableObject)null); }, Throws.TypeOf<ArgumentNullException>()); Assert.That(() => { manager.IsAnimated((IAnimatableProperty)null); }, Throws.TypeOf<ArgumentNullException>()); // Should throw exception. Assert.That(() => { manager.CreateController(null, objects); }, Throws.TypeOf<ArgumentNullException>()); Assert.That(() => { manager.CreateController(animation, (IEnumerable<IAnimatableObject>)null); }, Throws.TypeOf<ArgumentNullException>()); Assert.That(() => { manager.CreateController(null, objectA); }, Throws.TypeOf<ArgumentNullException>()); Assert.That(() => { manager.CreateController(animation, (IAnimatableObject)null); }, Throws.TypeOf<ArgumentNullException>()); Assert.That(() => { manager.CreateController(null, property); }, Throws.TypeOf<ArgumentNullException>()); Assert.That(() => { manager.CreateController(animation, (IAnimatableProperty)null); }, Throws.TypeOf<ArgumentNullException>()); // Should throw exception. Assert.That(() => { manager.StartAnimation(null, objects); }, Throws.TypeOf<ArgumentNullException>()); Assert.That(() => { manager.StartAnimation(animation, (IEnumerable<IAnimatableObject>)null); }, Throws.TypeOf<ArgumentNullException>()); Assert.That(() => { manager.StartAnimation(null, objectA); }, Throws.TypeOf<ArgumentNullException>()); Assert.That(() => { manager.StartAnimation(animation, (IAnimatableObject)null); }, Throws.TypeOf<ArgumentNullException>()); Assert.That(() => { manager.StartAnimation(null, property); }, Throws.TypeOf<ArgumentNullException>()); Assert.That(() => { manager.StartAnimation(animation, (IAnimatableProperty)null); }, Throws.TypeOf<ArgumentNullException>()); // Should not throw exception. Assert.That(() => manager.StopAnimation((IEnumerable<IAnimatableObject>)null), Throws.Nothing); Assert.That(() => manager.StopAnimation((IAnimatableObject)null), Throws.Nothing); Assert.That(() => manager.StopAnimation((IAnimatableProperty)null), Throws.Nothing); }
public void AnimateObjects() { var objectA = new AnimatableObject("ObjectA"); var propertyA1 = new AnimatableProperty<float> { Value = 10.0f }; objectA.Properties.Add("Value", propertyA1); var propertyA2 = new AnimatableProperty<float> { Value = 20.0f }; objectA.Properties.Add("Value2", propertyA2); var objectB = new AnimatableObject("ObjectB"); var propertyB = new AnimatableProperty<float> { Value = 30.0f }; objectB.Properties.Add("Value", propertyB); var objectC = new AnimatableObject("ObjectC"); var propertyC = new AnimatableProperty<float> { Value = 40.0f }; objectC.Properties.Add("Value", propertyC); var animationA1 = new SingleFromToByAnimation // Should be assigned to ObjectA { From = 100.0f, To = 200.0f, TargetObject = "ObjectXyz", // Ignored because ObjectA is selected by animationGroup1. TargetProperty = "Value", // Required. }; var animationA2 = new SingleFromToByAnimation // Should be assigned to ObjectA { From = 200.0f, To = 300.0f, TargetObject = "ObjectB", // Ignored because ObjectA is selected by animationGroup1. TargetProperty = "Value", // Required. }; var animationA3 = new Vector3FFromToByAnimation // Ignored because of incompatible type. { From = new Vector3F(300.0f), To = new Vector3F(400.0f), TargetObject = "ObjectA", TargetProperty = "Value", }; var animationA4 = new SingleFromToByAnimation // Ignored because TargetProperty is not set. { From = 400.0f, To = 500.0f, TargetObject = "", TargetProperty = "", }; var animationGroupA = new TimelineGroup { TargetObject = "ObjectA" }; animationGroupA.Add(animationA1); animationGroupA.Add(animationA2); animationGroupA.Add(animationA3); animationGroupA.Add(animationA4); var animationB1 = new SingleFromToByAnimation // Should be assigned to ObjectB { From = 100.0f, To = 200.0f, TargetObject = "ObjectB", TargetProperty = "Value", }; var animationA5 = new SingleFromToByAnimation { From = 600.0f, To = 700.0f, TargetObject = "", TargetProperty = "Value", }; var animationGroupRoot = new TimelineGroup(); animationGroupRoot.Add(animationGroupA); animationGroupRoot.Add(animationB1); animationGroupRoot.Add(animationA5); var manager = new AnimationManager(); // CreateController() var controller = manager.CreateController(animationGroupRoot, new[] { objectA, objectB, objectC }); Assert.AreEqual(propertyA1, ((AnimationInstance<float>)controller.AnimationInstance.Children[0].Children[0]).Property); Assert.AreEqual(propertyA1, ((AnimationInstance<float>)controller.AnimationInstance.Children[0].Children[1]).Property); Assert.AreEqual(null, ((AnimationInstance<Vector3F>)controller.AnimationInstance.Children[0].Children[2]).Property); Assert.AreEqual(null, ((AnimationInstance<float>)controller.AnimationInstance.Children[0].Children[3]).Property); Assert.AreEqual(propertyB, ((AnimationInstance<float>)controller.AnimationInstance.Children[1]).Property); Assert.AreEqual(propertyA1, ((AnimationInstance<float>)controller.AnimationInstance.Children[2]).Property); Assert.AreEqual(10.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(30.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsFalse(manager.IsAnimated(objectA)); Assert.IsFalse(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsFalse(manager.IsAnimated(objectB)); Assert.IsFalse(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); controller.Start(); controller.UpdateAndApply(); Assert.AreEqual(600.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(100.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsTrue(manager.IsAnimated(objectA)); Assert.IsTrue(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsTrue(manager.IsAnimated(objectB)); Assert.IsTrue(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); controller.Stop(); controller.UpdateAndApply(); Assert.AreEqual(10.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(30.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsFalse(manager.IsAnimated(objectA)); Assert.IsFalse(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsFalse(manager.IsAnimated(objectB)); Assert.IsFalse(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); // StartAnimation() controller = manager.StartAnimation(animationGroupRoot, new[] { objectA, objectB, objectC }); controller.UpdateAndApply(); Assert.AreEqual(propertyA1, ((AnimationInstance<float>)controller.AnimationInstance.Children[0].Children[0]).Property); Assert.AreEqual(propertyA1, ((AnimationInstance<float>)controller.AnimationInstance.Children[0].Children[1]).Property); Assert.AreEqual(null, ((AnimationInstance<Vector3F>)controller.AnimationInstance.Children[0].Children[2]).Property); Assert.AreEqual(null, ((AnimationInstance<float>)controller.AnimationInstance.Children[0].Children[3]).Property); Assert.AreEqual(propertyB, ((AnimationInstance<float>)controller.AnimationInstance.Children[1]).Property); Assert.AreEqual(propertyA1, ((AnimationInstance<float>)controller.AnimationInstance.Children[2]).Property); Assert.AreEqual(600.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(100.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsTrue(manager.IsAnimated(objectA)); Assert.IsTrue(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsTrue(manager.IsAnimated(objectB)); Assert.IsTrue(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); manager.StopAnimation(new[] { objectA, objectB, objectC }); manager.UpdateAndApplyAnimation(new[] { objectA, objectB, objectC }); Assert.AreEqual(10.0f, propertyA1.Value); Assert.AreEqual(20.0f, propertyA2.Value); Assert.AreEqual(30.0f, propertyB.Value); Assert.AreEqual(40.0f, propertyC.Value); Assert.IsFalse(manager.IsAnimated(objectA)); Assert.IsFalse(manager.IsAnimated(propertyA1)); Assert.IsFalse(manager.IsAnimated(propertyA2)); Assert.IsFalse(manager.IsAnimated(objectB)); Assert.IsFalse(manager.IsAnimated(propertyB)); Assert.IsFalse(manager.IsAnimated(objectC)); Assert.IsFalse(manager.IsAnimated(propertyC)); }