co_usb
Loading...
Searching...
No Matches
context.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <boost/capy/concept/executor.hpp>
5#include <boost/capy/ex/this_coro.hpp>
6#include <boost/capy/task.hpp>
7#include <concepts>
8#include <libusb-1.0/libusb.h>
9#include <ranges>
10#include <stdexcept>
11#include <stop_token>
12
13namespace co_usb
14{
15
16enum class use_service
17{
18 no = 0,
19 yes
20};
21
25void default_handler(libusb_context *ctx, std::stop_token st);
26
32template <use_service Service = use_service::yes> struct context;
33
34template <> struct context<use_service::yes>
35{
36 private:
37 template <boost::capy::Executor Exec,
38 std::invocable<libusb_context *, std::stop_token> HandlerFn>
39 void init (Exec &&exec, HandlerFn &&handler_fn)
40 {
41 libusb_context *ctx;
42 auto r = libusb_init(&ctx);
43 if (r != LIBUSB_SUCCESS)
44 {
45 throw std::runtime_error{"Cannot initialize libusb"};
46 }
47 m_ctx = {ctx, [] (libusb_context *ctx) { libusb_exit(ctx); }};
49 std::forward<Exec>(exec).context().template use_service<detail::handler_service>();
50 service.start_thread(m_ctx, std::forward<HandlerFn>(handler_fn));
51 m_ss = service.stop_source();
52 }
53
54 public:
55 template <boost::capy::Executor Exec> explicit context (Exec &&exec)
56 {
57 init(std::forward<Exec>(exec), default_handler);
58 }
59
60 template <boost::capy::Executor Exec,
61 std::invocable<libusb_context *, std::stop_token> HandlerFn>
63 {
64 init(std::forward<Exec>(exec), std::forward<HandlerFn>(handler_fn));
65 }
66
67 template <typename R, boost::capy::Executor Exec,
68 std::invocable<libusb_context *, std::stop_token> HandlerFn>
69 requires std::ranges::range<R> && std::same_as<std::ranges::range_value_t<R>, libusb_option>
71 {
72 init(std::forward<Exec>(exec), std::forward<HandlerFn>(handler_fn));
73 for (auto opt : options)
74 {
75 libusb_set_option(m_ctx, opt);
76 }
77 }
78
79 context(context const &) = delete;
80 context(context &&) = delete;
81
82 context &operator=(context const &) = delete;
83 context &operator=(context &&) = delete;
84
86 {
87 return m_ctx.get();
88 }
89
91 {
92 m_ss.request_stop();
93 }
94
95 auto get_token ()
96 {
97 return m_ss.get_token();
98 }
99
100 private:
101 std::shared_ptr<libusb_context> m_ctx;
102 std::stop_source m_ss;
103};
104
105template <> struct context<use_service::no>
106{
107 private:
108 void init();
109
110 public:
111 explicit context();
112
113 template <typename R>
114 requires std::ranges::range<R> && std::same_as<std::ranges::range_value_t<R>, libusb_option>
115 explicit context(R &&options)
116 {
117 init();
118 for (auto opt : options)
119 {
120 libusb_set_option(m_ctx, opt);
121 }
122 }
123
125
126 context(context const &) = delete;
127 context(context &&) = delete;
128
129 context &operator=(context const &) = delete;
130 context &operator=(context &&) = delete;
131
133 {
134 return m_ctx;
135 }
136
137 private:
138 libusb_context *m_ctx;
139};
140
141} // namespace co_usb
Definition context.hpp:14
void default_handler(libusb_context *ctx, std::stop_token st)
default handler function for the service
Definition context.cpp:24
use_service
Definition context.hpp:17
context(context const &)=delete
context & operator=(context const &)=delete
context(R &&options)
Definition context.hpp:115
auto * get() const noexcept
Definition context.hpp:132
context & operator=(context &&)=delete
auto * get() const noexcept
Definition context.hpp:85
context & operator=(context const &)=delete
auto get_token()
Definition context.hpp:95
context(Exec &&exec)
Definition context.hpp:55
auto request_stop()
Definition context.hpp:90
context(Exec &&exec, HandlerFn &&handler_fn)
Definition context.hpp:62
context(R &&options, Exec &&exec, HandlerFn &&handler_fn)
Definition context.hpp:70
context(context const &)=delete
context & operator=(context &&)=delete
libusb_context wrapper
Definition context.hpp:32
Service for handling libusb events.
Definition service.hpp:21
std::stop_source stop_source()
Definition service.cpp:10
void start_thread(std::shared_ptr< libusb_context > ctx, HandlerFn &&handler_fn)
Creates a default handler thread.
Definition service.hpp:32