2009-06-17 Jeffrey Stedfast <fejj@novell.com>
[moon.git] / src / clock.h
blobb6b4b16feb65705442620853bfbd45edc91149b3
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 */
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 GetHasStarted () { return has_started; }
197 bool GetWasStopped () { return was_stopped; }
198 void ClearHasStarted () { has_started = false; }
199 TimeManager* GetTimeManager () { return time_manager; }
201 TimeSpan begin_time;
203 enum ClockState {
204 Active, /* time is progressing. each tick results in a property value changing */
205 Filling, /* time is progressing. each tick results in NO property value changing */
206 Stopped /* time is no longer progressing */
208 ClockState GetClockState () { return state; }
210 // ClockController methods
211 virtual void Begin (TimeSpan parentTime);
212 void Pause ();
213 void Resume ();
214 virtual void Seek (TimeSpan timespan);
215 virtual void SeekAlignedToLastTick (TimeSpan timespan);
216 virtual void SkipToFill ();
217 virtual void Stop ();
219 void BeginOnTick (bool begin = true);
220 bool GetBeginOnTick () { return begin_on_tick; }
222 void SetRootParentTime (TimeSpan parentTime);
224 /* these shouldn't be used. they're called by the TimeManager and parent Clocks */
225 virtual void RaiseAccumulatedEvents ();
226 virtual void RaiseAccumulatedCompleted ();
227 virtual void ExtraRepeatAction () {};
228 virtual bool UpdateFromParentTime (TimeSpan parentTime);
229 void SetParentClock (ClockGroup *parent) { parent_clock = parent; }
230 virtual void SetTimeManager (TimeManager *manager) { time_manager = manager; }
231 virtual void Reset ();
233 // Events you can AddHandler to
234 const static int CurrentTimeInvalidatedEvent;
235 const static int CurrentStateInvalidatedEvent;
236 const static int CompletedEvent;
238 protected:
239 virtual ~Clock ();
241 TimeSpan ComputeNewTime ();
243 void FillOnNextTick ();
245 void SetClockState (ClockState state);
246 void SetCurrentTime (TimeSpan ts);
248 void Completed ();
250 // events to queue up
251 enum {
252 CURRENT_STATE_INVALIDATED = 0x01,
253 CURRENT_TIME_INVALIDATED = 0x02
255 void QueueEvent (int event);
257 bool calculated_natural_duration;
258 Duration natural_duration;
260 TimeSpan root_parent_time;
261 bool begin_on_tick;
263 // the start time of the current pause
264 TimeSpan begin_pause_time;
266 // the total amount of pause time we've accumulated
267 TimeSpan accumulated_pause_time;
269 ClockState state;
271 double progress;
273 TimeSpan current_time;
275 bool seeking;
276 TimeSpan seek_time;
278 private:
279 bool emit_completed;
280 bool has_completed;
281 TimeManager *time_manager;
282 ClockGroup *parent_clock;
284 bool is_paused;
286 bool has_started;
287 bool was_stopped;
288 Timeline *timeline;
289 int queued_events;
291 // for clocks with repeatbehavior that's not Forever and
292 // durations that aren't forever, this represents the time at
293 // which we'll hit our Fill.
294 TimeSpan fillTime;
298 /* @Namespace=None,ManagedDependencyProperties=None */
299 class ClockGroup : public Clock {
300 public:
301 ClockGroup (TimelineGroup *timeline, bool timeManagerClockGroup = false);
303 void AddChild (Clock *clock);
304 void RemoveChild (Clock *clock);
305 bool IsIdle () { return idle_hint; };
307 virtual void SetTimeManager (TimeManager *manager);
309 virtual void Begin (TimeSpan parentTime);
310 virtual void Seek (TimeSpan timespan);
311 virtual void SkipToFill ();
312 virtual void Stop ();
314 /* these shouldn't be used. they're called by the TimeManager and parent Clocks */
315 virtual void RaiseAccumulatedEvents ();
316 virtual void RaiseAccumulatedCompleted ();
318 virtual bool UpdateFromParentTime (TimeSpan parentTime);
320 GList *child_clocks;
322 virtual void Reset ();
324 protected:
325 virtual ~ClockGroup ();
327 private:
328 TimelineGroup *timeline;
329 bool idle_hint;
330 bool timemanager_clockgroup;
333 #endif /* MOON_CLOCK_H */