From a6b6d05925a6aa513974da305eae4bf213101250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Micha=C3=ABl=20Celerier?= Date: Fri, 30 Aug 2024 18:27:02 -0400 Subject: [PATCH] [patchers] Add support for sink messages --- include/avnd/binding/max/helpers.hpp | 14 ++++++++------ include/avnd/binding/max/messages.hpp | 23 +++++++++++++++++++++++ include/avnd/concepts/message.hpp | 9 +++++++++ 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/include/avnd/binding/max/helpers.hpp b/include/avnd/binding/max/helpers.hpp index 21c4722f..17f45063 100644 --- a/include/avnd/binding/max/helpers.hpp +++ b/include/avnd/binding/max/helpers.hpp @@ -88,10 +88,11 @@ static void process_generic_message(T& implementation, t_symbol* s) template static constexpr bool compatible(short type) { - if constexpr(requires(Arg arg) { arg = 0.f; }) - return type == A_FLOAT || type == A_LONG; - else if constexpr(requires(Arg arg) { arg = "str"; }) + // NOTE! has to be in this order as std::string x = 0.f; builds... + if constexpr(requires(Arg arg) { arg = "str"; }) return type == A_SYM; + else if constexpr(requires(Arg arg) { arg = 0.f; }) + return type == A_FLOAT || type == A_LONG; return false; } @@ -99,12 +100,13 @@ static constexpr bool compatible(short type) template static Arg convert(t_atom& atom) { - if constexpr(std::floating_point) + if constexpr(requires(Arg arg) { arg = "str"; }) + return atom.a_w.w_sym->s_name; + else if constexpr(std::floating_point) return atom.a_type == A_FLOAT ? atom.a_w.w_float : atom.a_w.w_long; else if constexpr(std::integral) return atom.a_type == A_LONG ? atom.a_w.w_long : atom.a_w.w_float; - else if constexpr(requires(Arg arg) { arg = "str"; }) - return atom.a_w.w_sym->s_name; + else static_assert(std::is_same_v, "Argument type not handled yet"); } diff --git a/include/avnd/binding/max/messages.hpp b/include/avnd/binding/max/messages.hpp index 38008e6c..d56e3ab6 100644 --- a/include/avnd/binding/max/messages.hpp +++ b/include/avnd/binding/max/messages.hpp @@ -166,6 +166,8 @@ struct messages { bool ok = false; std::string_view symname = s->s_name; + + // First try to locate explicit messages avnd::messages_introspection::for_all( avnd::get_messages(implementation), [&](M& field) { if(ok) @@ -175,6 +177,27 @@ struct messages ok = process_message(implementation.effect, field, symname, argc, argv); } }); + + // If that fails try to look for a sink message which accepts anything + if(!ok) + { + avnd::messages_introspection::for_all( + avnd::get_messages(implementation), [&](M& field) { + if(ok) + return; + if(avnd::tag_process_any_message) + { + static thread_local std::vector atoms; + atoms.clear(); + atoms.resize(argc + 1); + atoms[0] = t_atom{.a_type = A_SYM, .a_w = std::bit_cast(s)}; + for(int i = 0; i < argc; i++) + atoms[i + 1] = *argv; + ok = process_message( + implementation.effect, field, symname, atoms.size(), atoms.data()); + } + }); + } return ok; } return false; diff --git a/include/avnd/concepts/message.hpp b/include/avnd/concepts/message.hpp index 4a362bd7..8d4313b2 100644 --- a/include/avnd/concepts/message.hpp +++ b/include/avnd/concepts/message.hpp @@ -3,6 +3,7 @@ /* SPDX-License-Identifier: GPL-3.0-or-later OR BSL-1.0 OR CC0-1.0 OR CC-PDCC OR 0BSD */ #include +#include #include #include @@ -131,4 +132,12 @@ using second_message_argument template using third_message_argument = boost::mp11::mp_third::arguments>; + +/** + * This tag indicates that the message accepts any command + * and ignores its own message name. + */ +AVND_DEFINE_TAG(process_any_message) +template +concept any_message_port = tag_process_any_message; }