Commit e0e46032 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

EventManager: Allow events to be unregistered by copying the event manager and destroying the copy.

parent a0162191
...@@ -145,6 +145,23 @@ protected: ...@@ -145,6 +145,23 @@ protected:
{ {
} }
public:
EventManager(const EventManager& em)
: Internal( em )
{
// Use an empty list of events
}
EventManager& operator=(const EventManager& em)
{
Internal::operator=(em);
return *this;
}
EventManager(EventManager&&) = default;
EventManager& operator=(EventManager&&) = default;
protected:
/** /**
* @brief handle Provides the common behavior for all event handlers * @brief handle Provides the common behavior for all event handlers
* @param eventType The libvlc type of event * @param eventType The libvlc type of event
......
...@@ -49,6 +49,7 @@ class Internal ...@@ -49,6 +49,7 @@ class Internal
protected: protected:
Internal() = default; Internal() = default;
Internal( InternalPtr obj, Releaser releaser ) Internal( InternalPtr obj, Releaser releaser )
: m_obj{ obj, releaser } : m_obj{ obj, releaser }
{ {
......
...@@ -33,7 +33,7 @@ namespace VLC ...@@ -33,7 +33,7 @@ namespace VLC
{ {
class MediaPlayer; class MediaPlayer;
class EventManager; class MediaEventManager;
class Instance; class Instance;
class MediaList; class MediaList;
...@@ -302,14 +302,14 @@ public: ...@@ -302,14 +302,14 @@ public:
* *
* \return event manager object * \return event manager object
*/ */
MediaEventManagerPtr eventManager() MediaEventManager& eventManager()
{ {
if ( m_eventManager == NULL ) if ( m_eventManager == NULL )
{ {
libvlc_event_manager_t* obj = libvlc_media_event_manager(*this); libvlc_event_manager_t* obj = libvlc_media_event_manager(*this);
m_eventManager = std::make_shared<MediaEventManager>( obj ); m_eventManager = std::make_shared<MediaEventManager>( obj );
} }
return m_eventManager; return *m_eventManager;
} }
/** /**
...@@ -438,7 +438,7 @@ private: ...@@ -438,7 +438,7 @@ private:
private: private:
MediaEventManagerPtr m_eventManager; std::shared_ptr<MediaEventManager> m_eventManager;
}; };
} // namespace VLC } // namespace VLC
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
namespace VLC namespace VLC
{ {
class EventManager; class MediaDiscovererEventManager;
class Instance; class Instance;
class MediaDiscoverer : public Internal<libvlc_media_discoverer_t> class MediaDiscoverer : public Internal<libvlc_media_discoverer_t>
...@@ -71,14 +71,14 @@ public: ...@@ -71,14 +71,14 @@ public:
* *
* \return event manager object. * \return event manager object.
*/ */
MediaDiscovererEventManagerPtr eventManager() MediaDiscovererEventManager& eventManager()
{ {
if ( m_eventManager ) if ( m_eventManager )
{ {
libvlc_event_manager_t* obj = libvlc_media_discoverer_event_manager( *this ); libvlc_event_manager_t* obj = libvlc_media_discoverer_event_manager( *this );
m_eventManager = std::make_shared<MediaDiscovererEventManager>( obj ); m_eventManager = std::make_shared<MediaDiscovererEventManager>( obj );
} }
return m_eventManager; return *m_eventManager;
} }
/** /**
...@@ -92,7 +92,7 @@ public: ...@@ -92,7 +92,7 @@ public:
} }
private: private:
MediaDiscovererEventManagerPtr m_eventManager; std::shared_ptr<MediaDiscovererEventManager> m_eventManager;
}; };
} // namespace VLC } // namespace VLC
......
...@@ -30,7 +30,7 @@ namespace VLC ...@@ -30,7 +30,7 @@ namespace VLC
{ {
class Media; class Media;
class EventManager; class MediaListEventManager;
class MediaDiscoverer; class MediaDiscoverer;
class MediaLibrary; class MediaLibrary;
...@@ -225,18 +225,18 @@ public: ...@@ -225,18 +225,18 @@ public:
* *
* \return libvlc_event_manager * \return libvlc_event_manager
*/ */
MediaListEventManagerPtr eventManager() MediaListEventManager& eventManager()
{ {
if ( m_eventManager ) if ( m_eventManager )
{ {
libvlc_event_manager_t* obj = libvlc_media_list_event_manager( *this ); libvlc_event_manager_t* obj = libvlc_media_list_event_manager( *this );
m_eventManager = std::make_shared<MediaListEventManager>( obj ); m_eventManager = std::make_shared<MediaListEventManager>( obj );
} }
return m_eventManager; return *m_eventManager;
} }
private: private:
MediaListEventManagerPtr m_eventManager; std::shared_ptr<MediaListEventManager> m_eventManager;
}; };
} // namespace VLC } // namespace VLC
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
namespace VLC namespace VLC
{ {
class MediaListEventManager; class MediaListPlayerEventManager;
class MediaPlayer; class MediaPlayer;
class MediaList; class MediaList;
...@@ -65,14 +65,14 @@ public: ...@@ -65,14 +65,14 @@ public:
* *
* \return the event manager * \return the event manager
*/ */
MediaListPlayerEventManagerPtr eventManager() MediaListPlayerEventManager& eventManager()
{ {
if ( m_eventManager ) if ( m_eventManager )
{ {
libvlc_event_manager_t* obj = libvlc_media_list_player_event_manager(*this); libvlc_event_manager_t* obj = libvlc_media_list_player_event_manager(*this);
m_eventManager = std::make_shared<MediaListPlayerEventManager>( obj ); m_eventManager = std::make_shared<MediaListPlayerEventManager>( obj );
} }
return m_eventManager; return *m_eventManager;
} }
...@@ -198,7 +198,7 @@ public: ...@@ -198,7 +198,7 @@ public:
} }
private: private:
MediaListPlayerEventManagerPtr m_eventManager; std::shared_ptr<MediaListPlayerEventManager> m_eventManager;
}; };
......
...@@ -105,14 +105,14 @@ public: ...@@ -105,14 +105,14 @@ public:
* *
* \return the event manager associated with p_mi * \return the event manager associated with p_mi
*/ */
MediaPlayerEventManagerPtr eventManager() MediaPlayerEventManager& eventManager()
{ {
if ( m_eventManager == NULL ) if ( m_eventManager == NULL )
{ {
libvlc_event_manager_t* obj = libvlc_media_player_event_manager( *this ); libvlc_event_manager_t* obj = libvlc_media_player_event_manager( *this );
m_eventManager = std::make_shared<MediaPlayerEventManager>( obj ); m_eventManager = std::make_shared<MediaPlayerEventManager>( obj );
} }
return m_eventManager; return *m_eventManager;
} }
/** /**
...@@ -1573,8 +1573,7 @@ private: ...@@ -1573,8 +1573,7 @@ private:
} }
private: private:
MediaPlayerEventManagerPtr m_eventManager; std::shared_ptr<MediaPlayerEventManager> m_eventManager;
}; };
} // namespace VLC } // namespace VLC
......
...@@ -29,24 +29,6 @@ ...@@ -29,24 +29,6 @@
namespace VLC namespace VLC
{ {
class EventManager;
using EventManagerPtr = std::shared_ptr<EventManager>;
class MediaEventManager;
using MediaEventManagerPtr = std::shared_ptr<MediaEventManager>;
class MediaPlayerEventManager;
using MediaPlayerEventManagerPtr = std::shared_ptr<MediaPlayerEventManager>;
class MediaListPlayerEventManager;
using MediaListPlayerEventManagerPtr = std::shared_ptr<MediaListPlayerEventManager>;
class MediaDiscovererEventManager;
using MediaDiscovererEventManagerPtr = std::shared_ptr<MediaDiscovererEventManager>;
class MediaListEventManager;
using MediaListEventManagerPtr = std::shared_ptr<MediaListEventManager>;
class Media; class Media;
using MediaPtr = std::shared_ptr<Media>; using MediaPtr = std::shared_ptr<Media>;
......
...@@ -21,7 +21,7 @@ int main(int ac, char** av) ...@@ -21,7 +21,7 @@ int main(int ac, char** av)
auto media = VLC::Media(instance, av[1], VLC::Media::FromPath); auto media = VLC::Media(instance, av[1], VLC::Media::FromPath);
auto mp = VLC::MediaPlayer(media); auto mp = VLC::MediaPlayer(media);
auto eventManager = mp.eventManager(); auto eventManager = mp.eventManager();
eventManager->onPlaying([&media]() { eventManager.onPlaying([&media]() {
std::cout << media.mrl() << " is playing" << std::endl; std::cout << media.mrl() << " is playing" << std::endl;
}); });
/* /*
...@@ -34,7 +34,7 @@ int main(int ac, char** av) ...@@ -34,7 +34,7 @@ int main(int ac, char** av)
bool expected = true; bool expected = true;
auto& handler = mp.eventManager()->onPositionChanged([&expected](float pos) { auto& handler = mp.eventManager().onPositionChanged([&expected](float pos) {
std::cout << "position changed " << pos << std::endl; std::cout << "position changed " << pos << std::endl;
assert(expected); assert(expected);
}); });
...@@ -51,15 +51,46 @@ int main(int ac, char** av) ...@@ -51,15 +51,46 @@ int main(int ac, char** av)
std::cout << "Lambda called" << std::endl; std::cout << "Lambda called" << std::endl;
assert(expected); assert(expected);
}; };
auto& h1 = mp.eventManager()->onTimeChanged(l); auto& h1 = mp.eventManager().onTimeChanged(l);
auto& h2 = mp.eventManager()->onPositionChanged(l); auto& h2 = mp.eventManager().onPositionChanged(l);
std::this_thread::sleep_for( std::chrono::seconds( 2 ) ); std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
// Unregistering multiple events at once. // Unregistering multiple events at once.
// h1 and h2 are now invalid. // h1 and h2 are now invalid.
mp.eventManager()->unregister(h1, h2); mp.eventManager().unregister(h1, h2);
expected = false; expected = false;
std::this_thread::sleep_for( std::chrono::milliseconds(500) );
// Using scopped event manager to automatically unregister events
{
expected = true;
// This is a copy. Assigning to a reference wouldn't clear the registered events
auto em = mp.eventManager();
em.onPositionChanged([&expected](float) {
assert(expected);
});
std::this_thread::sleep_for( std::chrono::seconds(1) );
}
// From here, the lambda declared in the scope isn't registered anymore
expected = false;
std::this_thread::sleep_for( std::chrono::milliseconds(500) );
// Showing that copying an object shares the associated eventmanager
auto mp2 = mp;
expected = true;
auto& h3 = mp2.eventManager().onStopped([&expected]() {
std::cout << "MediaPlayer stopped" << std::endl;
assert(expected);
// expect a single call since both media player share the same event manager
expected = false;
});
mp.stop(); mp.stop();
// Unregister the RegisteredEvent from the other MP's event manager.
// It will be unregistered from both, and when the object gets destroyed
// by leaving the scope, it won't be unregistered from mp2's eventManager.
// If it did, libvlc would assert as the event has been unregistered already.
mp.eventManager().unregister(h3);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment