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 FOUNDATION_ACE_FRAMEWORKS_BASE_UTILS_VALUE_CHANGE_NOTIFIER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_BASE_UTILS_VALUE_CHANGE_NOTIFIER_H
18 
19 #include <list>
20 
21 #include "base/memory/ace_type.h"
22 #include "base/utils/noncopyable.h"
23 
24 namespace OHOS::Ace {
25 
26 class ValueChangeObserver : public virtual AceType {
27     DECLARE_ACE_TYPE(ValueChangeObserver, AceType);
28 
29 public:
30     virtual void OnValueChanged(bool needFireChangeEvent = true, bool needFireSelectChangeEvent = true) = 0;
31 
32 protected:
33     ValueChangeObserver() = default;
34     ~ValueChangeObserver() override = default;
35 
36     ACE_DISALLOW_COPY_AND_MOVE(ValueChangeObserver);
37 };
38 
39 /**
40  * @brief Used for observe a value change.
41  * @see example as TextEditController.
42  *
43  * Note: Make sure all methods calling on same thread.
44  *
45  * @tparam U is the value type.
46  */
47 template<class U>
48 class ValueChangeNotifier : public virtual AceType {
49     DECLARE_ACE_TYPE(ValueChangeNotifier<U>, AceType);
50 
51 public:
AddObserver(const WeakPtr<ValueChangeObserver> & observer)52     void AddObserver(const WeakPtr<ValueChangeObserver>& observer)
53     {
54         observers_.emplace_back(observer);
55     }
56 
RemoveObserver(const WeakPtr<ValueChangeObserver> & observer)57     void RemoveObserver(const WeakPtr<ValueChangeObserver>& observer)
58     {
59         observers_.remove(observer);
60     }
61 
62     void SetValue(U&& newValue, bool needFireChangeEvent = true)
63     {
64         if (newValue == value_) {
65             return;
66         }
67 
68         preValue_ = value_;
69         value_ = std::move(newValue);
70         Notify(needFireChangeEvent);
71     }
72 
73     void SetValue(const U& newValue, bool needFireChangeEvent = true)
74     {
75         if (newValue == value_) {
76             return;
77         }
78 
79         preValue_ = value_;
80         value_ = newValue;
81         Notify(needFireChangeEvent);
82     }
83 
GetValue()84     const U& GetValue() const
85     {
86         return value_;
87     }
88 
GetPreValue()89     const U& GetPreValue() const
90     {
91         return preValue_;
92     }
93 
94 private:
95     void Notify(bool needFireChangeEvent = true)
96     {
97         auto iter = observers_.begin();
98         while (iter != observers_.end()) {
99             const auto& observer = iter->Upgrade();
100             if (observer) {
101                 observer->OnValueChanged(needFireChangeEvent);
102                 iter++;
103             } else {
104                 iter = observers_.erase(iter);
105             }
106         }
107     }
108 
109     std::list<WeakPtr<ValueChangeObserver>> observers_;
110 
111     U value_;
112     U preValue_;
113 };
114 
115 }  // namespace OHOS::Ace
116 
117 #endif // FOUNDATION_ACE_FRAMEWORKS_BASE_UTILS_VALUE_CHANGE_NOTIFIER_H
118