TNB Library
TnbCommunicationReporter.h
[詳解]
1#pragma once
12#include "TnbAbstractReport.h"
13#include "TnbThread.h"
14#include "TnbCommunication.h"
15
16
17
18//TNB Library
19namespace TNB
20{
21
22
23
46{
47 DEFSUPER(CAbstractReport);
48public:
49
58 explicit CCommunicationReporter(ICommunication* pComm, DWORD dwInterfaceId = 0) : _super(dwInterfaceId)
59 {
60 m_piCommunication = pComm; // 通信クラス
61 m_lpbReceiveWork = NULL; // 受信用バッファアドレス
62 m_dwPollingTiming = 1; // 間隔
63 m_boIsConnect = false;
64 m_receivePacketMaxSize = E_ReceiveDataBufferSize;
65 m_hasOndemandStop = false;
66 }
67
70 {
71 if ( m_lpbReceiveWork != NULL )
72 {
73 delete[] m_lpbReceiveWork;
74 m_lpbReceiveWork = NULL;
75 }
76 }
77
82 virtual CStr GetReportName(void) const
83 {
84 return m_piCommunication->GetProperty().typeName;
85 }
86
92 virtual DWORD GetReportID(void) const
93 {
94 return m_piCommunication->GetProperty().typeId;
95 }
96
103 virtual bool IsAlive(void) const
104 {
105 return m_threadRecv.IsAlive() && m_piCommunication->IsOpened();
106 }
107
113 virtual bool IsConnect(void) const
114 {
115 return m_piCommunication->IsConnect();
116 }
117
128 virtual void SetIdleEventMode(int iInterval = 0)
129 {
130 _super::SetIdleEventMode(iInterval);
131 }
132
142 void SetReceivePollingTiming(DWORD dwPollingTiming)
143 {
144 m_dwPollingTiming = dwPollingTiming;
145 }
146
153 virtual bool Start(void)
154 {
155 if ( m_threadRecv.IsAlive() )
156 {
157 //スレッド停止
158 m_threadRecv.Stop();
159 }
160 if ( m_piCommunication->Open() )
161 {
162 const ICommunication::TProperty& param = m_piCommunication->GetProperty();
163 if ( param.receivePacketSize != INVALID_SIZE )
164 {
165 //サイズ固定だ
166 m_receivePacketMaxSize = param.receivePacketSize;
167 }
168 if ( m_lpbReceiveWork != NULL )
169 {
170 delete[] m_lpbReceiveWork;
171 }
172 m_lpbReceiveWork = new BYTE[m_receivePacketMaxSize];
173 //
174 m_threadRecv.SetRunner(this);
175 #ifdef _DEBUG
176 m_threadRecv.Start(CStr::Fmt(_T("%s:監視"), GetReportName()));
177 #else
178 m_threadRecv.Start();
179 #endif
180 return true;
181 }
182 return false;
183 }
184
189 virtual void Stop(void)
190 {
191 m_hasOndemandStop = true;
192 m_piCommunication->Close();
193 if ( m_threadRecv.IsAlive() )
194 {
195 //スレッド停止
196 m_threadRecv.Stop();
197 }
198 m_hasOndemandStop = false;
199 }
200
208 virtual bool Send(size_t dataSize, LPCVOID lpcvData)
209 {
210 if ( ! m_piCommunication->IsOpened() )
211 {
212 return false;
213 }
214 bool r = m_piCommunication->Send(dataSize, lpcvData) == dataSize;
215 if ( r )
216 {
217 _super::m_OnSend(dataSize, lpcvData);
218 }
219 return r;
220 }
221
226 virtual void Purge(void)
227 {
228 EXCLUSIVE( &m_syncReceive );
229 m_piCommunication->Purge();
230 }
231
237 {
238 return m_threadRecv;
239 }
240
241private:
242
244 enum
245 {
246 E_ReceiveDataBufferSize = 10000,
247 };
248 CSyncSection m_syncReceive;
249 CThread m_threadRecv;
250 ICommunication* m_piCommunication;
251 LPBYTE m_lpbReceiveWork;
252 DWORD m_dwPollingTiming;
253 bool m_boIsConnect;
254 bool m_hasOndemandStop;
255 size_t m_receivePacketMaxSize;
256
264 virtual DWORD Run(void)
265 {
266 CTickCount tick;
267 bool isReceived = true;
268 DWORD ec = 0;
269 //
270 while ( IsRunnable() )
271 {
272 if ( isReceived )
273 {
274 isReceived = false;
275 }
276 else if ( m_dwPollingTiming > 0 )
277 {
278 ::Sleep(m_dwPollingTiming);
279 }
280 //== 受信中排他ON
281 m_syncReceive.Lock();
282 ICommunication::EState s = m_piCommunication->Check();
283 ec = ::GetLastError();
284 if ( s == ICommunication::CLOSED )
285 {
286 m_syncReceive.Unlock();
287 break; //Closeされたら、終了
288 }
289 if ( s == ICommunication::OPENNING && m_boIsConnect )
290 {
291 //受信中排他OFF
292 m_syncReceive.Unlock();
293 //切断を通知。
295 m_boIsConnect = false;
296 continue;
297 }
298 if ( s == ICommunication::CONNECTING && ! m_boIsConnect )
299 {
300 //接続を通知。
302 {
303 break;
304 }
305 m_boIsConnect = true;
306 }
307 if ( m_piCommunication->CanReceive() )
308 {
309 size_t dwReceivedDataCount = INVALID_SIZE;
310 {
311 //---- 1Byte以上ある or わからない(INVALID_SIZE)。
312 if ( dwReceivedDataCount > m_receivePacketMaxSize )
313 {
314 dwReceivedDataCount = m_receivePacketMaxSize;
315 }
316 if ( m_lpbReceiveWork == NULL )
317 {
318 //受信中排他OFF
319 m_syncReceive.Unlock();
320 continue;
321 }
322 size_t dwReadBytes = m_piCommunication->Receive(dwReceivedDataCount, m_lpbReceiveWork);
323 //
324 if ( dwReadBytes == INVALID_SIZE )
325 {
326 //失敗
327 //受信中排他OFF
328 m_syncReceive.Unlock();
329 continue;
330 }
331 //コールバック関数へ通知。
332 if ( dwReadBytes > 0 )
333 {
334 //受信中排他OFF
335 m_syncReceive.Unlock();
336 CReportEvent ev(this);
337 ev.SetData(dwReadBytes, m_lpbReceiveWork);
338 if ( ! m_OnEvent(ev) )
339 {
340 break;
341 }
342 isReceived = true;
343 tick.Reset();
344 continue;
345 }
346 }
347 }
348 //受信中排他OFF
349 m_syncReceive.Unlock();
350 if ( _super::GetIdleInterval() > 0 )
351 {
352 //---- 受信データなし&IDLEイベント要求あり。
353 if ( tick.IsPassedAndReset(_super::GetIdleInterval()) )
354 {
355 //コールバック関数へ通知。
357 {
358 break;
359 }
360 }
361 }
362 }
363 //コールバック関数へ通知。
364 if ( m_boIsConnect )
365 {
366 m_boIsConnect = false;
367 //切断を通知。
369 }
370 m_piCommunication->Close();
371 ::SetLastError(ec);
372 if ( ! m_hasOndemandStop )
373 {
375 }
377 return 0;
378 }
379
381};
382
383
384
400template<typename COMM>
402{
403 DEFSUPER(CCommunicationReporter);
404public:
405
411 explicit CCommunicationReporterT(DWORD dwInterfaceId = 0) : _super(&m_comm, dwInterfaceId)
412 {
413 }
414
417 {
418 Stop();
419 }
420
427 {
428 return m_comm;
429 }
430
436 COMM* operator->(void)
437 {
438 return &m_comm;
439 }
440
446 const COMM& ReferCommunication(void) const
447 {
448 return m_comm;
449 }
450
456 const COMM* operator->(void) const
457 {
458 return &m_comm;
459 }
460
461private:
462 COMM m_comm;
463};
464
465
466
467}; // TNB
通信関係のヘッダ
通信関係のヘッダ
スレッド管理関係のヘッダ
通信アクセス抽象クラス
bool m_OnEvent(const CReportEvent &ev)
[内部] コールバック通知実行
通信レポータテンプレート
COMM * operator->(void)
[参照] 通信クラス参照.
const COMM * operator->(void) const
[参照] 通信クラス参照.
COMM & ReferCommunication(void)
[参照] 通信クラス参照.
virtual ~CCommunicationReporterT(void)
デストラクタ
CCommunicationReporterT(DWORD dwInterfaceId=0)
コンストラクタ
const COMM & ReferCommunication(void) const
[参照] 通信クラス参照.
通信レポータクラス
CThreadStatus & ReferThreadStatus(void)
[参照] 受信スレッド状態参照.
virtual ~CCommunicationReporter(void)
デストラクタ
virtual void Stop(void)
[操作] 通信レポート停止.
virtual void SetIdleEventMode(int iInterval=0)
[設定] アイドルイベント設定
virtual bool Send(size_t dataSize, LPCVOID lpcvData)
[送信] データ送信
virtual CStr GetReportName(void) const
[取得] レポート名.
virtual DWORD GetReportID(void) const
[取得] レポート ID.
virtual void Purge(void)
[設定] パージ.
virtual bool IsConnect(void) const
[確認] 接続されているか
void SetReceivePollingTiming(DWORD dwPollingTiming)
[設定] 受信チェック間隔設定.
CCommunicationReporter(ICommunication *pComm, DWORD dwInterfaceId=0)
コンストラクタ
friend class CCommunicationReporterTest
フレンドクラス宣言
virtual bool IsAlive(void) const
[確認] Aliveチェック.
virtual bool Start(void)
[操作] 通信レポート開始.
通信受信イベント管理クラス
Definition: TnbReport.h:70
static CStrT Fmt(const TCHAR *lpszFormat,...)
[作成] 書式付き文字列作成
Definition: TnbStr.h:1206
Section排他管理クラス
Definition: TnbSync.h:125
virtual bool Lock(DWORD dwTime=INFINITE) const
[排他] ロック
Definition: TnbSync.h:148
virtual void Unlock(void) const
[排他] アンロック
Definition: TnbSync.h:155
スレッド状態管理クラス
Definition: TnbThread.h:128
bool IsAlive(void) const
[確認] スレッドが生きているか
Definition: TnbThread.h:177
スレッド管理クラス
Definition: TnbThread.h:316
bool SetRunner(IRunner *pRunner)
[設定] ランナー、設定
Definition: TnbThread.h:420
bool Stop(DWORD dwWait=15000)
[設定] スレッド停止 スレッドに対して停止要求します。
Definition: TnbThread.h:505
bool Start(LPCTSTR lpszName=NULL)
[設定] スレッド開始
Definition: TnbThread.h:618
経過時間管理クラス
Definition: TnbTickCount.h:57
bool IsPassedAndReset(DWORD dwTime, bool isNow=true)
[確認] 経過確認&リセット.
Definition: TnbTickCount.h:128
void Reset(void)
[設定] リセット.
Definition: TnbTickCount.h:82
#define EXCLUSIVE(CLS)
簡易排他制御マクロ.
Definition: TnbSync.h:788
TNB Library
Definition: TnbDoxyTitle.txt:2
@ ReportEvent_End
終了.
Definition: TnbReport.h:31
@ ReportEvent_IrregularEnd
不正終了.
Definition: TnbReport.h:35
@ ReportEvent_Connect
接続.
Definition: TnbReport.h:33
@ ReportEvent_Disconnect
切断.
Definition: TnbReport.h:34
@ ReportEvent_Idle
アイドル.
Definition: TnbReport.h:30
スレッド実行管理ランナーインターフェース
Definition: TnbThread.h:341
bool IsRunnable(void) const
[確認] 実行可能か否か
Definition: TnbThread.h:355
性能プロパティ型.
size_t receivePacketSize
受信パケットサイズ。INVALID_SIZE なら制限なし。
通信インターフェース
virtual EState Check(void) const
[確認] チェック.
virtual bool Open(void)=0
[処理] オープン.
virtual bool IsOpened(void) const =0
[確認] オープン確認.
virtual const TProperty & GetProperty(void) const =0
[取得] 性能取得.
virtual void Close(void)=0
[処理] クローズ.
virtual size_t Send(size_t size, LPCVOID P)=0
[処理] 送信.
virtual void Purge(void)
[処理] パージ.
virtual bool IsConnect(void) const
[確認] 接続確認.
virtual bool CanReceive(void) const
[確認] 受信可能確認.
virtual size_t Receive(size_t size, LPVOID _P)=0
[処理] 受信.
@ CONNECTING
オープン&接続状態
@ CLOSED
クローズ状態
@ OPENNING
オープン状態
friend class CReportEvent
パートナークラス宣言
Definition: TnbReport.h:228