Skip to content

Commit

Permalink
[pd] Support much more data types for outlets
Browse files Browse the repository at this point in the history
  • Loading branch information
jcelerier committed Oct 2, 2023
1 parent 6d67263 commit 706a4c6
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 78 deletions.
5 changes: 0 additions & 5 deletions .github/workflows/build_cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,6 @@ jobs:
chmod +x ./fetch-sdk.sh
./fetch-sdk.sh
- uses: maxim-lobanov/setup-xcode@v1
if: matrix.config.name == 'macOS'
with:
xcode-version: latest-stable

- name: Build debug
shell: bash
run: |
Expand Down
21 changes: 11 additions & 10 deletions cmake/avendish.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,20 @@ include(avendish.example)
# Used for getting completion in IDEs...
function(avnd_register)
cmake_parse_arguments(AVND "" "TARGET;MAIN_FILE;MAIN_CLASS;C_NAME" "COMPILE_OPTIONS;COMPILE_DEFINITIONS;LINK_LIBRARIES" ${ARGN})

if(NOT TARGET "${AVND_TARGET}")
add_library("${AVND_TARGET}" STATIC $<TARGET_OBJECTS:avnd_dummy_lib>)
endif()

target_sources("${AVND_TARGET}" PRIVATE "${AVND_MAIN_FILE}")
if(AVND_COMPILE_OPTIONS)
target_compile_options("${AVND_TARGET}" PUBLIC "${AVND_COMPILE_OPTIONS}")
endif()
if(AVND_COMPILE_DEFINITIONS)
target_compile_definitions("${AVND_TARGET}" PUBLIC "${AVND_COMPILE_DEFINITIONS}")
endif()
if(AVND_LINK_LIBRARIES)
target_link_libraries("${AVND_TARGET}" PUBLIC "${AVND_LINK_LIBRARIES}")
endif()
target_sources("${AVND_TARGET}" PRIVATE "${AVND_MAIN_FILE}")
if(AVND_COMPILE_OPTIONS)
target_compile_options("${AVND_TARGET}" PUBLIC "${AVND_COMPILE_OPTIONS}")
endif()
if(AVND_COMPILE_DEFINITIONS)
target_compile_definitions("${AVND_TARGET}" PUBLIC "${AVND_COMPILE_DEFINITIONS}")
endif()
if(AVND_LINK_LIBRARIES)
target_link_libraries("${AVND_TARGET}" PUBLIC "${AVND_LINK_LIBRARIES}")
endif()
endfunction()

Expand Down
6 changes: 4 additions & 2 deletions include/avnd/binding/pd/message_processor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ struct message_processor
// Reserve space for controls
this->control_buffers.reserve_space(implementation, 16);

avnd::prepare(implementation, {});

