1 /* 2 * Copyright (c) 2024 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_ARKUI_ACE_ENGINE_FRAMEWORKS_CORE_COMMON_UPDATE_CONFIG_MANAGER_H 17 #define FOUNDATION_ARKUI_ACE_ENGINE_FRAMEWORKS_CORE_COMMON_UPDATE_CONFIG_MANAGER_H 18 19 #include <mutex> 20 #include <string> 21 #include <thread> 22 23 #include "base/memory/ace_type.h" 24 #include "base/thread/cancelable_callback.h" 25 #include "base/thread/task_executor.h" 26 #include "core/common/container.h" 27 28 namespace OHOS::Ace { 29 template<class T> 30 class UpdateConfigManager : public virtual AceType { 31 DECLARE_ACE_TYPE(UpdateConfigManager<T>, AceType); 32 public: 33 struct UpdateTask { 34 CancelableCallback<void()> updateTask; 35 T target; 36 }; 37 UpdateConfigSync(const T & config,std::function<void ()> && task)38 void UpdateConfigSync(const T& config, std::function<void()> &&task) 39 { 40 // Update current state 41 { 42 std::lock_guard<std::mutex> taskLock(updateTaskMutex_); 43 currentTask_.updateTask.Cancel(); 44 currentTask_.target = config; 45 } 46 47 task(); 48 } 49 50 void UpdatePromiseConfig(const T& config, std::function<void()> &&task, const RefPtr<Container>& container, 51 const std::string& taskName, TaskExecutor::TaskType type = TaskExecutor::TaskType::PLATFORM) 52 { 53 std::lock_guard<std::mutex> taskLock(updateTaskMutex_); 54 CancelUselessTaskLocked(); 55 currentTask_.target = config; 56 57 auto taskExecutor = container->GetTaskExecutor(); 58 CHECK_NULL_VOID(taskExecutor); 59 taskExecutor->PostTask(std::move(task), type, taskName); 60 } 61 62 void UpdateConfig(const T& config, std::function<void()> &&task, const RefPtr<Container>& container, 63 const std::string& taskName, TaskExecutor::TaskType type = TaskExecutor::TaskType::PLATFORM) 64 { 65 CancelableCallback<void()> cancelableTask(std::move(task)); 66 67 std::lock_guard<std::mutex> taskLock(updateTaskMutex_); 68 if (config == currentTask_.target) { 69 // If config is same as current/next state, return directely. 70 return; 71 } else { 72 // Try to cancel useless task. 73 CancelUselessTaskLocked(); 74 // Post new task. 75 PostUpdateConfigTaskLocked(config, std::move(cancelableTask), container, taskName, type); 76 } 77 } 78 StoreConfig(T & config)79 void StoreConfig(T& config) 80 { 81 aceConfig_ = config; 82 } 83 IsConfigsEqual(const ViewportConfig & other)84 bool IsConfigsEqual(const ViewportConfig& other) 85 { 86 return aceConfig_.config_ == other; 87 } 88 private: PostUpdateConfigTaskLocked(const T & config,CancelableCallback<void ()> && task,const RefPtr<Container> & container,const std::string & taskName,TaskExecutor::TaskType type)89 void PostUpdateConfigTaskLocked(const T& config, CancelableCallback<void()> &&task, 90 const RefPtr<Container>& container, const std::string& taskName, TaskExecutor::TaskType type) 91 { 92 currentTask_ = { 93 .updateTask = std::move(task), 94 .target = config, 95 }; 96 auto taskExecutor = container->GetTaskExecutor(); 97 CHECK_NULL_VOID(taskExecutor); 98 taskExecutor->PostTask(currentTask_.updateTask, type, taskName); 99 } 100 CancelUselessTaskLocked()101 void CancelUselessTaskLocked() 102 { 103 currentTask_.updateTask.Cancel(); 104 } 105 106 std::mutex updateTaskMutex_; 107 108 UpdateTask currentTask_; 109 110 T aceConfig_; 111 }; 112 } // OHOS::Ace 113 #endif // FOUNDATION_ARKUI_ACE_ENGINE_FRAMEWORKS_CORE_COMMON_UPDATE_CONFIG_MANAGER_H 114