1/*
2 * Copyright (c) 2021-2022 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 OHOS_SINGLETON_CONTAINER_H
17#define OHOS_SINGLETON_CONTAINER_H
18
19#include <any>
20#include <cstdint>
21#include <map>
22#include <set>
23#include <string>
24
25#include "wm_single_instance.h"
26namespace OHOS {
27namespace Rosen {
28class SingletonContainer {
29WM_DECLARE_SINGLE_INSTANCE_BASE(SingletonContainer);
30
31public:
32    void AddSingleton(const std::string& name, void* instance);
33
34    void SetSingleton(const std::string& name, void* instance);
35
36    void* GetSingleton(const std::string& name);
37
38    void* DependOn(const std::string& instance, const std::string& name);
39
40    static bool IsDestroyed()
41    {
42        return SingletonContainer::GetInstance().destroyed_;
43    }
44
45    template<class T>
46    static T& Get()
47    {
48        std::string nameT = __PRETTY_FUNCTION__;
49        nameT = nameT.substr(nameT.find("T = "));
50        nameT = nameT.substr(sizeof("T ="), nameT.length() - sizeof("T = "));
51        if (SingletonContainer::GetInstance().GetSingleton(nameT) == nullptr) {
52            return T::GetInstance();
53        }
54        return *(reinterpret_cast<T*>(SingletonContainer::GetInstance().GetSingleton(nameT)));
55    }
56
57    template<class T>
58    static void Set(T& instance)
59    {
60        std::string nameT = __PRETTY_FUNCTION__;
61        nameT = nameT.substr(nameT.find("T = "));
62        nameT = nameT.substr(sizeof("T ="), nameT.length() - sizeof("T = "));
63        SingletonContainer::GetInstance().SetSingleton(nameT, &instance);
64    }
65
66private:
67    SingletonContainer() = default;
68
69    virtual ~SingletonContainer();
70
71    struct Singleton {
72        void* value;
73        int32_t refCount;
74    };
75    std::map<std::string, int32_t> stringMap;
76    std::map<int32_t, SingletonContainer::Singleton> singletonMap;
77    std::map<int32_t, std::set<int32_t>> dependencySetMap;
78    bool destroyed_ { false };
79};
80} // namespace Rosen
81} // namespace OHOS
82#endif // FRAMEWORKS_WM_INCLUDE_SINGLETON_CONTAINER_H
83