SenseApis: New senseApiManager and X11XcbApi

Still fleshing these out but ultimately senseApiMgr will manage
sense apis, and the X11XcbApi is where we'll connect to Xcb and
read the screen.
This commit is contained in:
2025-01-08 06:26:36 -04:00
parent f594d29a2d
commit fe3f911db4
8 changed files with 248 additions and 2 deletions
+2 -1
View File
@@ -4,4 +4,5 @@ AM_CPPFLAGS+= -I"$(top_srcdir)/hcore/include"
bin_PROGRAMS = harikoff
harikoff_SOURCES = main.cpp
harikoff_LDADD = hcore/libhcore.a hcore/deviceManager/libdeviceManager.a
harikoff_LDADD = hcore/libhcore.a hcore/deviceManager/libdeviceManager.a \
hcore/senseApis/libsenseApis.a
+5
View File
@@ -43,6 +43,10 @@ AS_IF([test -z "${LEX}" || test -z "${YACC}"], [
AC_MSG_ERROR([LEX and YACC must both be available in PATH.])
])
AC_SEARCH_LIBS([dlopen], [dl ldl], [], [
AC_MSG_ERROR([dlopen() not found in libdl or libldl.])
])
AM_CPPFLAGS=m4_normalize(["-I\"\$(top_srcdir)/include\""])
AC_SUBST([AM_CPPFLAGS])
@@ -53,6 +57,7 @@ AC_CONFIG_HEADERS([include/config.h])
AC_CONFIG_FILES([
Makefile hcore/Makefile
hcore/deviceManager/Makefile
hcore/senseApis/Makefile
])
AC_CONFIG_COMMANDS_POST([
+1 -1
View File
@@ -1,4 +1,4 @@
SUBDIRS = deviceManager
SUBDIRS = deviceManager senseApis
AM_CPPFLAGS+= -I"$(top_srcdir)/hcore/include"
noinst_LIBRARIES = libhcore.a
+69
View File
@@ -0,0 +1,69 @@
#ifndef SENSE_API_MANAGER_H
#define SENSE_API_MANAGER_H
#include <config.h>
#include <memory>
#include <vector>
#include <string>
#include <optional>
#include <functional>
struct SenseApiInstance {
int a;
bool operator==(const SenseApiInstance& other) const {
return a == other.a;
}
};
class SenseApiLib {
public:
std::string libraryPath;
std::unique_ptr<void, decltype(&dlclose)> handle;
SenseApiLib(const std::string& path)
: libraryPath(path), handle(nullptr, &dlclose) {}
};
class SenseApiManager {
public:
static SenseApiManager& getInstance()
{
static SenseApiManager instance
{
#ifdef CONFIG_SENSEAPI_FOO
"builtinApi1",
#endif
#ifdef CONFIG_SENSEAPI_BAR
"builtinApi2",
#endif
// X11 XCB is always built-in.
"x11-xcb"
};
return instance;
}
void registerSenseApi(const SenseApiInstance& apiInstance);
void unregisterSenseApi(const SenseApiInstance& apiInstance);
SenseApiLib& loadSenseApiLib(const std::string& libraryPath);
std::optional<std::reference_wrapper<SenseApiLib>> getSenseApiLib(
const std::string& libraryPath);
void unloadSenseApiLib(const std::string& libraryPath);
private:
SenseApiManager() = delete;
SenseApiManager(std::initializer_list<std::string> builtinApis)
: builtinSenseApis(builtinApis) {}
~SenseApiManager() = default;
SenseApiManager(const SenseApiManager&) = delete;
SenseApiManager& operator=(const SenseApiManager&) = delete;
std::vector<std::unique_ptr<SenseApiInstance>> senseApiInstances;
std::vector<std::unique_ptr<SenseApiLib>> senseApiLibs;
const std::vector<std::string> builtinSenseApis;
};
#endif // SENSE_API_MANAGER_H
+24
View File
@@ -0,0 +1,24 @@
#ifndef X11_XCB_API_H
#define X11_XCB_API_H
#include <string>
#include <vector>
#include <memory>
class X11XcbApi
{
public:
X11XcbApi(const std::string& displayName);
~X11XcbApi();
void addDevice(const std::string& deviceSpec);
void removeDevice(const std::string& deviceSpec);
void addAllDevicesFromSpecs(const std::vector<std::string>& deviceSpecs);
private:
std::string displayName;
std::vector<std::shared_ptr<DeviceManager::SensorDeviceSpec>> deviceSpecs;
// Add other necessary members and methods
};
#endif // X11_XCB_API_H
+6
View File
@@ -0,0 +1,6 @@
AM_CPPFLAGS+= -I"$(top_srcdir)/hcore/include"
noinst_LIBRARIES=libsenseApis.a
libsenseApis_a_SOURCES=senseApiManager.cpp
senseApiManager.o: AM_CPPFLAGS+=-Wno-ignored-attributes
+94
View File
@@ -0,0 +1,94 @@
#include <dlfcn.h>
#include <iostream>
#include <stdexcept>
#include <optional>
#include <senseApis/senseApiManager.h>
std::vector<std::unique_ptr<SenseApiLib>> senseApiLibs;
std::vector<std::unique_ptr<SenseApiInstance>> senseApiInstances;
SenseApiLib& SenseApiManager::loadSenseApiLib(const std::string& libraryPath)
{
auto lib = std::make_unique<SenseApiLib>(libraryPath);
// Clear any existing error
dlerror();
lib->handle.reset(dlopen(libraryPath.c_str(), RTLD_LAZY));
if (!lib->handle)
{
std::string error = dlerror()
? dlerror()
: "Unknown error while opening shlib";
throw std::runtime_error(
std::string(__func__) + " - Cannot load library '"
+ libraryPath + "': "
+ error);
}
senseApiLibs.push_back(std::move(lib));
return *senseApiLibs.back();
}
std::optional<std::reference_wrapper<SenseApiLib>> SenseApiManager::getSenseApiLib(
const std::string& libraryPath)
{
auto it = std::find_if(senseApiLibs.begin(), senseApiLibs.end(),
[&libPath = libraryPath](const std::unique_ptr<SenseApiLib>& lib) {
return lib->libraryPath == libPath;
}
);
if (it != senseApiLibs.end()) { return **it; }
return std::nullopt;
}
void SenseApiManager::unloadSenseApiLib(const std::string& libraryPath)
{
auto it = std::find_if(senseApiLibs.begin(), senseApiLibs.end(),
[&lpath = libraryPath](const std::unique_ptr<SenseApiLib>& lib) {
return lib->libraryPath == lpath;
}
);
if (it != senseApiLibs.end())
{
senseApiLibs.erase(it);
return;
}
std::cerr << std::string(__func__) + ": Library not found: "
<< libraryPath << '\n';
}
void SenseApiManager::registerSenseApi(const SenseApiInstance& apiInstance)
{
auto it = std::find_if(
senseApiInstances.begin(), senseApiInstances.end(),
[&apiInstance](const std::unique_ptr<SenseApiInstance>& instance) {
return static_cast<const SenseApiInstance&>(*instance) == apiInstance;
});
if (it != senseApiInstances.end())
{
std::cerr << std::string(__func__)
+ ": Sense API Instance already registered.\n";
return;
}
senseApiInstances.push_back(std::make_unique<SenseApiInstance>(apiInstance));
}
void SenseApiManager::unregisterSenseApi(const SenseApiInstance& apiInstance)
{
auto it = std::find_if(
senseApiInstances.begin(), senseApiInstances.end(),
[&apiInstance](const std::unique_ptr<SenseApiInstance>& instance) {
return const_cast<const SenseApiInstance&>(*instance) == apiInstance;
});
if (it != senseApiInstances.end()) {
senseApiInstances.erase(it);
} else {
std::cerr << std::string(__func__) + ": Sense API Instance not found.\n";
}
}
+47
View File
@@ -0,0 +1,47 @@
#include <senseApis/x11-xcb.h>
#include <iostream>
X11XcbApi::X11XcbApi(const std::string& displayName)
: displayName(displayName)
{
}
X11XcbApi::~X11XcbApi() {
// Add any necessary cleanup code
}
bool X11XcbApi::initialize() {
// Add initialization code
std::cout << "Initializing X11 XCB API with display: " << displayName << std::endl;
return true;
}
void X11XcbApi::shutdown() {
// Add shutdown code
std::cout << "Shutting down X11 XCB API" << std::endl;
}
void X11XcbApi::addDevice(const std::string& deviceSpec) {
// Add code to add a device
auto device = std::make_shared<DeviceManager::SensorDeviceSpec>(deviceSpec);
deviceSpecs.push_back(device);
std::cout << "Adding device with spec: " << deviceSpec << std::endl;
}
void X11XcbApi::removeDevice(const std::string& deviceSpec) {
// Add code to remove a device
auto it = std::remove_if(deviceSpecs.begin(), deviceSpecs.end(),
[&deviceSpec](const std::shared_ptr<DeviceManager::SensorDeviceSpec>& device) {
return device->spec == deviceSpec;
});
if (it != deviceSpecs.end()) {
deviceSpecs.erase(it, deviceSpecs.end());
std::cout << "Removing device with spec: " << deviceSpec << std::endl;
}
}
void X11XcbApi::addAllDevicesFromSpecs(const std::vector<std::string>& deviceSpecs) {
for (const auto& spec : deviceSpecs) {
addDevice(spec);
}
}