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 #ifndef META_EXT_OBJECT_FACTORY_H
16 #define META_EXT_OBJECT_FACTORY_H
17 
18 #include <meta/interface/interface_helpers.h>
19 #include <meta/interface/intf_object_factory.h>
20 #include <meta/interface/intf_object_registry.h>
21 
22 #if defined(GetClassInfo)
23 #undef GetClassInfo
24 #endif
25 
META_BEGIN_NAMESPACE()26 META_BEGIN_NAMESPACE()
27 
28 /**
29  * @brief A base class which can be used to implement custom object factories.
30  */
31 class ObjectFactory : public IObjectFactory {
32     // Ignore refcounts as DefaultObjectFactory is always created as static object
33     // for the class for which it implements a factory.
34     void Ref() override {}
35     void Unref() override {}
36 
37 public:
38     ObjectFactory(const META_NS::ClassInfo& info) : info_(info) {}
39     CORE_NS::IInterface* GetInterface(const BASE_NS::Uid& uid) override
40     {
41         if (uid == CORE_NS::IInterface::UID) {
42             return this;
43         }
44         if (uid == IClassInfo::UID) {
45             return this;
46         }
47         if (uid == IObjectFactory::UID) {
48             return this;
49         }
50         return nullptr;
51     }
52     const CORE_NS::IInterface* GetInterface(const BASE_NS::Uid& uid) const override
53     {
54         return const_cast<ObjectFactory*>(this)->GetInterface(uid);
55     }
56     const META_NS::ClassInfo& GetClassInfo() const override
57     {
58         return info_;
59     }
60 
61 private:
62     META_NS::ClassInfo info_;
63 };
64 
65 template<typename FinalClass>
66 class PlainObjectFactory : public ObjectFactory {
67 public:
PlainObjectFactory(const META_NS::ClassInfo & info)68     PlainObjectFactory(const META_NS::ClassInfo& info) : ObjectFactory(info) {}
CreateInstance()69     IObject::Ptr CreateInstance() const override
70     {
71         return IObject::Ptr { new FinalClass };
72     }
73 };
74 
75 /**
76  * @brief The DefaultObjectFactory class implements the default object factory used
77  *        by ObjectFwd and such.
78  */
79 template<typename FinalClass>
80 class DefaultObjectFactory final : public PlainObjectFactory<FinalClass> {
81 public:
DefaultObjectFactory(const META_NS::ClassInfo & info)82     DefaultObjectFactory(const META_NS::ClassInfo& info) : PlainObjectFactory<FinalClass>(info) {}
GetClassStaticMetadata()83     const StaticObjectMetadata& GetClassStaticMetadata() const override
84     {
85         return FinalClass::GetStaticObjectMetadata();
86     }
GetClassInterfaces()87     const BASE_NS::vector<BASE_NS::Uid>& GetClassInterfaces() const override
88     {
89         static auto interfaces = FinalClass::GetStaticInterfaces();
90         return interfaces;
91     }
92 };
93 
94 /**
95  *  Helper macro for creating ObjectTypeInfo with machinery to register a class using the default object
96  *  factory and creating instances of it.
97  */
98 #define META_DEFINE_OBJECT_TYPE_INFO(FinalClass, ClassInfo)                                                      \
99     friend class META_NS::DefaultObjectFactory<FinalClass>;                                                      \
100                                                                                                                  \
101 public:                                                                                                          \
102     static META_NS::IObjectFactory::Ptr GetFactory()                                                             \
103     {                                                                                                            \
104         static META_NS::DefaultObjectFactory<FinalClass> factory(ClassInfo);                                     \
105         return META_NS::IObjectFactory::Ptr { &factory };                                                        \
106     }                                                                                                            \
107     static constexpr const META_NS::ObjectTypeInfo OBJECT_INFO { { META_NS::ObjectTypeInfo::UID }, GetFactory }; \
108                                                                                                                  \
109 private:
110 
111 META_END_NAMESPACE()
112 
113 #endif
114