1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * clock.h: Clock management
6 * Moonlight List (moonlight-list@lists.ximian.com)
8 * Copyright 2007 Novell, Inc. (http://www.novell.com)
10 * See the LICENSE file included with the distribution for details.
18 #include "collection.h"
22 * TimeSpan: signed int64 value, 100-nanosecond units (10 000 000 ticks per second)
23 * Pts: unsigned int64 value, same units as TimeSpan
28 typedef guint64 TimePts
;
30 #define TIMESPANTICKS_IN_SECOND 10000000
31 #define TIMESPANTICKS_IN_SECOND_FLOAT 10000000.0
33 #define TimeSpan_FromSeconds(s) ((TimeSpan)(s) * TIMESPANTICKS_IN_SECOND)
34 #define TimeSpan_ToSeconds(s) ((TimeSpan)(s) / TIMESPANTICKS_IN_SECOND)
36 #define TimeSpan_FromSecondsFloat(s) ((TimeSpan)((s) * TIMESPANTICKS_IN_SECOND_FLOAT))
37 #define TimeSpan_ToSecondsFloat(s) (((TimeSpan)(s)) / TIMESPANTICKS_IN_SECOND_FLOAT)
39 #define TimeSpan_ToPts(s) ((guint64) (s))
40 #define TimeSpan_FromPts(s) ((TimeSpan) (s))
42 #define PTS_PER_MILLISECOND 10000
44 #define MilliSeconds_ToPts(s) ((guint64) (s) * PTS_PER_MILLISECOND)
45 #define MilliSeconds_FromPts(s) ((s) / PTS_PER_MILLISECOND)
48 /* @Namespace=System.Windows */
56 Duration (TimeSpan duration
)
58 timespan (duration
) { }
60 Duration (const Duration
&duration
)
63 timespan
= duration
.timespan
;
66 Duration (DurationKind kind
) : k(kind
) { };
68 bool HasTimeSpan () { return k
== TIMESPAN
; }
69 TimeSpan
GetTimeSpan() { return timespan
; }
71 bool IsAutomatic () { return k
== AUTOMATIC
; }
72 bool IsForever () { return k
== FOREVER
; }
74 static Duration Automatic
;
75 static Duration Forever
;
77 // XXX tons more operators here
78 bool operator!= (const Duration
&v
) const
83 bool operator== (const Duration
&v
) const
89 return timespan
== v
.timespan
;
94 gint32
ToSeconds () { return TimeSpan_ToSeconds (timespan
); }
96 double ToSecondsFloat () { return TimeSpan_ToSecondsFloat (timespan
); }
98 // This should live in a TimeSpan class, but oh well.. */
99 static Duration
FromSeconds (int seconds
) { return Duration (TimeSpan_FromSeconds (seconds
)); }
100 static Duration
FromSecondsFloat (double seconds
) { return Duration (TimeSpan_FromSecondsFloat (seconds
)); }
109 /* @IncludeInKinds */
110 /* @Namespace=System.Windows.Media.Animation */
111 struct RepeatBehavior
{
118 RepeatBehavior (const RepeatBehavior
&repeat
)
121 duration
= repeat
.duration
;
122 count
= repeat
.count
;
125 RepeatBehavior (double count
)
129 RepeatBehavior (RepeatKind kind
) : k(kind
) { }
131 RepeatBehavior (TimeSpan duration
)
137 static RepeatBehavior Forever
;
139 bool operator!= (const RepeatBehavior
&v
) const
141 return !(*this == v
);
144 bool operator== (const RepeatBehavior
&v
) const
150 case DURATION
: return duration
== v
.duration
;
151 case COUNT
: return count
== v
.count
;
152 case FOREVER
: return true;
155 /* not reached. quiet g++ -Wall */
159 double GetCount () { return count
; }
160 TimeSpan
GetDuration() { return duration
; }
162 bool HasCount() { return k
== COUNT
; }
163 bool HasDuration () { return k
== DURATION
; }
165 bool IsForever () { return k
== FOREVER
; }
176 // Clocks and timelines
183 /* our clock is a mixture of the WPF Clock and ClockController
184 classes. as such, all clocks are controllable */
185 /* @Namespace=None,ManagedDependencyProperties=None */
186 class Clock
: public DependencyObject
{
188 Clock (Timeline
*timeline
);
190 ClockGroup
* GetParentClock () { return parent_clock
; }
191 double GetCurrentProgress () { return progress
; }
192 virtual TimeSpan
GetCurrentTime () { return current_time
; }
193 Timeline
* GetTimeline () { return timeline
; }
194 Duration
GetNaturalDuration ();
195 bool GetIsPaused () { return is_paused
; }
196 bool GetIsSeeking () { return is_seeking
; }
197 bool GetHasStarted () { return has_started
; }
198 bool GetWasStopped () { return was_stopped
; }
199 void ClearHasStarted () { has_started
= false; }
200 TimeManager
* GetTimeManager () { return time_manager
; }
205 Active
, /* time is progressing. each tick results in a property value changing */
206 Filling
, /* time is progressing. each tick results in NO property value changing */
207 Stopped
/* time is no longer progressing */
209 ClockState
GetClockState () { return state
; }
211 // ClockController methods
212 virtual void Begin (TimeSpan parentTime
);
215 virtual void Seek (TimeSpan timespan
);
216 virtual void SeekAlignedToLastTick (TimeSpan timespan
);
217 virtual void SkipToFill ();
218 virtual void Stop ();
220 void BeginOnTick (bool begin
= true);
221 bool GetBeginOnTick () { return begin_on_tick
; }
223 void SetRootParentTime (TimeSpan parentTime
);
225 /* these shouldn't be used. they're called by the TimeManager and parent Clocks */
226 virtual void RaiseAccumulatedEvents ();
227 virtual void RaiseAccumulatedCompleted ();
228 virtual void ExtraRepeatAction () {};
229 virtual bool UpdateFromParentTime (TimeSpan parentTime
);
230 void SetParentClock (ClockGroup
*parent
) { parent_clock
= parent
; }
231 virtual void SetTimeManager (TimeManager
*manager
) { time_manager
= manager
; }
232 virtual void Reset ();
234 // Events you can AddHandler to
235 const static int CurrentTimeInvalidatedEvent
;
236 const static int CurrentStateInvalidatedEvent
;
237 const static int CompletedEvent
;
242 TimeSpan
ComputeNewTime ();
244 void FillOnNextTick ();
246 void SetClockState (ClockState state
);
247 void SetCurrentTime (TimeSpan ts
);
249 void CalculateFillTime ();
253 // events to queue up
255 CURRENT_STATE_INVALIDATED
= 0x01,
256 CURRENT_TIME_INVALIDATED
= 0x02
258 void QueueEvent (int event
);
260 bool calculated_natural_duration
;
261 Duration natural_duration
;
263 TimeSpan root_parent_time
;
266 // the start time of the current pause
267 TimeSpan begin_pause_time
;
269 // the total amount of pause time we've accumulated
270 TimeSpan accumulated_pause_time
;
276 TimeSpan current_time
;
283 TimeManager
*time_manager
;
284 ClockGroup
*parent_clock
;
294 // for clocks with repeatbehavior that's not Forever and
295 // durations that aren't forever, this represents the time at
296 // which we'll hit our Fill.
301 /* @Namespace=None,ManagedDependencyProperties=None */
302 class ClockGroup
: public Clock
{
304 ClockGroup (TimelineGroup
*timeline
, bool timeManagerClockGroup
= false);
306 void AddChild (Clock
*clock
);
307 void RemoveChild (Clock
*clock
);
309 virtual void SetTimeManager (TimeManager
*manager
);
311 virtual void Begin (TimeSpan parentTime
);
312 virtual void SkipToFill ();
313 virtual void Stop ();
315 /* these shouldn't be used. they're called by the TimeManager and parent Clocks */
316 virtual void RaiseAccumulatedEvents ();
317 virtual void RaiseAccumulatedCompleted ();
319 virtual bool UpdateFromParentTime (TimeSpan parentTime
);
323 virtual void Reset ();
326 virtual ~ClockGroup ();
329 TimelineGroup
*timeline
;
330 bool timemanager_clockgroup
;
333 #endif /* MOON_CLOCK_H */