文章目录 1.全局消息通信 MsgHandler.h 单元测试(QTest) MsgHandlerUnitTest.h MsgHandlerUnitTest.cpp 2.实例间通信 InstMsgHandler.h 单元测试 InstMsgHandlerUnitTest.h InstMsgHandlerUnitTest.cpp
1.全局消息通信
1. 适用于类与类单个对象实例之间的通信,多个对象需要酌情使用
2. 支持优先级触发
3. 支持附带参数
4. 支持异步执行
5. 使用方式可以查看下方单元测试代码
MsgHandler.h
# pragma once # include <functional>
# include <unordered_map>
# include <map>
# include <string>
# include "any.h" class MsgHandler {
# ifdef _DEBUG using MsgType = std:: string;
# else using MsgType = const char * ;
# endif friend class MsgHandlerUnitTest ;
public : static MsgHandler* GetInstance ( ) { static MsgHandler i; return & i; } void SetAsyncExecFunc ( std:: function< void ( std:: function< void ( ) > ) > func) { asyncExecFunc_ = func; } void SetMainExecFunc ( std:: function< void ( std:: function< void ( ) > ) > func) { mainExecFunc_ = func; } void TriggerMsg_ ( MsgType msg, std:: any info = std:: any{ } ) { ExecMsgHandler ( msg, defaultExecFunc_, info) ; } void AsyncExecMsg_ ( MsgType msg, std:: any info = std:: any{ } ) { if ( ! asyncExecFunc_) throw std:: runtime_error ( "dont set async exec func" ) ; ExecMsgHandler ( msg, asyncExecFunc_, info) ; } void MainExecMsg_ ( MsgType msg, std:: any info = std:: any{ } ) { if ( ! mainExecFunc_) throw std:: runtime_error ( "dont set main exec func" ) ; ExecMsgHandler ( msg, mainExecFunc_, info) ; } void RegisterMsgHandler_ ( MsgType msg, void * t, std:: function< void ( std:: any) > func, int priority = 0 ) { globalMsgHandler_[ msg] [ priority] . insert ( { t, func } ) ; } void RegisterMsgHandler_ ( MsgType msg, void * t, std:: function< void ( ) > func, int priority = 0 ) { globalMsgHandler_[ msg] [ priority] . insert ( { t, [ = ] ( std:: any) { func ( ) ; } } ) ; } void Deregister_ ( void * t) { for ( auto & msgHandler : globalMsgHandler_) { PriorityMap& priorityMap = msgHandler. second; for ( auto & priorityEntry : priorityMap) { HandlerMap& handlerMap = priorityEntry. second; handlerMap. erase ( t) ; } } }
private : void ExecMsgHandler ( MsgType msg, std:: function< void ( std:: function< void ( ) > ) > func, std:: any info = std:: any{ } ) { auto it = globalMsgHandler_. find ( msg) ; if ( it != globalMsgHandler_. end ( ) ) { PriorityMap& priorityMap = it-> second; for ( auto & priorityEntry : priorityMap) { HandlerMap& handlerMap = priorityEntry. second; for ( auto & handlerEntry : handlerMap) { std:: function< void ( std:: any) > & handler = handlerEntry. second; func ( [ & handler, info] { handler ( info) ; } ) ; } } } }
private : MsgHandler ( ) = default ; using HandlerMap = std:: unordered_map< void * , std:: function< void ( std:: any) >> ; using PriorityMap = std:: map< int , HandlerMap, std:: greater< int >> ; std:: function< void ( std:: function< void ( ) > ) > defaultExecFunc_ = [ ] ( std:: function< void ( ) > func) { func ( ) ; } ; std:: function< void ( std:: function< void ( ) > ) > asyncExecFunc_; std:: function< void ( std:: function< void ( ) > ) > mainExecFunc_; std:: unordered_map< MsgType, PriorityMap> globalMsgHandler_;
} ; # define RegisterMsgHandler ( msg, . . . ) MsgHandler :: GetInstance ( ) -> RegisterMsgHandler_ ( #msg, this , __VA_ARGS__)
# define TriggerMsg ( msg, . . . ) MsgHandler :: GetInstance ( ) -> TriggerMsg_ ( #msg, __VA_ARGS__)
# define AsyncExecMsg ( msg, . . . ) MsgHandler :: GetInstance ( ) -> AsyncExecMsg_ ( #msg, __VA_ARGS__)
# define MainExecMsg ( msg, . . . ) MsgHandler :: GetInstance ( ) -> MainExecMsg_ ( #msg, __VA_ARGS__)
# define Deregister ( ) MsgHandler :: GetInstance ( ) -> Deregister_ ( this )
单元测试(QTest)
MsgHandlerUnitTest.h
# include <QTest>
# include <vector> class MsgHandlerUnitTest : public QObject { Q_OBJECT
private slots: void initTestCase ( ) ; void cleanupTestCase ( ) ; void init ( ) ; void cleanup ( ) ; void RegisterTest ( ) ; void DeregisterTest ( ) ; void PriorityPreTest ( ) ; void PriorityTest ( ) ; void TriggerNoParamTest ( ) ; void TriggerHasParamTest ( ) ; void AsyncTriggerTest ( ) ; void MainTriggerTest ( ) ; void MemoryLeakTest ( ) ;
private : bool VarifyResult ( ) ;
private : std:: vector< bool > m_results;
} ;
MsgHandlerUnitTest.cpp
# include "MsgHandlerUnitTest.h"
# include "MsgHandler.h"
# include <QTimer> class RunnableTask : public QRunnable {
public : RunnableTask ( std:: function< void ( ) > func) : func_ ( func) { setAutoDelete ( true ) ; } void run ( ) { func_ ( ) ; }
private : std:: function< void ( ) > func_;
} ; class AsyncThreadPool {
public : void AddTask ( std:: function< void ( ) > func) { QThreadPool :: globalInstance ( ) -> start ( new RunnableTask ( func) ) ; }
public : static AsyncThreadPool* GetInstance ( ) { static AsyncThreadPool i; return & i; }
private : AsyncThreadPool ( ) = default ;
} ;
# define GAsyncThreadPool AsyncThreadPool :: GetInstance ( ) int GetCurMemoryKB ( )
{ SetProcessWorkingSetSize ( GetCurrentProcess ( ) , - 1 , - 1 ) ; PROCESS_MEMORY_COUNTERS pmc; GetProcessMemoryInfo ( GetCurrentProcess ( ) , & pmc, sizeof ( pmc) ) ; auto curMemoryKB = pmc. WorkingSetSize / 1024 ; return curMemoryKB;
} enum Msg { A, B, C,
} ; void MsgHandlerUnitTest :: RegisterTest ( )
{ struct ClassA { ClassA ( ) { RegisterMsgHandler ( Msg:: A, [ this ] { } ) ; RegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassA ( ) { Deregister ( ) ; } } ; struct ClassB { ClassB ( ) { RegisterMsgHandler ( Msg:: A, [ this ] { } ) ; RegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassB ( ) { Deregister ( ) ; } } ; ClassA a1; const auto & globalMsgHandler = MsgHandler :: GetInstance ( ) -> globalMsgHandler_; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . at ( 0 ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . at ( 0 ) . size ( ) == 1 ) ; ClassA a2; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . at ( 0 ) . size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . at ( 0 ) . size ( ) == 2 ) ; ClassB b1; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . at ( 0 ) . size ( ) == 3 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . at ( 0 ) . size ( ) == 3 ) ; QVERIFY ( VarifyResult ( ) ) ;
} void MsgHandlerUnitTest :: DeregisterTest ( ) { struct ClassA { ClassA ( ) { RegisterMsgHandler ( Msg:: A, [ this ] { } ) ; RegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassA ( ) { Deregister ( ) ; } } ; const auto & globalMsgHandler = MsgHandler :: GetInstance ( ) -> globalMsgHandler_; { ClassA a1; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . at ( 0 ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . at ( 0 ) . size ( ) == 1 ) ; } m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . at ( 0 ) . size ( ) == 0 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . at ( 0 ) . size ( ) == 0 ) ; QVERIFY ( VarifyResult ( ) ) ;
} void MsgHandlerUnitTest :: PriorityPreTest ( ) { struct ClassA { ClassA ( ) { RegisterMsgHandler ( Msg:: A, [ this ] { } ) ; RegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassA ( ) { Deregister ( ) ; } } ; struct ClassB { ClassB ( ) { RegisterMsgHandler ( Msg:: A, [ this ] { } , 1 ) ; RegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } , 1 ) ; } ~ ClassB ( ) { Deregister ( ) ; } } ; const auto & globalMsgHandler = MsgHandler :: GetInstance ( ) -> globalMsgHandler_; ClassA a1; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . at ( 0 ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . at ( 0 ) . size ( ) == 1 ) ; ClassA a2; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . at ( 0 ) . size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . at ( 0 ) . size ( ) == 2 ) ; ClassB b; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . at ( 0 ) . size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . at ( 0 ) . size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . at ( 1 ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . at ( 1 ) . size ( ) == 1 ) ; QVERIFY ( VarifyResult ( ) ) ;
}
std:: vector< int > priorityTestvec;
void MsgHandlerUnitTest :: PriorityTest ( )
{ struct ClassA { ClassA ( ) { RegisterMsgHandler ( Msg:: A, [ this ] { priorityTestvec. push_back ( a) ; } ) ; RegisterMsgHandler ( Msg:: B, [ this ] { priorityTestvec. push_back ( a) ; } , 1 ) ; } ~ ClassA ( ) { Deregister ( ) ; } int a = 5 ; } ; struct ClassB { ClassB ( ) { RegisterMsgHandler ( Msg:: A, [ this ] { priorityTestvec. push_back ( b) ; } , 1 ) ; RegisterMsgHandler ( Msg:: B, [ this ] { priorityTestvec. push_back ( b) ; } ) ; } ~ ClassB ( ) { Deregister ( ) ; } int b = 10 ; } ; ClassA a; ClassB b; priorityTestvec. clear ( ) ; TriggerMsg ( Msg:: A) ; m_results. push_back ( priorityTestvec. size ( ) == 2 ) ; m_results. push_back ( priorityTestvec[ 0 ] == 10 && priorityTestvec[ 1 ] == 5 ) ; priorityTestvec. clear ( ) ; TriggerMsg ( Msg:: B) ; m_results. push_back ( priorityTestvec. size ( ) == 2 ) ; m_results. push_back ( priorityTestvec[ 0 ] == 5 && priorityTestvec[ 1 ] == 10 ) ; QVERIFY ( VarifyResult ( ) ) ;
} void MsgHandlerUnitTest :: TriggerNoParamTest ( )
{ struct ClassA { ClassA ( ) { RegisterMsgHandler ( Msg:: A, [ this ] { a = A; } ) ; RegisterMsgHandler ( Msg:: B, [ this ] { a = B; } ) ; } ~ ClassA ( ) { Deregister ( ) ; } int a = 0 ; } ; struct ClassB { ClassB ( ) { RegisterMsgHandler ( Msg:: A, [ this ] { b = A; } ) ; RegisterMsgHandler ( Msg:: B, [ this ] { b = B; } ) ; } ~ ClassB ( ) { Deregister ( ) ; } int b = 0 ; } ; const auto & globalMsgHandler = MsgHandler :: GetInstance ( ) -> globalMsgHandler_; ClassA a1; ClassB b1; m_results. push_back ( a1. a == 0 ) ; m_results. push_back ( b1. b == 0 ) ; TriggerMsg ( Msg:: A) ; m_results. push_back ( a1. a == A) ; m_results. push_back ( b1. b == A) ; TriggerMsg ( Msg:: B) ; m_results. push_back ( a1. a == B) ; m_results. push_back ( b1. b == B) ; QVERIFY ( VarifyResult ( ) ) ;
} void MsgHandlerUnitTest :: TriggerHasParamTest ( )
{ struct ClassA { ClassA ( ) { RegisterMsgHandler ( Msg:: C, [ this ] ( const std:: any& data) { a = std:: any_cast < int > ( data) ; } ) ; } ~ ClassA ( ) { Deregister ( ) ; } int a = 0 ; } ; struct ClassB { ClassB ( ) { RegisterMsgHandler ( Msg:: C, [ this ] ( const std:: any& data) { b = std:: any_cast < int > ( data) ; } ) ; } ~ ClassB ( ) { Deregister ( ) ; } int b = 0 ; } ; const auto & globalMsgHandler = MsgHandler :: GetInstance ( ) -> globalMsgHandler_; ClassA a1; ClassB b1; m_results. push_back ( a1. a == 0 ) ; m_results. push_back ( b1. b == 0 ) ; TriggerMsg ( Msg:: C, 5 ) ; m_results. push_back ( a1. a == 5 ) ; m_results. push_back ( b1. b == 5 ) ; TriggerMsg ( Msg:: C, 999 ) ; m_results. push_back ( a1. a == 999 ) ; m_results. push_back ( b1. b == 999 ) ; QVERIFY ( VarifyResult ( ) ) ;
} std:: vector< std:: thread:: id> AsyncTriggerTestVec;
void MsgHandlerUnitTest :: AsyncTriggerTest ( )
{ AsyncTriggerTestVec. push_back ( std:: this_thread:: get_id ( ) ) ; struct ClassA { ClassA ( ) { RegisterMsgHandler ( Msg:: A, [ this ] { AsyncTriggerTestVec. push_back ( std:: this_thread:: get_id ( ) ) ; } ) ; } ~ ClassA ( ) { Deregister ( ) ; } } ; ClassA a; AsyncExecMsg ( Msg:: A) ; while ( AsyncTriggerTestVec. size ( ) != 2 ) { QCoreApplication :: processEvents ( ) ; } m_results. push_back ( AsyncTriggerTestVec[ 0 ] != AsyncTriggerTestVec[ 1 ] ) ; QVERIFY ( VarifyResult ( ) ) ;
} std:: vector< std:: thread:: id> MainTriggerTestVec;
void MsgHandlerUnitTest :: MainTriggerTest ( )
{ MainTriggerTestVec. clear ( ) ; MainTriggerTestVec. push_back ( std:: this_thread:: get_id ( ) ) ; struct ClassA { ClassA ( ) { RegisterMsgHandler ( Msg:: A, [ this ] { MainTriggerTestVec. push_back ( std:: this_thread:: get_id ( ) ) ; MainExecMsg ( Msg:: B) ; } ) ; RegisterMsgHandler ( Msg:: B, [ this ] { MainTriggerTestVec. push_back ( std:: this_thread:: get_id ( ) ) ; } ) ; } ~ ClassA ( ) { Deregister ( ) ; } } ; ClassA a; AsyncExecMsg ( Msg:: A) ; while ( MainTriggerTestVec. size ( ) != 3 ) { QCoreApplication :: processEvents ( ) ; } m_results. push_back ( MainTriggerTestVec[ 0 ] != MainTriggerTestVec[ 1 ] && MainTriggerTestVec[ 1 ] != MainTriggerTestVec[ 2 ] && MainTriggerTestVec[ 0 ] == MainTriggerTestVec[ 2 ] ) ; QVERIFY ( VarifyResult ( ) ) ;
} void MsgHandlerUnitTest :: MemoryLeakTest ( )
{ struct ClassA { ClassA ( ) { RegisterMsgHandler ( Msg:: A, [ this ] { a = A; } ) ; RegisterMsgHandler ( Msg:: B, [ this ] { a = B; } ) ; RegisterMsgHandler ( Msg:: C, [ this ] ( const std:: any& data) { a = std:: any_cast < int > ( data) ; } ) ; } ~ ClassA ( ) { Deregister ( ) ; } int a = 0 ; } ; const auto & globalMsgHandler = MsgHandler :: GetInstance ( ) -> globalMsgHandler_; auto beginMemory = GetCurMemoryKB ( ) ; { std:: vector< ClassA* > vec; for ( int i = 0 ; i < 100000 ; ++ i) { vec. push_back ( new ClassA) ; } m_results. push_back ( globalMsgHandler. size ( ) == 3 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::C" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . at ( 0 ) . size ( ) == 100000 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . at ( 0 ) . size ( ) == 100000 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::C" ) . at ( 0 ) . size ( ) == 100000 ) ; for ( auto & v : vec) { delete v; } vec. clear ( ) ; m_results. push_back ( globalMsgHandler. size ( ) == 3 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::C" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . at ( 0 ) . size ( ) == 0 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . at ( 0 ) . size ( ) == 0 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::C" ) . at ( 0 ) . size ( ) == 0 ) ; } auto endMemory = GetCurMemoryKB ( ) ; QVERIFY ( endMemory - beginMemory < 30 ) ;
} bool MsgHandlerUnitTest :: VarifyResult ( )
{ bool result = true ; for ( auto & rlt : m_results) { if ( ! rlt) { result = false ; break ; } } return result;
} void MsgHandlerUnitTest :: initTestCase ( )
{ MsgHandler :: GetInstance ( ) -> SetAsyncExecFunc ( [ ] ( std:: function< void ( ) > func) { GAsyncThreadPool-> AddTask ( func) ; } ) ; MsgHandler :: GetInstance ( ) -> SetMainExecFunc ( [ ] ( std:: function< void ( ) > func) { QTimer :: singleShot ( 0 , qApp, func) ; } ) ;
} void MsgHandlerUnitTest :: cleanupTestCase ( )
{
} void MsgHandlerUnitTest :: init ( )
{ m_results. clear ( ) ; MsgHandler :: GetInstance ( ) -> globalMsgHandler_. clear ( ) ;
} void MsgHandlerUnitTest :: cleanup ( )
{
}
2.实例间通信
1. 适用于类与类相互关联的对象之间的通信
2. 不支持优先级触发
3. 支持附带参数
4. 不支持异步执行
5. 使用方式可以查看下方单元测试代码
InstMsgHandler.h
# pragma once # include <unordered_map>
# include <functional>
# include <unordered_set>
# include "any.h" class InstMsgHandler {
# ifdef _DEBUG using MsgType = std:: string;
# else using MsgType = const char * ;
# endif friend class InstMsgHandlerUnitTest ;
public : static InstMsgHandler* GetInstance ( ) { static InstMsgHandler i; return & i; } void XTriggerMsg_ ( MsgType msg, void * trigger, std:: any info = std:: any{ } ) { auto findHandler = globalMsgHandler_. find ( msg) ; if ( findHandler != globalMsgHandler_. end ( ) ) { auto & handlers = findHandler-> second; auto it = communicators_. find ( trigger) ; if ( it != communicators_. end ( ) ) { for ( const auto & communicator : it-> second) { auto handler = handlers. find ( communicator) ; if ( handler != handlers. end ( ) ) { handler-> second ( info) ; } } } } } void XRegisterMsgHandler_ ( MsgType msg, void * t, std:: function< void ( std:: any) > func) { globalMsgHandler_[ msg] . insert ( { t, func } ) ; } void XRegisterMsgHandler_ ( MsgType msg, void * t, std:: function< void ( ) > func) { globalMsgHandler_[ msg] . insert ( { t, [ = ] ( std:: any) { func ( ) ; } } ) ; } void XConnect_ ( void * c1, void * c2) { if ( c1 == c2) { communicators_[ c1] . insert ( c2) ; return ; } communicators_[ c1] . insert ( c2) ; communicators_[ c2] . insert ( c1) ; } void XDisconnect_ ( void * c1, void * c2) { if ( c1 == c2) { communicators_[ c1] . erase ( c2) ; return ; } communicators_[ c1] . erase ( c2) ; communicators_[ c2] . erase ( c1) ; } void XDeregister_ ( void * t) { XDisconnect_ ( t) ; DeregisterMsgHandler ( t) ; }
private : void XDisconnect_ ( void * t) { auto it = communicators_. find ( t) ; if ( it != communicators_. end ( ) ) { auto communicators = it-> second; for ( auto communicator : communicators) { communicators_[ communicator] . erase ( t) ; } } communicators_. erase ( t) ; } void DeregisterMsgHandler ( void * t) { for ( auto & msgHandler : globalMsgHandler_) { HandlerMap& handlerMap = msgHandler. second; handlerMap. erase ( t) ; } }
private : InstMsgHandler ( ) = default ; using HandlerMap = std:: unordered_map< void * , std:: function< void ( std:: any) >> ; std:: unordered_map< void * , std:: unordered_set< void * >> communicators_; std:: unordered_map< MsgType, HandlerMap> globalMsgHandler_;
} ; # define EXPAND ( . . . ) __VA_ARGS__
# define COUNT_ARGS_IMPL ( _1, _2, _3, N, . . . ) N
# define COUNT_ARGS ( . . . ) EXPAND ( COUNT_ARGS_IMPL ( __VA_ARGS__, 3 , 2 , 1 , 0 ) )
# define XCONNECT_IMPL_1 ( a) InstMsgHandler :: GetInstance ( ) -> XConnect_ ( this , a)
# define XCONNECT_IMPL_2 ( a, b) InstMsgHandler :: GetInstance ( ) -> XConnect_ ( a, b)
# define XCONNECT_IMPL ( n) XCONNECT_IMPL_## n
# define XCONNECT_DISPATCH ( n, . . . ) EXPAND ( XCONNECT_IMPL ( n) ( __VA_ARGS__) )
# define XConnect ( . . . ) XCONNECT_DISPATCH ( EXPAND ( COUNT_ARGS ( __VA_ARGS__) ) , __VA_ARGS__) # define XDISCONNECT_IMPL_1 ( a) InstMsgHandler :: GetInstance ( ) -> XDisconnect_ ( this , a)
# define XDISCONNECT_IMPL_2 ( a, b) InstMsgHandler :: GetInstance ( ) -> XDisconnect_ ( a, b)
# define XDISCONNECT_IMPL ( n) XDISCONNECT_IMPL_## n
# define XDISCONNECT_DISPATCH ( n, . . . ) EXPAND ( XDISCONNECT_IMPL ( n) ( __VA_ARGS__) )
# define XDisconnect ( . . . ) XDISCONNECT_DISPATCH ( EXPAND ( COUNT_ARGS ( __VA_ARGS__) ) , __VA_ARGS__) # define XRegisterMsgHandler ( msg, . . . ) InstMsgHandler :: GetInstance ( ) -> XRegisterMsgHandler_ ( #msg, this , __VA_ARGS__)
# define XTriggerMsg ( msg, . . . ) InstMsgHandler :: GetInstance ( ) -> XTriggerMsg_ ( #msg, this , __VA_ARGS__)
# define XDeregister ( ) InstMsgHandler :: GetInstance ( ) -> XDeregister_ ( this )
单元测试
InstMsgHandlerUnitTest.h
# include <QTest>
# include <vector> class InstMsgHandlerUnitTest : public QObject { Q_OBJECT
private slots: void initTestCase ( ) ; void cleanupTestCase ( ) ; void init ( ) ; void cleanup ( ) ; void RegisterTest ( ) ; void DeregisterTest ( ) ; void XConnectABTest ( ) ; void XDisconnectABTest ( ) ; void ABTriggerNoParamTest ( ) ; void ABTriggerHasParamTest ( ) ; void XConnectBaseTest ( ) ; void BaseTriggerNoParamTest ( ) ; void BaseTriggerHasParamTest ( ) ; void MemoryLeakTest ( ) ; void BaseMemoryLeakTest ( ) ;
private : bool VarifyResult ( ) ;
private : std:: vector< bool > m_results;
} ;
InstMsgHandlerUnitTest.cpp
# include "InstMsgHandlerUnitTest.h"
# include "InstMsgHandler.h" int GetCurMemoryKB ( )
{ SetProcessWorkingSetSize ( GetCurrentProcess ( ) , - 1 , - 1 ) ; PROCESS_MEMORY_COUNTERS pmc; GetProcessMemoryInfo ( GetCurrentProcess ( ) , & pmc, sizeof ( pmc) ) ; auto curMemoryKB = pmc. WorkingSetSize / 1024 ; return curMemoryKB;
} enum Msg { A, B, C,
} ; void InstMsgHandlerUnitTest :: RegisterTest ( )
{ struct ClassA { ClassA ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassA ( ) { XDeregister ( ) ; } } ; struct ClassB { ClassB ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassB ( ) { XDeregister ( ) ; } } ; ClassA a; const auto & globalMsgHandler = InstMsgHandler :: GetInstance ( ) -> globalMsgHandler_; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; ClassB b; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 2 ) ; QVERIFY ( VarifyResult ( ) ) ;
} void InstMsgHandlerUnitTest :: DeregisterTest ( )
{ struct ClassA { ClassA ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassA ( ) { XDeregister ( ) ; } } ; struct ClassB { ClassB ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassB ( ) { XDeregister ( ) ; } } ; const auto & globalMsgHandler = InstMsgHandler :: GetInstance ( ) -> globalMsgHandler_; const auto & communicators = InstMsgHandler :: GetInstance ( ) -> communicators_; { ClassA a; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; m_results. push_back ( communicators. size ( ) == 0 ) ; { ClassB b; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 2 ) ; XConnect ( & a, & b) ; m_results. push_back ( communicators. size ( ) == 2 ) ; m_results. push_back ( communicators. at ( & a) . size ( ) == 1 ) ; m_results. push_back ( communicators. at ( & b) . size ( ) == 1 ) ; } m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; m_results. push_back ( communicators. size ( ) == 1 ) ; m_results. push_back ( communicators. at ( & a) . size ( ) == 0 ) ; } m_results. push_back ( communicators. size ( ) == 0 ) ; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 0 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 0 ) ; QVERIFY ( VarifyResult ( ) ) ;
} void InstMsgHandlerUnitTest :: XConnectABTest ( )
{ struct ClassA { ClassA ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassA ( ) { XDeregister ( ) ; } } ; struct ClassB { ClassB ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassB ( ) { XDeregister ( ) ; } } ; ClassA a; ClassB b; XConnect ( & a, & b) ; const auto & globalMsgHandler = InstMsgHandler :: GetInstance ( ) -> globalMsgHandler_; const auto & communicators = InstMsgHandler :: GetInstance ( ) -> communicators_; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 2 ) ; m_results. push_back ( communicators. size ( ) == 2 ) ; m_results. push_back ( communicators. at ( & a) . size ( ) == 1 ) ; m_results. push_back ( communicators. at ( & b) . size ( ) == 1 ) ; QVERIFY ( VarifyResult ( ) ) ;
} void InstMsgHandlerUnitTest :: XDisconnectABTest ( )
{ struct ClassA { ClassA ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassA ( ) { XDeregister ( ) ; } } ; struct ClassB { ClassB ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassB ( ) { XDeregister ( ) ; } } ; ClassA a; ClassB b; XConnect ( & a, & b) ; const auto & globalMsgHandler = InstMsgHandler :: GetInstance ( ) -> globalMsgHandler_; const auto & communicators = InstMsgHandler :: GetInstance ( ) -> communicators_; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 2 ) ; m_results. push_back ( communicators. size ( ) == 2 ) ; m_results. push_back ( communicators. at ( & a) . size ( ) == 1 ) ; m_results. push_back ( communicators. at ( & b) . size ( ) == 1 ) ; XDisconnect ( & a, & b) ; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 2 ) ; m_results. push_back ( communicators. size ( ) == 2 ) ; m_results. push_back ( communicators. at ( & a) . size ( ) == 0 ) ; m_results. push_back ( communicators. at ( & b) . size ( ) == 0 ) ; QVERIFY ( VarifyResult ( ) ) ;
} int TriggerNoParamTestTempVar = 0 ;
void InstMsgHandlerUnitTest :: ABTriggerNoParamTest ( )
{ TriggerNoParamTestTempVar = 0 ; struct ClassA { ClassA ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { TriggerNoParamTestTempVar += 1 ; } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassA ( ) { XDeregister ( ) ; } void Call ( ) { XTriggerMsg ( Msg:: A) ; } } ; struct ClassB { ClassB ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { TriggerNoParamTestTempVar += 1 ; } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassB ( ) { XDeregister ( ) ; } void Call ( ) { XTriggerMsg ( Msg:: A) ; } } ; ClassA a; ClassB b; XConnect ( & a, & b) ; const auto & globalMsgHandler = InstMsgHandler :: GetInstance ( ) -> globalMsgHandler_; const auto & communicators = InstMsgHandler :: GetInstance ( ) -> communicators_; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 2 ) ; m_results. push_back ( communicators. size ( ) == 2 ) ; m_results. push_back ( communicators. at ( & a) . size ( ) == 1 ) ; m_results. push_back ( communicators. at ( & b) . size ( ) == 1 ) ; a. Call ( ) ; m_results. push_back ( TriggerNoParamTestTempVar == 1 ) ; b. Call ( ) ; m_results. push_back ( TriggerNoParamTestTempVar == 2 ) ; XDisconnect ( & a, & b) ; a. Call ( ) ; m_results. push_back ( TriggerNoParamTestTempVar == 2 ) ; b. Call ( ) ; m_results. push_back ( TriggerNoParamTestTempVar == 2 ) ; QVERIFY ( VarifyResult ( ) ) ;
} int TriggerHasParamTestTempVar = 0 ;
void InstMsgHandlerUnitTest :: ABTriggerHasParamTest ( )
{ TriggerHasParamTestTempVar = 0 ; struct ClassA { ClassA ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { TriggerHasParamTestTempVar = std:: any_cast < int > ( data) ; } ) ; } ~ ClassA ( ) { XDeregister ( ) ; } void Call ( ) { XTriggerMsg ( Msg:: B, 100 ) ; } } ; struct ClassB { ClassB ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { TriggerHasParamTestTempVar = std:: any_cast < int > ( data) ; } ) ; } ~ ClassB ( ) { XDeregister ( ) ; } void Call ( ) { XTriggerMsg ( Msg:: B, - 100 ) ; } } ; ClassA a; ClassB b; XConnect ( & a, & b) ; const auto & globalMsgHandler = InstMsgHandler :: GetInstance ( ) -> globalMsgHandler_; const auto & communicators = InstMsgHandler :: GetInstance ( ) -> communicators_; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 2 ) ; m_results. push_back ( communicators. size ( ) == 2 ) ; m_results. push_back ( communicators. at ( & a) . size ( ) == 1 ) ; m_results. push_back ( communicators. at ( & b) . size ( ) == 1 ) ; a. Call ( ) ; m_results. push_back ( TriggerHasParamTestTempVar == 100 ) ; b. Call ( ) ; m_results. push_back ( TriggerHasParamTestTempVar == - 100 ) ; QVERIFY ( VarifyResult ( ) ) ;
} void InstMsgHandlerUnitTest :: XConnectBaseTest ( )
{ struct ClassA { ClassA ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassA ( ) { XDeregister ( ) ; } } ; struct ClassB : ClassA { ClassB ( ) { XConnect ( this ) ; } ~ ClassB ( ) { XDeregister ( ) ; } } ; ClassB b; const auto & globalMsgHandler = InstMsgHandler :: GetInstance ( ) -> globalMsgHandler_; const auto & communicators = InstMsgHandler :: GetInstance ( ) -> communicators_; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; m_results. push_back ( communicators. size ( ) == 1 ) ; m_results. push_back ( communicators. at ( & b) . size ( ) == 1 ) ;
} int BaseTriggerNoParamTestTempVar = 0 ;
void InstMsgHandlerUnitTest :: BaseTriggerNoParamTest ( )
{ BaseTriggerNoParamTestTempVar = 0 ; struct ClassA { ClassA ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { BaseTriggerNoParamTestTempVar += 1 ; } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassA ( ) { XDeregister ( ) ; } void CallBase ( ) { XTriggerMsg ( Msg:: A) ; } } ; struct ClassB : ClassA { ClassB ( ) { XConnect ( this ) ; } ~ ClassB ( ) { XDeregister ( ) ; } void CallDriver ( ) { XTriggerMsg ( Msg:: A) ; } } ; ClassB b; const auto & globalMsgHandler = InstMsgHandler :: GetInstance ( ) -> globalMsgHandler_; const auto & communicators = InstMsgHandler :: GetInstance ( ) -> communicators_; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; m_results. push_back ( communicators. size ( ) == 1 ) ; m_results. push_back ( communicators. at ( & b) . size ( ) == 1 ) ; b. CallBase ( ) ; m_results. push_back ( BaseTriggerNoParamTestTempVar == 1 ) ; b. CallDriver ( ) ; m_results. push_back ( BaseTriggerNoParamTestTempVar == 2 ) ; QVERIFY ( VarifyResult ( ) ) ;
} int BaseTriggerHasParamTestTempVar = 0 ;
void InstMsgHandlerUnitTest :: BaseTriggerHasParamTest ( )
{ BaseTriggerHasParamTestTempVar = 0 ; struct ClassA { ClassA ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { BaseTriggerHasParamTestTempVar = std:: any_cast < int > ( data) ; } ) ; } ~ ClassA ( ) { XDeregister ( ) ; } void CallBase ( ) { XTriggerMsg ( Msg:: B, 100 ) ; } } ; struct ClassB : ClassA { ClassB ( ) { XConnect ( this ) ; } ~ ClassB ( ) { XDeregister ( ) ; } void CallDriver ( ) { XTriggerMsg ( Msg:: B, - 100 ) ; } } ; ClassB b; const auto & globalMsgHandler = InstMsgHandler :: GetInstance ( ) -> globalMsgHandler_; const auto & communicators = InstMsgHandler :: GetInstance ( ) -> communicators_; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 1 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 1 ) ; m_results. push_back ( communicators. size ( ) == 1 ) ; m_results. push_back ( communicators. at ( & b) . size ( ) == 1 ) ; b. CallBase ( ) ; m_results. push_back ( BaseTriggerHasParamTestTempVar == 100 ) ; b. CallDriver ( ) ; m_results. push_back ( BaseTriggerHasParamTestTempVar == - 100 ) ; QVERIFY ( VarifyResult ( ) ) ;
} void InstMsgHandlerUnitTest :: MemoryLeakTest ( )
{ struct ClassA { ClassA ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassA ( ) { XDeregister ( ) ; } int a = 0 ; } ; struct ClassB { ClassB ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassB ( ) { XDeregister ( ) ; } int b = 0 ; } ; auto beginMemory = GetCurMemoryKB ( ) ; { std:: vector< ClassA* > veca; std:: vector< ClassB* > vecb; for ( int i = 0 ; i < 10000 ; ++ i) { ClassA* a = new ClassA; ClassB* b = new ClassB; XConnect ( a, b) ; veca. push_back ( a) ; vecb. push_back ( b) ; } const auto & globalMsgHandler = InstMsgHandler :: GetInstance ( ) -> globalMsgHandler_; const auto & communicators = InstMsgHandler :: GetInstance ( ) -> communicators_; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 20000 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 20000 ) ; m_results. push_back ( communicators. size ( ) == 20000 ) ; for ( auto & communicator : communicators) { QVERIFY ( communicator. second. size ( ) == 1 ) ; } for ( auto & v : veca) { delete v; } for ( auto & v : vecb) { delete v; } veca. clear ( ) ; vecb. clear ( ) ; m_results. push_back ( globalMsgHandler. size ( ) == 2 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::A" ) . size ( ) == 0 ) ; m_results. push_back ( globalMsgHandler. at ( "Msg::B" ) . size ( ) == 0 ) ; m_results. push_back ( communicators. size ( ) == 0 ) ; } auto endMemory = GetCurMemoryKB ( ) ; QVERIFY ( endMemory - beginMemory < 30 ) ;
} void InstMsgHandlerUnitTest :: BaseMemoryLeakTest ( )
{ struct ClassA { ClassA ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; } ~ ClassA ( ) { XDeregister ( ) ; } int a = 0 ; } ; struct ClassB : ClassA { ClassB ( ) { XRegisterMsgHandler ( Msg:: A, [ this ] { } ) ; XRegisterMsgHandler ( Msg:: B, [ this ] ( const std:: any& data) { } ) ; XConnect ( this ) ; } ~ ClassB ( ) { XDeregister ( ) ; } int b = 0 ; } ; auto beginMemory = GetCurMemoryKB ( ) ; { std:: vector< ClassB* > vecb; for ( int i = 0 ; i < 10000 ; ++ i) { vecb. push_back ( new ClassB) ; } for ( auto & v : vecb) { delete v; } vecb. clear ( ) ; } auto endMemory = GetCurMemoryKB ( ) ; QVERIFY ( endMemory - beginMemory < 30 ) ;
} bool InstMsgHandlerUnitTest :: VarifyResult ( )
{ bool result = true ; for ( auto & rlt : m_results) { if ( ! rlt) { result = false ; break ; } } return result;
} void InstMsgHandlerUnitTest :: initTestCase ( )
{
} void InstMsgHandlerUnitTest :: cleanupTestCase ( )
{
} void InstMsgHandlerUnitTest :: init ( )
{ m_results. clear ( ) ; InstMsgHandler :: GetInstance ( ) -> globalMsgHandler_. clear ( ) ; InstMsgHandler :: GetInstance ( ) -> communicators_. clear ( ) ;
} void InstMsgHandlerUnitTest :: cleanup ( )
{
}