Skip to content

Commit

Permalink
Enhance/optional message args (#77)
Browse files Browse the repository at this point in the history
* optional args: sc wrapper updates

* optional args: KDTree try out
  • Loading branch information
weefuzzy authored May 3, 2022
1 parent 333a121 commit 4e5f0e4
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 23 deletions.
40 changes: 30 additions & 10 deletions include/wrapper/ArgsFromClient.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,38 +135,45 @@ struct ParamReader<sc_msg_iter>
}
}

static const char* argTypeToString(std::string&)

template <typename T>
static const char* argTypeToString(Optional<T>&)
{
return argTypeToString(T{});
}

static const char* argTypeToString(const std::string&)
{
return "string";
}

template <typename T>
static std::enable_if_t<std::is_integral<T>::value, const char*>
argTypeToString(T&)
argTypeToString(T)
{
return "integer";
}

template <typename T>
static std::enable_if_t<std::is_floating_point<T>::value, const char*>
argTypeToString(T&)
argTypeToString(T)
{
return "float";
}

static const char* argTypeToString(BufferT::type&)
static const char* argTypeToString(const BufferT::type&)
{
return "buffer";
}

static const char* argTypeToString(InputBufferT::type&)
static const char* argTypeToString(const InputBufferT::type&)
{
return "buffer";
}

template <typename P>
static std::enable_if_t<IsSharedClient<P>::value,const char*>
argTypeToString(P&)
argTypeToString(const P&)
{
return "shared_object"; //not ideal
}
Expand All @@ -179,28 +186,34 @@ struct ParamReader<sc_msg_iter>
template <typename T>
static std::enable_if_t<std::is_integral<T>::value
|| std::is_floating_point<T>::value, bool>
argTypeOK(T&, char tag)
argTypeOK(T, char tag)
{
return tag == 'i' || tag == 'f' || tag == 'd';
}

static bool argTypeOK(BufferT::type&, char tag)
static bool argTypeOK(const BufferT::type&, char tag)
{
return tag == 'i';
}

static bool argTypeOK(InputBufferT::type&, char tag)
static bool argTypeOK(const InputBufferT::type&, char tag)
{
return tag == 'i';
}

template <typename P>
static std::enable_if_t<IsSharedClient<P>::value,bool>
argTypeOK(P&, char tag)
argTypeOK(const P&, char tag)
{
return tag == 'i';
}

template<typename T>
static bool argTypeOK(const Optional<T>&, char tag)
{
return argTypeOK(T{},tag);
}

static auto fromArgs(World*, sc_msg_iter& args, std::string, int)
{
const char* recv = args.gets("");
Expand Down Expand Up @@ -266,6 +279,13 @@ struct ParamReader<sc_msg_iter>
res[i] = static_cast<Value>(args.geti());
return res;
}

template<typename T>
static auto fromArgs(World* w, sc_msg_iter& args, Optional<T>, int)
{
return Optional<T>{fromArgs(w,args,T{},int{})};
}

};


Expand Down
38 changes: 29 additions & 9 deletions include/wrapper/Messaging.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,35 @@ struct FluidSCMessaging{
};



template<typename T>
static auto constexpr filterOneOptional(const T&) { return std::make_tuple(T{}); }

template<typename T>
static auto constexpr filterOneOptional(const Optional<T>&) { return std::make_tuple(); }


template<typename...Ts>
static auto constexpr filterOptional(std::tuple<Ts...>)
{
return std::tuple_cat(filterOneOptional(Ts{})...);
}


template <typename Message>
static bool validateMessageArgs(Message* msg, sc_msg_iter* inArgs)
static Optional<size_t> validateMessageArgs(Message* msg, sc_msg_iter* inArgs)
{
//we can be sure that optional args always follow mandatory ones, as this is enforced at compile time in flucoma-core
using ArgTuple = decltype(msg->args);
using MandatoryArgsTuple = decltype(filterOptional(msg->args));

std::string tags(inArgs->tags + inArgs->count);//evidently this needs commenting: construct string at pointer offset by tag count, to pick up args
bool willContinue = true;
bool typesMatch = true;

auto& args = msg->args;

constexpr size_t expectedArgCount = std::tuple_size<ArgTuple>::value;
constexpr size_t expectedArgCount = std::tuple_size<MandatoryArgsTuple>::value;

/// TODO this squawks if we have a completion message, so maybe we can check if extra arg is a 'b' and squawk if not?
// if(tags.size() > expectedArgCount)
Expand All @@ -77,14 +94,16 @@ struct FluidSCMessaging{

auto tagsIter = tags.begin();
auto tagsEnd = tags.end();
ForEach(args,[&typesMatch,&tagsIter,&tagsEnd](auto& arg){
size_t argCount = 0;
ForEach(args,[&typesMatch,&tagsIter,&tagsEnd,firstTag=tags.begin(),&argCount](auto& arg){
if(tagsIter == tagsEnd)
{
typesMatch = false;
if(std::distance(firstTag,tagsIter) < expectedArgCount) typesMatch = false;
return;
}
char t = *(tagsIter++);
typesMatch = typesMatch && ParamReader<sc_msg_iter>::argTypeOK(arg,t);
argCount++;
});

willContinue = willContinue && typesMatch;
Expand Down Expand Up @@ -116,7 +135,7 @@ struct FluidSCMessaging{
report << ")\n";
}

return willContinue;
return willContinue ? Optional<size_t>(argCount) : Optional<size_t>();
}

static void refreshParams(Params& p, MessageResult<ParamValues>& r)
Expand All @@ -137,9 +156,9 @@ struct FluidSCMessaging{
msg->id = args->geti();
msg->replyAddr = copyReplyAddress(replyAddr);
///TODO make this step contingent on verbosity or something, in the name of effieciency
bool willContinue = validateMessageArgs(msg, args);
auto tagCount = validateMessageArgs(msg, args);

if(!willContinue)
if(!tagCount.has_value())
{
delete msg;
return;
Expand All @@ -148,9 +167,10 @@ struct FluidSCMessaging{

msg->name = std::string{'/'} + (const char*)(inUserData);

ForEach(msg-> args,[inWorld,&args](auto& thisarg)
ForEach(msg-> args,[inWorld,&args,tagCount,n=0](auto& thisarg)mutable
{
thisarg = ParamReader<sc_msg_iter>::fromArgs(inWorld, *args,thisarg,0);
if(n++ < tagCount.value())
thisarg = ParamReader<sc_msg_iter>::fromArgs(inWorld, *args,thisarg,0);
});

size_t completionMsgSize{args ? args->getbsize() : 0};
Expand Down
11 changes: 7 additions & 4 deletions release-packaging/Classes/FluidKDTree.sc
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@ FluidKDTree : FluidModelObject
this.prSendMsg(this.fitMsg(dataSet));
}

kNearestMsg{|buffer|
^this.prMakeMsg(\kNearest,id,this.prEncodeBuffer(buffer));
kNearestMsg{|buffer,k|
k !?
{^this.prMakeMsg(\kNearest,id,this.prEncodeBuffer(buffer),k);}
??
{^this.prMakeMsg(\kNearest,id,this.prEncodeBuffer(buffer));}
}

kNearest{ |buffer, action|
kNearest{ |buffer, k, action|
actions[\kNearest] = [strings(FluidMessageResponse,_,_),action];
this.prSendMsg(this.kNearestMsg(buffer));
this.prSendMsg(this.kNearestMsg(buffer,k));
}

kNearestDistMsg {|buffer|
Expand Down

0 comments on commit 4e5f0e4

Please sign in to comment.