#pragma once #include #include #include namespace pfc { class notifyList { public: typedef size_t token_t; typedef std::function notify_t; token_t add( notify_t f ) { auto token = ++ m_increment; m_notify[token] = f; return token; } void remove( token_t t ) { m_notify.erase(t); } void dispatch() { // Safeguard against someone altering our state in mid-dispatch auto temp = m_notify; for( auto walk = temp.begin(); walk != temp.end(); ++ walk ) { if ( m_notify.count( walk->first ) > 0 ) { // still there? walk->second(); } } } static std::shared_ptr make() { return std::make_shared(); } private: token_t m_increment = 0; std::map m_notify; }; typedef std::shared_ptr< notifyList > notifyListRef_t; class notifyEntry { public: notifyEntry() {} notifyEntry & operator<<( notifyList & l ) { PFC_ASSERT( m_list == nullptr ); m_list = &l; return *this; } notifyEntry & operator<<( notifyListRef_t l ) { PFC_ASSERT( m_list == nullptr ); m_listShared = l; m_list = &*l; return *this; } notifyEntry & operator<<( notifyList::notify_t f ) { PFC_ASSERT( m_list != nullptr ); PFC_ASSERT( m_token == 0 ); m_token = m_list->add( f ); return *this; } void clear() { if ( m_list != nullptr && m_token != 0 ) { m_list->remove(m_token); m_token = 0; } } ~notifyEntry() { clear(); } private: notifyListRef_t m_listShared; notifyList * m_list = nullptr; notifyList::token_t m_token = 0; notifyEntry( const notifyEntry & ) = delete; void operator=( const notifyEntry & ) = delete; }; }