source: trunk/DirectShowSpy/RunEvent.h @ 290

Last change on this file since 290 was 290, checked in by roman, 10 years ago

Added runtime event interface and generic property page

File size: 5.7 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2014
3// Created by Roman Ryltsov roman@alax.info, http://alax.info
4//
5// This source code is published to complement DirectShowSpy developer powertoy
6// and demonstrate the internal use of APIs and tricks powering the tool. It is
7// allowed to freely re-use the portions of the code in other projects, commercial
8// or otherwise (provided that you don’t pretend that you wrote the original tool).
9//
10// Please keep in mind that DirectShowSpy is a developer tool, it is strongly recommended
11// that it is not shipped with release grade software. It is allowed to distribute
12// DirectShowSpy if only it is not registered with Windows by default and either
13// used privately, or registered on specific throubleshooting request. The advice applies
14// to hooking methods used by DirectShowSpy in general as well.
15
16#pragma once
17
18#include "DirectShowSpy_i.h"
19
20////////////////////////////////////////////////////////////
21// CRunEventHelper
22
23class CRunEventHelper
24{
25public:
26
27        ////////////////////////////////////////////////////////
28        // CEventsT, CEvents
29
30        template <SIZE_T t_nItemCapacity = 256, SIZE_T t_nItemTextLength = 128>
31        class CEventsT
32        {
33        public:
34
35                ////////////////////////////////////////////////////
36                // CItem
37
38                class CItem
39                {
40                public:
41                        ULONGLONG m_nTime;
42                        CHAR m_pszText[t_nItemTextLength];
43
44                public:
45                // CItem
46                        CComVariantArray GetAsVariant(ULONGLONG nTime) const
47                        {
48                                CComVariantArray vValue;
49                                vValue.FromElements(2, CComVariant((LONG) (nTime - m_nTime) / 10000), CComVariant(m_pszText));
50                                return vValue;
51                        }
52                        BOOL SetAsVariant(CComVariantArray& vValue)
53                        {
54                                if(vValue.vt != (VT_ARRAY | VT_VARIANT))
55                                        return FALSE;
56                                _A(vValue.GetDimensionCount() == 1);
57                                CRoArrayT<CComVariantArray> Array;
58                                vValue.ToElementArray(Array);
59                                if(Array.GetCount() < 2)
60                                        return FALSE;
61                                m_nTime = Array[0].GetAsType(VT_I4).lVal * 10000;
62                                strncpy_s(m_pszText, CW2A(Array[1].GetAsType(VT_BSTR).bstrVal), _TRUNCATE);
63                                return TRUE;
64                        }
65                        BOOL SetAsVariant(VARIANT vValue)
66                        {
67                                return SetAsVariant(reinterpret_cast<CComVariantArray&>(vValue));
68                        }
69                        CString GetText(ULONGLONG nTime) const
70                        {
71                                CString sText;
72                                sText.AppendFormat(_T("%Id"), (LONG) (nTime - m_nTime));
73                                sText.AppendChar(_T('\t'));
74                                sText.Append(CA2CT(m_pszText));
75                                return sText;
76                        }
77                };
78
79        private:
80                mutable CRoLightCriticalSection m_DataCriticalSection;
81                BOOL m_bCapture;
82                CItem m_pItems[t_nItemCapacity];
83                SIZE_T m_nItemIndex;
84                SIZE_T m_nItemCount;
85                BOOL m_bTrace;
86                SIZE_T m_nTraceItemCount;
87
88        public:
89        // CEventsT
90                CEventsT() :
91                        m_bCapture(FALSE),
92                        m_bTrace(FALSE)
93                {
94                }
95                static SIZE_T GetCapacity()
96                {
97                        return t_nItemCapacity;
98                }
99                BOOL IsCapture() const
100                {
101                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
102                        return m_bCapture;
103                }
104                VOID SetCapture(BOOL bCapture)
105                {
106                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
107                        if(m_bCapture == bCapture)
108                                return;
109                        m_bCapture = bCapture;
110                        if(bCapture)
111                        {
112                                m_nItemIndex = 0;
113                                m_nItemCount = 0;
114                        }
115                }
116                VOID AddItemV(ULONGLONG nTime, LPCSTR pszFormat, va_list Arguments)
117                {
118                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
119                        if(!m_bCapture)
120                                return;
121                        CItem& Item = m_pItems[m_nItemIndex];
122                        Item.m_nTime = nTime;
123                        vsprintf_s(Item.m_pszText, pszFormat, Arguments);
124                        if(m_nItemCount < t_nItemCapacity)
125                                m_nItemCount++;
126                        ++m_nItemIndex %= t_nItemCapacity;
127                        if(m_bTrace && m_nTraceItemCount)
128                                m_nTraceItemCount--;
129                }
130                VOID AddItem(ULONGLONG nTime, LPCSTR pszFormat, ...)
131                {
132                        va_list Arguments;
133                        va_start(Arguments, pszFormat);
134                        AddItemV(pszFormat, Arguments);
135                        va_end(Arguments);
136                }
137                VOID AddItem(LPCSTR pszFormat, ...)
138                {
139                        va_list Arguments;
140                        va_start(Arguments, pszFormat);
141                        AddItemV(CMsAccurateFileTime::GetTime(), pszFormat, Arguments);
142                        va_end(Arguments);
143                }
144                CComVariantArray GetAsVariant() const
145                {
146                        CComVariantArray vValue;
147                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
148                        if(m_bCapture && m_nItemCount)
149                        {
150                                const ULONGLONG nTime = CMsAccurateFileTime::GetTime();
151                                CRoArrayT<CComVariantArray> Array;
152                                Array.SetCount(0, (INT) m_nItemCount);
153                                for(SIZE_T nItemIndex = 0; nItemIndex < m_nItemCount; nItemIndex++)
154                                {
155                                        const CItem& Item = m_pItems[((m_nItemIndex - 1) - nItemIndex + t_nItemCapacity) % t_nItemCapacity];
156                                        Array.Add(Item.GetAsVariant(nTime));
157                                }
158                                vValue.FromElementArray(Array);
159                        }
160                        return vValue;
161                }
162                SIZE_T GetText(CRoArrayT<CString>& Array) const
163                {
164                        _A(Array.IsEmpty());
165                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
166                        if(m_bCapture && m_nItemCount)
167                        {
168                                const ULONGLONG nTime = CMsAccurateFileTime::GetTime();
169                                Array.SetCount(0, (INT) m_nItemCount);
170                                for(SIZE_T nItemIndex = 0; nItemIndex < m_nItemCount; nItemIndex++)
171                                {
172                                        const CItem& Item = m_pItems[((m_nItemIndex - 1) - nItemIndex + t_nItemCapacity) % t_nItemCapacity];
173                                        Array.Add(Item.GetText(nTime));
174                                }
175                        }
176                        return Array.GetCount();
177                }
178                BOOL IsTrace() const
179                {
180                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
181                        return m_bTrace && !m_nTraceItemCount;
182                }
183                VOID SetTrace(BOOL bTrace, SIZE_T nTraceItemCount = 0)
184                {
185                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
186                        if(bTrace)
187                        {
188                                if(m_bTrace)
189                                        return; // Stick to Existing Schedule
190                                m_bTrace = TRUE;
191                                m_nTraceItemCount = nTraceItemCount;
192                        } else
193                                m_bTrace = FALSE;
194                }
195        };
196
197        typedef CEventsT<> CEvents;
198
199public:
200// CRunEventHelper
201};
Note: See TracBrowser for help on using the repository browser.