Update UNRAR.H
[xy_vsfilter.git] / src / filters / BaseClasses / dsschedule.h
bloba3940cfc6692649c7e23fe506bce1e28215b3c40
1 //------------------------------------------------------------------------------
2 // File: DSSchedule.h (replaces DirectX 8's schedule.h)
3 //
4 // Desc: DirectShow base classes.
5 //
6 // Copyright (c) 1996-2002 Microsoft Corporation. All rights reserved.
7 //------------------------------------------------------------------------------
10 #ifndef __CAMSchedule__
11 #define __CAMSchedule__
13 class CAMSchedule : private CBaseObject
15 public:
16 virtual ~CAMSchedule();
17 // ev is the event we should fire if the advise time needs re-evaluating
18 CAMSchedule( HANDLE ev );
20 DWORD GetAdviseCount();
21 REFERENCE_TIME GetNextAdviseTime();
23 // We need a method for derived classes to add advise packets, we return the cookie
24 DWORD_PTR AddAdvisePacket( const REFERENCE_TIME & time1, const REFERENCE_TIME & time2, HANDLE h, BOOL periodic );
25 // And a way to cancel
26 HRESULT Unadvise(DWORD_PTR dwAdviseCookie);
28 // Tell us the time please, and we'll dispatch the expired events. We return the time of the next event.
29 // NB: The time returned will be "useless" if you start adding extra Advises. But that's the problem of
30 // whoever is using this helper class (typically a clock).
31 REFERENCE_TIME Advise( const REFERENCE_TIME & rtTime );
33 // Get the event handle which will be set if advise time requires re-evaluation.
34 HANDLE GetEvent() const { return m_ev; }
36 private:
37 // We define the nodes that will be used in our singly linked list
38 // of advise packets. The list is ordered by time, with the
39 // elements that will expire first at the front.
40 class CAdvisePacket
42 public:
43 CAdvisePacket()
46 CAdvisePacket * m_next;
47 DWORD_PTR m_dwAdviseCookie;
48 REFERENCE_TIME m_rtEventTime; // Time at which event should be set
49 REFERENCE_TIME m_rtPeriod; // Periodic time
50 HANDLE m_hNotify; // Handle to event or semephore
51 BOOL m_bPeriodic; // TRUE => Periodic event
53 CAdvisePacket( CAdvisePacket * next, LONGLONG time ) : m_next(next), m_rtEventTime(time)
56 void InsertAfter( CAdvisePacket * p )
58 p->m_next = m_next;
59 m_next = p;
62 int IsZ() const // That is, is it the node that represents the end of the list
63 { return m_next == 0; }
65 CAdvisePacket * RemoveNext()
67 CAdvisePacket *const next = m_next;
68 CAdvisePacket *const new_next = next->m_next;
69 m_next = new_next;
70 return next;
73 void DeleteNext()
75 delete RemoveNext();
78 CAdvisePacket * Next() const
80 CAdvisePacket * result = m_next;
81 if (result->IsZ()) result = 0;
82 return result;
85 DWORD_PTR Cookie() const
86 { return m_dwAdviseCookie; }
89 // Structure is:
90 // head -> elmt1 -> elmt2 -> z -> null
91 // So an empty list is: head -> z -> null
92 // Having head & z as links makes insertaion,
93 // deletion and shunting much easier.
94 CAdvisePacket head, z; // z is both a tail and a sentry
96 volatile DWORD_PTR m_dwNextCookie; // Strictly increasing
97 volatile DWORD m_dwAdviseCount; // Number of elements on list
99 CCritSec m_Serialize;
101 // AddAdvisePacket: adds the packet, returns the cookie (0 if failed)
102 DWORD_PTR AddAdvisePacket( CAdvisePacket * pPacket );
103 // Event that we should set if the packed added above will be the next to fire.
104 const HANDLE m_ev;
106 // A Shunt is where we have changed the first element in the
107 // list and want it re-evaluating (i.e. repositioned) in
108 // the list.
109 void ShuntHead();
111 // Rather than delete advise packets, we cache them for future use
112 CAdvisePacket * m_pAdviseCache;
113 DWORD m_dwCacheCount;
114 enum { dwCacheMax = 5 }; // Don't bother caching more than five
116 void Delete( CAdvisePacket * pLink );// This "Delete" will cache the Link
118 // Attributes and methods for debugging
119 public:
120 #ifdef DEBUG
121 void DumpLinkedList();
122 #else
123 void DumpLinkedList() {}
124 #endif
128 #endif // __CAMSchedule__