0

I have an app which moves a car through specified locations on a map control. I'm using below code to achieve this functionality. But now I want to set a duration for this. I mean the car should reach at a particular time from start to endpoint. How can I do it. I'm passing the duration to timer as shown in the code.

  public class PathAnimation
{
    private const int _delay = 30;
    private DispatcherTimer _timerId;
    private int? _duration;
    private int _frameIdx = 0;
    private bool _isPaused;
    private DateTime _timerStart = DateTime.Now;

    public  PathAnimation(IntervalCallback intervalCallback,int? duration)
    {
        _duration = duration;
        _timerId = new DispatcherTimer();
        _timerId.Interval = new TimeSpan(0, 0, 0, 0, _delay);
        _timerId.Tick += (s, a) =>
        {
            if (!_isPaused)
            {
                if (intervalCallback != null)
                {
                    intervalCallback(AppGlobals._intervalLocs[_frameIdx], AppGlobals._intervalIdx[_frameIdx], _frameIdx);
                }
                 if ((DateTime.Now - _timerStart).TotalMilliseconds >= _duration.Value)
                {
                    _timerId.Stop();
                }
                _frameIdx++;

            }
        };
    }
    public delegate void IntervalCallback(BasicGeoposition loc, int pathIdx, int frameIdx);
    public void Play()
    {  _timerStart = DateTime.Now;
        _frameIdx = 0;
        _isPaused = false;
        _timerId.Start();
    }
    public void Pause()
    {
        _isPaused = true;
    }

    public void Stop()
    {
        if (_timerId.IsEnabled)
        {
            _frameIdx = 0;
            _isPaused = false;
            _timerId.Stop();
        }
    }
}

But now what happens is car reaches faster than the duration time and causes an out of index error on intervalCallback(AppGlobals._intervalLocs[_frameIdx], AppGlobals._intervalIdx[_frameIdx], _frameIdx);

nsds
  • 961
  • 4
  • 13
  • 39
  • Would you add what your problem is. In the code you showed us you are already setting a interval. If you want a maximum time you can introduce a counter which counts the ticks and multiply it with your interval time – TheTanic Aug 07 '18 at 10:17
  • I'm talking about duration. In my code I'm using 30 millisec of interval to call the timer. But my question is how can I stop the timer within the duration that I passed to the function PathAnimation – nsds Aug 07 '18 at 10:21
  • Either you make another timer, which has an interval of your duration, or you check in your Tick-Function if the duration exceeded – TheTanic Aug 07 '18 at 10:25
  • how to check it in Tick-Function if the duration exceeded? – nsds Aug 07 '18 at 10:51

1 Answers1

0

But now what happens is car reaches faster than the duration time and causes an out of index error ...

I am not sure about your logic here but to avoid getting an IndexOutOfRangeException you should make sure that the Count of the collection is always greater than the value that you pass to the indexer, e.g.:

_timerId.Tick += (s, a) =>
{
    if (!_isPaused)
    {
        if (intervalCallback != null 
            && AppGlobals._intervalLocs.Count > _frameIdx
            && AppGlobals._intervalIdx.Count > _frameIdx)
        {
            intervalCallback(AppGlobals._intervalLocs[_frameIdx], AppGlobals._intervalIdx[_frameIdx], _frameIdx);
        }

        _frameIdx++;

        if ((DateTime.Now - _timerStart).TotalMilliseconds >= _duration.Value)
            _timerId.Stop();
    }
};
mm8
  • 163,881
  • 10
  • 57
  • 88
  • With this condition it will not crash. But couldn't reach the goal. For ex : If _intervalLocs array contains 5 locations. and duration is set as 2minute. Those 5 location should cover within 2minutes exactly. Now it covers less than of 2 minutes – nsds Aug 08 '18 at 05:05
  • You are visting a location once every `_delay`, arent't you? That's how a timer works... – mm8 Aug 08 '18 at 09:33
  • You need to know the number of items in the array and set the interval of the timer accordingly. Do you want the timer to tick once per item in the array or what? – mm8 Aug 08 '18 at 09:56
  • my aim is moving a car on map from a start location to end location within a time. For that AppGlobals._intervalLocs contains all locations and duration variable contains the time – nsds Aug 08 '18 at 10:09
  • 1
    So set the Interval of the timer to `(double)duration.Value / _interValLocs.Count` ? – mm8 Aug 08 '18 at 10:15