SowingFiber
SowingFiber

Reputation: 1244

Can I start the dart Stopwatch with an initial value?

I am looking at the docs of Stopwatch and I'm sure that they don't have a method to start the stopwatch with the initial value.

I am developing an app that requires measuring the elapsed time. Therefore, Stopwatch becomes the obvious choice here. However, there is a use case, where the users of the app may accidentally close the app when clearing the background apps.

Since, running headless dart code in the background is kind of vague right now, I believe it is of best interest to keep track of time and the time gap, if there is any when resuming the app after an accidental close. A separate data object like the following could keep track of time and whether the stopwatch is running...

class StopwatchTracker{

  final stopwatch;
  final lastUpdated;
  final isRunning;
  final systemTime;

  StopwatchTracker({this.stopwatch, this.lastUpdated, this.isRunning, this.systemTime});

}

With this I have an object that has data about the lastUpdated time from the stopwatch. Compare this to the systemTime, which will be the device's current system time. Now, we can see if there is a gap between the lastUpdated time and the systemTime. If there is a gap, the stopwatch should "leap" to the time, by "gap" units.

This StopwatchTracker object will only be initialized on app start/resume and every few seconds, it will update the lastUpdated time. I think the logic is there, but, as I mentioned, the Stopwatch class in dart, doesn't have a method to initialize it with a starting value.

I'm wondering whether I could extend the Stopwatch class to house a method to do that. Or a second option will be to update the ellapsedMillis itself or add the gap in mills to the ellapsedMillis and then show the result on the screen.

Will love to hear from you guys on this!

Upvotes: 2

Views: 1712

Answers (2)

BJG87
BJG87

Reputation: 141

Stumbled across this question myself and thought SowingFiber's answer was fantastic. I did alter your Class slightly though to offer an alternative constructor that allows you to set the initial time straight away.

I also overrode the elapsed getter with the elapsedDuration getter to prevent accidentally getting the original elapsed time.

class RaceStopwatch extends Stopwatch {
  int _starterMilliseconds = 0;

  RaceStopwatch();

  RaceStopwatch.withStartTime({required int timeInMilliseconds})
      : _starterMilliseconds = timeInMilliseconds;

  @override
  Duration get elapsed {
    return elapsedDuration;
  }

  get elapsedDuration {
    return Duration(
        microseconds: elapsedMicroseconds + (_starterMilliseconds * 1000));
  }

  get elapsedMillis {
    return elapsedMilliseconds + _starterMilliseconds;
  }

  set milliseconds(int timeInMilliseconds) {
    _starterMilliseconds = timeInMilliseconds;
  }
}

Upvotes: 0

SowingFiber
SowingFiber

Reputation: 1244

Yes I can! > Well yes, but actually no

I cannot set the starting value of the stopwatch to start/resume at a certain time or even readjust the current running time.

The easiest solution I have found is to extend the class Stopwatch like so:

class StopWatch extends Stopwatch{
  int _starterMilliseconds = 0;

  StopWatch();

  get elapsedDuration{
    return Duration(
      microseconds: 
      this.elapsedMicroseconds + (this._starterMilliseconds * 1000)
    );
  }

  get elapsedMillis{
    return this.elapsedMilliseconds + this._starterMilliseconds;
  }

  set milliseconds(int timeInMilliseconds){
    this._starterMilliseconds = timeInMilliseconds;
  }

}

At present I don't require much more from this code. Just start the stopwatch at some point and then keep it running. And it can be easily extended for other get types of the class Stopwatch.

This is how I plan to use the class

void main() {
  var stopwatch = new StopWatch(); //Creates a new StopWatch, not Stopwatch
  stopwatch.start();               //start method, not overridden
  stopwatch.milliseconds = 10000;  //10 seconds have passed
  print(stopwatch.elapsedDuration);//returns the recalculated duration
  stopwatch.stop();
}

Want to play with the code, or test it out? Click here

Upvotes: 7

Related Questions