Skip to content

Commit

Permalink
[core] Refactor controls
Browse files Browse the repository at this point in the history
  • Loading branch information
jcelerier committed Oct 20, 2024
1 parent ef05b37 commit c616916
Show file tree
Hide file tree
Showing 11 changed files with 310 additions and 176 deletions.
11 changes: 11 additions & 0 deletions include/avnd/binding/ossia/callbacks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ struct do_callback<Self, Idx, Field, R, Args...>
port.data.write_value(std::move(vec), self.start_frame_for_this_tick);
}

// FIXME handle control feedback !
// if constexpr(avnd::control<Field>)
// {
// // Get the index of the control in [0; N[
// using type = typename Exec_T::processor_type;
// using controls = avnd::control_output_introspection<type>;
// constexpr int control_index = controls::field_index_to_index(idx);
//
// // Mark the control as changed
// self.control.outputs_set.set(control_index);
// }
if constexpr(!std::is_void_v<R>)
return R{};
}
Expand Down
28 changes: 24 additions & 4 deletions include/avnd/binding/ossia/controls.hpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,34 @@
#pragma once
#include <avnd/introspection/input.hpp>
#include <avnd/introspection/output.hpp>
#include <boost/smart_ptr/atomic_shared_ptr.hpp>
// #include <boost/smart_ptr/atomic_shared_ptr.hpp>
#include <ossia/detail/lockfree_queue.hpp>

namespace oscr
{

template <typename Field>
using controls_type = std::decay_t<decltype(Field::value)>;
struct controls_type;

template <avnd::parameter Field>
requires avnd::control<Field>
struct controls_type<Field>
{
using type = std::decay_t<decltype(Field::value)>;
};

template <typename Field>
using controls_type_t = typename controls_type<Field>::type;

template <avnd::callback Field>
requires avnd::control<Field>
struct controls_type<Field>
{
// FIXME maybe the tuple of arguments?
using type = ossia::value;
};

#if 0
template <typename T>
using atomic_shared_ptr = boost::atomic_shared_ptr<T>;

Expand All @@ -35,6 +54,7 @@ struct controls_mirror
std::bitset<i_size> inputs_bits;
std::bitset<o_size> outputs_bits;
};
#endif

