1 /* 2 * Copyright (C) 2005-2018 Team Kodi 3 * This file is part of Kodi - https://kodi.tv 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 * See LICENSES/README.md for more information. 7 */ 8 9 10 #include "Observer.h" 11 12 #include "threads/SingleLock.h" 13 14 #include <algorithm> 15 operator =(const Observable & observable)16Observable &Observable::operator=(const Observable &observable) 17 { 18 CSingleLock lock(m_obsCritSection); 19 20 m_bObservableChanged = static_cast<bool>(observable.m_bObservableChanged); 21 m_observers = observable.m_observers; 22 23 return *this; 24 } 25 IsObserving(const Observer & obs) const26bool Observable::IsObserving(const Observer &obs) const 27 { 28 CSingleLock lock(m_obsCritSection); 29 return std::find(m_observers.begin(), m_observers.end(), &obs) != m_observers.end(); 30 } 31 RegisterObserver(Observer * obs)32void Observable::RegisterObserver(Observer *obs) 33 { 34 CSingleLock lock(m_obsCritSection); 35 if (!IsObserving(*obs)) 36 { 37 m_observers.push_back(obs); 38 } 39 } 40 UnregisterObserver(Observer * obs)41void Observable::UnregisterObserver(Observer *obs) 42 { 43 CSingleLock lock(m_obsCritSection); 44 auto iter = std::remove(m_observers.begin(), m_observers.end(), obs); 45 if (iter != m_observers.end()) 46 m_observers.erase(iter); 47 } 48 NotifyObservers(const ObservableMessage message)49void Observable::NotifyObservers(const ObservableMessage message /* = ObservableMessageNone */) 50 { 51 // Make sure the set/compare is atomic 52 // so we don't clobber the variable in a race condition 53 auto bNotify = m_bObservableChanged.exchange(false); 54 55 if (bNotify) 56 SendMessage(message); 57 } 58 SetChanged(bool SetTo)59void Observable::SetChanged(bool SetTo) 60 { 61 m_bObservableChanged = SetTo; 62 } 63 SendMessage(const ObservableMessage message)64void Observable::SendMessage(const ObservableMessage message) 65 { 66 CSingleLock lock(m_obsCritSection); 67 68 for (auto& observer : m_observers) 69 { 70 observer->Notify(*this, message); 71 } 72 } 73