2009-12-07 Rolf Bjarne Kvinge <RKvinge@novell.com>
[moon.git] / src / clock.h
blobbe7914a7815c72fddede0edbfdeeff2a00c9ce22
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * clock.h: Clock management
5 * Contact:
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.
14 #ifndef MOON_CLOCK_H
15 #define MOON_CLOCK_H
17 #include <glib.h>
18 #include "collection.h"
21 * Time units:
22 * TimeSpan: signed int64 value, 100-nanosecond units (10 000 000 ticks per second)
23 * Pts: unsigned int64 value, same units as TimeSpan
24 * Milliseconds
25 * Seconds
26 */
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)
47 /* @IncludeInKinds */
48 /* @Namespace=System.Windows */
49 struct Duration {
50 enum DurationKind {
51 TIMESPAN,
52 AUTOMATIC,
53 FOREVER
56 Duration (TimeSpan duration)
57 : k (TIMESPAN),
58 timespan (duration) { }
60 Duration (const Duration &duration)
62 k = duration.k;
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
80 return !(*this == v);
83 bool operator== (const Duration &v) const
85 if (v.k != k)
86 return false;
88 if (v.k == TIMESPAN)
89 return timespan == v.timespan;
91 return true;
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)); }
102 private:
103 DurationKind k;
104 gint32 padding;
105 TimeSpan timespan;
109 /* @IncludeInKinds */
110 /* @Namespace=System.Windows.Media.Animation */
111 struct RepeatBehavior {
112 enum RepeatKind {
113 COUNT,
114 DURATION,
115 FOREVER
118 RepeatBehavior (const RepeatBehavior &repeat)
120 k = repeat.k;
121 duration = repeat.duration;
122 count = repeat.count;
125 RepeatBehavior (double count)
126 : k (COUNT),
127 count (count) { }
129 RepeatBehavior (RepeatKind kind) : k(kind) { }
131 RepeatBehavior (TimeSpan duration)
132 : k (DURATION),
133 duration (duration)
137 static RepeatBehavior Forever;
139 bool operator!= (const RepeatBehavior &v) const
141 return !(*this == v);
144 bool operator== (const RepeatBehavior &v) const
146 if (v.k != k)
147 return false;
149 switch (k) {
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 */
156 return false;
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; }
167 private:
168 RepeatKind k;
169 gint32 padding;
170 double count;
171 TimeSpan duration;
176 // Clocks and timelines
179 class TimeManager;
180 class Timeline;
181 class TimelineGroup;
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,ManagedEvents=Manual */
186 class Clock : public DependencyObject {
187 public:
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; }
202 TimeSpan begin_time;
204 enum ClockState {
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);
213 void Pause ();
214 void Resume ();
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;
239 virtual void Dispose ();
241 protected:
242 virtual ~Clock ();
244 TimeSpan ComputeNewTime ();
246 void FillOnNextTick ();
248 void SetClockState (ClockState state);
249 void SetCurrentTime (TimeSpan ts);
251 void CalculateFillTime ();
253 void Completed ();
255 // events to queue up
256 enum {
257 CURRENT_STATE_INVALIDATED = 0x01,
258 CURRENT_TIME_INVALIDATED = 0x02
260 void QueueEvent (int event);
262 bool calculated_natural_duration;
263 Duration natural_duration;
265 TimeSpan root_parent_time;
266 bool begin_on_tick;
268 // the start time of the current pause
269 TimeSpan begin_pause_time;
271 // the total amount of pause time we've accumulated
272 TimeSpan accumulated_pause_time;
274 ClockState state;
276 double progress;
278 TimeSpan current_time;
280 TimeSpan seek_time;
282 private:
283 bool emit_completed;
284 bool has_completed;
285 TimeManager *time_manager;
286 ClockGroup *parent_clock;
288 bool is_paused;
289 bool is_seeking;
291 bool has_started;
292 bool was_stopped;
293 Timeline *timeline;
294 int queued_events;
296 // for clocks with repeatbehavior that's not Forever and
297 // durations that aren't forever, this represents the time at
298 // which we'll hit our Fill.
299 TimeSpan fillTime;
303 /* @Namespace=None,ManagedDependencyProperties=None */
304 class ClockGroup : public Clock {
305 public:
306 ClockGroup (TimelineGroup *timeline, bool timeManagerClockGroup = false);
308 void AddChild (Clock *clock);
309 void RemoveChild (Clock *clock);
311 virtual void SetTimeManager (TimeManager *manager);
313 virtual void Begin (TimeSpan parentTime);
314 virtual void SkipToFill ();
315 virtual void Stop ();
317 /* these shouldn't be used. they're called by the TimeManager and parent Clocks */
318 virtual void RaiseAccumulatedEvents ();
319 virtual void RaiseAccumulatedCompleted ();
321 virtual bool UpdateFromParentTime (TimeSpan parentTime);
323 GList *child_clocks;
325 virtual void Reset ();
327 virtual void Dispose ();
329 protected:
330 virtual ~ClockGroup ();
332 private:
333 bool timemanager_clockgroup;
336 #endif /* MOON_CLOCK_H */