1/*
2 * Copyright 2009, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _MEDIA_EVENT_LOOPER_H
6#define _MEDIA_EVENT_LOOPER_H
7
8
9#include <MediaNode.h>
10#include <TimedEventQueue.h>
11
12
13/*! BMediaEventLooper spawns a thread which calls WaitForMessage, pushes
14	BMediaNode messages onto its BTimedEventQueues. informs you when it
15	is time to handle an event. Report your event latency, push other events
16	onto the queue and override HandleEvent to do your work.
17*/
18class BMediaEventLooper : public virtual BMediaNode {
19protected:
20	enum run_state {
21		B_IN_DISTRESS		= -1,
22		B_UNREGISTERED,
23		B_STOPPED,
24		B_STARTED,
25		B_QUITTING,
26		B_TERMINATED,
27		B_USER_RUN_STATES	= 0x4000
28	};
29
30protected:
31	explicit					BMediaEventLooper(
32									uint32 apiVersion = B_BEOS_VERSION);
33	virtual						~BMediaEventLooper();
34
35protected:
36	// BMediaNode interface
37	virtual	void				NodeRegistered();
38	virtual	void				Start(bigtime_t performanceTime);
39	virtual	void				Stop(bigtime_t performanceTime,
40									bool immediate);
41	virtual	void				Seek(bigtime_t mediaTime,
42									bigtime_t performanceTime);
43	virtual	void				TimeWarp(bigtime_t atRealTime,
44									bigtime_t toPerformanceTime);
45	virtual	status_t			AddTimer(bigtime_t atPerformanceTime,
46									int32 cookie);
47	virtual	void 				SetRunMode(run_mode mode);
48
49protected:
50	// BMediaEventLooper Hook functions
51
52	// NOTE: You must override this method to handle your events!
53	// You should not call HandleEvent directly.
54	virtual void				HandleEvent(const media_timed_event* event,
55									bigtime_t lateness,
56									bool realTimeEvent = false) = 0;
57
58	// Override this method to properly clean up any custom events you have
59	// added to your event queue.
60	virtual void				CleanUpEvent(const media_timed_event* event);
61
62	// NOTE: Called in offline mode to determine the current time of the node.
63	// Update your internal information whenever it changes.
64	virtual	bigtime_t			OfflineTime();
65
66	// NOTE: Override this method only if you know what you are doing!
67	// The default control loop function waits for messages, pops events
68	// off the queue and calls DispatchEvent.
69	virtual	void				ControlLoop();
70
71			thread_id			ControlThread();
72
73protected:
74			BTimedEventQueue* 	EventQueue();
75			BTimedEventQueue*	RealTimeQueue();
76
77			int32				Priority() const;
78			int32				RunState() const;
79			bigtime_t			EventLatency() const;
80			bigtime_t			BufferDuration() const;
81			bigtime_t			SchedulingLatency() const;
82
83	// NOTE: Use the priority constants from OS.h or suggest_thread_priority
84	// from scheduler.h. The passed priority will be clamped to be in range 5
85	// to 120.
86			status_t			SetPriority(int32 priority);
87			void				SetRunState(run_state state);
88			void				SetEventLatency(bigtime_t latency);
89			void				SetBufferDuration(bigtime_t duration);
90			void				SetOfflineTime(bigtime_t offTime);
91
92	// Spawns and resumes the control thread - must be called from
93	// NodeRegistered().
94			void				Run();
95
96	// Quits the control thread - must be called from your destructor.
97			void				Quit();
98
99	// Calls HandleEvent and does BMediaEventLooper event work
100			void				DispatchEvent(const media_timed_event* event,
101									bigtime_t lateness,
102									bool realTimeEvent = false);
103
104private:
105	static	int32				_ControlThreadStart(void* cookie);
106	static	void				_CleanUpEntry(const media_timed_event* event,
107									void* context);
108			void				_DispatchCleanUp(
109									const media_timed_event* event);
110
111private:
112			BTimedEventQueue	fEventQueue;
113			BTimedEventQueue	fRealTimeQueue;
114			thread_id			fControlThread;
115			int32				fCurrentPriority;
116			int32				fSetPriority;
117			vint32				fRunState;
118			bigtime_t			fEventLatency;
119			bigtime_t			fSchedulingLatency;
120			bigtime_t			fBufferDuration;
121			bigtime_t			fOfflineTime;
122			uint32				fApiVersion;
123
124protected:
125	virtual	status_t 	DeleteHook(BMediaNode * node);
126
127private:
128	// FBC padding and forbidden methods
129								BMediaEventLooper(const BMediaEventLooper&);
130			BMediaEventLooper&	operator=(const BMediaEventLooper&);
131
132	virtual	status_t		 	_Reserved_BMediaEventLooper_0(int32 arg, ...);
133	virtual	status_t 			_Reserved_BMediaEventLooper_1(int32 arg, ...);
134	virtual	status_t 			_Reserved_BMediaEventLooper_2(int32 arg, ...);
135	virtual	status_t 			_Reserved_BMediaEventLooper_3(int32 arg, ...);
136	virtual	status_t 			_Reserved_BMediaEventLooper_4(int32 arg, ...);
137	virtual	status_t 			_Reserved_BMediaEventLooper_5(int32 arg, ...);
138	virtual	status_t 			_Reserved_BMediaEventLooper_6(int32 arg, ...);
139	virtual	status_t 			_Reserved_BMediaEventLooper_7(int32 arg, ...);
140	virtual	status_t 			_Reserved_BMediaEventLooper_8(int32 arg, ...);
141	virtual	status_t 			_Reserved_BMediaEventLooper_9(int32 arg, ...);
142	virtual	status_t 			_Reserved_BMediaEventLooper_10(int32 arg, ...);
143	virtual	status_t 			_Reserved_BMediaEventLooper_11(int32 arg, ...);
144	virtual	status_t 			_Reserved_BMediaEventLooper_12(int32 arg, ...);
145	virtual	status_t 			_Reserved_BMediaEventLooper_13(int32 arg, ...);
146	virtual	status_t 			_Reserved_BMediaEventLooper_14(int32 arg, ...);
147	virtual	status_t 			_Reserved_BMediaEventLooper_15(int32 arg, ...);
148	virtual	status_t 			_Reserved_BMediaEventLooper_16(int32 arg, ...);
149	virtual	status_t 			_Reserved_BMediaEventLooper_17(int32 arg, ...);
150	virtual	status_t 			_Reserved_BMediaEventLooper_18(int32 arg, ...);
151	virtual	status_t 			_Reserved_BMediaEventLooper_19(int32 arg, ...);
152	virtual	status_t 			_Reserved_BMediaEventLooper_20(int32 arg, ...);
153	virtual	status_t 			_Reserved_BMediaEventLooper_21(int32 arg, ...);
154	virtual	status_t 			_Reserved_BMediaEventLooper_22(int32 arg, ...);
155	virtual	status_t 			_Reserved_BMediaEventLooper_23(int32 arg, ...);
156
157	bool						_reserved_bool_[4];
158	uint32						_reserved_BMediaEventLooper_[12];
159};
160
161#endif // _MEDIA_EVENT_LOOPER_H
162