Skip to content

Commit

Permalink
[pd/max] Many improvements
Browse files Browse the repository at this point in the history
- Support much more types in the pd inlets
- Add support for update() in more places
- Handle class_attribute in pd too, by not creating an inlet in that case
Thanks @josephlarralde for fixes on max sdk locating and other improvements !
  • Loading branch information
jcelerier committed Sep 22, 2024
1 parent bf665f6 commit 35398b6
Show file tree
Hide file tree
Showing 11 changed files with 442 additions and 35 deletions.
8 changes: 8 additions & 0 deletions cmake/avendish.examples.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ avnd_make_object(
)


avnd_make_object(
TARGET CompleteMessageExample
MAIN_FILE examples/Complete/CompleteMessageExample.hpp
MAIN_CLASS examples::helpers::CompleteMessageExample
C_NAME avnd_complete_message_example
)



# This one does not really make sense as a Pd or Max object
# (Pd has no notion of MIDI port)
Expand Down
4 changes: 4 additions & 0 deletions cmake/avendish.max.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ elseif(EXISTS "${AVND_MAXSDK_PATH}/c74support/max-includes")
set(MAXSDK_MAX_INCLUDE_DIR "${AVND_MAXSDK_PATH}/c74support/max-includes")
set(MAXSDK_MSP_INCLUDE_DIR "${AVND_MAXSDK_PATH}/c74support/msp-includes")
set(MAXSDK_JIT_INCLUDE_DIR "${AVND_MAXSDK_PATH}/c74support/jit-includes")
elseif(EXISTS "${AVND_MAXSDK_PATH}/source/max-sdk-base/c74support/max-includes")
set(MAXSDK_MAX_INCLUDE_DIR "${AVND_MAXSDK_PATH}/source/max-sdk-base/c74support/max-includes")
set(MAXSDK_MSP_INCLUDE_DIR "${AVND_MAXSDK_PATH}/source/max-sdk-base/c74support/msp-includes")
set(MAXSDK_JIT_INCLUDE_DIR "${AVND_MAXSDK_PATH}/source/max-sdk-base/c74support/jit-includes")
endif()

if(APPLE)
Expand Down
111 changes: 111 additions & 0 deletions examples/Complete/CompleteMessageExample.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#pragma once
#include <halp/callback.hpp>
#include <halp/controls.hpp>
#include <halp/messages.hpp>
#include <halp/meta.hpp>

#include <iostream>
#include <vector>

namespace examples::helpers
{
struct CompleteMessageExample
{
halp_meta(name, "CompleteMessageExample")
halp_meta(c_name, "avnd_complete_message_example")
halp_meta(author, "Jean-Michaël Celerier")
halp_meta(category, "Examples")
halp_meta(description, "Test all the Max & Pd features at once")
halp_meta(uuid, "ecbf8e41-5596-4d13-8407-6b962a02fa54")

struct
{
// Pd:
// - first inlet will receive either:
// * Numbers directly
// * The message [ Test1 123 >
// * The message [ test1 45 >
struct : halp::val_port<"Test1", int>
{
// Class attribute: always goes to the first inlet
// and does not create a new inlet
halp_flag(class_attribute);

void update(CompleteMessageExample& a)
{
std::cerr << "Test1: " << value << std::endl;
a.outputs.out_msg1(1.f, 10, "message1");
a.outputs.out_msg2("heya", "message2");
}
} test1;

struct : halp::val_port<"Test2", float>
{
// Class attribute: always goes to the first inlet
// and does not create a new inlet
halp_flag(class_attribute);

void update(CompleteMessageExample& a)
{
std::cerr << "Test2: " << value << std::endl;
}
} test2;
struct : halp::val_port<"Test3", float>
{
// Not a class attribute: will create a new inlet

void update(CompleteMessageExample& a)
{
std::cerr << "Test3: " << value << std::endl;
}
} test3;
struct : halp::val_port<"Test4", std::string>
{
// Not a class attribute: will create a new inlet

void update(CompleteMessageExample& a)
{
std::cerr << "Test4: " << value << std::endl;
}
} test4;
struct : halp::val_port<"Test5", std::vector<int>>
{
// Not a class attribute: will create a new inlet

void update(CompleteMessageExample& a)
{
std::cerr << "Test5: [ ";
for(auto v : value)
std::cerr << v << ", ";
std::cerr << "]\n";
}
} test5;
} inputs;

struct messages
{
struct
{
halp_meta(name, "m1");
void operator()(int a, float b, std::string c)
{
std::cerr << "m1: " << a << " " << b << " " << c << "\n";
}
} m1;
};

struct
{
halp::callback<"some_symbol", float, int, std::string> out_msg1;
halp::callback<"other_symbol", std::string, std::string> out_msg2;
} outputs;

void operator()()
{
std::cerr << "Test1: " << inputs.test1.value << "\n";
std::cerr << "Test2: " << inputs.test2.value << "\n";
std::cerr << "Test3: " << inputs.test3.value << "\n";
}
};

}
37 changes: 37 additions & 0 deletions examples/Complete/CompleteMessageExample.pd
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#N canvas 1344 0 956 1035 12;
#X obj 135 472 avnd_complete_message_example;
#X obj 138 523 print A;
#X obj 337 524 print B;
#X floatatom 143 306 5 0 0 0 - - - 0;
#X msg 135 76 Test1 1;
#X msg 137 228 m1 1 2.3 foobar;
#X msg 137 134 Test2 15;
#X msg 137 183 Test3 123;
#X floatatom 202 401 4 0 0 0 - - - 0;
#X obj 140 272 bng 18 250 50 0 empty empty empty 0 -9 0 12 #fcfcfc #000000 #000000;
#X text 182 306 Set Test1 \, update();
#X text 193 78 Set Test1 \, update();
#X text 162 273 operator()();
#X text 201 135 Set Test2 \, update();
#X text 208 184 Set Test3 \, update();
#X text 251 230 call m1();
#X symbolatom 268 438 10 0 0 0 - - - 0;
#X msg 361 445 list 1 32 17 14 6 145;
#X text 197 382 Set Test3 \, update();
#X msg 145 347 Test5 1 3 5 17 12;
#X msg 266 408 symbol hello;
#X text 367 407 Set Test4 \, update();
#X text 519 446 Set Test5 \, update();
#X connect 0 0 1 0;
#X connect 0 1 2 0;
#X connect 3 0 0 0;
#X connect 4 0 0 0;
#X connect 5 0 0 0;
#X connect 6 0 0 0;
#X connect 7 0 0 0;
#X connect 8 0 0 1;
#X connect 9 0 0 0;
#X connect 16 0 0 2;
#X connect 17 0 0 3;
#X connect 19 0 0 0;
#X connect 20 0 16 0;
6 changes: 6 additions & 0 deletions include/avnd/binding/max/outputs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ struct do_process_outlet
outlet_list(p, nullptr, l.atoms.size(), l.atoms.data());
}

