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)16 Observable &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) const26 bool 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)32 void 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)41 void 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)49 void 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)59 void Observable::SetChanged(bool SetTo)
60 {
61   m_bObservableChanged = SetTo;
62 }
63 
SendMessage(const ObservableMessage message)64 void 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