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