template <typename T>
struct controls_input_queue
Expand All @@ -52,7 +72,7 @@ struct controls_input_queue<T>
{
static constexpr int i_size = avnd::control_input_introspection<T>::size;
using i_tuple
= avnd::filter_and_apply<controls_type, avnd::control_input_introspection, T>;
= avnd::filter_and_apply<controls_type_t, avnd::control_input_introspection, T>;

ossia::mpmc_queue<i_tuple> ins_queue;
std::bitset<i_size> inputs_set;
Expand All @@ -64,7 +84,7 @@ struct controls_output_queue<T>
{
static constexpr int o_size = avnd::control_output_introspection<T>::size;
using o_tuple
= avnd::filter_and_apply<controls_type, avnd::control_output_introspection, T>;
= avnd::filter_and_apply<controls_type_t, avnd::control_output_introspection, T>;

ossia::mpmc_queue<o_tuple> outs_queue;

Expand Down
136 changes: 84 additions & 52 deletions include/avnd/binding/ossia/message_process.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
#pragma once
#include <avnd/common/aggregates.hpp>
#include <avnd/concepts/all.hpp>
#include <boost/mp11.hpp>
#include <ossia/network/value/value.hpp>

#include <optional>
#include <tuple>

namespace oscr
{
Expand Down Expand Up @@ -57,18 +64,31 @@ struct message_processor
const auto& vec = *val.target<std::vector<ossia::value>>();
if(vec.size() == count)
{
int i = 0; // FIXME doable at compile-time
std::apply([&self, &vec, &i]<typename... Ts>(Ts&&... args) {
(self.from_ossia_value(field, vec[i++], args, avnd::field_index<Idx>{}),
std::apply(
[&self, &vec, it = vec.begin()]<typename... Ts>(Ts&&... args) mutable {
(self.from_ossia_value(field, *(it++), args, avnd::field_index<Idx>{}),
...);
}, tuple);
return tuple;
}
break;
}
case ossia::val_type::MAP:
// FIXME
case ossia::val_type::MAP: {
static constexpr M field;
Args tuple;
const auto& vec = *val.target<ossia::value_map_type>();
if(vec.size() == count)
{
std::apply(
[&self, &vec, it = vec.begin()]<typename... Ts>(Ts&&... args) mutable {
(self.from_ossia_value(
field, (it++)->second, args, avnd::field_index<Idx>{}),
...);
}, tuple);
return tuple;
}
break;
}
default:
break;
}
Expand Down Expand Up @@ -96,51 +116,90 @@ struct message_processor
else
{
// M contains a function pointer to a free function f
f(first_args..., std::forward<Ts>(args)...);
f(std::forward<Args>(first_args)..., std::forward<Ts>(args)...);
}
},
res);
}

template <auto Idx, typename M>
void invoke_message_first_arg_is_object(
auto& self, const ossia::value& val, avnd::field_reflection<Idx, M>)
auto& self, const ossia::value& val, int64_t ts, avnd::field_reflection<Idx, M>)
{
auto& impl = self.impl;
using refl = avnd::message_reflection<M>;
using namespace boost::mp11;
using first_arg_type = std::remove_cvref_t<avnd::first_message_argument<M>>;
if constexpr(std::is_same_v<first_arg_type, T>)

if constexpr(avnd::tag_timestamp<M>)
{
using main_args = mp_pop_front<typename refl::arguments>;
using no_ref = mp_transform<std::remove_cvref_t, main_args>;
using args = mp_rename<no_ref, std::tuple>;
if constexpr(std::is_same_v<first_arg_type, T>)
{
static_assert(boost::mp11::mp_size<typename refl::arguments>::value >= 2);
using main_args = mp_pop_front<mp_pop_front<typename refl::arguments>>;
using no_ref = mp_transform<std::remove_cvref_t, main_args>;
using args = mp_rename<no_ref, std::tuple>;

if(auto res = value_to_argument_tuple<M, args, Idx>(self, val))
if(auto res = value_to_argument_tuple<M, args, Idx>(self, val))
{
for(auto& m : impl.effects())
{
invoke_message_impl<M>(self, *res, m, m, ts);
}
}
}
else
{
for(auto& m : impl.effects())
static_assert(boost::mp11::mp_size<typename refl::arguments>::value >= 1);
using main_args = mp_pop_front<typename refl::arguments>;
using no_ref = mp_transform<std::remove_cvref_t, main_args>;
using args = mp_rename<no_ref, std::tuple>;
if(auto res = value_to_argument_tuple<M, args, Idx>(self, val))
{
invoke_message_impl<M>(self, *res, m, m);
for(auto& m : impl.effects())
{
invoke_message_impl<M>(self, *res, m, ts);
}
}
}
}
else
{
using main_args = typename refl::arguments;
using no_ref = mp_transform<std::remove_cvref_t, main_args>;
using args = mp_rename<no_ref, std::tuple>;
if(auto res = value_to_argument_tuple<M, args, Idx>(self, val))
if constexpr(std::is_same_v<first_arg_type, T>)
{
for(auto& m : impl.effects())
static_assert(boost::mp11::mp_size<typename refl::arguments>::value >= 1);
using main_args = mp_pop_front<typename refl::arguments>;
using no_ref = mp_transform<std::remove_cvref_t, main_args>;
using args = mp_rename<no_ref, std::tuple>;

if(auto res = value_to_argument_tuple<M, args, Idx>(self, val))
{
invoke_message_impl<M>(self, *res, m);
for(auto& m : impl.effects())
{
invoke_message_impl<M>(self, *res, m, m);
}
}
}
else
{
using main_args = typename refl::arguments;
using no_ref = mp_transform<std::remove_cvref_t, main_args>;
using args = mp_rename<no_ref, std::tuple>;
if(auto res = value_to_argument_tuple<M, args, Idx>(self, val))
{
for(auto& m : impl.effects())
{
invoke_message_impl<M>(self, *res, m);
}
}
}
}
}

template <auto Idx, typename M>
void
invoke_message(auto& self, const ossia::value& val, avnd::field_reflection<Idx, M> idx)
void invoke_message(
auto& self, const ossia::value& val, int64_t ts,
avnd::field_reflection<Idx, M> idx)
{
auto& impl = self.impl;
if constexpr(!std::is_void_v<avnd::message_reflection<M>>)
Expand All @@ -154,37 +213,10 @@ struct message_processor
invoke_message_impl<M>(self, std::tuple<>{}, m);
}
}
else // if constexpr(refl::count == 1)
{
invoke_message_first_arg_is_object(self, val, idx);
}
/*
else
{
using namespace boost::mp11;
using first_arg_type = std::remove_cvref_t<avnd::first_message_argument<M>>;
using second_arg_type = std::remove_cvref_t<avnd::second_message_argument<M>>;
if constexpr(
std::is_same_v<first_arg_type, T> && avnd::has_tick<M>
&& std::is_same_v<second_arg_type, typename M::tick>)
{
using main_args = mp_pop_front<typename refl::arguments>;
using no_ref = mp_transform<std::remove_cvref_t, main_args>;
using args = mp_rename<no_ref, std::tuple>;
if(auto res = value_to_argument_tuple<M, args, Idx>(self, val))
{
for(auto& m : impl.effects())
{
invoke_message_impl<M>(self, *res, m, m);
}
}
}
else
{
invoke_message_first_arg_is_object(self, val, idx);
}
}*/
invoke_message_first_arg_is_object(self, val, ts, idx);
}
}
}

