View Issue Details

IDProjectCategoryView StatusLast Update
0001182NoesisGUIUnitypublic2019-02-24 06:44
Reporternokola Assigned Tosfernandez  
PriorityhighSeveritycrash 
Status closedResolutionfixed 
Product Version2.0.2f2 
Target Version2.2.0Fixed in Version2.2.0b5 
Summary0001182: App crash/hang with "Target Not Found" error when trying to stop storyboard in the same frame it's already started
Description

Noesis 2.1 beta4
Took us several days to debug due to crash (will open separate bug.) I'm trying to port the TiltEffect from Windows Phone to Noesis. The effect "tilts" a tile when you tap and hold it with finger and "releases" the tilt back to normal via custom animation set in code.
Long story short, there are many places in the code where we call storyboard.Stop(...) on already stopped storyboard and sometimes there are calls of Begin() and Stop() in the same frame.
The issue is that Noesis shows "target not found" error if you try to do storyboard.IsPlaying() or storyboard.Stop() on a storyboard that has just been started (sometimes several lines above in code)
I marked as severity Major since we've been trying to get this to work for months (even though we spend in total of several days, but have been putting it on the backburner) and didn't realize what the core of the issue is until now.

Steps To Reproduce
  1. Create new 3D project in Unity

  2. Add Noesis

  3. At end of ButtonsViewModel.cs from the samples add this, also attached:
    public class Test
    {
    private static Storyboard story;
    public static void PrepareTiltReturnStoryboard(Button button)
    {
    if (story != null)
    {
    story.Stop(); // all OK
    story = null;
    }
    else
    {
    button.Projection = new PlaneProjection();

            // setup animation
            Storyboard story = new Storyboard();
            story.Completed += (sender, args) => { button.Content = "done"; };
            DoubleAnimation anim = new DoubleAnimation();
            Storyboard.SetTargetProperty(anim, new PropertyPath("(UIElement.Projection).(PlaneProjection.RotationZ)"));
            anim.To = 45;
            anim.Duration = System.TimeSpan.FromSeconds(2);
            story.Children.Add(anim);
    
            Storyboard.SetTarget(anim, button);
            story.Begin(button, true);
            if (story.IsPlaying()) // ERROR: this code will show "Target Not Found" crash in Unity log 
            {
                story.Stop(); // this code will show "Target not Found" too in case the if() is removed
            }
        }
    }

    }

  4. In Buttons.xaml.cs update OnInitialized() to this:
    private void OnInitialized(object sender, EventArgs args)
    {
    this.DataContext = new ButtonsViewModel(FindName("StartButton") as Button);
    }

  5. On top of ButtonsViewModel get the _startButton:
    private Button _startButton;
    public ButtonsViewModel(Button startButton)
    {
    _startButton = startButton;
    StartCommand = new DelegateCommand(this.Start);
    SettingsCommand = new DelegateCommand(this.Settings);
    ExitCommand = new DelegateCommand(this.Exit);
    }

    public DelegateCommand StartCommand { get; private set; }
    public DelegateCommand SettingsCommand { get; private set; }
    public DelegateCommand ExitCommand { get; private set; }
    
    private void Start(object parameter)
    {
        Test.PrepareTiltReturnStoryboard(_startButton);

    #if NOESIS
    Debug.Log("Start Game");
    #endif
    }

  6. Run Buttons sample and press Start
    Expected:
    all OK
    Actual: Noesis exception in Unity log on the story.IsPlaying() line
    Sometime Noesis crashes after some time (seconds, maybe minute?)
    Noesis.dll caused an Access Violation (0xc0000005)
    in module Noesis.dll at 0033:d5c2bbfd.

Attached Files
Buttons.xaml.cs (841 bytes)   
#if UNITY_5_3_OR_NEWER
#define NOESIS
#endif

#if NOESIS
using Noesis;
#else
using System;
using System.Windows;
using System.Windows.Controls;
#endif

namespace Noesis.Samples
{
    /// <summary>
    /// Interaction logic for Buttons.xaml
    /// </summary>
    public partial class Buttons : UserControl
    {
        public Buttons()
        {
            this.Initialized += OnInitialized;
            this.InitializeComponent();
        }

#if NOESIS
        private void InitializeComponent()
        {
            Noesis.GUI.LoadComponent(this, "Assets/NoesisGUI/Samples/Buttons/Buttons.xaml");
        }
#endif

