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 
24 namespace OHOS {
25 
26 /**
27  * @brief Provides the parameters and data required to call the update method.
28  */
29 struct ObserverArg {
30 public:
31     virtual ~ObserverArg() = default;
32 };
33 
34 /**
35  * @brief Implements the <b>Observer</b> class.
36  */
37 class Observer;
38 
39 /**
40  * @brief Implements the observed class.
41  */
42 class Observable {
43 public:
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 
88 protected:
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 
107 protected:
108     std::set<std::shared_ptr<Observer>> obs; // A collection of observers.
109     std::mutex mutex_;
110 
111 private:
112     bool changed_ = false; // The state of this Observable object.
113 };
114 
115 class Observer {
116 public:
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