• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 SHAREDDATA_H
17 #define SHAREDDATA_H
18 
19 #include <functional>
20 #include <list>
21 #include <map>
22 #include <mutex>
23 #include <thread>
24 
25 #include "SharedDataManager.h"
26 #include "PreviewerEngineLog.h"
27 
28 template<typename T> class SharedData {
29 public:
SharedData()30     SharedData() : value(), isChanged(false), minValue(), maxValue() {}
31 
~SharedData()32     ~SharedData() {}
33 
value(v)34     SharedData(SharedDataType type, T v, T min = T(), T max = T()) : value(v), minValue(min), maxValue(max)
35     {
36         staticDataMutex.lock();
37         isChanged = false;
38         dataMap[type] = *this;
39         staticDataMutex.unlock();
40 
41         SharedDataManager::AddChecker(SharedData<T>::CheckAll);
42     }
43 
SetData(SharedDataType type,T v)44     static bool SetData(SharedDataType type, T v)
45     {
46         staticDataMutex.lock();
47         if (dataMap.find(type) == dataMap.end()) {
48             staticDataMutex.unlock();
49             FLOG("SharedData::SetData invalid data type.");
50             return false;
51         }
52 
53         SharedData data = dataMap[type];
54         if ((data.minValue != data.maxValue) && (v < data.minValue || v > data.maxValue)) {
55             staticDataMutex.unlock();
56             return false;
57         }
58         data.value = v;
59         data.isChanged = true;
60         dataMap[type] = data;
61         staticDataMutex.unlock();
62         return true;
63     }
64 
GetData(SharedDataType type)65     static T GetData(SharedDataType type)
66     {
67         const std::lock_guard<std::mutex> lock(staticDataMutex);
68         if (dataMap.find(type) == dataMap.end()) {
69             FLOG("SharedData::GetData invalid data type.");
70         }
71 
72         return dataMap[type].value;
73     }
74 
IsValid(SharedDataType type,T v)75     static bool IsValid(SharedDataType type, T v)
76     {
77         const std::lock_guard<std::mutex> lock(staticDataMutex);
78         if (dataMap.find(type) == dataMap.end()) {
79             FLOG("SharedData::IsValid invalid data type.");
80         }
81 
82         if ((dataMap[type].minValue != dataMap[type].maxValue) &&
83             (v < dataMap[type].minValue || v > dataMap[type].maxValue)) {
84             ILOG("%d %d %d", v, dataMap[type].minValue, dataMap[type].maxValue);
85             return false;
86         }
87 
88         return true;
89     }
90 
91     /*
92      * Checks whether the current data is changed.
93      * Return a list of data changed callback
94      */
Check()95     std::list<std::pair<std::function<void(T)>, T>> Check()
96     {
97         std::thread::id curThreadId = std::this_thread::get_id();
98         if (ticksMap.find(curThreadId) == ticksMap.end()) {
99             ticksMap[curThreadId] = 0;
100         }
101         uint32_t ticks = ticksMap[curThreadId] + 1;
102         ticksMap[curThreadId] = ticks;
103 
104         std::list<std::pair<std::function<void(T)>, T>> pairs;
105         if (!isChanged) {
106             return pairs;
107         }
108         for (auto iter = callBacks.begin(); iter != callBacks.end(); ++iter) {
109             if (iter->first == curThreadId && ticks % iter->second.second == 0) {
110                 isChanged = false;
111                 pairs.push_back(std::make_pair(iter->second.first, value));
112             }
113         }
114 
115         return pairs;
116     }
117 
118     /*
119      * Add a data changed callback
120      * type: Checked data type
121      * func: Callback
122      * threadId: Checks and callbacks are performed only in this thread.
123      * period: Indicates the detection period. The unit is 100 ms.
124      */
125     static void
126         AppendNotify(SharedDataType type, std::function<void(T)> func, std::thread::id threadId, uint32_t period = 1)
127     {
128         staticDataMutex.lock();
129         if (dataMap.find(type) == dataMap.end()) {
130             FLOG("SharedData::IsValid invalid data type.");
131         }
132         dataMap[type].callBacks[threadId] = std::pair<std::function<void(T)>, uint32_t>(func, period);
133         staticDataMutex.unlock();
134     }
135 
136     // Check whether the data is changes and execute the notification callback.
CheckAll()137     static void CheckAll()
138     {
139         std::list<std::pair<std::function<void(T)>, T>> pairs;
140         staticDataMutex.lock();
141         for (auto dataIter = dataMap.begin(); dataIter != dataMap.end(); ++dataIter) {
142             auto checkers = dataIter->second.Check();
143             pairs.insert(pairs.end(), checkers.begin(), checkers.end());
144         }
145         staticDataMutex.unlock();
146 
147         for (auto pair : pairs) {
148             pair.first(pair.second);
149         }
150     }
151 
152 private:
153     T value;
154     bool isChanged;
155     T minValue;
156     T maxValue;
157     // map<thread id, pair<callback, detection period>>
158     std::map<std::thread::id, std::pair<std::function<void(T)>, uint32_t>> callBacks;
159     // map<thread id, current time tick>
160     std::map<std::thread::id, uint32_t> ticksMap;
161     static std::map<SharedDataType, SharedData> dataMap;
162     static std::mutex staticDataMutex;
163 };
164 
165 template<typename T> std::map<SharedDataType, SharedData<T>> SharedData<T>::dataMap;
166 
167 template<typename T> std::mutex SharedData<T>::staticDataMutex;
168 
169 #endif // SHAREDDATA_H
170