From a4f96c8dfa17f746fd3d58c96ca599668e42be3a Mon Sep 17 00:00:00 2001 From: Hayodea Hakol Date: Mon, 13 Jan 2025 11:53:38 -0400 Subject: [PATCH] Senselib FFI: Use devDesc object in SenseApiLib, also add per-device metadata to xcbXorg We also had to write conversion constructors and so on to CSenseDeviceDesc. The technical debt that's being piled up from this C FFI is excessive. I think we'll end it here. API Libs will have to be written in C++ from now on. API Lib interfaces will be in C++. We'll use cross compilers to ensure stability for out-of-tree lib development. --- hcore/include/senseApis/senseApiLib.h | 4 ++- hcore/senseApis/senseApiManager.cpp | 18 +++++------ include/user/senseDeviceSpec.h | 43 +++++++++++++++++++++++++++ senseApis/xcbXorg/xcbXorg.cpp | 31 +++++++++++++++++-- 4 files changed, 84 insertions(+), 12 deletions(-) diff --git a/hcore/include/senseApis/senseApiLib.h b/hcore/include/senseApis/senseApiLib.h index 0e1e1f1..68d3f3f 100644 --- a/hcore/include/senseApis/senseApiLib.h +++ b/hcore/include/senseApis/senseApiLib.h @@ -32,7 +32,8 @@ public: SenseApiDesc() = default; SenseApiDesc(const CSenseApiDesc& cDesc) // The caller should sanity check before calling this constructor. - : name(cDesc.name) + : name(cDesc.name), + sal_mgmt_libOps(cDesc.sal_mgmt_libOps) { for (uint32_t i = 0; i < cDesc.numExportedImplexorApis; ++i) { @@ -51,6 +52,7 @@ public: std::string name; // These are the implexors whose APIs this lib exports. std::vector exportedImplexorApis; + Csal_mgmt_libOps* sal_mgmt_libOps; std::string stringify() const { std::string result = "Name: " + name + "\n"; diff --git a/hcore/senseApis/senseApiManager.cpp b/hcore/senseApis/senseApiManager.cpp index e9e1005..5760ea8 100644 --- a/hcore/senseApis/senseApiManager.cpp +++ b/hcore/senseApis/senseApiManager.cpp @@ -123,7 +123,7 @@ SenseApiManager::getSenseApiLibByApiName(const std::string& apiName) { auto it = std::find_if(senseApiLibs.begin(), senseApiLibs.end(), [&apiName](const std::unique_ptr& lib) { - return lib->getSenseApiDesc()->name == apiName; + return lib->senseApiDesc.name == apiName; } ); @@ -173,24 +173,24 @@ std::string SenseApiManager::stringifyLibs() const void SenseApiManager::initializeSenseApiLib(SenseApiLib& lib) { - if (!lib.getSenseApiDesc()->sal_mgmt_libOps->initializeInd) + if (!lib.senseApiDesc.sal_mgmt_libOps->initializeInd) { throw std::runtime_error( std::string(__func__) + ": initializeInd() is NULL for library '" + lib.libraryPath + "'"); } - lib.getSenseApiDesc()->sal_mgmt_libOps->initializeInd(); + lib.senseApiDesc.sal_mgmt_libOps->initializeInd(); } void SenseApiManager::finalizeSenseApiLib(SenseApiLib& lib) { - if (!lib.getSenseApiDesc()->sal_mgmt_libOps->finalizeInd) + if (!lib.senseApiDesc.sal_mgmt_libOps->finalizeInd) { throw std::runtime_error( std::string(__func__) + ": finalizeInd() is NULL for library '" + lib.libraryPath + "'"); } - lib.getSenseApiDesc()->sal_mgmt_libOps->finalizeInd(); + lib.senseApiDesc.sal_mgmt_libOps->finalizeInd(); } void SenseApiManager::initializeAllSenseApiLibs(void) @@ -217,14 +217,14 @@ void SenseApiManager::attachSenseDevice(const SenseDeviceSpec& spec) + spec.api + "'"); } auto& lib = libOpt.value().get(); - if (!lib.getSenseApiDesc()->sal_mgmt_libOps->attachDeviceReq) + if (!lib.senseApiDesc.sal_mgmt_libOps->attachDeviceReq) { throw std::runtime_error( std::string(__func__) + ": attachDeviceReq() is NULL for library '" + lib.libraryPath + "'"); } CSenseDeviceSpec cSpec(spec); - lib.getSenseApiDesc()->sal_mgmt_libOps->attachDeviceReq(&cSpec); + lib.senseApiDesc.sal_mgmt_libOps->attachDeviceReq(&cSpec); } void SenseApiManager::detachSenseDevice(const SenseDeviceSpec& spec) @@ -237,14 +237,14 @@ void SenseApiManager::detachSenseDevice(const SenseDeviceSpec& spec) + spec.api + "'"); } auto& lib = libOpt.value().get(); - if (!lib.getSenseApiDesc()->sal_mgmt_libOps->detachDeviceReq) + if (!lib.senseApiDesc.sal_mgmt_libOps->detachDeviceReq) { throw std::runtime_error( std::string(__func__) + ": detachDeviceReq() is NULL for library '" + lib.libraryPath + "'"); } CSenseDeviceSpec cSpec(spec); - lib.getSenseApiDesc()->sal_mgmt_libOps->detachDeviceReq(&cSpec); + lib.senseApiDesc.sal_mgmt_libOps->detachDeviceReq(&cSpec); } void SenseApiManager::attachAllSenseDevicesFromSpecs(void) diff --git a/include/user/senseDeviceSpec.h b/include/user/senseDeviceSpec.h index 000fb74..38cd9f1 100644 --- a/include/user/senseDeviceSpec.h +++ b/include/user/senseDeviceSpec.h @@ -71,6 +71,42 @@ struct CSenseDeviceSpec providerParams[spec.providerParams.size()] = nullptr; } + CSenseDeviceSpec(const CSenseDeviceSpec& other) + : sensorType(other.sensorType), + implexor(strdup(other.implexor)), + api(strdup(other.api)), + provider(strdup(other.provider)), + deviceSelector(strdup(other.deviceSelector)) + { + if (other.apiParams) { + size_t apiParamsSize = 0; + while (other.apiParams[apiParamsSize] != nullptr) { + ++apiParamsSize; + } + apiParams = new char*[apiParamsSize + 1]; + for (size_t i = 0; i < apiParamsSize; ++i) { + apiParams[i] = strdup(other.apiParams[i]); + } + apiParams[apiParamsSize] = nullptr; + } else { + apiParams = nullptr; + } + + if (other.providerParams) { + size_t providerParamsSize = 0; + while (other.providerParams[providerParamsSize] != nullptr) { + ++providerParamsSize; + } + providerParams = new char*[providerParamsSize + 1]; + for (size_t i = 0; i < providerParamsSize; ++i) { + providerParams[i] = strdup(other.providerParams[i]); + } + providerParams[providerParamsSize] = nullptr; + } else { + providerParams = nullptr; + } + } + ~CSenseDeviceSpec(void) { free(implexor); @@ -122,6 +158,13 @@ struct CSenseDeviceSpec return os.str(); } + + bool operator==(const CSenseDeviceSpec& other) const + { + return sensorType == other.sensorType && + strcmp(provider, other.provider) == 0 && + strcmp(deviceSelector, other.deviceSelector) == 0; + } #endif char sensorType; diff --git a/senseApis/xcbXorg/xcbXorg.cpp b/senseApis/xcbXorg/xcbXorg.cpp index 34ce5a7..e8da141 100644 --- a/senseApis/xcbXorg/xcbXorg.cpp +++ b/senseApis/xcbXorg/xcbXorg.cpp @@ -2,9 +2,24 @@ #include #include #include +#include #include #include "xcbXorg.h" +class AttachedDevice { +public: + AttachedDevice(const CSenseDeviceSpec &spec) : deviceSpec(spec) {} + + const CSenseDeviceSpec& getSpec() const { + return deviceSpec; + } + +private: + CSenseDeviceSpec deviceSpec; +}; + +static std::vector attachedDevices; + struct XcbConnectionInfo { std::unique_ptr connection; int screenNumber; @@ -82,13 +97,25 @@ int xcbXorg_finalizeInd(void) static sal_mlo_attachDeviceReqFn xcbXorg_attachDeviceReq; int xcbXorg_attachDeviceReq(const CSenseDeviceSpec *const desc) { - std::cout << __func__ << ": Attaching device spec: " << *desc << "\n"; + attachedDevices.emplace_back(*desc); + + std::ostringstream os; + for (const auto& device : attachedDevices) { + os << device.getSpec(); + } + std::cout << __func__ << ": >>>> Attaching device spec: " << *desc << "\n" + << " >>>> Current attached devices:\n" << os.str(); return 0; } static sal_mlo_detachDeviceReqFn xcbXorg_detachDeviceReq; int xcbXorg_detachDeviceReq(const CSenseDeviceSpec *const spec) { - std::cout << __func__ << "\n"; + auto it = std::remove_if(attachedDevices.begin(), attachedDevices.end(), + [spec](const AttachedDevice &device) { + return device.getSpec() == *spec; + }); + attachedDevices.erase(it, attachedDevices.end()); + std::cout << __func__ << ": Detaching device spec\n"; return 0; }