ab930a2df3
Register comparator types via a dedicated manager and expose lookup/create hooks through SmoCallbacks so stimbuff libs can resolve comparators at load time. Co-authored-by: Cursor <cursoragent@cursor.com>
176 lines
4.6 KiB
C++
176 lines
4.6 KiB
C++
#include <algorithm>
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
#include <comparatorLibs/comparatorApiManager.h>
|
|
#include <loadableLib/loadableLibraryManager.h>
|
|
#include <user/comparatorApiDesc.h>
|
|
#include <user/senseApiDesc.h>
|
|
|
|
namespace smo {
|
|
namespace comparator_lib {
|
|
|
|
namespace {
|
|
|
|
void registerExportedComparatorTypes(
|
|
ComparatorApiManager::Resources& resources,
|
|
const cologex::ComparatorLibDesc& libDesc)
|
|
{
|
|
for (const auto& exportedType : libDesc.exportedComparatorTypes)
|
|
{
|
|
const uint64_t packedTypeId = exportedType.typeId.pack();
|
|
if (resources.typeRegistry.contains(packedTypeId))
|
|
{
|
|
throw std::runtime_error(
|
|
std::string(__func__)
|
|
+ ": Duplicate comparator type registration for vendorId=0x"
|
|
+ std::to_string(exportedType.typeId.vendorId)
|
|
+ " typeId=0x"
|
|
+ std::to_string(exportedType.typeId.typeId));
|
|
}
|
|
|
|
auto registeredType =
|
|
std::make_shared<cologex::ExportedComparatorTypeDesc>(
|
|
exportedType);
|
|
resources.typeRegistry.emplace(packedTypeId, registeredType);
|
|
}
|
|
}
|
|
|
|
void unregisterExportedComparatorTypes(
|
|
ComparatorApiManager::Resources& resources,
|
|
const cologex::ComparatorLibDesc& libDesc)
|
|
{
|
|
for (const auto& exportedType : libDesc.exportedComparatorTypes) {
|
|
resources.typeRegistry.erase(exportedType.typeId.pack());
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
ComparatorLib& ComparatorApiManager::loadComparatorLib(
|
|
const std::string& libraryPath)
|
|
{
|
|
loadable_lib::LoadableLibraryManager& llm =
|
|
loadable_lib::LoadableLibraryManager::getInstance();
|
|
|
|
if (getComparatorLib(libraryPath))
|
|
{
|
|
throw std::runtime_error(
|
|
std::string(__func__) + ": ComparatorLib already loaded: "
|
|
+ libraryPath);
|
|
}
|
|
|
|
std::shared_ptr<loadable_lib::LoadableLibraryManager::LoadedSharedLibrary>
|
|
loadedLibrary = llm.loadSharedLibrary(libraryPath);
|
|
|
|
auto descFn = loadable_lib::LoadableLibraryManager::resolveSymbol<
|
|
SMO_GET_COMPARATOR_LIB_DESC_FN_TYPEDEF *>(
|
|
loadedLibrary->getDlopenHandle(),
|
|
SMO_GET_COMPARATOR_LIB_DESC_FN_NAME_STR);
|
|
|
|
const stim_buff::SmoCallbacks& callbacks =
|
|
stim_buff::getSmoCallbacks();
|
|
const cologex::ComparatorLibDesc& libDesc = descFn(callbacks);
|
|
|
|
auto lib = std::make_shared<ComparatorLib>(loadedLibrary, descFn);
|
|
lib->setComparatorLibDesc(libDesc);
|
|
|
|
registerExportedComparatorTypes(s.rsrc, lib->comparatorLibDesc);
|
|
s.rsrc.libs.push_back(lib);
|
|
|
|
return *lib;
|
|
}
|
|
|
|
void ComparatorApiManager::unloadComparatorLib(const std::string& libraryPath)
|
|
{
|
|
auto& libs = s.rsrc.libs;
|
|
auto it = std::find_if(
|
|
libs.begin(), libs.end(),
|
|
[&libraryPath](const std::shared_ptr<ComparatorLib>& lib) {
|
|
return lib->loadedSharedLibrary->libraryPath == libraryPath;
|
|
});
|
|
|
|
if (it == libs.end())
|
|
{
|
|
std::cerr << std::string(__func__) + ": Library not found: "
|
|
<< libraryPath << '\n';
|
|
return;
|
|
}
|
|
|
|
unregisterExportedComparatorTypes(s.rsrc, (*it)->comparatorLibDesc);
|
|
std::shared_ptr<loadable_lib::LoadableLibraryManager::LoadedSharedLibrary>
|
|
loadedLibrary = (*it)->loadedSharedLibrary;
|
|
libs.erase(it);
|
|
|
|
loadable_lib::LoadableLibraryManager::getInstance()
|
|
.unloadSharedLibrary(loadedLibrary);
|
|
}
|
|
|
|
void ComparatorApiManager::unloadAllComparatorLibs(void)
|
|
{
|
|
auto libs = s.rsrc.libs;
|
|
s.rsrc.libs.clear();
|
|
s.rsrc.typeRegistry.clear();
|
|
|
|
for (const auto& lib : libs)
|
|
{
|
|
loadable_lib::LoadableLibraryManager::getInstance()
|
|
.unloadSharedLibrary(lib->loadedSharedLibrary);
|
|
}
|
|
}
|
|
|
|
std::optional<std::shared_ptr<ComparatorLib>>
|
|
ComparatorApiManager::getComparatorLib(const std::string& libraryPath)
|
|
{
|
|
auto& libs = s.rsrc.libs;
|
|
auto it = std::find_if(
|
|
libs.begin(), libs.end(),
|
|
[&libraryPath](const std::shared_ptr<ComparatorLib>& lib) {
|
|
return lib->loadedSharedLibrary->libraryPath == libraryPath;
|
|
});
|
|
|
|
if (it != libs.end()) {
|
|
return *it;
|
|
}
|
|
|
|
return std::nullopt;
|
|
}
|
|
|
|
std::shared_ptr<cologex::ExportedComparatorTypeDesc>
|
|
ComparatorApiManager::getComparatorType(cologex::ComparatorTypeId typeId)
|
|
{
|
|
const uint64_t packedTypeId = typeId.pack();
|
|
auto it = s.rsrc.typeRegistry.find(packedTypeId);
|
|
if (it == s.rsrc.typeRegistry.end()) {
|
|
return {};
|
|
}
|
|
|
|
return it->second;
|
|
}
|
|
|
|
std::unique_ptr<cologex::Comparator> ComparatorApiManager::getNewComparatorInstance(
|
|
cologex::ComparatorTypeId typeId)
|
|
{
|
|
return getNewComparatorInstance(getComparatorType(typeId));
|
|
}
|
|
|
|
std::unique_ptr<cologex::Comparator> ComparatorApiManager::getNewComparatorInstance(
|
|
const std::shared_ptr<cologex::ExportedComparatorTypeDesc>& comparatorType)
|
|
{
|
|
if (!comparatorType)
|
|
{
|
|
throw std::runtime_error(
|
|
std::string(__func__) + ": comparatorType is null");
|
|
}
|
|
|
|
if (!comparatorType->getNewInstance)
|
|
{
|
|
throw std::runtime_error(
|
|
std::string(__func__) + ": getNewInstance is null");
|
|
}
|
|
|
|
return comparatorType->getNewInstance();
|
|
}
|
|
|
|
} // namespace comparator_lib
|
|
} // namespace smo
|