Expand All @@ -196,7 +228,7 @@ struct message_processor
return;
for(const auto& val : inl.data.get_data())
{
invoke_message(self, val.value, avnd::field_reflection<Idx, M>{});
invoke_message(self, val.value, val.timestamp, avnd::field_reflection<Idx, M>{});
}
}
};
Expand Down
4 changes: 2 additions & 2 deletions include/avnd/binding/ossia/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ class safe_node_base_base : public ossia::nonowning_graph_node
[[no_unique_address]] oscr::message_processor<T> messages;

using control_input_values_type
= avnd::filter_and_apply<controls_type, avnd::control_input_introspection, T>;
= avnd::filter_and_apply<controls_type_t, avnd::control_input_introspection, T>;
using control_output_values_type
= avnd::filter_and_apply<controls_type, avnd::control_output_introspection, T>;
= avnd::filter_and_apply<controls_type_t, avnd::control_output_introspection, T>;
};

template <std::size_t Index, typename F>
Expand Down
27 changes: 10 additions & 17 deletions include/avnd/binding/ossia/port_run_postprocess.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,7 @@ struct process_after_run
{
}
template <avnd::parameter Field, std::size_t Idx>
requires(!avnd::control<Field> && !ossia_port<Field>)
void write_value(
Field& ctrl, ossia::value_outlet& port, auto& val, int64_t ts,
avnd::field_index<Idx>) const noexcept
{
if(auto v = to_ossia_value(ctrl, val); v.valid())
port->write_value(std::move(v), ts);
}

template <avnd::parameter Field, std::size_t Idx>
requires(avnd::control<Field> && !ossia_port<Field>)
requires(!ossia_port<Field>)
void write_value(
Field& ctrl, ossia::value_outlet& port, auto& val, int64_t ts,
avnd::field_index<Idx> idx) const noexcept
Expand All @@ -97,13 +87,16 @@ struct process_after_run
{
port->write_value(std::move(v), ts);

// Get the index of the control in [0; N[
using type = typename Exec_T::processor_type;
using controls = avnd::control_output_introspection<type>;
constexpr int control_index = controls::field_index_to_index(idx);
if constexpr(avnd::control<Field>)
{
// Get the index of the control in [0; N[
using type = typename Exec_T::processor_type;
using controls = avnd::control_output_introspection<type>;
constexpr int control_index = controls::field_index_to_index(idx);

// Mark the control as changed
self.control.outputs_set.set(control_index);
// Mark the control as changed
self.control.outputs_set.set(control_index);
}
}
}

Expand Down
11 changes: 10 additions & 1 deletion include/avnd/binding/ossia/to_value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,9 @@ ossia::value to_ossia_value(const avnd::variant_ish auto& v)
{
return to_ossia_value_rec(v);
}
ossia::value to_ossia_value(const avnd::optional_ish auto& v)
template <avnd::optional_ish T>
requires(!std::is_same_v<std::optional<ossia::value>, T>)
ossia::value to_ossia_value(const T& v)
{
return to_ossia_value_rec(v);
}
Expand Down Expand Up @@ -451,6 +453,13 @@ inline ossia::value to_ossia_value(const T& v)
return v;
}

template <typename T>
requires std::is_same_v<std::optional<ossia::value>, T>
inline ossia::value to_ossia_value(const T& v)
{
return v ? *v : ossia::value{};
}

inline ossia::value to_ossia_value(auto& field, const auto& src)
{
return to_ossia_value(src);
Expand Down
1 change: 1 addition & 0 deletions include/avnd/concepts/all.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <avnd/concepts/audio_processor.hpp>
#include <avnd/concepts/callback.hpp>
#include <avnd/concepts/channels.hpp>
#include <avnd/concepts/control.hpp>
#include <avnd/concepts/curve.hpp>
#include <avnd/concepts/dynamic_ports.hpp>
#include <avnd/concepts/fft.hpp>
Expand Down
Loading

0 comments on commit c616916

Please sign in to comment.