OGLplus  (0.59.0) a C++ wrapper for rendering APIs

api.hpp
Go to the documentation of this file.
1 #ifndef OALPLUS_ALC_API_API_HPP
9 #define OALPLUS_ALC_API_API_HPP
10 
11 #include "c_api.hpp"
12 #include "enum_types.hpp"
13 #include <eagine/scope_exit.hpp>
14 #include <eagine/span.hpp>
15 #include <eagine/string_list.hpp>
16 
17 namespace eagine::oalp {
18 //------------------------------------------------------------------------------
19 #define OALPAFP(FUNC) decltype(c_api::FUNC), &c_api::FUNC
20 //------------------------------------------------------------------------------
25 template <typename ApiTraits>
26 class basic_alc_operations : public basic_alc_c_api<ApiTraits> {
27 
28 public:
29  using api_traits = ApiTraits;
31 
32  using device_handle = typename alc_types::device_type*;
33  using context_handle = typename alc_types::context_type*;
34  using enum_type = typename alc_types::enum_type;
35  using size_type = typename alc_types::size_type;
36  using char_type = typename alc_types::char_type;
37  using int_type = typename alc_types::int_type;
38 
39  template <typename W, W c_api::*F, typename Signature = typename W::signature>
40  class func;
41 
42  template <typename W, W c_api::*F, typename RVC, typename... Params>
43  class func<W, F, RVC(Params...)>
44  : public wrapped_c_api_function<c_api, api_traits, nothing_t, W, F> {
45  using base = wrapped_c_api_function<c_api, api_traits, nothing_t, W, F>;
46 
47  private:
48  template <typename Res>
49  constexpr auto _check(device_handle dev, Res&& res) const noexcept {
50  res.error_code(this->api().GetError(dev));
51  return std::forward<Res>(res);
52  }
53 
54  protected:
55  template <typename... Args>
56  constexpr auto
57  _chkcall(device_handle dev, Args&&... args) const noexcept {
58  return this->_check(dev, this->_call(std::forward<Args>(args)...));
59  }
60 
61  using base::_conv;
62 
63  public:
64  using base::base;
65 
66  constexpr auto operator()(Params... params) const noexcept {
67  return this->_chkcall(_conv(params)...)
68  .cast_to(type_identity<RVC>{});
69  }
70  };
71 
72  // open_device
73  struct : func<OALPAFP(OpenDevice)> {
74  using func<OALPAFP(OpenDevice)>::func;
75 
76  constexpr auto operator()() const noexcept {
77  return this->_chkcall(nullptr, nullptr);
78  }
79 
80  auto operator()(string_view name) const noexcept {
81  return this->_chkcall(nullptr, c_str(name));
82  }
83  } open_device;
84 
85  // close_device
86  struct : func<OALPAFP(CloseDevice)> {
87  using func<OALPAFP(CloseDevice)>::func;
88 
89  constexpr auto operator()(device_handle dev) const noexcept {
90  return this->_chkcall(dev, dev);
91  }
92 
93  auto raii(device_handle dev) noexcept {
94  return eagine::finally([=]() { (*this)(dev); });
95  }
96  } close_device;
97 
98  // create_context
99  struct : func<OALPAFP(CreateContext)> {
100  using func<OALPAFP(CreateContext)>::func;
101 
102  constexpr auto operator()(device_handle dev) const noexcept {
103  return this->_chkcall(dev, dev, nullptr);
104  }
105 
106  constexpr auto operator()(
107  device_handle dev,
108  span<const int_type> attributes) const noexcept {
109  return this->_chkcall(dev, dev, attributes.data());
110  }
111  } create_context;
112 
113  // destroy_context
114  struct : func<OALPAFP(DestroyContext)> {
115  using func<OALPAFP(DestroyContext)>::func;
116 
117  constexpr auto
118  operator()(device_handle dev, context_handle ctx) const noexcept {
119  return this->_chkcall(dev, ctx);
120  }
121 
122  auto raii(device_handle dev, context_handle ctx) noexcept {
123  return eagine::finally([=]() { (*this)(dev, ctx); });
124  }
125  } destroy_context;
126 
127  // make_context_current
128  struct : func<OALPAFP(MakeContextCurrent)> {
129  using func<OALPAFP(MakeContextCurrent)>::func;
130 
131  constexpr auto
132  operator()(device_handle dev, context_handle ctx) const noexcept {
133  return this->_chkcall(dev, ctx);
134  }
135 
136  constexpr auto operator()(device_handle dev) const noexcept {
137  return this->_chkcall(dev, nullptr);
138  }
139 
140  constexpr auto operator()(context_handle ctx) const noexcept {
141  return this->_chkcall(nullptr, ctx);
142  }
143 
144  constexpr auto operator()() const noexcept {
145  return this->_chkcall(nullptr, nullptr);
146  }
147 
148  auto raii(device_handle dev) noexcept {
149  return eagine::finally([=]() { (*this)(dev); });
150  }
151 
152  auto raii() noexcept {
153  return eagine::finally([=]() { (*this)(); });
154  }
155  } make_context_current;
156 
157  // get_current_context
158  struct : func<OALPAFP(GetCurrentContext)> {
159  using func<OALPAFP(GetCurrentContext)>::func;
160 
161  constexpr auto operator()(device_handle dev) const noexcept {
162  return this->_chkcall(dev);
163  }
164 
165  constexpr auto operator()() const noexcept {
166  return this->_chkcall(nullptr);
167  }
168  } get_current_context;
169 
170  // get_integer
171  struct : func<OALPAFP(GetIntegerv)> {
172  using func<OALPAFP(GetIntegerv)>::func;
173 
174  constexpr auto
175  operator()(device_handle dev, alc_integer_query query) const noexcept {
176  int_type result{};
177  return this
178  ->_chkcall(dev, dev, enum_type(query), size_type(1), &result)
179  .replaced_with(result);
180  }
181 
182  constexpr auto operator()(alc_integer_query query) const noexcept {
183  return (*this)(nullptr, query);
184  }
185 
186  constexpr auto operator()(
187  device_handle dev,
188  alc_integer_query query,
189  span<int_type> dst) const noexcept {
190  return this->_chkcall(
191  dev, dev, enum_type(query), size_type(dst.size()), dst.data());
192  }
193  } get_integer;
194 
195  // get_string
196  struct : func<OALPAFP(GetString)> {
197  using func<OALPAFP(GetString)>::func;
198 
199  constexpr auto
200  operator()(device_handle dev, alc_string_query query) const noexcept {
201  return this->_chkcall(dev, dev, enum_type(query))
202  .cast_to(type_identity<string_view>{});
203  }
204 
205  constexpr auto operator()(alc_string_query query) const noexcept {
206  return (*this)(nullptr, query);
207  }
208 
209  constexpr auto operator()(device_handle) const noexcept {
210  return this->_fake_empty_c_str().cast_to(
212  }
213  } get_string;
214 
215  // get_strings
216  auto get_strings(
217  device_handle dev,
218  alc_string_query query,
219  char separator) noexcept {
220  return get_string(dev, query).transformed([separator](auto src) {
221  return split_into_string_list(src, separator);
222  });
223  }
224 
225  // get_extensions
226  auto get_extensions(device_handle dev) noexcept {
227 #ifdef ALC_EXTENSIONS
228  return get_string(dev, alc_string_query(ALC_EXTENSIONS))
229 #else
230  return get_string(dev)
231 #endif
232  .transformed(
233  [](auto src) { return split_into_string_list(src, ' '); });
234  }
235 
236  // get_default_device_specifier
237  auto get_default_device_specifier() noexcept {
238 #ifdef ALC_DEFAULT_DEVICE_SPECIFIER
239  return get_string(
240  nullptr, alc_string_query(ALC_DEFAULT_DEVICE_SPECIFIER));
241 #else
242  return get_string(nullptr);
243 #endif
244  }
245 
246  // get_device_specifiers
247  auto get_device_specifiers() noexcept {
248 #ifdef ALC_DEVICE_SPECIFIER
249  return get_string(nullptr, alc_string_query(ALC_DEVICE_SPECIFIER))
250 #else
251  return get_string(nullptr)
252 #endif
253  .transformed(
254  [](auto src) { return split_into_string_list(src, '\0'); });
255  }
256 
257  // get_capture_default_device_specifier
258  auto get_capture_default_device_specifier() noexcept {
259 #ifdef ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
260  return get_string(
261  nullptr, alc_string_query(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
262 #else
263  return get_string(nullptr);
264 #endif
265  }
266 
267  // get_capture_device_specifiers
268  auto get_capture_device_specifiers() noexcept {
269 #ifdef ALC_CAPTURE_DEVICE_SPECIFIER
270  return get_string(
271  nullptr, alc_string_query(ALC_CAPTURE_DEVICE_SPECIFIER))
272 #else
273  return get_string(nullptr)
274 #endif
275  .transformed(
276  [](auto src) { return split_into_string_list(src, '\0'); });
277  }
278 
279  basic_alc_operations(api_traits& traits);
280 };
281 //------------------------------------------------------------------------------
282 #undef OALPAFP
283 //------------------------------------------------------------------------------
284 } // namespace eagine::oalp
285 
286 #endif // OALPLUS_ALC_API_API_HPP
alc_api_function< context_type *(device_type *, const int_type *), nullptr > CreateContext
Definition: c_api.hpp:164
static constexpr auto c_str(memory::basic_span< C, P, S > s) -> std::enable_if_t< std::is_convertible_v< memory::basic_span< C, P, S >, basic_string_span< C, P, S >>, basic_c_str< C, P, S >>
Functions that construct a basic_c_str from a basic_string_span.
Definition: string_span.hpp:226
Class wrapping the functions from the ALC API.
Definition: api.hpp:26
Class wrapping the C-functions from the ALC API.
Definition: c_api.hpp:31
Class representing "none" / "nothing" values.
Definition: nothing.hpp:17
alc_api_function< context_type *(), nullptr > GetCurrentContext
Definition: c_api.hpp:191
alc_api_function< bool_type(device_type *), nullptr > CloseDevice
Definition: c_api.hpp:129
alc_api_function< void(device_type *, enum_type, size_type, int_type *), nullptr > GetIntegerv
Definition: c_api.hpp:150
alc_api_function< const char_type *(device_type *, enum_type), nullptr > GetString
Definition: c_api.hpp:143
static auto finally(Func func) -> func_on_scope_exit< Func >
Function constructing on-scope-exit actions.
Definition: scope_exit.hpp:144
alc_api_function< bool_type(context_type *), nullptr > MakeContextCurrent
Definition: c_api.hpp:186
alc_api_function< device_type *(const char_type *), nullptr > OpenDevice
Definition: c_api.hpp:111
Template type used mostly for function type-tag dispatching.
Definition: type_identity.hpp:19
AL-related code is placed in this namespace.
Definition: oalplus.hpp:11
alc_api_function< void(context_type *), nullptr > DestroyContext
Definition: c_api.hpp:179
Typed enumeration for ALC integer query constants.
Definition: enum_types.hpp:39
alc_api_function< enum_type(device_type *), nullptr > GetError
Definition: c_api.hpp:90
Typed enumeration for ALC string query constants.
Definition: enum_types.hpp:32

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).