/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "class_registry.h"
#include
#include "meta/base/interface_utils.h"
META_BEGIN_NAMESPACE()
void ClassRegistry::Clear()
{
std::unique_lock lock { mutex_ };
objectFactories_.clear();
}
bool ClassRegistry::Unregister(const IObjectFactory::Ptr& fac)
{
if (!fac) {
CORE_LOG_E("ClassRegistry: Cannot unregister a null object factory");
return false;
}
size_t erased = 0;
{
std::unique_lock lock { mutex_ };
erased = objectFactories_.erase(fac->GetClassInfo());
}
if (erased) {
onUnregistered_->Invoke({ fac });
return true;
}
return false;
}
bool ClassRegistry::Register(const IObjectFactory::Ptr& fac)
{
if (!fac) {
CORE_LOG_E("ClassRegistry: Cannot register a null object factory");
return false;
}
{
std::unique_lock lock { mutex_ };
auto& info = fac->GetClassInfo();
auto& i = objectFactories_[info];
if (i) {
CORE_LOG_W("ClassRegistry: Cannot register a class that was already registered [name=%s, uid=%s]",
info.Name().data(), info.Id().ToString().c_str());
return false;
}
i = fac;
}
onRegistered_->Invoke({ fac });
return true;
}
IObjectFactory::ConstPtr ClassRegistry::GetObjectFactory(const BASE_NS::Uid& uid) const
{
std::shared_lock lock { mutex_ };
auto it = objectFactories_.find(uid);
return it != objectFactories_.end() ? it->second : nullptr;
}
BASE_NS::string ClassRegistry::GetClassName(BASE_NS::Uid uid) const
{
std::shared_lock lock { mutex_ };
auto it = objectFactories_.find(uid);
return it != objectFactories_.end() ? BASE_NS::string(it->second->GetClassInfo().Name())
: BASE_NS::string("Unknown class id [") + BASE_NS::to_string(uid) + "]";
}
BASE_NS::vector ClassRegistry::GetAllTypes(
ObjectCategoryBits category, bool strict, bool excludeDeprecated) const
{
std::shared_lock lock { mutex_ };
BASE_NS::vector infos;
for (auto&& v : objectFactories_) {
const auto& factory = v.second;
if (excludeDeprecated && (factory->GetClassInfo().category & ObjectCategoryBits::DEPRECATED)) {
// Omit DEPRECATED classes if excludeDeprecated flag is true
continue;
}
if (CheckCategoryBits(factory->GetClassInfo().category, category, strict)) {
infos.emplace_back(factory);
}
}
return infos;
}
BASE_NS::vector ClassRegistry::GetAllTypes(
const BASE_NS::vector& interfaceUids, bool strict, bool excludeDeprecated) const
{
std::shared_lock lock { mutex_ };
BASE_NS::vector infos;
for (auto&& v : objectFactories_) {
const auto& factory = v.second;
if (factory->GetClassInfo().category & ObjectCategoryBits::INTERNAL) {
// Omit classes with INTERNAL flag from the list
continue;
}
if (excludeDeprecated && (factory->GetClassInfo().category & ObjectCategoryBits::DEPRECATED)) {
// Omit DEPRECATED classes if excludeDeprecated flag is true
continue;
}
if (CheckInterfaces(factory->GetClassInterfaces(), interfaceUids, strict)) {
infos.push_back(factory);
}
}
return infos;
}
META_END_NAMESPACE()