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"; return "string";
} }
template <typename T> template <typename T>
static std::enable_if_t<std::is_integral<T>::value, const char*> static std::enable_if_t<std::is_integral<T>::value, const char*>
argTypeToString(T&) argTypeToString(T)
{ {
return "integer"; return "integer";
} }
template <typename T> template <typename T>
static std::enable_if_t<std::is_floating_point<T>::value, const char*> static std::enable_if_t<std::is_floating_point<T>::value, const char*>
argTypeToString(T&) argTypeToString(T)
{ {
return "float"; return "float";
} }
static const char* argTypeToString(BufferT::type&) static const char* argTypeToString(const BufferT::type&)
{ {
return "buffer"; return "buffer";
} }
static const char* argTypeToString(InputBufferT::type&) static const char* argTypeToString(const InputBufferT::type&)
{ {
return "buffer"; return "buffer";
} }
template <typename P> template <typename P>
static std::enable_if_t<IsSharedClient<P>::value,const char*> static std::enable_if_t<IsSharedClient<P>::value,const char*>
argTypeToString(P&) argTypeToString(const P&)
{ {
return "shared_object"; //not ideal return "shared_object"; //not ideal
} }
@ -179,28 +186,34 @@ struct ParamReader<sc_msg_iter>
template <typename T> template <typename T>
static std::enable_if_t<std::is_integral<T>::value static std::enable_if_t<std::is_integral<T>::value
|| std::is_floating_point<T>::value, bool> || std::is_floating_point<T>::value, bool>
argTypeOK(T&, char tag) argTypeOK(T, char tag)
{ {
return tag == 'i' || tag == 'f' || tag == 'd'; 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'; return tag == 'i';
} }
static bool argTypeOK(InputBufferT::type&, char tag) static bool argTypeOK(const InputBufferT::type&, char tag)
{ {
return tag == 'i'; return tag == 'i';
} }
template <typename P> template <typename P>
static std::enable_if_t<IsSharedClient<P>::value,bool> static std::enable_if_t<IsSharedClient<P>::value,bool>
argTypeOK(P&, char tag) argTypeOK(const P&, char tag)
{ {
return tag == 'i'; 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) static auto fromArgs(World*, sc_msg_iter& args, std::string, int)
{ {
const char* recv = args.gets(""); const char* recv = args.gets("");
@ -266,6 +279,13 @@ struct ParamReader<sc_msg_iter>
res[i] = static_cast<Value>(args.geti()); res[i] = static_cast<Value>(args.geti());
return res; 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> 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 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 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 willContinue = true;
@ -59,7 +76,7 @@ struct FluidSCMessaging{
auto& args = msg->args; 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? /// 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) // if(tags.size() > expectedArgCount)
@ -77,14 +94,16 @@ struct FluidSCMessaging{
auto tagsIter = tags.begin(); auto tagsIter = tags.begin();
auto tagsEnd = tags.end(); 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) if(tagsIter == tagsEnd)
{ {
typesMatch = false; if(std::distance(firstTag,tagsIter) < expectedArgCount) typesMatch = false;
return; return;
} }
char t = *(tagsIter++); char t = *(tagsIter++);
typesMatch = typesMatch && ParamReader<sc_msg_iter>::argTypeOK(arg,t); typesMatch = typesMatch && ParamReader<sc_msg_iter>::argTypeOK(arg,t);
argCount++;
}); });
willContinue = willContinue && typesMatch; willContinue = willContinue && typesMatch;
@ -116,7 +135,7 @@ struct FluidSCMessaging{
report << ")\n"; report << ")\n";
} }
return willContinue; return willContinue ? Optional<size_t>(argCount) : Optional<size_t>();
} }
static void refreshParams(Params& p, MessageResult<ParamValues>& r) static void refreshParams(Params& p, MessageResult<ParamValues>& r)
@ -137,9 +156,9 @@ struct FluidSCMessaging{
msg->id = args->geti(); msg->id = args->geti();
msg->replyAddr = copyReplyAddress(replyAddr); msg->replyAddr = copyReplyAddress(replyAddr);
///TODO make this step contingent on verbosity or something, in the name of effieciency ///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; delete msg;
return; return;
@ -148,9 +167,10 @@ struct FluidSCMessaging{
msg->name = std::string{'/'} + (const char*)(inUserData); 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}; size_t completionMsgSize{args ? args->getbsize() : 0};

@ -24,13 +24,16 @@ FluidKDTree : FluidModelObject
this.prSendMsg(this.fitMsg(dataSet)); this.prSendMsg(this.fitMsg(dataSet));
} }
kNearestMsg{|buffer| kNearestMsg{|buffer,k|
^this.prMakeMsg(\kNearest,id,this.prEncodeBuffer(buffer)); 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]; actions[\kNearest] = [strings(FluidMessageResponse,_,_),action];
this.prSendMsg(this.kNearestMsg(buffer)); this.prSendMsg(this.kNearestMsg(buffer,k));
} }
kNearestDistMsg {|buffer| kNearestDistMsg {|buffer|

Loading…
Cancel
Save