/// Initialize controls
if constexpr(avnd::has_inputs<T>)
{
Expand Down Expand Up @@ -180,15 +182,15 @@ message_processor_metaclass<T>::message_processor_metaclass()
{
message_processor_metaclass::instance = this;
using instance = message_processor<T>;

/*
#if !defined(_MSC_VER)
static_assert(std::is_aggregate_v<T>);
static_assert(std::is_aggregate_v<instance>);
static_assert(std::is_nothrow_constructible_v<instance>);
static_assert(std::is_nothrow_move_constructible_v<instance>);
static_assert(std::is_nothrow_move_assignable_v<instance>);
#endif

*/
/// Small wrapper methods which will call into our actual type ///

// Ctor
Expand Down
185 changes: 124 additions & 61 deletions include/avnd/binding/pd/outputs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@ namespace pd
{

template <typename T>
requires std::is_arithmetic_v<T>
inline void value_to_pd(t_atom& atom, T v) noexcept
{
atom = {.a_type = A_FLOAT, .a_w = {.w_float = (t_float)v}};
}

inline void value_to_pd(t_atom& atom, bool v) noexcept
{
atom = {.a_type = A_FLOAT, .a_w = {.w_float = v ? 1.0f : 0.0f}};
}
inline void value_to_pd(t_atom& atom, const char* v) noexcept
{
atom = {.a_type = A_SYMBOL, .a_w = {.w_symbol = gensym(v)}};
}
inline void value_to_pd(t_atom& atom, std::string_view v) noexcept
{
atom = {.a_type = A_SYMBOL, .a_w = {.w_symbol = gensym(v.data())}};
}
inline void value_to_pd(t_atom& atom, const std::string& v) noexcept
{
atom = {.a_type = A_SYMBOL, .a_w = {.w_symbol = gensym(v.c_str())}};
}

template <typename T>
requires std::is_aggregate_v<T>
void value_to_pd(t_outlet* outlet, T v)
{
constexpr int sz = avnd::pfr::tuple_size_v<T>;
Expand Down Expand Up @@ -51,15 +76,102 @@ void value_to_pd(t_outlet* outlet, T v)
}
}

inline void value_to_pd(t_outlet* outlet, int v) noexcept
template <typename T>
requires avnd::vector_ish<T>
void value_to_pd(t_outlet* outlet, const T& v)
{
outlet_float(outlet, v);
static thread_local std::vector<t_atom> atoms;
const int N = v.size();
atoms.clear();
atoms.resize(N);

for(int i = 0; i < N; i++)
{
value_to_pd(atoms[i], v[i]);
}
outlet_list(outlet, &s_list, v.size(), atoms.data());
}

template <typename T, std::size_t N>
requires avnd::array_ish<T, N>
void value_to_pd(t_outlet* outlet, const T& v)
{
std::array<t_atom, N> atoms;

for(int i = 0; i < N; i++)
{
value_to_pd(atoms[i], v[i]);
}

outlet_list(outlet, &s_list, v.size(), atoms.data());
}

template <typename T>
requires avnd::set_ish<T>
void value_to_pd(t_outlet* outlet, const T& v)
{
static thread_local std::vector<t_atom> atoms;
const int N = v.size();
atoms.clear();
atoms.resize(N);

int i = 0;
for(auto& element : v)
{
value_to_pd(atoms[i++], element);
}
outlet_list(outlet, &s_list, v.size(), atoms.data());
}

template <typename T>
requires avnd::map_ish<T>
void value_to_pd(t_outlet* outlet, const T& v)
{
static thread_local std::vector<t_atom> atoms;
const int N = v.size();
atoms.clear();
atoms.resize(2 * N);

int i = 0;
for(auto& [key, value] : v)
{
value_to_pd(atoms[i++], key);
value_to_pd(atoms[i++], value);
}
outlet_list(outlet, &s_list, v.size(), atoms.data());
}
inline void value_to_pd(t_outlet* outlet, float v) noexcept

template <typename T>
requires avnd::variant_ish<T>
void value_to_pd(t_outlet* outlet, const T& v)
{
using namespace std;
visit(v, [&](const auto& element) { value_to_pd(outlet, element); });
}

template <typename T>
requires avnd::pair_ish<T>
void value_to_pd(t_outlet* outlet, const T& v)
{
t_atom atoms[2];

value_to_pd(atoms[0], v.first);
value_to_pd(atoms[1], v.second);
}

template <typename T>
requires avnd::optional_ish<T>
void value_to_pd(t_outlet* outlet, const T& v)
{
if(v)
value_to_pd(outlet, *v);
}

inline void value_to_pd(t_outlet* outlet, std::integral auto v) noexcept
{
outlet_float(outlet, v);
}
inline void value_to_pd(t_outlet* outlet, double v) noexcept
inline void value_to_pd(t_outlet* outlet, std::floating_point auto v) noexcept
{
outlet_float(outlet, v);
}
Expand Down Expand Up @@ -135,69 +247,21 @@ struct value_writer
template <typename T>
struct outputs
{
template <avnd::function_view_ish call_type>
static void init_func_view(call_type& call, t_outlet& outlet)
template <typename R, typename... Args, template <typename...> typename F>
static void init_func_view(F<R(Args...)>& call, t_outlet& outlet)
{
using func_t = typename call_type::type;
using refl = avnd::function_reflection_t<func_t>;

call.context = &outlet;
call.function = nullptr;
if constexpr(refl::count == 0)
{
call.function = [](void* ptr) {
t_outlet* p = static_cast<t_outlet*>(ptr);
outlet_bang(p);
};
}
else if constexpr(refl::count == 1)
{
if constexpr(std::is_same_v<func_t, void(float)>)
{
call.function = [](void* ptr, float f) {
t_outlet* p = static_cast<t_outlet*>(ptr);
outlet_float(p, f);
};
}
else if constexpr(std::is_same_v<func_t, void(const char*)>)
{
call.function = [](void* ptr, const char* f) {
t_outlet* p = static_cast<t_outlet*>(ptr);
outlet_symbol(p, gensym(f));
};
}
}
else
{
AVND_STATIC_TODO(call_type);
}
call.function = [](void* ptr, Args... args) {
t_outlet* p = static_cast<t_outlet*>(ptr);
value_to_pd(p, std::forward<Args>(args)...);
};
}

template <typename R, typename... Args, template <typename...> typename F>
static void init_func(F<R(Args...)>& call, t_outlet& outlet)
{
using func_t = R(Args...);
using refl = avnd::function_reflection_t<func_t>;

if constexpr(refl::count == 0)
{
call = [&outlet] { outlet_bang(&outlet); };
}
else if constexpr(refl::count == 1)
{
if constexpr(std::is_same_v<func_t, void(float)>)
{
call = [&outlet](float f) { outlet_float(&outlet, f); };
}
else if constexpr(std::is_same_v<func_t, void(const char*)>)
{
call = [&outlet](const char* f) { outlet_symbol(&outlet, gensym(f)); };
}
}
else
{
AVND_STATIC_TODO(F<R(Args...)>);
}
call
= [&outlet](Args... args) { value_to_pd(&outlet, std::forward<Args>(args)...); };
}

template <avnd::callback C>
Expand Down Expand Up @@ -251,5 +315,4 @@ struct outputs

std::array<t_outlet*, avnd::output_introspection<T>::size> outlets;
};

}

0 comments on commit 706a4c6

Please sign in to comment.