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.
This commit is contained in:
2025-01-13 11:53:38 -04:00
parent 660f0f0e73
commit a4f96c8dfa
4 changed files with 84 additions and 12 deletions
+3 -1
View File
@@ -32,7 +32,8 @@ public:
SenseApiDesc() = default; SenseApiDesc() = default;
SenseApiDesc(const CSenseApiDesc& cDesc) SenseApiDesc(const CSenseApiDesc& cDesc)
// The caller should sanity check before calling this constructor. // 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) for (uint32_t i = 0; i < cDesc.numExportedImplexorApis; ++i)
{ {
@@ -51,6 +52,7 @@ public:
std::string name; std::string name;
// These are the implexors whose APIs this lib exports. // These are the implexors whose APIs this lib exports.
std::vector<ExportedImplexorApiDesc> exportedImplexorApis; std::vector<ExportedImplexorApiDesc> exportedImplexorApis;
Csal_mgmt_libOps* sal_mgmt_libOps;
std::string stringify() const { std::string stringify() const {
std::string result = "Name: " + name + "\n"; std::string result = "Name: " + name + "\n";
+9 -9
View File
@@ -123,7 +123,7 @@ SenseApiManager::getSenseApiLibByApiName(const std::string& apiName)
{ {
auto it = std::find_if(senseApiLibs.begin(), senseApiLibs.end(), auto it = std::find_if(senseApiLibs.begin(), senseApiLibs.end(),
[&apiName](const std::unique_ptr<SenseApiLib>& lib) { [&apiName](const std::unique_ptr<SenseApiLib>& 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) void SenseApiManager::initializeSenseApiLib(SenseApiLib& lib)
{ {
if (!lib.getSenseApiDesc()->sal_mgmt_libOps->initializeInd) if (!lib.senseApiDesc.sal_mgmt_libOps->initializeInd)
{ {
throw std::runtime_error( throw std::runtime_error(
std::string(__func__) + ": initializeInd() is NULL for library '" std::string(__func__) + ": initializeInd() is NULL for library '"
+ lib.libraryPath + "'"); + lib.libraryPath + "'");
} }
lib.getSenseApiDesc()->sal_mgmt_libOps->initializeInd(); lib.senseApiDesc.sal_mgmt_libOps->initializeInd();
} }
void SenseApiManager::finalizeSenseApiLib(SenseApiLib& lib) void SenseApiManager::finalizeSenseApiLib(SenseApiLib& lib)
{ {
if (!lib.getSenseApiDesc()->sal_mgmt_libOps->finalizeInd) if (!lib.senseApiDesc.sal_mgmt_libOps->finalizeInd)
{ {
throw std::runtime_error( throw std::runtime_error(
std::string(__func__) + ": finalizeInd() is NULL for library '" std::string(__func__) + ": finalizeInd() is NULL for library '"
+ lib.libraryPath + "'"); + lib.libraryPath + "'");
} }
lib.getSenseApiDesc()->sal_mgmt_libOps->finalizeInd(); lib.senseApiDesc.sal_mgmt_libOps->finalizeInd();
} }
void SenseApiManager::initializeAllSenseApiLibs(void) void SenseApiManager::initializeAllSenseApiLibs(void)
@@ -217,14 +217,14 @@ void SenseApiManager::attachSenseDevice(const SenseDeviceSpec& spec)
+ spec.api + "'"); + spec.api + "'");
} }
auto& lib = libOpt.value().get(); auto& lib = libOpt.value().get();
if (!lib.getSenseApiDesc()->sal_mgmt_libOps->attachDeviceReq) if (!lib.senseApiDesc.sal_mgmt_libOps->attachDeviceReq)
{ {
throw std::runtime_error( throw std::runtime_error(
std::string(__func__) + ": attachDeviceReq() is NULL for library '" std::string(__func__) + ": attachDeviceReq() is NULL for library '"
+ lib.libraryPath + "'"); + lib.libraryPath + "'");
} }
CSenseDeviceSpec cSpec(spec); CSenseDeviceSpec cSpec(spec);
lib.getSenseApiDesc()->sal_mgmt_libOps->attachDeviceReq(&cSpec); lib.senseApiDesc.sal_mgmt_libOps->attachDeviceReq(&cSpec);
} }
void SenseApiManager::detachSenseDevice(const SenseDeviceSpec& spec) void SenseApiManager::detachSenseDevice(const SenseDeviceSpec& spec)
@@ -237,14 +237,14 @@ void SenseApiManager::detachSenseDevice(const SenseDeviceSpec& spec)
+ spec.api + "'"); + spec.api + "'");
} }
auto& lib = libOpt.value().get(); auto& lib = libOpt.value().get();
if (!lib.getSenseApiDesc()->sal_mgmt_libOps->detachDeviceReq) if (!lib.senseApiDesc.sal_mgmt_libOps->detachDeviceReq)
{ {
throw std::runtime_error( throw std::runtime_error(
std::string(__func__) + ": detachDeviceReq() is NULL for library '" std::string(__func__) + ": detachDeviceReq() is NULL for library '"
+ lib.libraryPath + "'"); + lib.libraryPath + "'");
} }
CSenseDeviceSpec cSpec(spec); CSenseDeviceSpec cSpec(spec);
lib.getSenseApiDesc()->sal_mgmt_libOps->detachDeviceReq(&cSpec); lib.senseApiDesc.sal_mgmt_libOps->detachDeviceReq(&cSpec);
} }
void SenseApiManager::attachAllSenseDevicesFromSpecs(void) void SenseApiManager::attachAllSenseDevicesFromSpecs(void)
+43
View File
@@ -71,6 +71,42 @@ struct CSenseDeviceSpec
providerParams[spec.providerParams.size()] = nullptr; 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) ~CSenseDeviceSpec(void)
{ {
free(implexor); free(implexor);
@@ -122,6 +158,13 @@ struct CSenseDeviceSpec
return os.str(); return os.str();
} }
bool operator==(const CSenseDeviceSpec& other) const
{
return sensorType == other.sensorType &&
strcmp(provider, other.provider) == 0 &&
strcmp(deviceSelector, other.deviceSelector) == 0;
}
#endif #endif
char sensorType; char sensorType;
+29 -2
View File
@@ -2,9 +2,24 @@
#include <algorithm> #include <algorithm>
#include <stdexcept> #include <stdexcept>
#include <memory> #include <memory>
#include <vector>
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include "xcbXorg.h" #include "xcbXorg.h"
class AttachedDevice {
public:
AttachedDevice(const CSenseDeviceSpec &spec) : deviceSpec(spec) {}
const CSenseDeviceSpec& getSpec() const {
return deviceSpec;
}
private:
CSenseDeviceSpec deviceSpec;
};
static std::vector<AttachedDevice> attachedDevices;
struct XcbConnectionInfo { struct XcbConnectionInfo {
std::unique_ptr<xcb_connection_t, decltype(&xcb_disconnect)> connection; std::unique_ptr<xcb_connection_t, decltype(&xcb_disconnect)> connection;
int screenNumber; int screenNumber;
@@ -82,13 +97,25 @@ int xcbXorg_finalizeInd(void)
static sal_mlo_attachDeviceReqFn xcbXorg_attachDeviceReq; static sal_mlo_attachDeviceReqFn xcbXorg_attachDeviceReq;
int xcbXorg_attachDeviceReq(const CSenseDeviceSpec *const desc) 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; return 0;
} }
static sal_mlo_detachDeviceReqFn xcbXorg_detachDeviceReq; static sal_mlo_detachDeviceReqFn xcbXorg_detachDeviceReq;
int xcbXorg_detachDeviceReq(const CSenseDeviceSpec *const spec) 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; return 0;
} }