2 using System.Collections.Generic;
3 using System.ComponentModel;
5 using System.Runtime.CompilerServices;
7 using System.Threading;
8 using System.Threading.Tasks;
9 using Tizen.Multimedia;
10 using Tizen.Multimedia.Vision;
13 namespace Fitness.Services
16 /// Common base class for all exercise services.
18 public abstract class BaseExerciseService
20 private readonly PoseDetector poseDetector = new PoseDetector();
21 private int isInferencing = 0;
22 private TimeSpan timeLeft;
23 private TimeSpan duration;
24 private Tizen.NUI.Timer timer;
25 private bool timerConfigured = false;
26 private bool workoutStopped = false;
29 /// Event raised when workout time left has changed.
31 public event EventHandler<TimeLeftChangedEventArgs> TimeLeftChanged;
34 /// Event raised when workout time is up.
36 public event EventHandler WorkoutTimeEnded;
39 /// Gets or sets the duration of the workout.
41 public TimeSpan Duration
44 set => duration = value;
48 /// Gets the time remaining until the end of the exercise.
50 public TimeSpan TimeLeft => timeLeft;
53 /// Gets or sets a value indicating whether timer has been configured.
55 protected bool TimerConfigured
57 get => timerConfigured;
58 set => timerConfigured = value;
62 /// Detects performing the exercise based on given preview image data.
64 /// <param name="previewFrame">Preview image data.</param>
65 /// <returns>A task that represents the exercise detection.</returns>
66 public async Task DetectExercise(Tizen.Multimedia.PreviewFrame previewFrame)
68 var stopwatch = new System.Diagnostics.Stopwatch();
73 if (Interlocked.Exchange(ref isInferencing, 1) == 0)
75 var plane = previewFrame.Plane as TriplePlane;
78 throw new System.Exception($"Unsupported plane type: {previewFrame.Plane.GetType()}");
81 uint width = (uint)previewFrame.Resolution.Width;
82 uint height = (uint)previewFrame.Resolution.Height;
84 var landmarks = await poseDetector.Detect(plane, height, width);
86 DetectExercise(landmarks);
93 catch (System.Exception exception)
95 Services.Logger.Error(exception.Message + System.Environment.NewLine + exception.StackTrace);
100 Services.Logger.Debug($"total time {stopwatch.ElapsedMilliseconds} msec");
102 Interlocked.Exchange(ref isInferencing, 0);
109 public void StartWorkout()
111 if (!TimerConfigured)
117 workoutStopped = false;
123 public void StopWorkout()
126 workoutStopped = true;
130 /// Detects performing the exercise based on given landmarks.
132 /// <param name="landmarks">Body landmarks.</param>
133 protected abstract void DetectExercise(Landmark[,] landmarks);
135 private void ConfigureTimer()
137 timer = new Tizen.NUI.Timer(1000);
140 timer.Tick += (sender, args) =>
142 if (timeLeft.CompareTo(TimeSpan.FromSeconds(0)) <= 0)
146 WorkoutTimeEnded?.Invoke(this, EventArgs.Empty);
150 timeLeft = timeLeft.Subtract(TimeSpan.FromSeconds(1));
151 TimeLeftChanged?.Invoke(this, new TimeLeftChangedEventArgs()
157 TimerConfigured = true;