summaryrefslogtreecommitdiffstats
path: root/xbmc/utils/Observer.h
blob: 49c9b3c2ab0926f1b8c719767261a6f314f54814 (plain)
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
 *  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.
 */

#pragma once

#include "threads/CriticalSection.h"

#include <atomic>
#include <vector>

class Observable;
class ObservableMessageJob;

typedef enum
{
  ObservableMessageNone,
  ObservableMessagePeripheralsChanged,
  ObservableMessageSettingsChanged,
  ObservableMessageButtonMapsChanged,
  // Used for example when the subtitle alignment position change
  ObservableMessagePositionChanged,
  ObservableMessageGamePortsChanged,
  ObservableMessageGameAgentsChanged,
} ObservableMessage;

class Observer
{
public:
  Observer() = default;
  virtual ~Observer() = default;
  /*!
   * @brief Process a message from an observable.
   * @param obs The observable that sends the message.
   * @param msg The message.
   */
  virtual void Notify(const Observable &obs, const ObservableMessage msg) = 0;
};

class Observable
{
  friend class ObservableMessageJob;

public:
  Observable() = default;
  virtual ~Observable() = default;
  Observable& operator=(const Observable& observable);

  /*!
   * @brief Register an observer.
   * @param obs The observer to register.
   */
  virtual void RegisterObserver(Observer *obs);

  /*!
   * @brief Unregister an observer.
   * @param obs The observer to unregister.
   */
  virtual void UnregisterObserver(Observer *obs);

  /*!
   * @brief Send a message to all observers when m_bObservableChanged is true.
   * @param message The message to send.
   */
  virtual void NotifyObservers(const ObservableMessage message = ObservableMessageNone);

  /*!
   * @brief Mark an observable changed.
   * @param bSetTo True to mark the observable changed, false to mark it as unchanged.
   */
  virtual void SetChanged(bool bSetTo = true);

  /*!
   * @brief Check whether this observable is being observed by an observer.
   * @param obs The observer to check.
   * @return True if this observable is being observed by the given observer, false otherwise.
   */
  virtual bool IsObserving(const Observer &obs) const;

protected:
  /*!
   * @brief Send a message to all observer when m_bObservableChanged is true.
   * @param obs The observer that sends the message.
   * @param message The message to send.
   */
  void SendMessage(const ObservableMessage message);

  std::atomic<bool>       m_bObservableChanged{false}; /*!< true when the observable is marked as changed, false otherwise */
  std::vector<Observer *> m_observers;                 /*!< all observers */
  mutable CCriticalSection m_obsCritSection; /*!< mutex */
};