Files
ts-qt/components/ffmsep/cpstream_core.hh

97 lines
2.9 KiB
C++

#pragma once
#include "components/ffmsep/cpdecoder.hh"
#include "components/ffmsep/tactile/tacdec.hh"
#include <chrono>
#include <cstdint>
#include <functional>
#include <future>
#include <memory>
#include <optional>
#include <serial/serial.h>
#include <string>
#include <vector>
using namespace std::chrono_literals;
namespace ffmsep {
namespace persist {
struct WriteResult;
} // namespace persist
struct DecodedFrame {
CPFrame frame;
CPCodecID id = CPCodecID::Unknow;
std::chrono::steady_clock::time_point received_at{};
std::int64_t pts = 0;
std::optional<tactile::TactileFrame> tactile;
std::vector<std::uint16_t> tactile_pressures;
std::optional<tactile::MatrixSize> tactile_matrix_size;
};
struct CPStreamConfig {
std::string port;
std::uint32_t baudrate = 115200;
serial::Timeout timeout = serial::Timeout::simpleTimeout(50);
serial::bytesize_t bytesize = serial::eightbits;
serial::parity_t parity = serial::parity_none;
serial::stopbits_t stopbits = serial::stopbits_one;
serial::flowcontrol_t flowcontrol = serial::flowcontrol_none;
std::size_t read_chunk_size = 256;
std::size_t packet_queue_capacity = 128;
std::size_t frame_queue_capacity = 16;
CPCodecID codec_id = CPCodecID::Unknow;
std::string codec_name;
std::vector<std::uint8_t> slave_request_command{};
std::chrono::milliseconds slave_request_interval{200ms};
};
class CPStreamCore {
public:
using FrameCallback = std::function<void(std::shared_ptr<DecodedFrame>)>;
explicit CPStreamCore(CPStreamConfig config = {});
~CPStreamCore();
CPStreamCore(const CPStreamCore&) = delete;
CPStreamCore& operator=(const CPStreamCore&) = delete;
bool open(const CPStreamConfig& config);
bool open();
bool reopen(const CPStreamConfig& config);
void close();
bool start();
void stop();
[[nodiscard]] bool is_open() const noexcept;
[[nodiscard]] bool is_running() const noexcept;
bool send(const std::vector<std::uint8_t>& data);
bool send(const std::uint8_t* data, std::size_t size);
std::optional<std::shared_ptr<DecodedFrame>> try_pop_frame();
bool wait_for_frame(std::shared_ptr<DecodedFrame>& frame, std::chrono::milliseconds timeout);
void clear_frames();
void set_frame_queue_capacity(std::size_t capacity);
void clear_recorded_frames();
[[nodiscard]] std::size_t recorded_frame_count() const;
std::future<persist::WriteResult> export_recorded_frames(const std::string& path,
bool clear_after_export = false);
void set_frame_callback(FrameCallback callback);
[[nodiscard]] CPStreamConfig config() const;
[[nodiscard]] std::string last_error() const;
static std::vector<serial::PortInfo> list_available_ports();
private:
struct Impl;
std::unique_ptr<Impl> impl_;
};
} // namespace ffmsep