#pragma once #include #include #include #include #include #include #ifdef emit #undef emit #endif namespace fc { template class signal { private: typedef std::function func_type; typedef std::vector> list_type; public: typedef void* connection_id_type; template connection_id_type connect( Functor&& f ) { fc::unique_lock lock(_mutex); //auto c = new std::function( fc::forward(f) ); _handlers.push_back( std::make_shared(f) ); return reinterpret_cast(_handlers.back().get()); } #ifdef WIN32 template void emit( Arg&& arg ) { list_type handlers = getHandlers(); for( size_t i = 0; i < handlers.size(); ++i ) { (*handlers[i])( fc::forward(arg) ); } } void operator()() { list_type handlers = getHandlers(); for( size_t i = 0; i < handlers.size(); ++i ) { (*handlers[i])(); } } template void operator()( Arg&& arg ) { list_type handlers = getHandlers(); for( size_t i = 0; i < handlers.size(); ++i ) { (*handlers[i])( fc::forward(arg) ); } } template void emit( Arg&& arg, Arg2&& arg2 ) { list_type handlers = getHandlers(); for( size_t i = 0; i < handlers.size(); ++i ) { (*handlers[i])( fc::forward(arg), fc::forward(arg2) ); } } template void operator()( Arg&& arg, Arg2&& arg2 ) { list_type handlers = getHandlers(); for( size_t i = 0; i < handlers.size(); ++i ) { (*handlers[i])( fc::forward(arg), fc::forward(arg2) ); } } template void emit( Arg&& arg, Arg2&& arg2, Arg3&& arg3 ) { list_type handlers = getHandlers(); for( size_t i = 0; i < handlers.size(); ++i ) { (*handlers[i])( fc::forward(arg), fc::forward(arg2), fc::forward(arg3) ); } } template void operator()( Arg&& arg, Arg2&& arg2, Arg3&& arg3 ) { list_type handlers = getHandlers(); for( size_t i = 0; i < handlers.size(); ++i ) { (*handlers[i])( fc::forward(arg), fc::forward(arg2), fc::forward(arg3) ); } } #else template void emit( Args&&... args ) { list_type handlers = getHandlers(); for( size_t i = 0; i < handlers.size(); ++i ) { (*handlers[i])( fc::forward(args)... ); } } template void operator()( Args&&... args ) { list_type handlers = getHandlers(); for( size_t i = 0; i < handlers.size(); ++i ) { (*handlers[i])( fc::forward(args)... ); } } #endif void disconnect( connection_id_type cid ) { fc::unique_lock lock(_mutex); auto itr = _handlers.begin(); while( itr != _handlers.end() ) { if( reinterpret_cast(itr->get()) == cid ) { _handlers.erase(itr); } ++itr; } } signal() { _handlers.reserve(4); } //~signal() //{ // for( auto itr = _handlers.begin(); itr != _handlers.end(); ++itr ) // { // delete *itr; // } // _handlers.clear(); //} private: fc::mutex _mutex; list_type _handlers; list_type getHandlers() { fc::unique_lock lock(_mutex); list_type handlers(_handlers); return handlers; } }; }