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 #include "class_registry.h"
17
18 #include <base/util/uid_util.h>
19
20 #include "meta/base/interface_utils.h"
21
META_BEGIN_NAMESPACE()22 META_BEGIN_NAMESPACE()
23
24 void ClassRegistry::Clear()
25 {
26 std::unique_lock lock { mutex_ };
27 objectFactories_.clear();
28 }
29
Unregister(const IObjectFactory::Ptr & fac)30 bool ClassRegistry::Unregister(const IObjectFactory::Ptr& fac)
31 {
32 if (!fac) {
33 CORE_LOG_E("ClassRegistry: Cannot unregister a null object factory");
34 return false;
35 }
36 size_t erased = 0;
37 {
38 std::unique_lock lock { mutex_ };
39 erased = objectFactories_.erase(fac->GetClassInfo());
40 }
41 if (erased) {
42 Invoke<IOnClassRegistrationChanged>(
43 EventOnClassUnregistered(MetadataQuery::EXISTING), ClassRegistrationInfo { fac });
44 return true;
45 }
46 return false;
47 }
48
Register(const IObjectFactory::Ptr & fac)49 bool ClassRegistry::Register(const IObjectFactory::Ptr& fac)
50 {
51 if (!fac) {
52 CORE_LOG_E("ClassRegistry: Cannot register a null object factory");
53 return false;
54 }
55 {
56 std::unique_lock lock { mutex_ };
57 auto& info = fac->GetClassInfo();
58 auto& i = objectFactories_[info];
59 if (i) {
60 CORE_LOG_W("ClassRegistry: Cannot register a class that was already registered [name=%s, uid=%s]",
61 info.Name().data(), info.Id().ToString().c_str());
62 return false;
63 }
64 i = fac;
65 }
66 Invoke<IOnClassRegistrationChanged>(EventOnClassRegistered(MetadataQuery::EXISTING), ClassRegistrationInfo { fac });
67 return true;
68 }
69
GetObjectFactory(const BASE_NS::Uid & uid) const70 IObjectFactory::ConstPtr ClassRegistry::GetObjectFactory(const BASE_NS::Uid& uid) const
71 {
72 std::shared_lock lock { mutex_ };
73 auto it = objectFactories_.find(uid);
74 return it != objectFactories_.end() ? it->second : nullptr;
75 }
76
GetClassName(BASE_NS::Uid uid) const77 BASE_NS::string ClassRegistry::GetClassName(BASE_NS::Uid uid) const
78 {
79 std::shared_lock lock { mutex_ };
80 auto it = objectFactories_.find(uid);
81 return it != objectFactories_.end() ? BASE_NS::string(it->second->GetClassInfo().Name())
82 : BASE_NS::string("Unknown class id [") + BASE_NS::to_string(uid) + "]";
83 }
84
GetAllTypes(ObjectCategoryBits category,bool strict,bool excludeDeprecated) const85 BASE_NS::vector<IClassInfo::ConstPtr> ClassRegistry::GetAllTypes(
86 ObjectCategoryBits category, bool strict, bool excludeDeprecated) const
87 {
88 std::shared_lock lock { mutex_ };
89 BASE_NS::vector<IClassInfo::ConstPtr> infos;
90 for (auto&& v : objectFactories_) {
91 const auto& factory = v.second;
92 if (excludeDeprecated && (factory->GetClassInfo().category & ObjectCategoryBits::DEPRECATED)) {
93 // Omit DEPRECATED classes if excludeDeprecated flag is true
94 continue;
95 }
96 if (CheckCategoryBits(factory->GetClassInfo().category, category, strict)) {
97 infos.emplace_back(factory);
98 }
99 }
100 return infos;
101 }
102
GetAllTypes(const BASE_NS::vector<BASE_NS::Uid> & interfaceUids,bool strict,bool excludeDeprecated) const103 BASE_NS::vector<IClassInfo::ConstPtr> ClassRegistry::GetAllTypes(
104 const BASE_NS::vector<BASE_NS::Uid>& interfaceUids, bool strict, bool excludeDeprecated) const
105 {
106 std::shared_lock lock { mutex_ };
107 BASE_NS::vector<IClassInfo::ConstPtr> infos;
108 for (auto&& v : objectFactories_) {
109 const auto& factory = v.second;
110 if (factory->GetClassInfo().category & ObjectCategoryBits::INTERNAL) {
111 // Omit classes with INTERNAL flag from the list
112 continue;
113 }
114 if (excludeDeprecated && (factory->GetClassInfo().category & ObjectCategoryBits::DEPRECATED)) {
115 // Omit DEPRECATED classes if excludeDeprecated flag is true
116 continue;
117 }
118 if (CheckInterfaces(factory->GetClassInterfaces(), interfaceUids, strict)) {
119 infos.push_back(factory);
120 }
121 }
122 return infos;
123 }
124
125 META_END_NAMESPACE()
126