1e0dac50fSopenharmony_ci/* 2e0dac50fSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3e0dac50fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e0dac50fSopenharmony_ci * you may not use this file except in compliance with the License. 5e0dac50fSopenharmony_ci * You may obtain a copy of the License at 6e0dac50fSopenharmony_ci * 7e0dac50fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e0dac50fSopenharmony_ci * 9e0dac50fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e0dac50fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e0dac50fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e0dac50fSopenharmony_ci * See the License for the specific language governing permissions and 13e0dac50fSopenharmony_ci * limitations under the License. 14e0dac50fSopenharmony_ci */ 15e0dac50fSopenharmony_ci 16e0dac50fSopenharmony_ci#include "singleton_container.h" 17e0dac50fSopenharmony_ci#include <mutex> 18e0dac50fSopenharmony_ci#include "window_manager_hilog.h" 19e0dac50fSopenharmony_ci 20e0dac50fSopenharmony_cinamespace OHOS { 21e0dac50fSopenharmony_cinamespace Rosen { 22e0dac50fSopenharmony_cinamespace { 23e0dac50fSopenharmony_ciconstexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SingletonContainer"}; 24e0dac50fSopenharmony_ci} // namespace 25e0dac50fSopenharmony_ciWM_IMPLEMENT_SINGLE_INSTANCE(SingletonContainer) 26e0dac50fSopenharmony_ci 27e0dac50fSopenharmony_ciSingletonContainer::~SingletonContainer() 28e0dac50fSopenharmony_ci{ 29e0dac50fSopenharmony_ci destroyed_ = true; 30e0dac50fSopenharmony_ci while (singletonMap.empty() == false) { 31e0dac50fSopenharmony_ci auto it = singletonMap.begin(); 32e0dac50fSopenharmony_ci while (it != singletonMap.end()) { 33e0dac50fSopenharmony_ci if (it->second.refCount > 0) { 34e0dac50fSopenharmony_ci it++; 35e0dac50fSopenharmony_ci continue; 36e0dac50fSopenharmony_ci } 37e0dac50fSopenharmony_ci 38e0dac50fSopenharmony_ci if (dependencySetMap.find(it->first) != dependencySetMap.end()) { 39e0dac50fSopenharmony_ci for (auto mid : dependencySetMap[it->first]) { 40e0dac50fSopenharmony_ci singletonMap[mid].refCount--; 41e0dac50fSopenharmony_ci } 42e0dac50fSopenharmony_ci dependencySetMap.erase(it->first); 43e0dac50fSopenharmony_ci } 44e0dac50fSopenharmony_ci 45e0dac50fSopenharmony_ci for (const auto &[k, v] : stringMap) { 46e0dac50fSopenharmony_ci if (v == it->first) { 47e0dac50fSopenharmony_ci WLOGFD("remove %{public}s", k.c_str()); 48e0dac50fSopenharmony_ci break; 49e0dac50fSopenharmony_ci } 50e0dac50fSopenharmony_ci } 51e0dac50fSopenharmony_ci singletonMap.erase(it++); 52e0dac50fSopenharmony_ci } 53e0dac50fSopenharmony_ci } 54e0dac50fSopenharmony_ci} 55e0dac50fSopenharmony_ci 56e0dac50fSopenharmony_civoid SingletonContainer::AddSingleton(const std::string& name, void* instance) 57e0dac50fSopenharmony_ci{ 58e0dac50fSopenharmony_ci if (stringMap.find(name) == stringMap.end()) { 59e0dac50fSopenharmony_ci static int32_t nextId = 0; 60e0dac50fSopenharmony_ci singletonMap[nextId].value = instance; 61e0dac50fSopenharmony_ci singletonMap[nextId].refCount = 0; 62e0dac50fSopenharmony_ci WLOGD("add %{public}s", name.c_str()); 63e0dac50fSopenharmony_ci stringMap[name] = nextId++; 64e0dac50fSopenharmony_ci } else { 65e0dac50fSopenharmony_ci WLOGFE("add failed: %{public}s", name.c_str()); 66e0dac50fSopenharmony_ci } 67e0dac50fSopenharmony_ci} 68e0dac50fSopenharmony_ci 69e0dac50fSopenharmony_civoid SingletonContainer::SetSingleton(const std::string& name, void* instance) 70e0dac50fSopenharmony_ci{ 71e0dac50fSopenharmony_ci if (stringMap.find(name) == stringMap.end()) { 72e0dac50fSopenharmony_ci AddSingleton(name, instance); 73e0dac50fSopenharmony_ci } else { 74e0dac50fSopenharmony_ci WLOGI("set %{public}s", name.c_str()); 75e0dac50fSopenharmony_ci singletonMap[stringMap[name]].value = instance; 76e0dac50fSopenharmony_ci } 77e0dac50fSopenharmony_ci} 78e0dac50fSopenharmony_ci 79e0dac50fSopenharmony_civoid* SingletonContainer::GetSingleton(const std::string& name) 80e0dac50fSopenharmony_ci{ 81e0dac50fSopenharmony_ci if (stringMap.find(name) == stringMap.end()) { 82e0dac50fSopenharmony_ci WLOGFE("can not get %{public}s", name.c_str()); 83e0dac50fSopenharmony_ci return nullptr; 84e0dac50fSopenharmony_ci } 85e0dac50fSopenharmony_ci if (singletonMap.find(stringMap[name]) == singletonMap.end()) { 86e0dac50fSopenharmony_ci WLOGFE("can not find singleton, name is %{public}s", name.c_str()); 87e0dac50fSopenharmony_ci return nullptr; 88e0dac50fSopenharmony_ci } 89e0dac50fSopenharmony_ci return singletonMap[stringMap[name]].value; 90e0dac50fSopenharmony_ci} 91e0dac50fSopenharmony_ci 92e0dac50fSopenharmony_civoid* SingletonContainer::DependOn(const std::string& instance, const std::string& name) 93e0dac50fSopenharmony_ci{ 94e0dac50fSopenharmony_ci auto& instanceDependencySet = dependencySetMap[stringMap[instance]]; 95e0dac50fSopenharmony_ci if (instanceDependencySet.find(stringMap[name]) == instanceDependencySet.end()) { 96e0dac50fSopenharmony_ci WLOGFD("%{public}s DependOn %{public}s", instance.c_str(), name.c_str()); 97e0dac50fSopenharmony_ci instanceDependencySet.insert(stringMap[name]); 98e0dac50fSopenharmony_ci singletonMap[stringMap[name]].refCount++; 99e0dac50fSopenharmony_ci } 100e0dac50fSopenharmony_ci return GetSingleton(name); 101e0dac50fSopenharmony_ci} 102e0dac50fSopenharmony_ci} // namespace Rosen 103e0dac50fSopenharmony_ci} // namespace OHOS 104