        private void OnInitialized(object sender, EventArgs args)
        {
            this.DataContext = new ButtonsViewModel(FindName("StartButton") as Button);
        }
    }
}
Buttons.xaml.cs (841 bytes)   
ButtonsViewModel.cs (2,567 bytes)   
#if UNITY_5_3_OR_NEWER
#define NOESIS
#endif

#if NOESIS
using Noesis;
using UnityEngine;

#else
using System;
#endif

namespace Noesis.Samples
{
    /// <summary>
    /// Buttons sample view model
    /// </summary>
    public class ButtonsViewModel
    {
        private Button _startButton;
        public ButtonsViewModel(Button startButton)
        {
            _startButton = startButton;
            StartCommand = new DelegateCommand(this.Start);
            SettingsCommand = new DelegateCommand(this.Settings);
            ExitCommand = new DelegateCommand(this.Exit);
        }

        public DelegateCommand StartCommand { get; private set; }
        public DelegateCommand SettingsCommand { get; private set; }
        public DelegateCommand ExitCommand { get; private set; }

        private void Start(object parameter)
        {
            Test.PrepareTiltReturnStoryboard(_startButton);
#if NOESIS
            Debug.Log("Start Game");
#endif
        }

        private void Settings(object parameter)
        {
#if NOESIS
            Debug.Log("Change Settings");
#endif
        }

        private void Exit(object parameter)
        {
#if NOESIS
            Debug.Log("Exit Game");
#endif
        }
    }

    public class Test
    {
        private static Storyboard story;
        public static void PrepareTiltReturnStoryboard(Button button)
        {
            if (story != null)
            {
                story.Stop(); // all OK
                story = null;
            }
            else
            {
                button.Projection = new PlaneProjection();

                // setup animation
                Storyboard story = new Storyboard();
                story.Completed += (sender, args) => { button.Content = "done"; };
                DoubleAnimation anim = new DoubleAnimation();
                Storyboard.SetTargetProperty(anim, new PropertyPath("(UIElement.Projection).(PlaneProjection.RotationZ)"));
                anim.To = 45;
                anim.Duration = System.TimeSpan.FromSeconds(2);
                story.Children.Add(anim);

                Storyboard.SetTarget(anim, button);
                story.Begin(button, true);
                if (story.IsPlaying()) // ERROR: this code will show "Target Not Found" crash in Unity log 
                {
                    story.Stop(); // ERROR: this code will show "Target not Found" too in case the if() is removed
                }
            }
        }
    }
}
ButtonsViewModel.cs (2,567 bytes)   
PlatformAny

Activities

sfernandez

sfernandez

2018-12-10 18:04

manager   ~0005361

We fixed the crash and improved the error messages related to Storyboard playing.

In this particular scenario, though, the correct way of calling IsPlaying() is providing the same target used to start the animation, otherwise it won't be able to find the corresponding animation Clock created for playing the animation:


if (story.IsPlaying(button))
{
story.Stop(button);
}

Issue History

Date Modified Username Field Change
2017-11-13 02:05 nokola New Issue
2017-11-13 02:05 nokola File Added: crashStoryboardLog.zip
2017-11-13 02:05 nokola File Added: Buttons.xaml.cs
2017-11-13 02:05 nokola File Added: ButtonsViewModel.cs
2017-11-13 02:15 nokola Description Updated
2017-11-13 10:37 sfernandez Assigned To => sfernandez
2017-11-13 10:37 sfernandez Status new => assigned
2018-11-01 02:14 jsantos View Status public => private
2018-11-22 21:21 sfernandez Target Version => 2.2.0
2018-11-22 21:21 sfernandez View Status private => public
2018-11-22 21:21 sfernandez Platform => Any
2018-12-10 18:04 sfernandez Status assigned => resolved
2018-12-10 18:04 sfernandez Resolution open => fixed
2018-12-10 18:04 sfernandez Fixed in Version => 2.2.0b5
2018-12-10 18:04 sfernandez Note Added: 0005361
2019-02-24 06:44 nokola Status resolved => closed
2022-04-06 08:45 jsantos File Deleted: crashStoryboardLog.zip
2025-10-10 13:29 jsantos Category Unity3D => Unity