Type-safe OSC message sending
This commit is contained in:
parent
07fd16017f
commit
e1c607e28a
3 changed files with 91 additions and 6 deletions
|
|
@ -219,6 +219,7 @@ target_link_libraries (sfizz_parser PUBLIC absl::strings PRIVATE absl::flat_hash
|
||||||
# OSC messaging library
|
# OSC messaging library
|
||||||
set (SFIZZ_MESSAGING_HEADERS
|
set (SFIZZ_MESSAGING_HEADERS
|
||||||
sfizz/Messaging.h
|
sfizz/Messaging.h
|
||||||
|
sfizz/Messaging.hpp
|
||||||
sfizz_message.h)
|
sfizz_message.h)
|
||||||
|
|
||||||
set (SFIZZ_MESSAGING_SOURCES
|
set (SFIZZ_MESSAGING_SOURCES
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,14 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "sfizz_message.h"
|
#include "sfizz_message.h"
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
namespace sfz {
|
namespace sfz {
|
||||||
|
|
||||||
|
template <char Tag> struct OscDataTraits;
|
||||||
|
template <char Tag> using OscType = typename OscDataTraits<Tag>::type;
|
||||||
|
template <char Tag> using OscDecayedType = typename std::decay<OscType<Tag>>::type;
|
||||||
|
|
||||||
class Client {
|
class Client {
|
||||||
public:
|
public:
|
||||||
explicit Client(void* data) : data_(data) {}
|
explicit Client(void* data) : data_(data) {}
|
||||||
|
|
@ -17,15 +22,18 @@ public:
|
||||||
bool canReceive() const { return receive_ != nullptr; }
|
bool canReceive() const { return receive_ != nullptr; }
|
||||||
void receive(int delay, const char* path, const char* sig, const sfizz_arg_t* args);
|
void receive(int delay, const char* path, const char* sig, const sfizz_arg_t* args);
|
||||||
|
|
||||||
|
template <char... Sig>
|
||||||
|
void receive(int delay, const char* path, OscDecayedType<Sig>... values);
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <char Tag>
|
||||||
|
sfizz_arg_t make_arg(OscDecayedType<Tag> value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void* data_ = nullptr;
|
void* data_ = nullptr;
|
||||||
sfizz_receive_t* receive_ = nullptr;
|
sfizz_receive_t* receive_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void Client::receive(int delay, const char* path, const char* sig, const sfizz_arg_t* args)
|
|
||||||
{
|
|
||||||
if (receive_)
|
|
||||||
receive_(data_, delay, path, sig, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sfz
|
} // namespace sfz
|
||||||
|
|
||||||
|
#include "Messaging.hpp"
|
||||||
|
|
|
||||||
76
src/sfizz/Messaging.hpp
Normal file
76
src/sfizz/Messaging.hpp
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "Messaging.h"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace sfz {
|
||||||
|
|
||||||
|
///
|
||||||
|
inline void Client::receive(int delay, const char* path, const char* sig, const sfizz_arg_t* args)
|
||||||
|
{
|
||||||
|
if (receive_)
|
||||||
|
receive_(data_, delay, path, sig, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <char... Sig>
|
||||||
|
inline void Client::receive(int delay, const char* path, OscDecayedType<Sig>... values)
|
||||||
|
{
|
||||||
|
constexpr size_t size = sizeof...(Sig);
|
||||||
|
char sig[size + 1] { Sig..., '\0' };
|
||||||
|
sfizz_arg_t args[size] { OscDataTraits<Sig>::make_arg(values)... };
|
||||||
|
receive(delay, path, sig, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#define OSC_SCALAR_TRAITS(tag, member) \
|
||||||
|
template <> struct OscDataTraits<tag> { \
|
||||||
|
typedef decltype(sfizz_arg_t::member) type; \
|
||||||
|
static_assert(std::is_scalar<type>::value, ""); \
|
||||||
|
static inline sfizz_arg_t make_arg(type v) { \
|
||||||
|
sfizz_arg_t a; a.member = v; return a; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#define OSC_BYTEARRAY_TRAITS(tag, member) \
|
||||||
|
template <> struct OscDataTraits<tag> { \
|
||||||
|
typedef decltype(sfizz_arg_t::member) type; \
|
||||||
|
static_assert(std::is_array<type>::value, ""); \
|
||||||
|
static inline sfizz_arg_t make_arg(type v) { \
|
||||||
|
sfizz_arg_t a; \
|
||||||
|
std::memcpy(a.member, v, sizeof(a.member)); \
|
||||||
|
return a; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#define OSC_VOID_TRAITS(tag) \
|
||||||
|
template <> struct OscDataTraits<tag> { \
|
||||||
|
typedef struct Nothing {} type; \
|
||||||
|
static inline sfizz_arg_t make_arg(type v) { \
|
||||||
|
sfizz_arg_t a; (void)v; return a; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
OSC_SCALAR_TRAITS('i', i);
|
||||||
|
OSC_SCALAR_TRAITS('c', i);
|
||||||
|
OSC_SCALAR_TRAITS('r', i);
|
||||||
|
OSC_BYTEARRAY_TRAITS('m', m);
|
||||||
|
OSC_SCALAR_TRAITS('h', h);
|
||||||
|
OSC_SCALAR_TRAITS('f', f);
|
||||||
|
OSC_SCALAR_TRAITS('d', d);
|
||||||
|
OSC_SCALAR_TRAITS('s', s);
|
||||||
|
OSC_SCALAR_TRAITS('S', s);
|
||||||
|
OSC_SCALAR_TRAITS('b', b);
|
||||||
|
OSC_VOID_TRAITS('T');
|
||||||
|
OSC_VOID_TRAITS('F');
|
||||||
|
OSC_VOID_TRAITS('N');
|
||||||
|
OSC_VOID_TRAITS('I');
|
||||||
|
|
||||||
|
#undef OSC_SCALAR_TRAITS
|
||||||
|
#undef OSC_BYTEARRAY_TRAITS
|
||||||
|
#undef OSC_VOID_TRAITS
|
||||||
|
|
||||||
|
} // namespace sfz
|
||||||
Loading…
Add table
Reference in a new issue