Enhance/optional message args (#77)

* optional args: sc wrapper updates

* optional args: KDTree try out
nix
Owen Green 4 years ago committed by GitHub
parent 333a121524
commit 4e5f0e4070
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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
}
@ -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("");
@ -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{})};
}
};

@ -48,10 +48,27 @@ 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;
@ -59,7 +76,7 @@ struct FluidSCMessaging{
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)
@ -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;
@ -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)
@ -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;
@ -148,8 +167,9 @@ 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
{
if(n++ < tagCount.value())
thisarg = ParamReader<sc_msg_iter>::fromArgs(inWorld, *args,thisarg,0);
});

@ -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|

Loading…
Cancel
Save