LivoxProto1: port to sscl::co framework

Code now actually looks a lot cleaner, tbh.
This commit is contained in:
2026-05-28 20:13:12 -04:00
parent bbc16dc4c4
commit 25efccf6c5
20 changed files with 1275 additions and 2145 deletions
+2 -3
View File
@@ -18,12 +18,11 @@ or event-driven APIs.
include/adapters/
README.md
boostAsio/
<boost asio adapter awaiters>
deadlineTimerAReq.h
opencl/
<OpenCL adapter awaiters>
smo/
cpsCallbackAReq.h
livoxProto1CpsAwaiters.h
<other SMO/internal callback adapters>
```
@@ -32,7 +31,7 @@ include/adapters/
- Name adapter awaiter wrapper functions `get<fnName>AReqAwaiter()`, where
`<fnName>` is the wrapped CPS/API request symbol with its library prefix
removed and each `_`-delimited segment Pascal-cased (e.g.
`livoxProto1_getOrCreateDeviceReq``getGetOrCreateDeviceReqAReqAwaiter()`).
`someLib_someOperationReq``getSomeOperationReqAReqAwaiter()`).
- Keep adapters small and single-purpose; but unify where possible to reduce
code duplication.
- Make result types explicit for multi-argument callbacks.
+95 -16
View File
@@ -2,31 +2,110 @@
#define ADAPTERS_BOOST_ASIO_DEADLINE_TIMER_AREQ_H
#include <boostAsioLinkageFix.h>
#include <functional>
#include <atomic>
#include <coroutine>
#include <memory>
#include <optional>
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/post.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <adapters/smo/cpsCallbackAReq.h>
#include <boost/system/error_code.hpp>
namespace adapters::boostAsio {
using TimerWaitCbFn = std::function<void(bool success)>;
/** Coroutine awaiter: true if the delay elapsed, false if cancelled/aborted. */
class DeadlineTimerAReq
{
public:
struct AsyncState
{
std::atomic<bool> settled{false};
bool timerExpiredNormally = false;
std::coroutine_handle<> callerSchedHandle;
std::shared_ptr<boost::asio::deadline_timer> timer;
};
inline auto deadlineTimerWaitAReq(
DeadlineTimerAReq(
boost::asio::io_service &resumeIoService,
const boost::posix_time::milliseconds delay,
std::optional<std::shared_ptr<boost::asio::deadline_timer>> &timerOut)
: asyncState(std::make_shared<AsyncState>()),
resumeIoService(resumeIoService)
{
asyncState->timer =
std::make_shared<boost::asio::deadline_timer>(resumeIoService);
timerOut = asyncState->timer;
asyncState->timer->expires_from_now(delay);
asyncState->timer->async_wait(
[this](const boost::system::error_code &error)
{
onTimer(error);
});
}
bool await_ready() const noexcept
{
return asyncState->settled.load(std::memory_order_acquire);
}
bool await_suspend(std::coroutine_handle<> caller) noexcept
{
if (asyncState->settled.load(std::memory_order_acquire)) {
return false;
}
asyncState->callerSchedHandle = caller;
return true;
}
bool await_resume() const noexcept
{
return asyncState->timerExpiredNormally;
}
private:
void onTimer(const boost::system::error_code &error)
{
if (asyncState->settled.exchange(true)) {
return;
}
asyncState->timerExpiredNormally = !error;
signalSettledAndResumeCaller();
}
void signalSettledAndResumeCaller()
{
std::coroutine_handle<> handle = asyncState->callerSchedHandle;
if (!handle) {
return;
}
boost::asio::post(resumeIoService, handle);
}
std::shared_ptr<AsyncState> asyncState;
boost::asio::io_service &resumeIoService;
};
inline auto getDeadlineTimerAReqAwaiter(
boost::asio::io_service &ioService,
const boost::posix_time::milliseconds delay)
{
return smo::cpsBoundary::CpsCallbackAReq<bool, TimerWaitCbFn, std::function<void(sscl::cps::Callback<TimerWaitCbFn>)>>(
ioService,
[&ioService, delay](sscl::cps::Callback<TimerWaitCbFn> cb)
{
auto timer = std::make_shared<boost::asio::deadline_timer>(ioService);
timer->expires_from_now(delay);
timer->async_wait(
[timer, cb](const boost::system::error_code &error) mutable
{
cb.callbackFn(!error);
});
});
std::optional<std::shared_ptr<boost::asio::deadline_timer>> timerOut;
return DeadlineTimerAReq(ioService, delay, timerOut);
}
inline auto getDeadlineTimerAReqAwaiter(
boost::asio::io_service &ioService,
const boost::posix_time::milliseconds delay,
std::optional<std::shared_ptr<boost::asio::deadline_timer>> &timerOut)
{
return DeadlineTimerAReq(ioService, delay, timerOut);
}
} // namespace adapters::boostAsio
+1 -3
View File
@@ -80,9 +80,7 @@ private:
return;
}
boost::asio::post(
resumeIoService,
[handle]() { handle.resume(); });
boost::asio::post(resumeIoService, handle);
}
std::shared_ptr<AsyncState> asyncState;
@@ -1,121 +0,0 @@
#ifndef ADAPTERS_SMO_LIVOX_PROTO1_CPS_AWAITERS_H
#define ADAPTERS_SMO_LIVOX_PROTO1_CPS_AWAITERS_H
#include <cstdint>
#include <memory>
#include <adapters/smo/cpsCallbackAReq.h>
#include <livoxProto1/livoxProto1.h>
#include <spinscale/componentThread.h>
namespace adapters::smo {
struct GetOrCreateDeviceResult
{
bool success = false;
std::shared_ptr<livoxProto1::Device> device;
};
struct GetReturnModeResult
{
bool success = false;
uint8_t returnMode = 0;
};
inline auto getGetOrCreateDeviceReqAReqAwaiter(
boost::asio::io_service &resumeIoService,
livoxProto1_getOrCreateDeviceReqFn *fn,
const std::string &deviceIdentifier,
const std::shared_ptr<sscl::ComponentThread> &componentThread,
int commandTimeoutMs,
int retryDelayMs,
const std::string &smoIp,
uint8_t smoSubnetNbits,
uint16_t dataPort,
uint16_t cmdPort,
uint16_t imuPort)
{
return ::smo::cpsBoundary::CpsCallbackAReq<
GetOrCreateDeviceResult,
livoxProto1_getOrCreateDeviceReqCbFn,
std::function<void(sscl::cps::Callback<livoxProto1_getOrCreateDeviceReqCbFn>)>>(
resumeIoService,
[=](sscl::cps::Callback<livoxProto1_getOrCreateDeviceReqCbFn> cb)
{
(*fn)(
deviceIdentifier,
componentThread,
commandTimeoutMs, retryDelayMs,
smoIp, smoSubnetNbits,
dataPort, cmdPort, imuPort,
std::move(cb));
});
}
inline auto getDeviceGetReturnModeReqAReqAwaiter(
boost::asio::io_service &resumeIoService,
livoxProto1_device_getReturnModeReqFn *fn,
std::shared_ptr<livoxProto1::Device> device)
{
return ::smo::cpsBoundary::CpsCallbackAReq<
GetReturnModeResult,
livoxProto1_device_getReturnModeReqCbFn,
std::function<void(sscl::cps::Callback<livoxProto1_device_getReturnModeReqCbFn>)>>(
resumeIoService,
[=](sscl::cps::Callback<livoxProto1_device_getReturnModeReqCbFn> cb)
{
(*fn)(device, std::move(cb));
});
}
inline auto getDeviceEnablePcloudDataReqAReqAwaiter(
boost::asio::io_service &resumeIoService,
livoxProto1_device_enablePcloudDataReqFn *fn,
std::shared_ptr<livoxProto1::Device> device)
{
return ::smo::cpsBoundary::CpsCallbackAReq<
bool,
livoxProto1_device_enablePcloudDataReqCbFn,
std::function<void(sscl::cps::Callback<livoxProto1_device_enablePcloudDataReqCbFn>)>>(
resumeIoService,
[=](sscl::cps::Callback<livoxProto1_device_enablePcloudDataReqCbFn> cb)
{
(*fn)(device, std::move(cb));
});
}
inline auto getDeviceDisablePcloudDataReqAReqAwaiter(
boost::asio::io_service &resumeIoService,
livoxProto1_device_disablePcloudDataReqFn *fn,
std::shared_ptr<livoxProto1::Device> device)
{
return ::smo::cpsBoundary::CpsCallbackAReq<
bool,
livoxProto1_device_disablePcloudDataReqCbFn,
std::function<void(sscl::cps::Callback<livoxProto1_device_disablePcloudDataReqCbFn>)>>(
resumeIoService,
[=](sscl::cps::Callback<livoxProto1_device_disablePcloudDataReqCbFn> cb)
{
(*fn)(device, std::move(cb));
});
}
inline auto getDestroyDeviceReqAReqAwaiter(
boost::asio::io_service &resumeIoService,
livoxProto1_destroyDeviceReqFn *fn,
std::shared_ptr<livoxProto1::Device> device)
{
return ::smo::cpsBoundary::CpsCallbackAReq<
bool,
livoxProto1_destroyDeviceReqCbFn,
std::function<void(sscl::cps::Callback<livoxProto1_destroyDeviceReqCbFn>)>>(
resumeIoService,
[=](sscl::cps::Callback<livoxProto1_destroyDeviceReqCbFn> cb)
{
(*fn)(device, std::move(cb));
});
}
} // namespace adapters::smo
#endif // ADAPTERS_SMO_LIVOX_PROTO1_CPS_AWAITERS_H