Full template on getting arguments in SC (no full specialisations)

nix
Alex Harker 7 years ago
parent abf3e5cb77
commit 73c6fef292

@ -21,23 +21,12 @@ class FluidSCWrapper;
namespace impl {
template <typename Client, typename T, size_t N>
struct Setter;
template <size_t N, typename T>
struct ArgumentGetter;
template <size_t N, typename T>
struct ControlGetter;
template <typename T>
using msg_iter_method = T (sc_msg_iter::*)(T);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Iterate over kr/ir inputs via callbacks from params object
struct FloatControlsIter
{
FloatControlsIter(float **vals, size_t N)
: mValues(vals)
, mSize(N)
: mValues(vals)
, mSize(N)
{}
float next() { return mCount >= mSize ? 0 : *mValues[mCount++]; }
@ -56,99 +45,6 @@ private:
size_t mCount{0};
};
// General case
template <size_t N, typename T>
struct GetControl
{
T operator()(World *, FloatControlsIter &controls) { return controls.next(); }
};
template <size_t N, typename T>
struct ControlGetter : public GetControl<N, typename T::type>
{};
// Specializations
template <size_t N>
struct ControlGetter<N, BufferT>
{
auto operator()(World *w, FloatControlsIter &iter)
{
typename LongT::type bufnum = iter.next();
return typename BufferT::type(bufnum >= 0 ? new SCBufferAdaptor(bufnum, w) : nullptr);
}
};
template <size_t N>
struct ControlGetter<N, FloatPairsArrayT>
{
typename FloatPairsArrayT::type operator()(World *, FloatControlsIter &iter)
{
return {iter.next(), iter.next(),iter.next(), iter.next()};
}
};
template <size_t N>
struct ControlGetter<N, FFTParamsT>
{
typename FFTParamsT::type operator()(World *, FloatControlsIter &iter)
{
return {static_cast<long>(iter.next()), static_cast<long>(iter.next()), static_cast<long>(iter.next())};
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Iterate over arguments in sc_msg_iter, via callbacks from params object
template <size_t N, typename T, msg_iter_method<T> Method>
struct GetArgument
{
T operator()(World *w, sc_msg_iter *args)
{
T r = (args->*Method)(T{0});
return r;
}
};
// General cases
template <size_t N>
struct ArgumentGetter<N, FloatT> : public GetArgument<N, float, &sc_msg_iter::getf>
{};
template <size_t N>
struct ArgumentGetter<N, LongT> : public GetArgument<N, int32, &sc_msg_iter::geti>
{};
template <size_t N>
struct ArgumentGetter<N, EnumT> : public GetArgument<N, int32, &sc_msg_iter::geti>
{};
// Specializations
template <size_t N>
struct ArgumentGetter<N, BufferT>
{
auto operator()(World *w, sc_msg_iter *args)
{
typename LongT::type bufnum = args->geti(-1);
return typename BufferT::type(bufnum >= 0 ? new SCBufferAdaptor(bufnum, w) : nullptr);
}
};
template <size_t N>
struct ArgumentGetter<N, FloatPairsArrayT>
{
typename FloatPairsArrayT::type operator()(World *w, sc_msg_iter *args)
{
return {args->getf(), args->getf(),args->getf(), args->getf()};
}
};
template <size_t N>
struct ArgumentGetter<N, FFTParamsT>
{
typename FFTParamsT::type operator()(World *w, sc_msg_iter *args) { return {args->geti(), args->geti(), args->geti()}; }
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Real Time Processor
@ -420,6 +316,52 @@ using FluidSCWrapperBase = FluidSCWrapperImpl<Client, FluidSCWrapper<Client>, is
template <typename C>
class FluidSCWrapper : public impl::FluidSCWrapperBase<C>
{
using FloatControlsIter = impl::FloatControlsIter;
// Iterate over arguments in sc_msg_iter, via callbacks from params object
template <typename ArgType, size_t N, typename T>
struct GetArgument
{
auto fromArgs(World *w, FloatControlsIter& args, LongT::type) { return args.next(); }
auto fromArgs(World *w, FloatControlsIter& args, FloatT::type) { return args.next(); }
auto fromArgs(World *w, sc_msg_iter* args, LongT::type) { return args->geti(); }
auto fromArgs(World *w, sc_msg_iter* args, FloatT::type) { return args->getf(); }
auto fromArgs(World *w, sc_msg_iter* args) { return args->geti(-1); }
auto fromArgs(World *w, FloatControlsIter& args) { return args.next(); }
auto fromArgs(World *w, ArgType args, BufferT::type)
{
typename LongT::type bufnum = fromArgs(w, args);
return BufferT::type(bufnum >= 0 ? new SCBufferAdaptor(bufnum, w) : nullptr);
}
template <size_t... Is>
static typename T::type makeVal(std::vector<ParamLiteralType<T>> &v, std::index_sequence<Is...>)
{
return typename T::type{v[Is]...};
}
typename T::type operator()(World *w, ArgType args)
{
constexpr size_t argSize = Client::getParameterDescriptors().template get<N>().fixedSize;
std::vector<ParamLiteralType<T>> v;
for (auto i = 0; i < argSize; i++)
v.push_back(fromArgs(w, args, ParamLiteralType<T>()));
return makeVal(v, std::make_index_sequence<argSize>());
}
};
template <size_t N, typename T>
using ArgumentGetter = GetArgument<sc_msg_iter*, N, T>;
template <size_t N, typename T>
using ControlGetter = GetArgument<FloatControlsIter&, N, T>;
public:
using Client = C;
using ParameterSetType = typename C::ParamSetType;
@ -453,17 +395,17 @@ public:
impl::FluidSCWrapperBase<Client>::setup(ft, name);
}
static auto& setParams(ParameterSetType& p, bool verbose, World* world, impl::FloatControlsIter& inputs)
static auto& setParams(ParameterSetType& p, bool verbose, World* world, FloatControlsIter& inputs)
{
//We won't even try and set params if the arguments don't match
if(inputs.size() == C::getParameterDescriptors().count())
p.template setParameterValues<impl::ControlGetter>(verbose, world, inputs);
p.template setParameterValues<ControlGetter>(verbose, world, inputs);
return p;
}
static auto& setParams(ParameterSetType& p, bool verbose, World* world, sc_msg_iter *args)
{
p.template setParameterValues<impl::ArgumentGetter>(verbose,world, args);
p.template setParameterValues<ArgumentGetter>(verbose,world, args);
return p;
}
};
@ -476,4 +418,3 @@ void makeSCWrapper(const char *name, InterfaceTable *ft)
} // namespace client
} // namespace fluid

Loading…
Cancel
Save