1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef UTILS_BASE_OBSERVER_H
17#define UTILS_BASE_OBSERVER_H
18
19#include <memory>
20#include <vector>
21#include <set>
22#include <mutex>
23
24namespace OHOS {
25
26/**
27 * @brief Provides the parameters and data required to call the update method.
28 */
29struct ObserverArg {
30public:
31    virtual ~ObserverArg() = default;
32};
33
34/**
35 * @brief Implements the <b>Observer</b> class.
36 */
37class Observer;
38
39/**
40 * @brief Implements the observed class.
41 */
42class Observable {
43public:
44    virtual ~Observable() = default;
45    /**
46     * @brief Adds the specified observer to the set of observers.
47     *
48     * If `o` is valid and does not exist in the observer set, the observer
49     * will be added; otherwise, this function will return directly.
50     */
51    void AddObserver(const std::shared_ptr<Observer>& o);
52
53    /**
54     * @brief Removes the specified observer.
55     */
56    void RemoveObserver(const std::shared_ptr<Observer>& o);
57
58    /**
59     * @brief Removes all observers.
60     */
61    void RemoveAllObservers();
62
63    /**
64     * @brief Notifies all observers with no data passed.
65     *
66     * This function is equivalent to <b>NotifyObservers(nullptr)</b>.
67     */
68    void NotifyObservers();
69
70    /**
71     * @brief Notifies all observers, with the data 'arg' passed to
72	 * the observers.
73     *
74     * If `changed_` is true, call the `Update()` function to notify all
75     * observers to respond.
76     *
77     * @param arg Indicates the parameters and data to be used for
78	 * <b>Observer::Update()</b>.
79     * @see ObserverArg.
80     */
81    void NotifyObservers(const ObserverArg* arg);
82
83    /**
84     * @brief Obtains the number of observers.
85     */
86    int GetObserversCount();
87
88protected:
89
90    /**
91     * @brief Obtains the state of this <b>Observable</b> object.
92     *
93     * @return Returns the value of `changed_`.
94     */
95    bool HasChanged();
96
97    /**
98     * @brief Sets the state of this <b>Observable</b> object to true.
99     */
100    void SetChanged();
101
102    /**
103     * @brief Set the state of this <b>Observable</b> object to false.
104     */
105    void ClearChanged();
106
107protected:
108    std::set<std::shared_ptr<Observer>> obs; // A collection of observers.
109    std::mutex mutex_;
110
111private:
112    bool changed_ = false; // The state of this Observable object.
113};
114
115class Observer {
116public:
117    virtual ~Observer() = default;
118    /**
119     * @brief Updates this observer.
120     *
121     * It will be called when this observer is notified by an
122	 * <b>Observable</b> object.
123     */
124    virtual void Update(const Observable* o, const ObserverArg* arg) = 0;
125};
126}
127#endif