aboutsummaryrefslogtreecommitdiffstats
path: root/src/base/UTime.pas
diff options
context:
space:
mode:
authortobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>2010-04-22 01:04:24 +0000
committertobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>2010-04-22 01:04:24 +0000
commitedfc692c991e08af0163aa6812e5972478d7191b (patch)
tree2580b6460cd805a3782c39404e6208c05dc0a435 /src/base/UTime.pas
parent776e4ffb42b0cc5f32c2dcc54745a3537e3bcc15 (diff)
downloadusdx-edfc692c991e08af0163aa6812e5972478d7191b.tar.gz
usdx-edfc692c991e08af0163aa6812e5972478d7191b.tar.xz
usdx-edfc692c991e08af0163aa6812e5972478d7191b.zip
- now it is possible to sync lyrics to audio
- ini option SyncTo added - lyric to audio is default now (instead of sync audio to lyrics) - modified RelativeTimer (hopefully easier to use and more self-explanatory) git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@2273 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to 'src/base/UTime.pas')
-rw-r--r--src/base/UTime.pas158
1 files changed, 97 insertions, 61 deletions
diff --git a/src/base/UTime.pas b/src/base/UTime.pas
index 83844cb5..0610ef59 100644
--- a/src/base/UTime.pas
+++ b/src/base/UTime.pas
@@ -40,20 +40,26 @@ type
function GetTime(): real;
end;
+ TRelativeTimerState = (rtsStopped, rtsWait, rtsPaused, rtsRunning);
+
TRelativeTimer = class
private
AbsoluteTime: int64; // system-clock reference time for calculation of CurrentTime
- RelativeTimeOffset: real;
- Paused: boolean;
+ RelativeTime: real;
TriggerMode: boolean;
+ State: TRelativeTimerState;
public
- constructor Create(TriggerMode: boolean = false);
+ constructor Create();
+ procedure Start(WaitForTrigger: boolean = false);
procedure Pause();
- procedure Resume();
+ procedure Stop();
function GetTime(): real;
- function GetAndResetTime(): real;
- procedure SetTime(Time: real; Trigger: boolean = true);
- procedure Reset();
+ procedure SetTime(Time: real);
+ function GetState(): TRelativeTimerState;
+ end;
+
+ TSyncSource = class
+ function GetClock(): real; virtual; abstract;
end;
procedure CountSkipTimeSet;
@@ -126,85 +132,115 @@ end;
* TRelativeTimer
**}
-(*
- * creates a new timer.
- * if triggermode is false (default), the timer
- * will immediately begin with counting.
- * if triggermode is true, it will wait until get/settime() or pause() is called
- * for the first time.
+(**
+ * Creates a new relative timer.
+ * A relative timer works like a stop-watch. It can be paused and
+ * resumed afterwards, continuing with the counter it had when it was paused.
*)
-constructor TRelativeTimer.Create(TriggerMode: boolean);
+constructor TRelativeTimer.Create();
begin
- inherited Create();
- Self.TriggerMode := TriggerMode;
- Reset();
- Paused := false;
+ State := rtsStopped;
+ AbsoluteTime := 0;
+ RelativeTime := 0;
end;
-procedure TRelativeTimer.Pause();
+(**
+ * Starts the timer.
+ * If WaitForTrigger is false the timer will be started immediately.
+ * If WaitForTrigger is true the timer will be started when a trigger event
+ * occurs. A trigger event is a call of one of the Get-/SetTime() methods.
+ * In addition the timer can be started by calling this method again with
+ * WaitForTrigger set to false.
+ *)
+procedure TRelativeTimer.Start(WaitForTrigger: boolean = false);
begin
- RelativeTimeOffset := GetTime();
- Paused := true;
+ case (State) of
+ rtsStopped, rtsPaused: begin
+ if (WaitForTrigger) then
+ begin
+ State := rtsWait;
+ end
+ else
+ begin
+ State := rtsRunning;
+ AbsoluteTime := SDL_GetTicks();
+ end;
+ end;
+
+ rtsWait: begin
+ if (not WaitForTrigger) then
+ begin
+ State := rtsRunning;
+ AbsoluteTime := SDL_GetTicks();
+ RelativeTime := 0;
+ end;
+ end;
+ end;
end;
-procedure TRelativeTimer.Resume();
+(**
+ * Pauses the timer and leaves the counter untouched.
+ *)
+procedure TRelativeTimer.Pause();
begin
- AbsoluteTime := SDL_GetTicks();
- Paused := false;
+ if (State = rtsRunning) then
+ begin
+ // Important: GetTime() must be called in running state
+ RelativeTime := GetTime();
+ State := rtsPaused;
+ end;
end;
-(*
- * Returns the counter of the timer.
- * If in TriggerMode it will return 0 and start the counter on the first call.
+(**
+ * Stops the timer and sets its counter to 0.
*)
-function TRelativeTimer.GetTime: real;
+procedure TRelativeTimer.Stop();
begin
- // initialize absolute time on first call in triggered mode
- if (TriggerMode and (AbsoluteTime = 0)) then
+ if (State <> rtsStopped) then
begin
- AbsoluteTime := SDL_GetTicks();
- Result := RelativeTimeOffset;
- Exit;
+ State := rtsStopped;
+ RelativeTime := 0;
end;
-
- if Paused then
- Result := RelativeTimeOffset
- else
- Result := RelativeTimeOffset + (SDL_GetTicks() - AbsoluteTime) / cSDLCorrectionRatio;
end;
-(*
- * Returns the counter of the timer and resets the counter to 0 afterwards.
- * Note: In TriggerMode the counter will not be stopped as with Reset().
+(**
+ * Returns the current counter of the timer.
+ * If WaitForTrigger was true in Start() the timer will be started
+ * if it was not already running.
*)
-function TRelativeTimer.GetAndResetTime(): real;
+function TRelativeTimer.GetTime(): real;
begin
- Result := GetTime();
- SetTime(0);
+ case (State) of
+ rtsStopped, rtsPaused:
+ Result := RelativeTime;
+ rtsRunning:
+ Result := RelativeTime + (SDL_GetTicks() - AbsoluteTime) / cSDLCorrectionRatio;
+ rtsWait: begin
+ // start triggered
+ State := rtsRunning;
+ AbsoluteTime := SDL_GetTicks();
+ Result := RelativeTime;
+ end;
+ end;
end;
-(*
- * Sets the timer to the given time. This will trigger in TriggerMode if
- * Trigger is set to true. Otherwise the counter's state will not change.
+(**
+ * Sets the counter of the timer.
+ * If WaitForTrigger was true in Start() the timer will be started
+ * if it was not already running.
*)
-procedure TRelativeTimer.SetTime(Time: real; Trigger: boolean);
+procedure TRelativeTimer.SetTime(Time: real);
begin
- RelativeTimeOffset := Time;
- if ((not TriggerMode) or Trigger) then
- AbsoluteTime := SDL_GetTicks();
+ RelativeTime := Time;
+ AbsoluteTime := SDL_GetTicks();
+ // start triggered
+ if (State = rtsWait) then
+ State := rtsRunning;
end;
-(*
- * Resets the counter of the timer to 0.
- * If in TriggerMode the timer will not start counting until it is triggered again.
- *)
-procedure TRelativeTimer.Reset();
+function TRelativeTimer.GetState(): TRelativeTimerState;
begin
- RelativeTimeOffset := 0;
- if (TriggerMode) then
- AbsoluteTime := 0
- else
- AbsoluteTime := SDL_GetTicks();
+ Result := State;
end;
end.