17c804472Sopenharmony_ci/* 27c804472Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 37c804472Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 47c804472Sopenharmony_ci * you may not use this file except in compliance with the License. 57c804472Sopenharmony_ci * You may obtain a copy of the License at 67c804472Sopenharmony_ci * 77c804472Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 87c804472Sopenharmony_ci * 97c804472Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 107c804472Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 117c804472Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 127c804472Sopenharmony_ci * See the License for the specific language governing permissions and 137c804472Sopenharmony_ci * limitations under the License. 147c804472Sopenharmony_ci */ 157c804472Sopenharmony_ci 167c804472Sopenharmony_ci#ifndef SHAREDDATA_H 177c804472Sopenharmony_ci#define SHAREDDATA_H 187c804472Sopenharmony_ci 197c804472Sopenharmony_ci#include <functional> 207c804472Sopenharmony_ci#include <list> 217c804472Sopenharmony_ci#include <map> 227c804472Sopenharmony_ci#include <mutex> 237c804472Sopenharmony_ci#include <thread> 247c804472Sopenharmony_ci 257c804472Sopenharmony_ci#include "SharedDataManager.h" 267c804472Sopenharmony_ci#include "PreviewerEngineLog.h" 277c804472Sopenharmony_ci 287c804472Sopenharmony_citemplate<typename T> class SharedData { 297c804472Sopenharmony_cipublic: 307c804472Sopenharmony_ci SharedData() : value(), isChanged(false), minValue(), maxValue() {} 317c804472Sopenharmony_ci 327c804472Sopenharmony_ci ~SharedData() {} 337c804472Sopenharmony_ci 347c804472Sopenharmony_ci SharedData(SharedDataType type, T v, T min = T(), T max = T()) : value(v), minValue(min), maxValue(max) 357c804472Sopenharmony_ci { 367c804472Sopenharmony_ci staticDataMutex.lock(); 377c804472Sopenharmony_ci isChanged = false; 387c804472Sopenharmony_ci dataMap[type] = *this; 397c804472Sopenharmony_ci staticDataMutex.unlock(); 407c804472Sopenharmony_ci 417c804472Sopenharmony_ci SharedDataManager::AddChecker(SharedData<T>::CheckAll); 427c804472Sopenharmony_ci } 437c804472Sopenharmony_ci 447c804472Sopenharmony_ci static bool SetData(SharedDataType type, T v) 457c804472Sopenharmony_ci { 467c804472Sopenharmony_ci staticDataMutex.lock(); 477c804472Sopenharmony_ci if (dataMap.find(type) == dataMap.end()) { 487c804472Sopenharmony_ci staticDataMutex.unlock(); 497c804472Sopenharmony_ci FLOG("SharedData::SetData invalid data type."); 507c804472Sopenharmony_ci return false; 517c804472Sopenharmony_ci } 527c804472Sopenharmony_ci 537c804472Sopenharmony_ci SharedData data = dataMap[type]; 547c804472Sopenharmony_ci if ((data.minValue != data.maxValue) && (v < data.minValue || v > data.maxValue)) { 557c804472Sopenharmony_ci staticDataMutex.unlock(); 567c804472Sopenharmony_ci return false; 577c804472Sopenharmony_ci } 587c804472Sopenharmony_ci data.value = v; 597c804472Sopenharmony_ci data.isChanged = true; 607c804472Sopenharmony_ci dataMap[type] = data; 617c804472Sopenharmony_ci staticDataMutex.unlock(); 627c804472Sopenharmony_ci return true; 637c804472Sopenharmony_ci } 647c804472Sopenharmony_ci 657c804472Sopenharmony_ci static T GetData(SharedDataType type) 667c804472Sopenharmony_ci { 677c804472Sopenharmony_ci const std::lock_guard<std::mutex> lock(staticDataMutex); 687c804472Sopenharmony_ci if (dataMap.find(type) == dataMap.end()) { 697c804472Sopenharmony_ci FLOG("SharedData::GetData invalid data type."); 707c804472Sopenharmony_ci } 717c804472Sopenharmony_ci 727c804472Sopenharmony_ci return dataMap[type].value; 737c804472Sopenharmony_ci } 747c804472Sopenharmony_ci 757c804472Sopenharmony_ci static bool IsValid(SharedDataType type, T v) 767c804472Sopenharmony_ci { 777c804472Sopenharmony_ci const std::lock_guard<std::mutex> lock(staticDataMutex); 787c804472Sopenharmony_ci if (dataMap.find(type) == dataMap.end()) { 797c804472Sopenharmony_ci FLOG("SharedData::IsValid invalid data type."); 807c804472Sopenharmony_ci } 817c804472Sopenharmony_ci 827c804472Sopenharmony_ci if ((dataMap[type].minValue != dataMap[type].maxValue) && 837c804472Sopenharmony_ci (v < dataMap[type].minValue || v > dataMap[type].maxValue)) { 847c804472Sopenharmony_ci ILOG("%d %d %d", v, dataMap[type].minValue, dataMap[type].maxValue); 857c804472Sopenharmony_ci return false; 867c804472Sopenharmony_ci } 877c804472Sopenharmony_ci 887c804472Sopenharmony_ci return true; 897c804472Sopenharmony_ci } 907c804472Sopenharmony_ci 917c804472Sopenharmony_ci /* 927c804472Sopenharmony_ci * Checks whether the current data is changed. 937c804472Sopenharmony_ci * Return a list of data changed callback 947c804472Sopenharmony_ci */ 957c804472Sopenharmony_ci std::list<std::pair<std::function<void(T)>, T>> Check() 967c804472Sopenharmony_ci { 977c804472Sopenharmony_ci std::thread::id curThreadId = std::this_thread::get_id(); 987c804472Sopenharmony_ci if (ticksMap.find(curThreadId) == ticksMap.end()) { 997c804472Sopenharmony_ci ticksMap[curThreadId] = 0; 1007c804472Sopenharmony_ci } 1017c804472Sopenharmony_ci uint32_t ticks = ticksMap[curThreadId] + 1; 1027c804472Sopenharmony_ci ticksMap[curThreadId] = ticks; 1037c804472Sopenharmony_ci 1047c804472Sopenharmony_ci std::list<std::pair<std::function<void(T)>, T>> pairs; 1057c804472Sopenharmony_ci if (!isChanged) { 1067c804472Sopenharmony_ci return pairs; 1077c804472Sopenharmony_ci } 1087c804472Sopenharmony_ci for (auto iter = callBacks.begin(); iter != callBacks.end(); ++iter) { 1097c804472Sopenharmony_ci if (iter->first == curThreadId && ticks % iter->second.second == 0) { 1107c804472Sopenharmony_ci isChanged = false; 1117c804472Sopenharmony_ci pairs.push_back(std::make_pair(iter->second.first, value)); 1127c804472Sopenharmony_ci } 1137c804472Sopenharmony_ci } 1147c804472Sopenharmony_ci 1157c804472Sopenharmony_ci return pairs; 1167c804472Sopenharmony_ci } 1177c804472Sopenharmony_ci 1187c804472Sopenharmony_ci /* 1197c804472Sopenharmony_ci * Add a data changed callback 1207c804472Sopenharmony_ci * type: Checked data type 1217c804472Sopenharmony_ci * func: Callback 1227c804472Sopenharmony_ci * threadId: Checks and callbacks are performed only in this thread. 1237c804472Sopenharmony_ci * period: Indicates the detection period. The unit is 100 ms. 1247c804472Sopenharmony_ci */ 1257c804472Sopenharmony_ci static void 1267c804472Sopenharmony_ci AppendNotify(SharedDataType type, std::function<void(T)> func, std::thread::id threadId, uint32_t period = 1) 1277c804472Sopenharmony_ci { 1287c804472Sopenharmony_ci staticDataMutex.lock(); 1297c804472Sopenharmony_ci if (dataMap.find(type) == dataMap.end()) { 1307c804472Sopenharmony_ci FLOG("SharedData::IsValid invalid data type."); 1317c804472Sopenharmony_ci } 1327c804472Sopenharmony_ci dataMap[type].callBacks[threadId] = std::pair<std::function<void(T)>, uint32_t>(func, period); 1337c804472Sopenharmony_ci staticDataMutex.unlock(); 1347c804472Sopenharmony_ci } 1357c804472Sopenharmony_ci 1367c804472Sopenharmony_ci // Check whether the data is changes and execute the notification callback. 1377c804472Sopenharmony_ci static void CheckAll() 1387c804472Sopenharmony_ci { 1397c804472Sopenharmony_ci std::list<std::pair<std::function<void(T)>, T>> pairs; 1407c804472Sopenharmony_ci staticDataMutex.lock(); 1417c804472Sopenharmony_ci for (auto dataIter = dataMap.begin(); dataIter != dataMap.end(); ++dataIter) { 1427c804472Sopenharmony_ci auto checkers = dataIter->second.Check(); 1437c804472Sopenharmony_ci pairs.insert(pairs.end(), checkers.begin(), checkers.end()); 1447c804472Sopenharmony_ci } 1457c804472Sopenharmony_ci staticDataMutex.unlock(); 1467c804472Sopenharmony_ci 1477c804472Sopenharmony_ci for (auto pair : pairs) { 1487c804472Sopenharmony_ci pair.first(pair.second); 1497c804472Sopenharmony_ci } 1507c804472Sopenharmony_ci } 1517c804472Sopenharmony_ci 1527c804472Sopenharmony_ciprivate: 1537c804472Sopenharmony_ci T value; 1547c804472Sopenharmony_ci bool isChanged; 1557c804472Sopenharmony_ci T minValue; 1567c804472Sopenharmony_ci T maxValue; 1577c804472Sopenharmony_ci // map<thread id, pair<callback, detection period>> 1587c804472Sopenharmony_ci std::map<std::thread::id, std::pair<std::function<void(T)>, uint32_t>> callBacks; 1597c804472Sopenharmony_ci // map<thread id, current time tick> 1607c804472Sopenharmony_ci std::map<std::thread::id, uint32_t> ticksMap; 1617c804472Sopenharmony_ci static std::map<SharedDataType, SharedData> dataMap; 1627c804472Sopenharmony_ci static std::mutex staticDataMutex; 1637c804472Sopenharmony_ci}; 1647c804472Sopenharmony_ci 1657c804472Sopenharmony_citemplate<typename T> std::map<SharedDataType, SharedData<T>> SharedData<T>::dataMap; 1667c804472Sopenharmony_ci 1677c804472Sopenharmony_citemplate<typename T> std::mutex SharedData<T>::staticDataMutex; 1687c804472Sopenharmony_ci 1697c804472Sopenharmony_ci#endif // SHAREDDATA_H 170