void operator()(const avnd::variant_ish auto& v) const noexcept
{
using namespace std;
visit([](const auto& val) { (*this)(val); }, v);
}

void operator()(const avnd::map_ish auto& v) const noexcept
{
/*
Expand Down
47 changes: 30 additions & 17 deletions include/avnd/binding/pd/helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,35 +91,25 @@ static void process_generic_message(T& implementation, t_symbol* s)
template <typename Arg>
static constexpr bool compatible(t_atomtype type)
{
if constexpr(requires(Arg arg) { arg = 0.f; })
return type == t_atomtype::A_FLOAT;
else if constexpr(requires(Arg arg) { arg = "str"; })
if constexpr(requires(Arg arg) { arg = "str"; })
return type == t_atomtype::A_SYMBOL;
else if constexpr(requires(Arg arg) { arg = 0.f; })
return type == t_atomtype::A_FLOAT;

return false;
}

template <typename Arg>
static Arg convert(t_atom& atom)
{
if constexpr(requires(Arg arg) { arg = 0.f; })
return atom.a_w.w_float;
else if constexpr(requires(Arg arg) { arg = "str"; })
if constexpr(requires(Arg arg) { arg = "str"; })
return atom.a_w.w_symbol->s_name;
else if constexpr(requires(Arg arg) { arg = 0.f; })
return atom.a_w.w_float;
else
static_assert(std::is_same_v<void, Arg>, "Argument type not handled yet");
}

t_symbol* symbol_for_port(avnd::float_parameter auto& port)
{
return &s_float;
}

t_symbol* symbol_for_port(avnd::string_parameter auto& port)
{
return &s_symbol;
}

t_symbol* symbol_for_port(avnd::mono_audio_port auto& port)
{
return &s_signal;
Expand All @@ -130,9 +120,32 @@ t_symbol* symbol_for_port(avnd::poly_audio_port auto& port)
return &s_signal;
}

t_symbol* symbol_for_port(auto& port)
t_symbol* symbol_for_port(avnd::parameter auto& port)
{
using type = std::remove_cvref_t<decltype(port.value)>;
if constexpr(avnd::vector_ish<type>)
return &s_list;
else if constexpr(avnd::set_ish<type>)
return &s_list;
else if constexpr(avnd::map_ish<type>)
return &s_list;
else if constexpr(avnd::pair_ish<type>)
return &s_list;
else if constexpr(avnd::tuple_ish<type>)
return &s_list;
else if constexpr(avnd::span_ish<type>)
return &s_list;
else if constexpr(std::floating_point<type>)
return &s_float;
else if constexpr(std::integral<type>)
return &s_float;
else if constexpr(avnd::string_ish<type>)
return &s_symbol;
return &s_anything; // TODO is that correct ?
}

t_symbol* symbol_for_port(auto& port)
{
return &s_anything; // TODO is that correct ?
}
}
Loading

0 comments on commit 35398b6

Please sign in to comment.