From 27a0542530b98104322cc3bc2b42160ce5c47976 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Thu, 2 Jun 2016 01:15:29 +0900 Subject: [PATCH 01/30] replace many part --- .../Publisher/ofxOscPublishCondition.h | 55 + .../Publisher/ofxOscPublishParameter.h | 212 +++ .../ofxOscPublisherSetImplementation.h | 93 + .../Publisher/ofxOscPublisherStructs.h | 88 + .../Subscriber/ofxOscSubscribeParameter.h | 150 ++ .../ofxOscSubscriberLoadImplementation.h | 209 +++ src/details/ofxOscArrayPublisher.h | 201 +++ ...bosc_settings.h => ofxPubSubOscSettings.h} | 10 +- src/details/ofxPubSubOscTypeTraits.h | 149 ++ src/details/ofxPubSubOscTypeUtils.h | 366 ++++ .../ofxpubsubosc_publish_value_wrappers.h | 196 --- .../ofxpubsubosc_subscribe_value_wrappers.h | 68 - src/details/ofxpubsubosc_type_traits.h | 98 -- src/details/ofxpubsubosc_type_utils.h | 83 - src/ofxOscPublisher.h | 1522 ++++++----------- src/ofxOscSubscriber.h | 1148 ++++--------- src/ofxPubSubOsc.h | 15 +- 17 files changed, 2370 insertions(+), 2293 deletions(-) create mode 100644 src/details/Publisher/ofxOscPublishCondition.h create mode 100644 src/details/Publisher/ofxOscPublishParameter.h create mode 100644 src/details/Publisher/ofxOscPublisherSetImplementation.h create mode 100644 src/details/Publisher/ofxOscPublisherStructs.h create mode 100644 src/details/Subscriber/ofxOscSubscribeParameter.h create mode 100644 src/details/Subscriber/ofxOscSubscriberLoadImplementation.h create mode 100644 src/details/ofxOscArrayPublisher.h rename src/details/{ofxpubsubosc_settings.h => ofxPubSubOscSettings.h} (71%) create mode 100644 src/details/ofxPubSubOscTypeTraits.h create mode 100644 src/details/ofxPubSubOscTypeUtils.h delete mode 100644 src/details/ofxpubsubosc_publish_value_wrappers.h delete mode 100644 src/details/ofxpubsubosc_subscribe_value_wrappers.h delete mode 100644 src/details/ofxpubsubosc_type_traits.h delete mode 100644 src/details/ofxpubsubosc_type_utils.h diff --git a/src/details/Publisher/ofxOscPublishCondition.h b/src/details/Publisher/ofxOscPublishCondition.h new file mode 100644 index 0000000..0958989 --- /dev/null +++ b/src/details/Publisher/ofxOscPublishCondition.h @@ -0,0 +1,55 @@ +// +// ofxOscPublishCondition.h +// +// Created by ISHII 2bit on 2016/05/31. +// +// + +#pragma once + +#ifndef ofxOscPublishCondition_h +#define ofxOscPublishCondition_h + +#include +#include + +#include "ofxPubSubOscSettings.h" + +namespace ofx { + namespace PubSubOsc { + namespace Publish { + struct BasicCondition { + BasicCondition() : bPublishNow(true) {}; + + inline bool getCondition() { return isPublishNow() && inner_condition(); }; + + inline bool isPublishNow() const { return bPublishNow; }; + inline void setEnablePublish(bool bEnablePublish) { this->bPublishNow = bEnablePublish; }; + + virtual bool inner_condition() { return true; }; + + using Ref = std::shared_ptr; + private: + bool bPublishNow; + }; + + struct Condition : BasicCondition { + Condition(bool &ref) : BasicCondition(), ref(ref) {}; + virtual bool inner_condition() { return ref; }; + private: + bool &ref; + }; + + struct ConditionFunction : BasicCondition { + ConditionFunction(std::function getter) : BasicCondition(), getter(getter) {}; + virtual bool inner_condition() { return getter(); }; + private: + std::function getter; + }; + + using ConditionRef = BasicCondition::Ref; + }; + }; +}; + +#endif /* ofxOscPublishCondition_h */ diff --git a/src/details/Publisher/ofxOscPublishParameter.h b/src/details/Publisher/ofxOscPublishParameter.h new file mode 100644 index 0000000..a77fad0 --- /dev/null +++ b/src/details/Publisher/ofxOscPublishParameter.h @@ -0,0 +1,212 @@ +// +// ofxOscPublishParameter.h +// +// Created by ISHII 2bit on 2016/05/31. +// +// + +#pragma once + +#ifndef ofxOscPublishParameter_h +#define ofxOscPublishParameter_h + +#include +#include +#include + +#include "ofxPubSubOscSettings.h" +#include "ofxOscPublishCondition.h" +#include "ofxOscPublisherSetImplementation.h" + +namespace ofx { + namespace PubSubOsc { + namespace Publish { + struct AbstractParameter { + AbstractParameter() : condition(new BasicCondition) {} + virtual bool write(ofxOscMessage &m, const std::string &address) = 0; + void setCondition(ConditionRef ref) { condition = ref; }; + + inline void setEnablePublish(bool bEnablePublish) { condition->setEnablePublish(bEnablePublish); }; + inline bool isPublishNow() const { return condition->isPublishNow(); }; + protected: + bool canPublish() { + return condition->getCondition(); + } + private: + ConditionRef condition; + }; + + using ParameterRef = std::shared_ptr; + + template + struct Parameter : AbstractParameter { + Parameter(T &t) + : t(t) {} + + virtual bool write(ofxOscMessage &m, const std::string &address) { + if(!canPublish() || !isChanged()) return false; + m.setAddress(address); + set(m, get()); + return true; + } + protected: + virtual bool isChanged() { return true; } + virtual type_ref get() { return t; } + T &t; + }; + + template + struct Parameter : Parameter { + Parameter(T &t) + : Parameter(t) {} + + protected: + virtual bool isChanged() { + if(old != this->get()) { + old = this->get(); + return true; + } else { + return false; + } + } + + T old; + }; + + template + struct Parameter : AbstractParameter { + Parameter(Base (&t)[size]) + : t(t) { for(std::size_t i = 0; i < size; i++) old[i] = t[i]; } + virtual ~Parameter() { }; + + virtual bool write(ofxOscMessage &m, const std::string &address) { + if(!canPublish() || !isChanged()) return false; + m.setAddress(address); + set(m, get()); + return true; + } + + protected: + virtual bool isChanged() { + bool isChange = false; + for(int i = 0; i < size; i++) { + isChange = isChange || (old[i] != get()[i]); + if(isChange) break; + } + + if(isChange) { + for(int i = 0; i < size; i++) { + old[i] = get()[i]; + } + return true; + } else { + return false; + } + } + + virtual Base (&get())[size] { return t; } + Base (&t)[size]; + Base old[size]; + }; + + template + struct ConstParameter : AbstractParameter { + ConstParameter(const T &t) + : t(t) {} + + virtual bool write(ofxOscMessage &m, const std::string &address) { + if(!canPublish() || !isChanged()) return false; + m.setAddress(address); + set(m, get()); + return true; + } + protected: + virtual bool isChanged() { return true; } + virtual const T &get() { return t; } + const T t; + }; + + template + struct ConstParameter : ConstParameter { + ConstParameter(const T &t) + : ConstParameter(t) {} + + protected: + virtual bool isChanged() { + static bool initial{true}; + bool tmp = initial; + initial = false; + return tmp; + } + }; + + template + struct ConstParameter : AbstractParameter { + ConstParameter(const Base (&t)[size]) + : t(t) {} + + virtual bool write(ofxOscMessage &m, const std::string &address) { + if(!canPublish() || !isChanged()) return false; + m.setAddress(address); + set(m, get()); + return true; + } + + protected: + virtual bool isChanged() { return true; } + + virtual const Base (&get())[size] { return t; } + const Base (&t)[size]; + }; + + template + struct ConstParameter : ConstParameter { + ConstParameter(const Base(&t)[size]) + : ConstParameter(t) {} + + protected: + virtual bool isChanged() { + static bool initial{true}; + bool tmp = initial; + initial = false; + return tmp; + } + }; + + template + struct FunctionParameter : Parameter { + using Function = std::function; + FunctionParameter(Function getter) + : Parameter(dummy) + , getter(getter) {} + + protected: + virtual type_ref get() { return dummy = getter(); } + Function getter; + remove_ref dummy; + }; + + template + struct FunctionParameter : Parameter { + using T = Base (&)[size]; + using Function = std::function; + FunctionParameter(Function getter) + : Parameter(dummy) + , getter(getter) {} + + protected: + virtual Base (&get())[size] { + Base (&arr)[size] = getter(); + for(std::size_t i = 0; i < size; i++) dummy[i] = arr[i]; + return dummy; + } + Function getter; + Base dummy[size]; + }; + + using Targets = std::multimap; + }; + }; +}; + +#endif /* ofxOscPublishParameter_h */ diff --git a/src/details/Publisher/ofxOscPublisherSetImplementation.h b/src/details/Publisher/ofxOscPublisherSetImplementation.h new file mode 100644 index 0000000..235403a --- /dev/null +++ b/src/details/Publisher/ofxOscPublisherSetImplementation.h @@ -0,0 +1,93 @@ +// +// ofxOscPublisherSetImplementation.h +// +// Created by ISHII 2bit on 2016/05/29. +// +// + +#pragma once + +#ifndef ofxOscPublisherSetImplementation_h +#define ofxOscPublisherSetImplementation_h + +#include "ofxOscMessage.h" + +#include "ofxPubSubOscSettings.h" +#include "ofxPubSubOscTypeUtils.h" +#include "ofxPubSubOscTypeTraits.h" + +namespace ofx { + namespace PubSubOsc { + template + inline auto set(ofxOscMessage &m, T v) + -> enable_if_t::value> + { m.addIntArg(v); } + + template + inline auto set(ofxOscMessage &m, T v) + -> enable_if_t::value> + { m.addInt64Arg(v); } + +#define define_set_float(type) inline void set(ofxOscMessage &m, type v) { m.addFloatArg(v); } + define_set_float(float); + define_set_float(double); +#undef define_set_float + inline void set(ofxOscMessage &m, const std::string &v) { m.addStringArg(v); } + inline void set(ofxOscMessage &m, const ofBuffer &v) { m.addBlobArg(v); }; + + + template + inline void setVec(ofxOscMessage &m, const T &v) { + for(int i = 0; i < n; i++) { set(m, v[i]); } + } + + template + inline void set(ofxOscMessage &m, const ofColor_ &v) { setVec<4>(m, v); } + inline void set(ofxOscMessage &m, const ofVec2f &v) { setVec<2>(m, v); } + inline void set(ofxOscMessage &m, const ofVec3f &v) { setVec<3>(m, v); } + inline void set(ofxOscMessage &m, const ofVec4f &v) { setVec<4>(m, v); } + inline void set(ofxOscMessage &m, const ofQuaternion &v) { setVec<4>(m, v); } + + inline void set(ofxOscMessage &m, const ofMatrix3x3 &v) { + set(m, v.a); + set(m, v.b); + set(m, v.c); + set(m, v.d); + set(m, v.e); + set(m, v.f); + set(m, v.g); + set(m, v.h); + set(m, v.i); + } + + inline void set(ofxOscMessage &m, const ofMatrix4x4 &v) { + for(int j = 0; j < 4; j++) for(int i = 0; i < 4; i++) set(m, v(i, j)); + } + + inline void set(ofxOscMessage &m, const ofRectangle &v) { + set(m, v.x); + set(m, v.y); + set(m, v.width); + set(m, v.height); + } + + template + inline void set(ofxOscMessage &m, const U (&v)[size]) { + for(int i = 0; i < size; i++) { set(m, v[i]); } + } + + template + inline void set(ofxOscMessage &m, const std::vector &v) { + for(int i = 0; i < v.size(); i++) { set(m, v[i]); } + } + +#pragma mark ofParameter / ofParameterGroup + + template + inline void set(ofxOscMessage &m, const ofParameter &p) { + set(m, p.get()); + } + }; +}; + +#endif /* ofxOscPublisherSetImplementation_h */ diff --git a/src/details/Publisher/ofxOscPublisherStructs.h b/src/details/Publisher/ofxOscPublisherStructs.h new file mode 100644 index 0000000..6fbd527 --- /dev/null +++ b/src/details/Publisher/ofxOscPublisherStructs.h @@ -0,0 +1,88 @@ +// +// ofxOscPublisherStructs.h +// ofxPubSubOscDev +// +// Created by ISHII 2bit on 2016/05/31. +// +// + +#pragma once + +#ifndef ofxOscPublisherStructs_h +#define ofxOscPublisherStructs_h + +#include + +namespace ofx { + namespace PubSubOsc { + namespace Publish { + struct IP { + IP(const IP &ip) + : ip(ip.ip) {} + + IP(const std::string &ip) + : ip(ip) {} + + bool operator<(const IP &rhs) const { + return ip < rhs.ip; + } + + std::string ip; + private: + IP(); + }; + + struct Destination { + Destination() {} + Destination(const Destination &destination) + : ip(destination.ip) + , port(destination.port) {} + + Destination(const std::string &ip, int port) + : ip(ip) + , port(port) {} + + inline bool operator<(const Destination &rhs) const { + return (ip != rhs.ip) ? (ip < rhs.ip) : (port < rhs.port); + } + + inline bool operator!=(const Destination &rhs) const { + return ip != rhs.ip || port != rhs.port; + } + + std::string ip; + int port; + private: + }; + + struct DestinationWithAddress { + DestinationWithAddress(const DestinationWithAddress &destination) + : destination(destination.destination) + , address(destination.address) {} + + DestinationWithAddress(const std::string &ip, int port, const std::string &address) + : destination(ip, port) + , address(address) {} + + inline bool operator<(const DestinationWithAddress &rhs) const { + return (destination != rhs.destination) ? (destination < rhs.destination) : (address < rhs.address); + } + + operator Destination() const { + return destination; + } + + inline operator const Destination&() const { + return destination; + } + + Destination destination; + std::string address; + private: + DestinationWithAddress(); + }; + }; + }; +}; + +#endif /* ofxOscPublisherStructs_h */ diff --git a/src/details/Subscriber/ofxOscSubscribeParameter.h b/src/details/Subscriber/ofxOscSubscribeParameter.h new file mode 100644 index 0000000..7d13631 --- /dev/null +++ b/src/details/Subscriber/ofxOscSubscribeParameter.h @@ -0,0 +1,150 @@ +// +// ofxOscSubscribeParameter.h +// ofxPubSubOscDev +// +// Created by ISHII 2bit on 2016/05/29. +// +// + +#pragma once + +#ifndef ofxOscSubscribeParameter_h +#define ofxOscSubscribeParameter_h + +#include "ofxOscMessage.h" +#include "ofxOscSubscriberLoadImplementation.h" + +namespace ofx { + namespace PubSubOsc { + namespace Subscribe { + struct AbstractParameter { + virtual void read(ofxOscMessage &message, std::size_t offset = 0) = 0; + virtual std::size_t size() const = 0; + }; + + using ParameterRef = std::shared_ptr; + + template + struct Parameter : AbstractParameter, type_traits { + Parameter(T &t) : t(t) {} + virtual void read(ofxOscMessage &message, std::size_t offset = 0) override + { load(message, t, offset); } + virtual std::size_t size() const override { return type_traits::size; }; + + private: + + T &t; + }; + + template + struct TupleParameter : AbstractParameter, type_traits> { + TupleParameter(std::vector &&t) : t(std::move(t)) {} + virtual void read(ofxOscMessage &message, std::size_t offset = 0) override + { load(message, t, offset); } + virtual std::size_t size() const override { return type_traits>::size; }; + + private: + + std::vector t; + }; + + namespace detail { + template + void read_to_tuple(index_sequence &&, + ofxOscMessage &m, + std::tuple &t, + std::size_t offset) { + std::size_t o{0}; + std::vector{(load(m, std::get(t), offset + o), o += type_traits::size) ...}; + } + + template + void read_to_tuple(ofxOscMessage &m, std::tuple &t, std::size_t offset) { + read_to_tuple(index_sequence_for(), m, t, offset); + } + }; + + template + struct SetterFunctionParameter : AbstractParameter, type_traits> { + using Setter = std::function; + SetterFunctionParameter(Setter setter) : setter(setter) {}; + + virtual void read(ofxOscMessage &message, std::size_t offset = 0) override { + std::tuple ...> t; + Subscribe::detail::read_to_tuple ...>(message, t, offset); + apply(setter, t); + } + virtual std::size_t size() const override { return type_traits>::size; }; + + private: + Setter setter; + }; + + template + struct SetterFunctionParameter : AbstractParameter, type_traits { + using Setter = std::function; + SetterFunctionParameter(Setter setter) : setter(setter) {}; + + virtual void read(ofxOscMessage &message, std::size_t offset = 0) override { + setter(message); + } + virtual std::size_t size() const override { return type_traits::size; }; + + private: + Setter setter; + }; + + template + struct SetterFunctionParameter::value>, T, Ts ...> : AbstractParameter, type_traits> { + using Setter = std::function; + SetterFunctionParameter(Setter setter) : setter(setter) {}; + + virtual void read(ofxOscMessage &message, std::size_t offset = 0) override { + std::tuple t; + Subscribe::detail::read_to_tuple(message, t, offset); + apply(setter, t); + } + virtual std::size_t size() const override { return type_traits>::size; }; + + private: + Setter setter; + }; + + template + struct SetterFunctionParameter : AbstractParameter, type_traits { + using Setter = std::function; + SetterFunctionParameter(Setter setter) : setter(setter) {}; + + virtual void read(ofxOscMessage &message, std::size_t offset = 0) override { + setter(); + } + virtual std::size_t size() const override { return type_traits::size; }; + + private: + Setter setter; + }; + + +#pragma mark load for ParameterRef + inline void load(ofxOscMessage &m, ParameterRef &ref, std::size_t offset = 0) { + ref->read(m, offset); + } + + inline void load(ofxOscMessage &m, std::vector &v, std::size_t offset = 0) { + std::size_t o = 0; + for(int i = 0; i < v.size(); i++) { + if(m.getNumArgs() < offset + o + v[i]->size()) { + ofLogWarning("ofxPubSubOsc::Subscriber") << "less args"; + break; + } + load(m, v[i], offset + o); + o += v[i]->size(); + } + } + + using Targets = std::multimap; + }; + }; +}; + +#endif /* ofxOscSubscribeParameter_h */ diff --git a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h new file mode 100644 index 0000000..598c276 --- /dev/null +++ b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h @@ -0,0 +1,209 @@ +// +// ofxOscSubscriberLoadImplementation.h +// +// Created by ISHII 2bit on 2016/05/29. +// +// + +#pragma once + +#ifndef ofxOscSubscriberLoadImplementation_h +#define ofxOscSubscriberLoadImplementation_h + +#include "ofxOscMessage.h" + +#include "ofxPubSubOscSettings.h" +#include "ofxPubSubOscTypeUtils.h" +#include "ofxPubSubOscTypeTraits.h" + +namespace ofx { + namespace PubSubOsc { +#define define_set_arithmetic(type) \ + inline void load(ofxOscMessage &m, type &v, std::size_t offset = 0) { \ + if(m.getArgType(offset) == OFXOSC_TYPE_INT32) v = m.getArgAsInt32(offset); \ + else if(m.getArgType(offset) == OFXOSC_TYPE_INT64) v = m.getArgAsInt64(offset); \ + else if(m.getArgType(offset) == OFXOSC_TYPE_FLOAT) v = m.getArgAsFloat(offset); \ + else if(m.getArgType(offset) == OFXOSC_TYPE_DOUBLE) v = m.getArgAsDouble(offset); \ + else if(m.getArgType(offset) == OFXOSC_TYPE_STRING) v = ofToDouble(m.getArgAsString(offset)); \ +} + + define_set_arithmetic(bool); + define_set_arithmetic(char); + define_set_arithmetic(unsigned char); + define_set_arithmetic(short); + define_set_arithmetic(unsigned short); + define_set_arithmetic(int); + define_set_arithmetic(unsigned int); + define_set_arithmetic(long); + define_set_arithmetic(unsigned long); + define_set_arithmetic(long long); + define_set_arithmetic(unsigned long long); + + define_set_arithmetic(float); + define_set_arithmetic(double); +#undef define_set_arithmetic + + inline void load(ofxOscMessage &m, std::string &v, std::size_t offset = 0) { + if(m.getArgType(offset) == OFXOSC_TYPE_STRING) v = m.getArgAsString(offset); + else if(m.getArgType(offset) == OFXOSC_TYPE_FLOAT) v = ofToString(m.getArgAsFloat(offset)); + else if(m.getArgType(offset) == OFXOSC_TYPE_DOUBLE) v = ofToString(m.getArgAsDouble(offset)); + else if(m.getArgType(offset) == OFXOSC_TYPE_INT32) v = ofToString(m.getArgAsInt32(offset)); + else if(m.getArgType(offset) == OFXOSC_TYPE_INT64) v = ofToString(m.getArgAsInt64(offset)); + else v = m.getArgAsString(offset); + } + + inline void load(ofxOscMessage &m, ofBuffer &v, std::size_t offset = 0) { + v = m.getArgAsBlob(offset); + } + +#pragma mark ofColor_ + template + inline void loadColor(ofxOscMessage &m, ofColor_ &v, U defaultValue, std::size_t offset = 0) { + if(m.getNumArgs() == 1) { + load(m, v.r, offset); + load(m, v.g, offset); + load(m, v.b, offset); + v.a = defaultValue; + } else if(m.getNumArgs() == 3) { + load(m, v.r, offset + 0); + load(m, v.g, offset + 1); + load(m, v.b, offset + 2); + v.a = defaultValue; + } else { + load(m, v.r, offset + 0); + load(m, v.g, offset + 1); + load(m, v.b, offset + 2); + load(m, v.a, offset + 3); + } + } + + inline void load(ofxOscMessage &m, ofColor &v, std::size_t offset = 0) { + loadColor(m, v, 255, offset); + } + inline void load(ofxOscMessage &m, ofShortColor &v, std::size_t offset = 0) { + loadColor(m, v, 65535, offset); + } + inline void load(ofxOscMessage &m, ofFloatColor &v, std::size_t offset = 0) { + loadColor(m, v, 1.0f, offset); + } + +#pragma mark oF container type + template + inline void loadVec(ofxOscMessage &m, U &v, std::size_t offset = 0) { + for(int i = 0; i < min(static_cast(m.getNumArgs() - offset), n); i++) { + load(m, v[i], offset + i); + } + } + + inline void load(ofxOscMessage &m, ofVec2f &v, std::size_t offset = 0) { + loadVec<2>(m, v, offset); + } + inline void load(ofxOscMessage &m, ofVec3f &v, std::size_t offset = 0) { + loadVec<3>(m, v, offset); + } + inline void load(ofxOscMessage &m, ofVec4f &v, std::size_t offset = 0) { + loadVec<4>(m, v, offset); + } + inline void load(ofxOscMessage &m, ofQuaternion &v, std::size_t offset = 0) { + loadVec<4>(m, v, offset); + } + inline void load(ofxOscMessage &m, ofMatrix3x3 &v, std::size_t offset = 0) { + loadVec<9>(m, v, offset); + } + + inline void load(ofxOscMessage &m, ofMatrix4x4 &v, std::size_t offset = 0) { + for(int j = 0; j < 4; j++) for(int i = 0; i < 4; i++) { + load(m, v(i, j), offset + 4 * j + i); + } + } + + inline void load(ofxOscMessage &m, ofRectangle &v, std::size_t offset = 0) { + load(m, v.x, offset + 0); + load(m, v.y, offset + 1); + load(m, v.width, offset + 2); + load(m, v.height, offset + 3); + } + +#pragma mark ofParameter / ofParameterGroup + + template + inline void load(ofxOscMessage &m, ofParameter &p, std::size_t offset = 0) { + U u; + load(m, u, offset); + p.set(u); + } + + inline void load(ofxOscMessage &m, ofAbstractParameter &p, std::size_t offset = 0) { +#define type_convert(type_) if(p.type() == typeid(ofParameter).name()) { load(m, p.cast(), offset); return; } + type_convert(float); + type_convert(double); + type_convert(int); + type_convert(unsigned int); + type_convert(long); + type_convert(unsigned long); + type_convert(ofColor); + type_convert(ofRectangle); + type_convert(ofVec2f); + type_convert(ofVec3f); + type_convert(ofVec4f); + type_convert(ofQuaternion); + type_convert(ofMatrix3x3); + type_convert(ofMatrix4x4); + + type_convert(ofFloatColor); + type_convert(ofShortColor); + + type_convert(bool); + type_convert(char); + type_convert(unsigned char); + type_convert(short); + type_convert(unsigned short); + type_convert(long long); + type_convert(unsigned long long); + type_convert(ofBuffer); + ofLogWarning("ofxOscSubscriber") << "ofAbstractParameter: Unknown type \"" << p.type() << "\", bind to " << m.getAddress() << ". we ignored."; +#undef type_convert + } + + inline void load(ofxOscMessage &m, ofParameterGroup &pg, std::size_t offset = 0) { + if(m.getArgType(0) == OFXOSC_TYPE_INT32) { + if(pg.size() <= m.getArgAsInt32(0)) { + ofLogWarning("ofxOscSubscriber") << "ofAbstractParameterGroup: not contain index \"" << m.getArgAsInt32(0) << "\""; + return; + } + load(m, pg.get(m.getArgAsInt32(0)), offset + 1); + } else if(m.getArgType(0) == OFXOSC_TYPE_INT64) { + if(pg.size() <= m.getArgAsInt64(0)) { + ofLogWarning("ofxOscSubscriber") << "ofAbstractParameterGroup: not contain index \"" << m.getArgAsInt64(0) << "\""; + return; + } + load(m, pg.get(m.getArgAsInt64(0)), offset + 1); + } else if(m.getArgType(0) == OFXOSC_TYPE_STRING) { + if(!pg.contains(m.getArgAsString(0))) { + ofLogWarning("ofxOscSubscriber") << "ofAbstractParameterGroup: not contain key \"" << m.getArgAsString(0) << "\""; + return; + } + load(m, pg.get(m.getArgAsString(0)), offset + 1); + } + } + +#pragma mark vector + template + inline void load(ofxOscMessage &m, U (&v)[size], std::size_t offset = 0) { + for(int i = 0; i < min(size, (m.getNumArgs() - offset) / type_traits::size); i++) { + load(m, v[i], offset + i * type_traits::size); + } + } + + template + inline void load(ofxOscMessage &m, std::vector &v, std::size_t offset = 0) { + std::size_t num = (m.getNumArgs() - offset) / type_traits::size; + if(v.size() != num) v.resize(num); + for(int i = 0; i < num; i++) { + load(m, v[i], offset + i * type_traits::size); + } + } + }; +}; + +#endif /* ofxOscSubscriberLoadImplementation_h */ diff --git a/src/details/ofxOscArrayPublisher.h b/src/details/ofxOscArrayPublisher.h new file mode 100644 index 0000000..b568374 --- /dev/null +++ b/src/details/ofxOscArrayPublisher.h @@ -0,0 +1,201 @@ +// +// ofxOscArrayPublisher.h +// ofxPubSubOscDev +// +// Created by ISHII 2bit on 2016/05/29. +// +// + +#pragma once + +#ifndef ofxOscArrayPublisher_h +#define ofxOscArrayPublisher_h + +#include + +namespace ofx { + namespace PubSubOsc { + namespace detail { + template + struct abstract_stream { + virtual T get() { return T(); }; + }; + + template + struct raw_stream : abstract_stream { + raw_stream(T &v) + : v(v) {}; + virtual T get() { return v; }; + private: + T &v; + }; + + template + struct getter_function_stream : abstract_stream { + getter_function_stream(T (*getter)()) + : getter(getter) {}; + virtual T get() { return getter(); }; + private: + T (*getter)(); + }; + + template + struct getter_method_stream : abstract_stream { + getter_method_stream(U &obj, T (U::*getter)()) + : obj(obj) + , getter(getter) {}; + + virtual T get() { return (obj.*getter)(); }; + private: + U &obj; + T (U::*getter)(); + }; + + template + struct const_getter_method_stream : abstract_stream { + const_getter_method_stream(const U &obj, T (U::*getter)() const) + : obj(obj) + , getter(getter) {}; + + virtual T get() { return (obj.*getter)(); }; + private: + const U &obj; + T (U::*getter)() const; + }; + + +#pragma mark pointer stream + + template + struct abstract_pointer_stream { + virtual T *get() { return NULL; }; + T operator [](std::size_t n) { return get()[n]; }; + }; + + template + struct raw_pointer_stream : abstract_pointer_stream { + raw_pointer_stream(T *ptr) + : ptr(ptr) {}; + + virtual T *get() { return ptr; }; + private: + T *ptr; + }; + + template + struct getter_function_pointer_stream : abstract_pointer_stream { + getter_function_pointer_stream(T (*getter)()) + : getter(getter) {}; + + virtual T *get() { return getter(); }; + private: + T (*getter)(); + }; + + template + struct getter_method_pointer_stream : abstract_pointer_stream { + getter_method_pointer_stream(U &obj, T (U::*getter)()) + : obj(obj) + , getter(getter) {}; + + virtual T *get() { return (obj.*getter)(); }; + private: + U &obj; + T (U::*getter)(); + }; + + template + struct const_getter_method_pointer_stream : abstract_pointer_stream { + const_getter_method_pointer_stream(const U &obj, T (U::*getter)() const) + : obj(obj) + , getter(getter) {}; + + virtual T *get() { return (obj.*getter)(); }; + private: + const U &obj; + T (U::*getter)() const; + }; + +#pragma mark factory + + template + std::shared_ptr > pointer_stream_factory(T *t) { + return std::shared_ptr >(new raw_pointer_stream(t)); + } + + template + std::shared_ptr > pointer_stream_factory(T (*g)()) { + return std::shared_ptr >(new getter_function_pointer_stream(g)); + } + + template + std::shared_ptr > pointer_stream_factory(U &that, T (U::*g)()) { + return std::shared_ptr >(new getter_method_pointer_stream(that, g)); + } + + template + std::shared_ptr > pointer_stream_factory(const U &that, T (U::*g)() const) { + return std::shared_ptr >(new const_getter_method_pointer_stream(that, g)); + } + }; + + template + struct ArrayPublisher { + using inner_type = const T; + using const_array_t = T const (&)[s]; + + ArrayPublisher(T *v) + : stream(PubSubOsc::detail::pointer_stream_factory(v)) {} + + ArrayPublisher(T (*getter)()) + : stream(PubSubOsc::detail::pointer_stream_factory(getter)) {} + template + + ArrayPublisher(U &that, T (U::*getter)()) + : stream(PubSubOsc::detail::pointer_stream_factory(that, getter)) {} + template + + ArrayPublisher(const U &that, T (U::*getter)() const) + : stream(PubSubOsc::detail::pointer_stream_factory(that, getter)) {} + virtual ~ArrayPublisher() { } + + T operator[](std::size_t n) const { return stream[n]; }; + + std::size_t size() const { return s; }; + operator const_array_t() { return get(); }; + const_array_t get() { return reinterpret_cast(stream.get()); }; + protected: + std::shared_ptr > stream; + }; + + template + struct ArrayPublisher : ArrayPublisher {}; + + template + struct ArrayBuffer { + using inner_type = T; + using array_t = T (&)[s]; + + ArrayBuffer() : v(malloc(sizeof(T) * s)) {} + virtual ~ArrayBuffer() { free(v); v = NULL; } + + array_t operator=(const ArrayPublisher &arr) { for(int i = 0; i < size(); i++) v[i] = arr[i]; return get(); }; + bool operator!=(const ArrayPublisher &arr) const { for(int i = 0; i < size(); i++) if(v[i] != arr[i]) return true; return false; }; + bool operator==(const ArrayPublisher &arr) const { for(int i = 0; i < size(); i++) if(v[i] != arr[i]) return false; return true; }; + T operator[](std::size_t n) const { return v[n]; }; + T &operator[](std::size_t n) { return v[n]; }; + + std::size_t size() const { return s; }; + operator array_t() { return get(); }; + array_t get() { return reinterpret_cast(reinterpret_cast(v[0])); }; + protected: + T *v; + }; + + template + struct ArrayBuffer : ArrayBuffer {}; + + }; +}; + +#endif /* ofxOscArrayPublisher_h */ diff --git a/src/details/ofxpubsubosc_settings.h b/src/details/ofxPubSubOscSettings.h similarity index 71% rename from src/details/ofxpubsubosc_settings.h rename to src/details/ofxPubSubOscSettings.h index 2d5c1b0..ce842c5 100644 --- a/src/details/ofxpubsubosc_settings.h +++ b/src/details/ofxPubSubOscSettings.h @@ -1,17 +1,19 @@ // -// ofxpubsubosc_settings.h +// ofxPubSubSettings.h // // Created by ISHII 2bit on 2015/09/17. // // -#ifndef ofxPubSubDevelopProject_ofxpubsubosc_settings_h -#define ofxPubSubDevelopProject_ofxpubsubosc_settings_h +#pragma once + +#ifndef ofxPubSubOscSettings_h +#define ofxPubSubOscSettings_h #pragma mark versioning tags #define OFX_PUBSUBOSC_VERSION_MAJOR 0 -#define OFX_PUBSUBOSC_VERSION_MINOR 2 +#define OFX_PUBSUBOSC_VERSION_MINOR 3 #define OFX_PUBSUBOSC_VERSION_PATCH 0 #define OFX_PUBSUBOSC_MULTISUBSCRIBE 1 diff --git a/src/details/ofxPubSubOscTypeTraits.h b/src/details/ofxPubSubOscTypeTraits.h new file mode 100644 index 0000000..76bf34e --- /dev/null +++ b/src/details/ofxPubSubOscTypeTraits.h @@ -0,0 +1,149 @@ +// +// ofxPubSubOscTypeTraits.h +// +// Created by ISHII 2bit on 2016/05/29. +// +// + +#pragma once + +#ifndef ofxPubSubOscTypeTraits_h +#define ofxPubSubOscTypeTraits_h + +#include + +#include "ofVectorMath.h" +#include "ofFileUtils.h" +#include "ofxOscMessage.h" + +#include "ofxOscArrayPublisher.h" + +namespace ofx { + namespace PubSubOsc { + template + struct type_traits { + using inner_type = T; + static constexpr std::size_t size = 1; + static constexpr bool has_array_operator = false; + }; + + template <> + struct type_traits { + using inner_type = void; + static constexpr std::size_t size = 0; + static constexpr bool has_array_operator = false; + }; + + template <> + struct type_traits { + using inner_type = ofxOscMessage; + static constexpr std::size_t size = 0; + static constexpr bool has_array_operator = false; + }; + + namespace detail { + template + struct size_sum { + static constexpr std::size_t value = type_traits::size + size_sum::value; + }; + + template + struct size_sum { + static constexpr std::size_t value = type_traits::size; + }; + }; + + template + struct type_traits> { + using inner_type = std::tuple; + static constexpr std::size_t size = PubSubOsc::detail::size_sum::value; + static constexpr bool has_array_operator = false; + }; + + template + struct type_traits> { + using inner_type = std::tuple; + static constexpr std::size_t size = PubSubOsc::detail::size_sum::value; + static constexpr bool has_array_operator = false; + }; + + template + struct type_traits > { + using inner_type = T; + static constexpr std::size_t size = 4; + static constexpr bool has_array_operator = true; + }; + + template <> + struct type_traits { + using inner_type = float; + static constexpr std::size_t size = 2; + static constexpr bool has_array_operator = true; + }; + + template <> + struct type_traits { + using inner_type = float; + static constexpr std::size_t size = 3; + static constexpr bool has_array_operator = true; + }; + + template <> + struct type_traits { + using inner_type = float; + static constexpr std::size_t size = 4; + static constexpr bool has_array_operator = true; + }; + + template <> + struct type_traits { + using inner_type = float; + static constexpr std::size_t size = 4; + static constexpr bool has_array_operator = true; + }; + + template <> + struct type_traits { + using inner_type = float; + static constexpr std::size_t size = 9; + static constexpr bool has_array_operator = false; // because don't has "float operator[](int n) const" + }; + + template <> + struct type_traits { + using inner_type = float; + static constexpr std::size_t size = 16; + static constexpr bool has_array_operator = false; + }; + + template <> + struct type_traits { + using inner_type = float; + static constexpr std::size_t size = 4; + static constexpr bool has_array_operator = false; + }; + + template + struct type_traits { + using inner_type = T; + static constexpr std::size_t size = type_traits::size * array_size; + static constexpr bool has_array_operator = true; + }; + + template + struct type_traits > { + using inner_type = typename ArrayPublisher::inner_type; + static constexpr std::size_t size = type_traits::size * array_size; + static constexpr bool has_array_operator = true; + }; + + template + struct type_traits > { + using inner_type = typename ArrayBuffer::inner_type; + static constexpr std::size_t size = type_traits::size * array_size; + static constexpr bool has_array_operator = true; + }; + }; +}; + +#endif /* ofxPubSubOscTypeTraits_h */ diff --git a/src/details/ofxPubSubOscTypeUtils.h b/src/details/ofxPubSubOscTypeUtils.h new file mode 100644 index 0000000..2ae71b4 --- /dev/null +++ b/src/details/ofxPubSubOscTypeUtils.h @@ -0,0 +1,366 @@ +// +// ofxPubSubOscTypeUtils.h +// +// Created by ISHII 2bit on 2016/05/29. +// +// + +#pragma once + +#ifndef ofxPubSubOscTypeUtils_h +#define ofxPubSubOscTypeUtils_h + +#include +#include + +#include "ofxPubSubOscSettings.h" + +namespace ofx { + namespace PubSubOsc { + template + using get_type = typename T::type; + + template + using enable_if_t = get_type>; + + template + using conditional_t = get_type>; + + template + using type_at = get_type>>; + + namespace detail { + template + struct remove_const_reference { + using type = T; + }; + template + struct remove_const_reference : remove_const_reference {}; + template + struct remove_const_reference : remove_const_reference {}; + template + struct remove_const_reference : remove_const_reference {}; + }; + + template + using remove_const_reference = get_type>; + + template + using remove_ref = get_type>; + + template + using add_reference_if_non_arithmetic = std::conditional::value, T, T&>; + + template + using type_ref = typename add_reference_if_non_arithmetic::type; + + template + struct is_integral_and_lt_64bit { + static const bool value = std::is_integral::value && (sizeof(T) < 8); + }; + + template + struct is_integral_and_geq_64bit { + static const bool value = std::is_integral::value && (8 <= sizeof(T)); + }; + +#pragma mark function + + template + struct is_callable { + template + struct checker {}; + template static std::true_type test(checker *); + template static std::false_type test(...); + static constexpr bool value = decltype(test(nullptr))::value; + }; + + template + struct is_callable { + static constexpr bool value = true; + }; + + template + struct is_callable { + static constexpr bool value = true; + }; + + template + struct is_callable { + static constexpr bool value = true; + }; + + template + struct is_callable { + static constexpr bool value = true; + }; + + template + struct is_callable> { + static constexpr bool value = true; + }; + + namespace detail { + template + struct function_traits { + static constexpr std::size_t arity = sizeof...(arguments); + using result_type = ret; + using arguments_types_tuple = std::tuple; + template + using argument_type = type_at; + using function_type = std::function; + template + static constexpr function_type cast(function_t f) { + return static_cast(f); + } + }; + }; + + template + struct function_traits : public function_traits {}; + + template + struct function_traits + : detail::function_traits {}; + + template + struct function_traits + : detail::function_traits {}; + + template + struct function_traits + : detail::function_traits {}; + + template + struct function_traits + : detail::function_traits {}; + + template + struct function_traits + : detail::function_traits {}; + + template + struct function_traits> + : detail::function_traits {}; + + template + using result_type = typename function_traits::result_type; + + template + using arguments_types_tuple = typename function_traits::arguments_types_tuple; + + template + using argument_type = typename function_traits::template argument_type; + + template + struct arity { + static constexpr std::size_t value = function_traits::arity; + }; + + template + constexpr auto cast_lambda(function_t f) + -> typename function_traits::function_type { + return static_cast::function_type>(f); + } + +#pragma mark method + + template + struct is_bindable + : public std::false_type {}; + + template + struct is_bindable + : public std::true_type {}; + + template + struct is_bindable + : public std::true_type {}; + + template + struct is_bindable + : public std::true_type {}; + + template + struct is_bindable + : public std::true_type {}; + + template + struct is_bindable + : public std::true_type {}; + + template + struct is_bindable + : public std::true_type {}; + + template + struct get_arg_num; + + template + struct get_arg_num { + static constexpr std::size_t value = sizeof...(args); + }; + + template + struct get_arg_num { + static constexpr std::size_t value = sizeof...(args); + }; + + template + constexpr std::size_t get_arg_num_v() { + return get_arg_num::value; + } + +#define P(n) std::placeholders:: _##n + + template + auto bind(obj o, meth m) + -> enable_if_t() == 0, typename function_traits::function_type> { + return std::bind(m, o); + } + + template + auto bind(obj o, meth m) + -> enable_if_t() == 1, typename function_traits::function_type> { + return std::bind(m, o, P(1)); + } + + template + auto bind(obj o, meth m) + -> enable_if_t() == 2, typename function_traits::function_type> { + return std::bind(m, o, P(1), P(2)); + } + + template + auto bind(obj o, meth m) + -> enable_if_t() == 3, typename function_traits::function_type> { + return std::bind(m, o, P(1), P(2), P(3)); + } + + template + auto bind(obj o, meth m) + -> enable_if_t() == 4, typename function_traits::function_type> { + return std::bind(m, o, P(1), P(2), P(3), P(4)); + } + + template + auto bind(obj o, meth m) + -> enable_if_t() == 5, typename function_traits::function_type> { + return std::bind(m, o, P(1), P(2), P(3), P(4), P(5)); + } + + template + auto bind(obj o, meth m) + -> enable_if_t() == 6, typename function_traits::function_type> { + return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6)); + } + + template + auto bind(obj o, meth m) + -> enable_if_t() == 7, typename function_traits::function_type> { + return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6), P(7)); + } + + template + auto bind(obj o, meth m) + -> enable_if_t() == 8, typename function_traits::function_type> { + return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6), P(7), P(8)); + } + + template + auto bind(obj o, meth m) + -> enable_if_t() == 9, typename function_traits::function_type> { + return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6), P(7), P(8), P(9)); + } + + template + auto bind(obj o, meth m) + -> enable_if_t() == 10, typename function_traits::function_type> { + return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6), P(7), P(8), P(9), P(10)); + } + +#undef P + +#pragma mark sequences + namespace sequences { + template + struct integer_sequence { + using value_type = type; + static constexpr std::size_t size() noexcept { return sizeof...(ns); } + }; + + namespace detail { + template + struct make_integer_sequence { + struct sequence_wrapper { using type = integer_sequence; }; + using type = get_type, + sequence_wrapper + >>; + }; + }; + + template + using make_integer_sequence = get_type>; + + template + using index_sequence = integer_sequence; + + template + using make_index_sequence = make_integer_sequence; + + template + using index_sequence_for = make_index_sequence; + }; + using namespace sequences; + + namespace applying { + template + res apply(std::function f, + std::tuple ...> &args, + index_sequence &&) + { + return f(std::forward(std::get(args)) ...); + } + + template + res apply(std::function f, std::tuple ...> &args) { + return apply(f, args, index_sequence_for()); + } + }; + using namespace applying; + }; +}; + + +bool operator==(const ofMatrix3x3 &x, const ofMatrix3x3 &y) { + return (x.a == y.a) && (x.b == y.b) && (x.c == y.c) + && (x.d == y.d) && (x.e == y.e) && (x.f == y.f) + && (x.g == y.g) && (x.h == y.h) && (x.i == y.i); +} + +bool operator!=(const ofMatrix3x3 &x, const ofMatrix3x3 &y) { + return !operator==(x, y); +} + +bool operator==(const ofMatrix4x4 &x, const ofMatrix4x4 &y) { + return (x._mat[0][0] == y._mat[0][0]) && (x._mat[0][1] == y._mat[0][1]) && (x._mat[0][2] == y._mat[0][2]) && (x._mat[0][3] == y._mat[0][3]) + && (x._mat[1][0] == y._mat[1][0]) && (x._mat[1][1] == y._mat[1][1]) && (x._mat[1][2] == y._mat[1][2]) && (x._mat[1][3] == y._mat[1][3]) + && (x._mat[2][0] == y._mat[2][0]) && (x._mat[2][1] == y._mat[2][1]) && (x._mat[2][2] == y._mat[2][2]) && (x._mat[2][3] == y._mat[2][3]) + && (x._mat[3][0] == y._mat[3][0]) && (x._mat[3][1] == y._mat[3][1]) && (x._mat[3][2] == y._mat[3][2]) && (x._mat[3][3] == y._mat[3][3]); +} + +bool operator!=(const ofMatrix4x4 &x, const ofMatrix4x4 &y) { + return !operator==(x, y); +} + +bool operator==(const ofBuffer &x, const ofBuffer &y) { + return (x.size() == y.size()) && (memcmp(x.getData(), y.getData(), x.size()) == 0); +} + +bool operator!=(const ofBuffer &x, const ofBuffer &y) { + return !operator==(x, y); +} + +#endif /* ofxPubSubOscTypeUtils_h */ diff --git a/src/details/ofxpubsubosc_publish_value_wrappers.h b/src/details/ofxpubsubosc_publish_value_wrappers.h deleted file mode 100644 index c39b9c5..0000000 --- a/src/details/ofxpubsubosc_publish_value_wrappers.h +++ /dev/null @@ -1,196 +0,0 @@ -// -// ofxpubsubosc_publish_wrappers.h -// -// Created by ISHII 2bit on 2015/05/27. -// -// - -#pragma once - -#include "ofxpubsubosc_type_utils.h" - -namespace ofxpubsubosc { - namespace publish { - template - struct abstract_stream { - virtual T get() { return T(); }; - }; - - template - struct raw_stream : abstract_stream { - raw_stream(T &v) - : v(v) {}; - virtual T get() { return v; }; - private: - T &v; - }; - - template - struct getter_function_stream : abstract_stream { - getter_function_stream(T (*getter)()) - : getter(getter) {}; - virtual T get() { return getter(); }; - private: - T (*getter)(); - }; - - template - struct getter_method_stream : abstract_stream { - getter_method_stream(U &obj, T (U::*getter)()) - : obj(obj) - , getter(getter) {}; - - virtual T get() { return (obj.*getter)(); }; - private: - U &obj; - T (U::*getter)(); - }; - - template - struct const_getter_method_stream : abstract_stream { - const_getter_method_stream(const U &obj, T (U::*getter)() const) - : obj(obj) - , getter(getter) {}; - - virtual T get() { return (obj.*getter)(); }; - private: - const U &obj; - T (U::*getter)() const; - }; - - -#pragma mark pointer stream - - template - struct abstract_pointer_stream { - virtual T *get() { return NULL; }; - T operator [](std::size_t n) { return get()[n]; }; - }; - - template - struct raw_pointer_stream : abstract_pointer_stream { - raw_pointer_stream(T *ptr) - : ptr(ptr) {}; - - virtual T *get() { return ptr; }; - private: - T *ptr; - }; - - template - struct getter_function_pointer_stream : abstract_pointer_stream { - getter_function_pointer_stream(T (*getter)()) - : getter(getter) {}; - - virtual T *get() { return getter(); }; - private: - T (*getter)(); - }; - - template - struct getter_method_pointer_stream : abstract_pointer_stream { - getter_method_pointer_stream(U &obj, T (U::*getter)()) - : obj(obj) - , getter(getter) {}; - - virtual T *get() { return (obj.*getter)(); }; - private: - U &obj; - T (U::*getter)(); - }; - - template - struct const_getter_method_pointer_stream : abstract_pointer_stream { - const_getter_method_pointer_stream(const U &obj, T (U::*getter)() const) - : obj(obj) - , getter(getter) {}; - - virtual T *get() { return (obj.*getter)(); }; - private: - const U &obj; - T (U::*getter)() const; - }; - -#pragma mark factory - - template - std::shared_ptr > pointer_stream_factory(T *t) { - return std::shared_ptr >(new raw_pointer_stream(t)); - } - - template - std::shared_ptr > pointer_stream_factory(T (*g)()) { - return std::shared_ptr >(new getter_function_pointer_stream(g)); - } - - template - std::shared_ptr > pointer_stream_factory(U &that, T (U::*g)()) { - return std::shared_ptr >(new getter_method_pointer_stream(that, g)); - } - - template - std::shared_ptr > pointer_stream_factory(const U &that, T (U::*g)() const) { - return std::shared_ptr >(new const_getter_method_pointer_stream(that, g)); - } - -#pragma mark array publisher - - template - struct array_publisher { - using inner_type = const T; - using const_array_t = T const (&)[s]; - - array_publisher(T *v) - : stream(pointer_stream_factory(v)) {} - - array_publisher(T (*getter)()) - : stream(pointer_stream_factory(getter)) {} - template - - array_publisher(U &that, T (U::*getter)()) - : stream(pointer_stream_factory(that, getter)) {} - template - - array_publisher(const U &that, T (U::*getter)() const) - : stream(pointer_stream_factory(that, getter)) {} - virtual ~array_publisher() { } - - T operator[](std::size_t n) const { return stream[n]; }; - - std::size_t size() const { return s; }; - operator const_array_t() { return get(); }; - const_array_t get() { return reinterpret_cast(stream.get()); }; - protected: - std::shared_ptr > stream; - }; - - template - struct array_publisher : array_publisher {}; - -#pragma mark array buffer - - template - struct array_buffer { - using inner_type = T; - using array_t = T (&)[s]; - - array_buffer() : v(malloc(sizeof(T) * s)) {} - virtual ~array_buffer() { free(v); v = NULL; } - - array_t operator=(const array_publisher &arr) { for(int i = 0; i < size(); i++) v[i] = arr[i]; return get(); }; - bool operator!=(const array_publisher &arr) const { for(int i = 0; i < size(); i++) if(v[i] != arr[i]) return true; return false; }; - bool operator==(const array_publisher &arr) const { for(int i = 0; i < size(); i++) if(v[i] != arr[i]) return false; return true; }; - T operator[](std::size_t n) const { return v[n]; }; - T &operator[](std::size_t n) { return v[n]; }; - - std::size_t size() const { return s; }; - operator array_t() { return get(); }; - array_t get() { return reinterpret_cast(reinterpret_cast(v[0])); }; - protected: - T *v; - }; - - template - struct array_buffer : array_buffer {}; - }; -}; \ No newline at end of file diff --git a/src/details/ofxpubsubosc_subscribe_value_wrappers.h b/src/details/ofxpubsubosc_subscribe_value_wrappers.h deleted file mode 100644 index 1382231..0000000 --- a/src/details/ofxpubsubosc_subscribe_value_wrappers.h +++ /dev/null @@ -1,68 +0,0 @@ -// -// ofxpubsubosc_subscribe_value_wrappers.h -// -// Created by ISHII 2bit on 2015/06/07. -// -// - -#pragma once - -#include "ofxpubsubosc_type_utils.h" - -namespace ofxpubsubosc { - namespace subscribe { - template - struct abstract_stream { - virtual void set(const typename remove_const_reference::type &t) {}; - }; - - template - struct raw_stream : abstract_stream { - raw_stream(T &v) - : v(v) {}; - virtual void set(const typename remove_const_reference::type &t) { this->t = t; }; - private: - T &v; - }; - - template - struct setter_function_stream : abstract_stream { - setter_function_stream(U (*setter)(T)) - : setter(setter) {}; - virtual void set(const typename remove_const_reference::type &t) { setter(t); }; - private: - U (*setter)(T); - }; - - template - struct setter_method_stream : abstract_stream { - setter_method_stream(C &obj, U (C::*setter)(T)) - : obj(obj) - , setter(setter) {}; - virtual void set(const typename remove_const_reference::type &t) { (obj.*setter)(t); }; - private: - C &obj; - U (C::*setter)(T); - }; - - template - std::shared_ptr > stream_factory(T &t) { - return std::shared_ptr >(new raw_stream(t)); - } - - template - std::shared_ptr > stream_factory(U (*setter)(T)) { - return std::shared_ptr >(new setter_function_stream(setter)); - } - - template - std::shared_ptr > stream_factory(C &o, U (C::*setter)(T)) { - return std::shared_ptr >(new setter_method_stream(o, setter)); - } - - template - std::shared_ptr > stream_factory(C *o, U (C::*setter)(T)) { - return std::shared_ptr >(new setter_method_stream(*o, setter)); - } - } -}; \ No newline at end of file diff --git a/src/details/ofxpubsubosc_type_traits.h b/src/details/ofxpubsubosc_type_traits.h deleted file mode 100644 index 6d6b33c..0000000 --- a/src/details/ofxpubsubosc_type_traits.h +++ /dev/null @@ -1,98 +0,0 @@ -// -// ofxpubsubosc_type_traits.h -// -// Created by ISHII 2bit on 2015/05/12. -// -// - -#pragma once - -#include "ofMain.h" -#include "ofxpubsubosc_subscribe_value_wrappers.h" -#include "ofxpubsubosc_publish_value_wrappers.h" - -namespace ofxpubsubosc { - template - struct type_traits { - using inner_type = T; - static const std::size_t size = 1; - static const bool has_array_operator = false; - }; - - template - struct type_traits > { - using inner_type = T; - static const std::size_t size = 4; - static const bool has_array_operator = true; - }; - - template <> - struct type_traits { - using inner_type = float; - static const std::size_t size = 2; - static const bool has_array_operator = true; - }; - - template <> - struct type_traits { - using inner_type = float; - static const std::size_t size = 3; - static const bool has_array_operator = true; - }; - - template <> - struct type_traits { - using inner_type = float; - static const std::size_t size = 4; - static const bool has_array_operator = true; - }; - - template <> - struct type_traits { - using inner_type = float; - static const std::size_t size = 4; - static const bool has_array_operator = true; - }; - - template <> - struct type_traits { - using inner_type = float; - static const std::size_t size = 9; - static const bool has_array_operator = false; // because don't has "float operator[](int n) const" - }; - - template <> - struct type_traits { - using inner_type = float; - static const std::size_t size = 16; - static const bool has_array_operator = false; - }; - - template <> - struct type_traits { - using inner_type = float; - static const std::size_t size = 4; - static const bool has_array_operator = false; - }; - - template - struct type_traits { - using inner_type = T; - static const std::size_t size = ofxpubsubosc::type_traits::size * array_size; - static const bool has_array_operator = true; - }; - - template - struct type_traits > { - using inner_type = typename publish::array_publisher::inner_type; - static const std::size_t size = ofxpubsubosc::type_traits::size * array_size; - static const bool has_array_operator = true; - }; - - template - struct type_traits > { - using inner_type = typename publish::array_buffer::inner_type; - static const std::size_t size = ofxpubsubosc::type_traits::size * array_size; - static const bool has_array_operator = true; - }; -}; \ No newline at end of file diff --git a/src/details/ofxpubsubosc_type_utils.h b/src/details/ofxpubsubosc_type_utils.h deleted file mode 100644 index 4eb92dd..0000000 --- a/src/details/ofxpubsubosc_type_utils.h +++ /dev/null @@ -1,83 +0,0 @@ -// -// ofxpubsubosc_type_utils.h -// -// Created by ISHII 2bit on 2015/06/07. -// -// - -#pragma once - -#include "ofxpubsubosc_settings.h" - -namespace ofxpubsubosc { - template - using is_not_ofxoscmessage = std::enable_if, ofxOscMessage>::value, U>; - - namespace { - template - struct remove_const_reference { - using type = T; - }; - - template - struct remove_const_reference : remove_const_reference {}; - - template - struct remove_const_reference : remove_const_reference {}; - - template - struct remove_const_reference : remove_const_reference {}; - - template - using add_reference_if_non_arithmetic = std::conditional::value, T, T&>; - }; -}; - -bool operator==(const ofMatrix3x3 &x, const ofMatrix3x3 &y) { - return (x.a == y.a) && (x.b == y.b) && (x.c == y.c) - && (x.d == y.d) && (x.e == y.e) && (x.f == y.f) - && (x.g == y.g) && (x.h == y.h) && (x.i == y.i); -} - -bool operator!=(const ofMatrix3x3 &x, const ofMatrix3x3 &y) { - return !operator==(x, y); -} - -bool operator==(const ofMatrix4x4 &x, const ofMatrix4x4 &y) { - return (x._mat[0][0] == y._mat[0][0]) && (x._mat[0][1] == y._mat[0][1]) && (x._mat[0][2] == y._mat[0][2]) && (x._mat[0][3] == y._mat[0][3]) - && (x._mat[1][0] == y._mat[1][0]) && (x._mat[1][1] == y._mat[1][1]) && (x._mat[1][2] == y._mat[1][2]) && (x._mat[1][3] == y._mat[1][3]) - && (x._mat[2][0] == y._mat[2][0]) && (x._mat[2][1] == y._mat[2][1]) && (x._mat[2][2] == y._mat[2][2]) && (x._mat[2][3] == y._mat[2][3]) - && (x._mat[3][0] == y._mat[3][0]) && (x._mat[3][1] == y._mat[3][1]) && (x._mat[3][2] == y._mat[3][2]) && (x._mat[3][3] == y._mat[3][3]); -} - -bool operator!=(const ofMatrix4x4 &x, const ofMatrix4x4 &y) { - return !operator==(x, y); -} - -bool operator==(const ofBuffer &x, const ofBuffer &y) { - return (x.size() == y.size()) && (memcmp(x.getData(), y.getData(), x.size()) == 0); -} - -bool operator!=(const ofBuffer &x, const ofBuffer &y) { - return !operator==(x, y); -} - -#if (OF_VERSION_MAJOR == 0) && ((OF_VERSION_MINOR < 9) || ((OF_VERSION_MINOR == 9) && (OF_VERSION_PATCH == 0))) - -std::ostream &operator<<(std::ostream &os, const ofQuaternion &q) { - os << q.x() << ", " << q.y() << ", " << q.z() << ", " << q.w(); - return os; -} - -std::istream &operator>>(std::istream &is, ofQuaternion &q) { - is >> q.x(); - is.ignore(2); - is >> q.y(); - is.ignore(2); - is >> q.z(); - is.ignore(2); - is >> q.w(); - return is; -} - -#endif diff --git a/src/ofxOscPublisher.h b/src/ofxOscPublisher.h index dfee9d7..2d1afd9 100644 --- a/src/ofxOscPublisher.h +++ b/src/ofxOscPublisher.h @@ -1,1080 +1,495 @@ // -// ofxOscPublisher.h +// ofxPublisher.h // -// Created by ISHII 2bit on 2015/05/11. +// Created by ISHII 2bit on 2016/05/29. // // #pragma once -#include "ofMain.h" -#include "ofxOsc.h" +#ifndef ofxPublisher_h +#define ofxPublisher_h -#include "details/ofxpubsubosc_settings.h" -#include "details/ofxpubsubosc_type_utils.h" +#include "ofxOsc.h" -#include +#include "ofxOscPublisherSetImplementation.h" +#include "ofxOscPublishCondition.h" +#include "ofxOscPublishParameter.h" +#include "ofxOscPublisherStructs.h" namespace ofx { - using namespace ofxpubsubosc; - - namespace { - template - using remove_ref = typename std::remove_reference::type; - - template - using type_ref = typename add_reference_if_non_arithmetic::type; - - template - struct is_integral_and_lt_64bit { - static const bool value = std::is_integral::value && (sizeof(T) < 8); - }; - - template - struct is_integral_and_geq_64bit { - static const bool value = std::is_integral::value && (8 <= sizeof(T)); - }; - }; - - class OscPublisherManager { - public: - class OscPublisher; - - private: - struct SetImplementation { - protected: - template - inline typename std::enable_if::value>::type set(ofxOscMessage &m, T v) const { m.addIntArg(v); } - - template - inline typename std::enable_if::value>::type set(ofxOscMessage &m, T v) const { m.addInt64Arg(v); } - -#define define_set_float(type) inline void set(ofxOscMessage &m, type v) const { m.addFloatArg(v); } - define_set_float(float); - define_set_float(double); -#undef define_set_float - inline void set(ofxOscMessage &m, const std::string &v) const { m.addStringArg(v); } - inline void set(ofxOscMessage &m, const ofBuffer &v) const { m.addBlobArg(v); }; - template - inline void set(ofxOscMessage &m, const ofColor_ &v) const { setVec<4>(m, v); } - inline void set(ofxOscMessage &m, const ofVec2f &v) const { setVec<2>(m, v); } - inline void set(ofxOscMessage &m, const ofVec3f &v) const { setVec<3>(m, v); } - inline void set(ofxOscMessage &m, const ofVec4f &v) const { setVec<4>(m, v); } - inline void set(ofxOscMessage &m, const ofQuaternion &v) const { setVec<4>(m, v); } - - template - inline void setVec(ofxOscMessage &m, const T &v) const { - for(int i = 0; i < n; i++) { set(m, v[i]); } - } - - inline void set(ofxOscMessage &m, const ofMatrix3x3 &v) const { - set(m, v.a); - set(m, v.b); - set(m, v.c); - set(m, v.d); - set(m, v.e); - set(m, v.f); - set(m, v.g); - set(m, v.h); - set(m, v.i); - } - - inline void set(ofxOscMessage &m, const ofMatrix4x4 &v) const { - for(int j = 0; j < 4; j++) for(int i = 0; i < 4; i++) set(m, v(i, j)); - } - - inline void set(ofxOscMessage &m, const ofRectangle &v) const { - set(m, v.x); - set(m, v.y); - set(m, v.width); - set(m, v.height); - } - - template - inline void set(ofxOscMessage &m, const U (&v)[size]) const { - for(int i = 0; i < size; i++) { set(m, v[i]); } - } - - template - inline void set(ofxOscMessage &m, const std::vector &v) const { - for(int i = 0; i < v.size(); i++) { set(m, v[i]); } - } - -#pragma mark ofParameter / ofParameterGroup - - template - inline void set(ofxOscMessage &m, const ofParameter &p) const { - set(m, p.get()); - } - }; - -#pragma mark Condition - - struct BasicCondition { - BasicCondition() : bPublishNow(true) {}; - - inline bool getCondition() { return isPublishNow() && inner_condition(); }; - - inline bool isPublishNow() const { return bPublishNow; }; - inline void setEnablePublish(bool bEnablePublish) { this->bPublishNow = bEnablePublish; }; - - virtual bool inner_condition() { return true; }; - - using Ref = std::shared_ptr; - private: - bool bPublishNow; - }; - - struct ConditionRef : BasicCondition { - ConditionRef(bool &ref) : BasicCondition(), ref(ref) {}; - virtual bool inner_condition() { return ref; }; - private: - bool &ref; - }; - - struct ConditionFunction : BasicCondition { - ConditionFunction(bool (*getter)()) : BasicCondition(), getter(getter) {}; - virtual bool inner_condition() { return getter(); }; - private: - bool (*getter)(); - }; - - template - struct ConditionMethod : BasicCondition { - ConditionMethod(T &that, bool (T::*getter)()) - : BasicCondition() - , that(that) - , getter(getter) {}; - - virtual bool inner_condition() { return (that.*getter)(); }; - private: - T &that; // dirty!!! - bool (T::*getter)(); - }; - - template - struct ConstConditionMethod : BasicCondition { - ConstConditionMethod(const T &that, bool (T::*getter)() const) - : BasicCondition() - , that(that) - , getter(getter) {}; - - virtual bool inner_condition() { return (that.*getter)(); }; - private: - const T &that; - bool (T::*getter)() const; - }; - - using BasicConditionRef = BasicCondition::Ref; - -#pragma mark Parameter - - struct AbstractParameter { - AbstractParameter() : condition(new BasicCondition) {} - virtual bool setMessage(ofxOscMessage &m, const std::string &address) = 0; - void setCondition(BasicConditionRef ref) { condition = ref; }; - - inline void setEnablePublish(bool bEnablePublish) { condition->setEnablePublish(bEnablePublish); }; - inline bool isPublishNow() const { return condition->isPublishNow(); }; - protected: - bool canPublish() { - return condition->getCondition(); - } - private: - BasicConditionRef condition; - }; - - template - struct Parameter : AbstractParameter, SetImplementation { - Parameter(T &t) - : t(t) {} - - virtual bool setMessage(ofxOscMessage &m, const std::string &address) { - if(!canPublish() || !isChanged()) return false; - m.setAddress(address); - set(m, get()); - return true; - } - protected: - virtual bool isChanged() { return true; } - virtual type_ref get() { return t; } - T &t; - }; - - template - struct Parameter : Parameter { - Parameter(T &t) - : Parameter(t) {} - - protected: - virtual bool isChanged() { - if(old != this->get()) { - old = this->get(); - return true; - } else { - return false; - } - } - - T old; - }; - - template - struct Parameter : AbstractParameter, SetImplementation { - Parameter(Base (&t)[size]) - : t(t) { for(std::size_t i = 0; i < size; i++) old[i] = t[i]; } - virtual ~Parameter() { }; - - virtual bool setMessage(ofxOscMessage &m, const std::string &address) { - if(!canPublish() || !isChanged()) return false; - m.setAddress(address); - set(m, get()); - return true; - } - - protected: - virtual bool isChanged() { - bool isChange = false; - for(int i = 0; i < size; i++) { - isChange = isChange || (old[i] != get()[i]); - if(isChange) break; - } + namespace PubSubOsc { + namespace Publish { + class PublishIdentifier { + std::string address; + ParameterRef ref; + Destination key; - if(isChange) { - for(int i = 0; i < size; i++) { - old[i] = get()[i]; - } - return true; - } else { - return false; + void invalidate() { + address = ""; + ref = nullptr; + key = Destination(); } - } - - virtual Base (&get())[size] { return t; } - Base (&t)[size]; - Base old[size]; - }; - - template - struct ConstParameter : AbstractParameter, SetImplementation { - ConstParameter(const T &t) - : t(t) {} - - virtual bool setMessage(ofxOscMessage &m, const std::string &address) { - if(!canPublish() || !isChanged()) return false; - m.setAddress(address); - set(m, get()); - return true; - } - protected: - virtual bool isChanged() { return true; } - virtual const T &get() { return t; } - const T t; - }; - - template - struct ConstParameter : ConstParameter { - ConstParameter(const T &t) - : ConstParameter(t) {} - - protected: - virtual bool isChanged() { - static bool initial{true}; - bool tmp = initial; - initial = false; - return tmp; - } - }; - - template - struct ConstParameter : AbstractParameter, SetImplementation { - ConstParameter(const Base (&t)[size]) - : t(t) {} - - virtual bool setMessage(ofxOscMessage &m, const std::string &address) { - if(!canPublish() || !isChanged()) return false; - m.setAddress(address); - set(m, get()); - return true; - } - - protected: - virtual bool isChanged() { return true; } - - virtual const Base (&get())[size] { return t; } - const Base (&t)[size]; - }; - - template - struct ConstParameter : ConstParameter { - ConstParameter(const Base(&t)[size]) - : ConstParameter(t) {} - - protected: - virtual bool isChanged() { - static bool initial{true}; - bool tmp = initial; - initial = false; - return tmp; - } - }; - - template - struct GetterFunctionParameter : Parameter { - using GetterFunction = T (*)(); - GetterFunctionParameter(GetterFunction getter) - : Parameter(dummy) - , getter(getter) {} - - protected: - virtual type_ref get() { return dummy = getter(); } - GetterFunction getter; - remove_ref dummy; - }; - - template - struct GetterFunctionParameter : Parameter { - using T = Base (&)[size]; - using GetterFunction = T (*)(); - GetterFunctionParameter(GetterFunction getter) - : Parameter(dummy) - , getter(getter) {} - - protected: - virtual Base (&get())[size] { - Base (&arr)[size] = getter(); - for(std::size_t i = 0; i < size; i++) dummy[i] = arr[i]; - return dummy; - } - GetterFunction getter; - Base dummy[size]; - }; - - template - struct GetterParameter : Parameter { - using Getter = T (C::*)(); - - GetterParameter(C &that, Getter getter) - : Parameter(dummy) - , getter(getter) - , that(that) {} - - protected: - virtual type_ref get() { return dummy = (that.*getter)(); } - Getter getter; - C &that; - remove_ref dummy; - }; - - template - struct GetterParameter : Parameter { - using T = Base (&)[size]; - using Getter = T (C::*)(); - - GetterParameter(C &that, Getter getter) - : Parameter(dummy) - , getter(getter) - , that(that) {} - - protected: - virtual T get() { - T arr = (that.*getter)(); - for(std::size_t i = 0; i < size; i++) dummy[i] = arr[i]; - return dummy; - } - Getter getter; - C &that; - Base dummy[size]; - }; - - template - struct ConstGetterParameter : Parameter { - using Getter = T (C::*)() const; - - ConstGetterParameter(const C &that, Getter getter) - : Parameter(dummy) - , getter(getter) - , that(that) {} - - protected: - virtual type_ref get() { return dummy = (that.*getter)(); } - Getter getter; - const C &that; - remove_ref dummy; - }; - - template - struct ConstGetterParameter : Parameter { - using T = Base (&)[size]; - using Getter = T (C::*)() const; - - ConstGetterParameter(const C &that, Getter getter) - : Parameter(dummy) - , getter(getter) - , that(that) {} - - protected: - virtual T get() { - T arr = (that.*getter)(); - for(std::size_t i = 0; i < size; i++) dummy[i] = arr[i]; - return dummy; - } - Getter getter; - const C &that; - Base dummy[size]; - }; - - using ParameterRef = std::shared_ptr; - using Targets = std::multimap; - - public: - struct IP { - IP(const IP &ip) - : ip(ip.ip) {} - - IP(const std::string &ip) - : ip(ip) {} - - bool operator<(const IP &rhs) const { - return ip < rhs.ip; - } - - std::string ip; - private: - IP(); - }; - - struct Destination { - Destination() {} - Destination(const Destination &destination) - : ip(destination.ip) - , port(destination.port) {} - - Destination(const std::string &ip, int port) - : ip(ip) - , port(port) {} - - inline bool operator<(const Destination &rhs) const { - return (ip != rhs.ip) ? (ip < rhs.ip) : (port < rhs.port); - } - - inline bool operator!=(const Destination &rhs) const { - return ip != rhs.ip || port != rhs.port; - } - - std::string ip; - int port; - private: - }; - - struct DestinationWithAddress { - DestinationWithAddress(const DestinationWithAddress &destination) - : destination(destination.destination) - , address(destination.address) {} - - DestinationWithAddress(const std::string &ip, int port, const std::string &address) - : destination(ip, port) - , address(address) {} - - inline bool operator<(const DestinationWithAddress &rhs) const { - return (destination != rhs.destination) ? (destination < rhs.destination) : (address < rhs.address); - } - - operator Destination() const { - return destination; - } - - inline operator const Destination&() const { - return destination; - } - - Destination destination; - std::string address; - private: - DestinationWithAddress(); - }; - - class Identifier { - std::string address; - ParameterRef ref; - Destination key; - - void invalidate() { - address = ""; - ref = nullptr; - key = Destination(); - } - public: - Identifier() {} - Identifier(const std::string &address, const ParameterRef &ref, const Destination &key) - : address(address) - , ref(ref) - , key(key) {} - - const Destination &getKey() const { return key; }; - bool isValid() const { return static_cast(ref); } - - friend class OscPublisher; - }; - - public: - class OscPublisher { - Targets::const_iterator findFromTargets(const Identifier &identifier, const Targets &targets) const { - if(!identifier.isValid()) return targets.end(); - Targets::const_iterator it = targets.find(identifier.address); - if(it != targets.end()) { - for(std::size_t i = 0, size = targets.count(identifier.address); i < size; ++i, ++it) { - if(it->second == identifier.ref) { - return it; + public: + PublishIdentifier() {} + PublishIdentifier(const std::string &address, const ParameterRef &ref, const Destination &key) + : address(address) + , ref(ref) + , key(key) {} + + const Destination &getKey() const { return key; }; + bool isValid() const { return static_cast(ref); } + + friend class Publisher; + }; + + class Publisher { + Targets::const_iterator findFromTargets(const PublishIdentifier &identifier, const Targets &targets) const { + if(!identifier.isValid()) return targets.end(); + Targets::const_iterator it = targets.find(identifier.address); + if(it != targets.end()) { + for(std::size_t i = 0, size = targets.count(identifier.address); i < size; ++i, ++it) { + if(it->second == identifier.ref) { + return it; + } } } + return targets.end(); } - return targets.end(); - } - - inline Targets::const_iterator findPublished(const Identifier &identifier) const { - return findFromTargets(identifier, targets); - } - - inline Targets::const_iterator findRegistered(const Identifier &identifier) const { - return findFromTargets(identifier, registeredTargets); - } - - - public: -#pragma mark publish - - inline Identifier publish(const std::string &address, ParameterRef ref) { - targets.insert(std::make_pair(address, ref)); - return {address, ref, destination}; - } - - Identifier publish(const std::string &address, const char * const value, bool whenValueIsChanged = true) { - ParameterRef p; - return publish(address, std::string(value), whenValueIsChanged); - } - - template - Identifier publish(const std::string &address, T &value, bool whenValueIsChanged = true) { - ParameterRef p; - if(whenValueIsChanged) p = ParameterRef(new Parameter(value)); - else p = ParameterRef(new Parameter(value)); - return publish(address, p); - } - - template - Identifier publish(const std::string &address, const T &value, bool whenValueIsChanged = true) { - ParameterRef p; - if(whenValueIsChanged) p = ParameterRef(new ConstParameter(value)); - else p = ParameterRef(new ConstParameter(value)); - return publish(address, p); - } - - template - Identifier publish(const std::string &address, T (*getter)(), bool whenValueIsChanged = true) { - ParameterRef p; - if(whenValueIsChanged) p = ParameterRef(new GetterFunctionParameter(getter)); - else p = ParameterRef(new GetterFunctionParameter(getter)); - return publish(address, p); - } - - template - Identifier publish(const std::string &address, C *that, T (C::*getter)(), bool whenValueIsChanged = true) { - ParameterRef p; - if(whenValueIsChanged) p = ParameterRef(new GetterParameter(*that, getter)); - else p = ParameterRef(new GetterParameter(*that, getter)); - return publish(address, p); - } - - template - Identifier publish(const std::string &address, C &that, T (C::*getter)(), bool whenValueIsChanged = true) { - ParameterRef p; - if(whenValueIsChanged) p = ParameterRef(new GetterParameter(that, getter)); - else p = ParameterRef(new GetterParameter(that, getter)); - return publish(address, p); - } - - template - Identifier publish(const std::string &address, const C * const that, T (C::*getter)() const, bool whenValueIsChanged = true) { - ParameterRef p; - if(whenValueIsChanged) p = ParameterRef(new ConstGetterParameter(*that, getter)); - else p = ParameterRef(new ConstGetterParameter(*that, getter)); - return publish(address, p); - } - - template - Identifier publish(const std::string &address, const C &that, T (C::*getter)() const, bool whenValueIsChanged = true) { - ParameterRef p; - if(whenValueIsChanged) p = ParameterRef(new ConstGetterParameter(that, getter)); - else p = ParameterRef(new ConstGetterParameter(that, getter)); - return publish(address, p); - } - + + inline Targets::const_iterator findPublished(const PublishIdentifier &identifier) const { + return findFromTargets(identifier, targets); + } + + inline Targets::const_iterator findRegistered(const PublishIdentifier &identifier) const { + return findFromTargets(identifier, registeredTargets); + } + + template + inline auto make_parameter_ref(T &value, bool whenValueIsChanged = false) + -> enable_if_t::value, ParameterRef> + { + if(whenValueIsChanged) return ParameterRef(new Parameter(value)); + else return ParameterRef(new Parameter(value)); + } + + template + inline auto make_parameter_ref(const T &value, bool whenValueIsChanged = false) + -> enable_if_t::value, ParameterRef> + { + if(whenValueIsChanged) return ParameterRef(new ConstParameter(value)); + else return ParameterRef(new ConstParameter(value)); + } + + template + inline auto make_parameter_ref(std::function func, bool whenValueIsChanged = false) + -> enable_if_t::value, ParameterRef> + { + if(whenValueIsChanged) return ParameterRef(new FunctionParameter(func)); + else return ParameterRef(new FunctionParameter(func)); + } + + template + inline auto make_parameter_ref(Func &func, bool whenValueIsChanged = false) + -> enable_if_t::value, ParameterRef> + { + return make_parameter_ref(function_traits::cast(func), whenValueIsChanged); + } + + template + inline auto make_parameter_ref(Obj &&obj, Meth &&meth, bool whenValueIsChanged = false) + -> enable_if_t::value, ParameterRef> + { + return make_parameter_ref(bind(std::forward(obj), std::forward(meth)), whenValueIsChanged); + } + + inline PublishIdentifier publish_impl(const std::string &address, ParameterRef ref) { + targets.insert(std::make_pair(address, ref)); + return {address, ref, destination}; + } + + public: + #pragma mark publish + + PublishIdentifier publish(const std::string &address, const char * const value, bool whenValueIsChanged = true) { + ParameterRef p = make_parameter_ref(value, whenValueIsChanged); + return publish_impl(address, p); + } + + template + auto publish(const std::string &address, T &value, bool whenValueIsChanged = true) + -> enable_if_t::value, PublishIdentifier> + { + ParameterRef p = make_parameter_ref(value, whenValueIsChanged); + return publish_impl(address, p); + } + + template + auto publish(const std::string &address, const T &value, bool whenValueIsChanged = true) + -> enable_if_t::value, PublishIdentifier> + { + ParameterRef p = make_parameter_ref(value, whenValueIsChanged); + return publish_impl(address, p); + } + + template + PublishIdentifier publish(const std::string &address, std::function getter, bool whenValueIsChanged = true) { + ParameterRef p = make_parameter_ref(getter, whenValueIsChanged); + return publish_impl(address, p); + } + + template + auto publish(const std::string &address, Func &&func, bool whenValueIsChanged = true) + -> enable_if_t::value, PublishIdentifier> + { + return publish(address, function_traits::cast(func)); + } + + template + auto publish(const std::string &address, Obj &&obj, Meth &&meth, bool whenValueIsChanged = true) + -> enable_if_t::value, PublishIdentifier> + { + ParameterRef p = make_parameter_ref(obj, meth); + return publish(address, p, whenValueIsChanged); + } + #pragma mark publish conditional #pragma mark condition is bool value ref - - Identifier publishIf(bool &condition, const std::string &address, const char * const value) { - ParameterRef p; - return publishIf(condition, address, std::string(value)); - } - - template - Identifier publishIf(bool &condition, const std::string &address, T &value) { - ParameterRef p = ParameterRef(new Parameter(value)); - p->setCondition(std::shared_ptr(new ConditionRef(condition))); - return publish(address, p); - } - - template - Identifier publishIf(bool &condition, const std::string &address, const T &value) { - ParameterRef p = ParameterRef(new ConstParameter(value)); - p->setCondition(std::shared_ptr(new ConditionRef(condition))); - return publish(address, p); - } - - template - Identifier publishIf(bool &condition, const std::string &address, T (*getter)()) { - ParameterRef p = ParameterRef(new GetterFunctionParameter(getter)); - p->setCondition(std::shared_ptr(new ConditionRef(condition))); - return publish(address, p); - } - - template - Identifier publishIf(bool &condition, const std::string &address, C *that, T (C::*getter)()) { - ParameterRef p = ParameterRef(new GetterParameter(*that, getter)); - p->setCondition(std::shared_ptr(new ConditionRef(condition))); - return publish(address, p); - } - - template - Identifier publishIf(bool &condition, const std::string &address, C &that, T (C::*getter)()) { - ParameterRef p = ParameterRef(new GetterParameter(that, getter)); - p->setCondition(std::shared_ptr(new ConditionRef(condition))); - return publish(address, p); - } - - template - Identifier publishIf(bool &condition, const std::string &address, const C * const that, T (C::*getter)() const) { - ParameterRef p = ParameterRef(new ConstGetterParameter(*that, getter)); - p->setCondition(std::shared_ptr(new ConditionRef(condition))); - return publish(address, p); - } - - template - Identifier publishIf(bool &condition, const std::string &address, const C &that, T (C::*getter)() const) { - ParameterRef p = ParameterRef(new ConstGetterParameter(that, getter)); - p->setCondition(std::shared_ptr(new ConditionRef(condition))); - return publish(address, p); - } - -#pragma mark condition is function - - template - Identifier publishIf(bool (*condition)(), const std::string &address, T &value) { - ParameterRef p = ParameterRef(new Parameter(value)); - p->setCondition(std::shared_ptr(new ConditionFunction(condition))); - return publish(address, p); - } - - template - Identifier publishIf(bool (*condition)(), const std::string &address, T (*getter)()) { - ParameterRef p = ParameterRef(new GetterFunctionParameter(getter)); - p->setCondition(std::shared_ptr(new ConditionFunction(condition))); - return publish(address, p); - } - - template - Identifier publishIf(bool (*condition)(), const std::string &address, C *that, T (C::*getter)()) { - ParameterRef p = ParameterRef(new GetterParameter(*that, getter)); - p->setCondition(std::shared_ptr(new ConditionFunction(condition))); - return publish(address, p); - } - - template - Identifier publishIf(bool (*condition)(), const std::string &address, C &that, T (C::*getter)()) { - ParameterRef p = ParameterRef(new GetterParameter(that, getter)); - p->setCondition(std::shared_ptr(new ConditionFunction(condition))); - return publish(address, p); - } - - template - Identifier publishIf(bool (*condition)(), const std::string &address, const C * const that, T (C::*getter)() const) { - ParameterRef p = ParameterRef(new ConstGetterParameter(*that, getter)); - p->setCondition(std::shared_ptr(new ConditionFunction(condition))); - return publish(address, p); - } - - template - Identifier publishIf(bool (*condition)(), const std::string &address, const C &that, T (C::*getter)() const) { - ParameterRef p = ParameterRef(new ConstGetterParameter(that, getter)); - p->setCondition(std::shared_ptr(new ConditionFunction(condition))); - return publish(address, p); - } - -#pragma mark condition is method - - template - Identifier publishIf(Condition &condition, bool (Condition::*method)(), const std::string &address, T &value) { - ParameterRef p = ParameterRef(new Parameter(value)); - p->setCondition(std::shared_ptr(new ConditionMethod(condition, method))); - return publish(address, p); - } - - template - Identifier publishIf(Condition &condition, bool (Condition::*method)(), const std::string &address, T (*getter)()) { - ParameterRef p = ParameterRef(new GetterFunctionParameter(getter)); - p->setCondition(std::shared_ptr(new ConditionMethod(condition, method))); - return publish(address, p); - } - - template - Identifier publishIf(Condition &condition, bool (Condition::*method)(), const std::string &address, C *that, T (C::*getter)()) { - ParameterRef p = ParameterRef(new GetterParameter(*that, getter)); - p->setCondition(std::shared_ptr(new ConditionMethod(condition, method))); - return publish(address, p); - } - - template - Identifier publishIf(Condition &condition, bool (Condition::*method)(), const std::string &address, C &that, T (C::*getter)()) { - ParameterRef p = ParameterRef(new GetterParameter(that, getter)); - p->setCondition(std::shared_ptr(new ConditionMethod(condition, method))); - return publish(address, p); - } - - template - Identifier publishIf(Condition &condition, bool (Condition::*method)(), const std::string &address, const C * const that, T (C::*getter)() const) { - ParameterRef p = ParameterRef(new ConstGetterParameter(*that, getter)); - p->setCondition(std::shared_ptr(new ConditionMethod(condition, method))); - return publish(address, p); - } - - template - Identifier publishIf(Condition &condition, bool (Condition::*method)(), const std::string &address, const C &that, T (C::*getter)() const) { - ParameterRef p = ParameterRef(new ConstGetterParameter(that, getter)); - p->setCondition(std::shared_ptr(new ConditionMethod(condition, method))); - return publish(address, p); - } - -#pragma mark condition is const method - - template - Identifier publishIf(const Condition &condition, bool (Condition::*method)() const, const std::string &address, T &value) { - ParameterRef p = ParameterRef(new Parameter(value)); - p->setCondition(std::shared_ptr(new ConstConditionMethod(condition, method))); - return publish(address, p); - } - - template - Identifier publishIf(const Condition &condition, bool (Condition::*method)() const, const std::string &address, T (*getter)()) { - ParameterRef p = ParameterRef(new GetterFunctionParameter(getter)); - p->setCondition(std::shared_ptr(new ConstConditionMethod(condition, method))); - return publish(address, p); - } - - template - Identifier publishIf(const Condition &condition, bool (Condition::*method)() const, const std::string &address, C *that, T (C::*getter)()) { - ParameterRef p = ParameterRef(new GetterParameter(*that, getter)); - p->setCondition(std::shared_ptr(new ConstConditionMethod(condition, method))); - return publish(address, p); - } - - template - Identifier publishIf(const Condition &condition, bool (Condition::*method)() const, const std::string &address, C &that, T (C::*getter)()) { - ParameterRef p = ParameterRef(new GetterParameter(that, getter)); - p->setCondition(std::shared_ptr(new ConstConditionMethod(condition, method))); - return publish(address, p); - } - - template - Identifier publishIf(const Condition &condition, bool (Condition::*method)() const, const std::string &address, const C * const that, T (C::*getter)() const) { - ParameterRef p = ParameterRef(new ConstGetterParameter(*that, getter)); - p->setCondition(std::shared_ptr(new ConstConditionMethod(condition, method))); - return publish(address, p); - } - - template - Identifier publishIf(const Condition &condition, bool (Condition::*method)() const, const std::string &address, const C &that, T (C::*getter)() const) { - ParameterRef p = ParameterRef(new ConstGetterParameter(that, getter)); - p->setCondition(std::shared_ptr(new ConstConditionMethod(condition, method))); - return publish(address, p); - } - -#pragma mark unpublish - - void unpublish(const std::string &address) { - if(targets.find(address) == targets.end()) targets.erase(address); - } - - void unpublish(Identifier &identifier) { - if(!identifier.isValid()) return; - Targets::const_iterator it{findPublished(identifier)}; - if(it != targets.end()) { - targets.erase(it); + + PublishIdentifier publishIf(bool &condition, const std::string &address, const char * const value) { + ParameterRef p = make_parameter_ref(value); + p->setCondition(ConditionRef(new Condition(condition))); + return publish_impl(address, p); } - identifier.invalidate(); - } - - void unpublish() { - targets.clear(); - } - -#pragma mark stop publish temporary - - void stopPublishTemporary(const std::string &address) { - if(isPublished(address)) { - Targets::iterator it = targets.find(address); - for(std::size_t i = 0, size = targets.count(address); i < size; i++, ++it) { + + template + PublishIdentifier publishIf(bool &condition, const std::string &address, T &value) { + ParameterRef p = make_parameter_ref(value); + p->setCondition(ConditionRef(new Condition(condition))); + return publish_impl(address, p); + } + + template + PublishIdentifier publishIf(bool &condition, const std::string &address, const T &value) { + ParameterRef p = make_parameter_ref(value); + p->setCondition(ConditionRef(new Condition(condition))); + return publish_impl(address, p); + } + + template + PublishIdentifier publishIf(bool &condition, const std::string &address, std::function getter) { + ParameterRef p = make_parameter_ref(getter); + p->setCondition(ConditionRef(new Condition(condition))); + return publish_impl(address, p); + } + + template + auto publishIf(bool &condition, const std::string &address, Obj &&obj, Meth &&meth) + -> enable_if_t::value, PublishIdentifier> + { + return publishIf(condition, address, bind(obj, meth)); + } + + #pragma mark condition is function + + template + PublishIdentifier publishIf(std::function condition, const std::string &address, T &value) { + ParameterRef p = make_parameter_ref(value); + p->setCondition(std::shared_ptr(new ConditionFunction(condition))); + return publish_impl(address, p); + } + + template + PublishIdentifier publishIf(std::function condition, const std::string &address, std::function getter) { + ParameterRef p = make_parameter_ref(getter); + p->setCondition(std::shared_ptr(new ConditionFunction(condition))); + return publish_impl(address, p); + } + + template + auto publishIf(std::function condition, const std::string &address, Obj &&obj, Meth &&meth) + -> enable_if_t::value, PublishIdentifier> + { + return publishIf(condition, address, bind(obj, meth)); + } + + #pragma mark condition is method + + template + auto publishIf(CondObj &&obj, CondMeth &&meth, Args && ... args) + -> enable_if_t::value, PublishIdentifier> + { + return publishIf(bind(obj, meth), std::forward(args) ...); + } + + #pragma mark unpublish + + void unpublish(const std::string &address) { + if(targets.find(address) == targets.end()) targets.erase(address); + } + + void unpublish(PublishIdentifier &identifier) { + if(!identifier.isValid()) return; + Targets::const_iterator it{findPublished(identifier)}; + if(it != targets.end()) { + targets.erase(it); + } + identifier.invalidate(); + } + + void unpublish() { + targets.clear(); + } + + #pragma mark stop publish temporary + + void stopPublishTemporary(const std::string &address) { + if(isPublished(address)) { + Targets::iterator it = targets.find(address); + for(std::size_t i = 0, size = targets.count(address); i < size; i++, ++it) { + it->second->setEnablePublish(false); + } + } + } + + void stopPublishTemporary(const PublishIdentifier &identifier) { + if(!identifier.isValid()) return; + Targets::const_iterator it{findPublished(identifier)}; + if(it != targets.end()) { it->second->setEnablePublish(false); } } - } - - void stopPublishTemporary(const Identifier &identifier) { - if(!identifier.isValid()) return; - Targets::const_iterator it{findPublished(identifier)}; - if(it != targets.end()) { - it->second->setEnablePublish(false); + + void resumePublish(const std::string &address) { + if(isPublished(address)) { + Targets::iterator it = targets.find(address); + for(std::size_t i = 0, size = targets.count(address); i < size; i++, ++it) { + it->second->setEnablePublish(true); + } + } } - } - - void resumePublish(const std::string &address) { - if(isPublished(address)) { - Targets::iterator it = targets.find(address); - for(std::size_t i = 0, size = targets.count(address); i < size; i++, ++it) { + + void resumePublishTemporary(const PublishIdentifier &identifier) { + if(!identifier.isValid()) return; + Targets::const_iterator it{findPublished(identifier)}; + if(it != targets.end()) { it->second->setEnablePublish(true); } } - } - - void resumePublishTemporary(const Identifier &identifier) { - if(!identifier.isValid()) return; - Targets::const_iterator it{findPublished(identifier)}; - if(it != targets.end()) { - it->second->setEnablePublish(true); + + #pragma mark doRegister + + inline PublishIdentifier doRegister(const std::string &address, ParameterRef ref) { + registeredTargets.insert(std::make_pair(address, ref)); + return {address, ref, destination}; } - } - -#pragma mark doRegister - - inline Identifier doRegister(const std::string &address, ParameterRef ref) { - registeredTargets.insert(std::make_pair(address, ref)); - return {address, ref, destination}; - } - - template - Identifier doRegister(const std::string &address, T &value) { - return doRegister(address, ParameterRef(new Parameter(value))); - } - - template - Identifier doRegister(const std::string &address, T (*getter)()) { - return doRegister(address, ParameterRef(new GetterFunctionParameter(getter))); - } - - template - Identifier doRegister(const std::string &address, C *that, T (C::*getter)()) { - return doRegister(address, ParameterRef(new GetterParameter(*that, getter))); - } - - template - Identifier doRegister(const std::string &address, C &that, T (C::*getter)()) { - return doRegister(address, ParameterRef(new GetterParameter(that, getter))); - } - - template - Identifier doRegister(const std::string &address, const C * const that, T (C::*getter)() const) { - return doRegister(address, ParameterRef(new ConstGetterParameter(*that, getter))); - } - - template - Identifier doRegister(const std::string &address, const C &that, T (C::*getter)() const) { - return doRegister(address, ParameterRef(new ConstGetterParameter(that, getter))); - } - -#pragma mark publishRegistered - - inline void publishRegistered(const std::string &address) { - Targets::iterator it = registeredTargets.find(address); - if(it == registeredTargets.end()) { - ofLogWarning("ofxPubSubOsc") << address << " is not registered."; + + template + PublishIdentifier doRegister(const std::string &address, T &value) { + return doRegister(address, make_parameter_ref(value)); } - ofxOscMessage m; - for(std::size_t i = 0, size = registeredTargets.count(address); i < size; i++, ++it) { - if(it->second->setMessage(m, it->first)) sender.sendMessage(m); - m.clear(); + + template + PublishIdentifier doRegister(const std::string &address, std::function getter) { + return doRegister(address, make_parameter_ref(getter)); } - } - - inline void publishRegistered(const Identifier &identifier) { - if(!identifier.isValid()) return; - Targets::const_iterator it{findRegistered(identifier)}; - if(it != registeredTargets.end()) { + + template + auto doRegister(const std::string &address, Obj &&obj, Meth &&meth) + -> enable_if_t::value, PublishIdentifier> + { + return doRegister(address, bind(obj, meth)); + } + + #pragma mark publishRegistered + + inline void publishRegistered(const std::string &address) { + Targets::iterator it = registeredTargets.find(address); + if(it == registeredTargets.end()) { + ofLogWarning("ofxPubSubOsc") << address << " is not registered."; + } ofxOscMessage m; - if(it->second->setMessage(m, it->first)) sender.sendMessage(m); - m.clear(); + for(std::size_t i = 0, size = registeredTargets.count(address); i < size; i++, ++it) { + if(it->second->write(m, it->first)) sender.sendMessage(m); + m.clear(); + } } - } - -#pragma mark unregister - - inline void unregister(const std::string &address) { - if(registeredTargets.find(address) == registeredTargets.end()) registeredTargets.erase(address); - } - - inline void unregister(Identifier &identifier) { - if(!identifier.isValid()) return; - Targets::const_iterator it{findRegistered(identifier)}; - if(it != registeredTargets.end()) { - registeredTargets.erase(it); + + inline void publishRegistered(const PublishIdentifier &identifier) { + if(!identifier.isValid()) return; + Targets::const_iterator it{findRegistered(identifier)}; + if(it != registeredTargets.end()) { + ofxOscMessage m; + if(it->second->write(m, it->first)) sender.sendMessage(m); + m.clear(); + } } - identifier.invalidate(); - } - - inline void unregister() { - registeredTargets.clear(); - } - -#pragma mark status - - inline bool isPublished() const { - return !targets.empty(); - } - - inline bool isPublished(const Identifier &identifier) const { - if(!identifier.isValid()) false; - return isPublished() && (findPublished(identifier) != targets.end()); - } - - inline bool isPublished(const std::string &address) const { - return isPublished() && (targets.find(address) != targets.end()); - } - - inline bool isEnabled(const std::string &address) const { - // TODO: fix - return isPublished(address) && targets.find(address)->second->isPublishNow(); - } - - inline bool isEnabled(const Identifier &identifier) const { - if(!identifier.isValid()) return false; - Targets::const_iterator it{findPublished(identifier)}; - return (it != targets.end()) && it->second->isPublishNow(); - } - - inline bool isRegistered() const { - return !registeredTargets.empty(); - } - - inline bool isRegistered(const std::string &address) const { - return isRegistered() && (registeredTargets.find(address) != registeredTargets.end()); - } - - using Ref = std::shared_ptr; - - static void setUseBundle(bool b) { - bUseBundle = b; - } - - static bool isUseBundle() { - return bUseBundle; - } - - private: - OscPublisher(const Destination &destination) - : destination(destination) { - sender.setup(destination.ip, destination.port); - } - - void update() { - ofxOscMessage m; - if(isUseBundle()) { - ofxOscBundle bundle; + + #pragma mark unregister + + inline void unregister(const std::string &address) { + if(registeredTargets.find(address) == registeredTargets.end()) registeredTargets.erase(address); + } + + inline void unregister(PublishIdentifier &identifier) { + if(!identifier.isValid()) return; + Targets::const_iterator it{findRegistered(identifier)}; + if(it != registeredTargets.end()) { + registeredTargets.erase(it); + } + identifier.invalidate(); + } + + inline void unregister() { + registeredTargets.clear(); + } + + #pragma mark status + + inline bool isPublished() const { + return !targets.empty(); + } + + inline bool isPublished(const PublishIdentifier &identifier) const { + if(!identifier.isValid()) false; + return isPublished() && (findPublished(identifier) != targets.end()); + } + + inline bool isPublished(const std::string &address) const { + return isPublished() && (targets.find(address) != targets.end()); + } + + inline bool isEnabled(const std::string &address) const { + // TODO: fix + return isPublished(address) && targets.find(address)->second->isPublishNow(); + } + + inline bool isEnabled(const PublishIdentifier &identifier) const { + if(!identifier.isValid()) return false; + Targets::const_iterator it{findPublished(identifier)}; + return (it != targets.end()) && it->second->isPublishNow(); + } + + inline bool isRegistered() const { + return !registeredTargets.empty(); + } + + inline bool isRegistered(const std::string &address) const { + return isRegistered() && (registeredTargets.find(address) != registeredTargets.end()); + } + + using Ref = std::shared_ptr; + + static bool &bUseBundle() { + static bool b; + return b; + } + + static void setUseBundle(bool b) { + bUseBundle() = b; + } + + static bool isUseBundle() { + return bUseBundle(); + } + + private: + Publisher(const Destination &destination) + : destination(destination) { + sender.setup(destination.ip, destination.port); + } + + void update() { + ofxOscMessage m; + if(isUseBundle()) { + ofxOscBundle bundle; + for(Targets::iterator it = targets.begin(); it != targets.end(); ++it) { + if(it->second->write(m, it->first)) bundle.addMessage(m); + m.clear(); + } + if(bundle.getMessageCount()) sender.sendBundle(bundle); + bundle.clear(); + return; + } for(Targets::iterator it = targets.begin(); it != targets.end(); ++it) { - if(it->second->setMessage(m, it->first)) bundle.addMessage(m); + if(it->second->write(m, it->first)) sender.sendMessage(m); m.clear(); } - if(bundle.getMessageCount()) sender.sendBundle(bundle); - bundle.clear(); - return; + } - for(Targets::iterator it = targets.begin(); it != targets.end(); ++it) { - if(it->second->setMessage(m, it->first)) sender.sendMessage(m); - m.clear(); + + Destination destination; + ofxOscSender sender; + Targets targets; + Targets registeredTargets; + friend class PublisherManager; + }; + + class PublisherManager { + public: + using Publishers = std::map; + + static PublisherManager &getSharedInstance() { + static PublisherManager *sharedInstance = new PublisherManager; + return *sharedInstance; } - } - - Destination destination; - ofxOscSender sender; - Targets targets; - Targets registeredTargets; - static bool bUseBundle; - friend class OscPublisherManager; + static Publisher &getOscPublisher(const std::string &ip, int port) { + Publishers &publishers = getSharedInstance().publishers; + Destination destination(ip, port); + if(publishers.find(destination) == publishers.end()) { + publishers.insert(std::make_pair(destination, Publisher::Ref(new Publisher(destination)))); + } + return *(publishers[destination].get()); + } + + void update(ofEventArgs &args) { + for(Publishers::iterator it = publishers.begin(); it != publishers.end(); ++it) { + it->second->update(); + } + } + PublisherManager() { + ofAddListener(ofEvents().update, this, &PublisherManager::update, OF_EVENT_ORDER_AFTER_APP); + } + virtual ~PublisherManager() { + ofRemoveListener(ofEvents().update, this, &PublisherManager::update, OF_EVENT_ORDER_AFTER_APP); + } + Publishers publishers; + + #pragma mark iterator + public: + using iterator = Publishers::iterator; + using const_iterator = Publishers::const_iterator; + using reverse_iterator = Publishers::reverse_iterator; + using const_reverse_iterator = Publishers::const_reverse_iterator; + + iterator begin() { return publishers.begin(); } + iterator end() { return publishers.end(); } + + const_iterator begin() const { return publishers.cbegin(); } + const_iterator end() const { return publishers.cend(); } + const_iterator cbegin() const { return publishers.cbegin(); } + const_iterator cend() const { return publishers.cend(); } + + reverse_iterator rbegin() { return publishers.rbegin(); } + reverse_iterator rend() { return publishers.rend(); } + + const_reverse_iterator rbegin() const { return publishers.crbegin(); } + const_reverse_iterator rend() const { return publishers.crend(); } + const_reverse_iterator crbegin() const { return publishers.crbegin(); } + const_reverse_iterator crend() const { return publishers.crend(); } + }; }; - - using OscPublishers = std::map; - - static OscPublisherManager &getSharedInstance() { - static OscPublisherManager *sharedInstance = new OscPublisherManager; - return *sharedInstance; - } - - static OscPublisher &getOscPublisher(const std::string &ip, int port) { - OscPublishers &publishers = getSharedInstance().publishers; - Destination destination(ip, port); - if(publishers.find(destination) == publishers.end()) { - publishers.insert(std::make_pair(destination, OscPublisher::Ref(new OscPublisher(destination)))); - } - return *(publishers[destination].get()); - } - - void update(ofEventArgs &args) { - for(OscPublishers::iterator it = publishers.begin(); it != publishers.end(); ++it) { - it->second->update(); - } - } - OscPublisherManager() { - ofAddListener(ofEvents().update, this, &OscPublisherManager::update, OF_EVENT_ORDER_AFTER_APP); - } - virtual ~OscPublisherManager() { - ofRemoveListener(ofEvents().update, this, &OscPublisherManager::update, OF_EVENT_ORDER_AFTER_APP); - } - OscPublishers publishers; - -#pragma mark iterator - public: - using iterator = OscPublishers::iterator; - using const_iterator = OscPublishers::const_iterator; - using reverse_iterator = OscPublishers::reverse_iterator; - using const_reverse_iterator = OscPublishers::const_reverse_iterator; - - iterator begin() { return publishers.begin(); } - iterator end() { return publishers.end(); } - - const_iterator begin() const { return publishers.cbegin(); } - const_iterator end() const { return publishers.cend(); } - const_iterator cbegin() const { return publishers.cbegin(); } - const_iterator cend() const { return publishers.cend(); } - - reverse_iterator rbegin() { return publishers.rbegin(); } - reverse_iterator rend() { return publishers.rend(); } - - const_reverse_iterator rbegin() const { return publishers.crbegin(); } - const_reverse_iterator rend() const { return publishers.crend(); } - const_reverse_iterator crbegin() const { return publishers.crbegin(); } - const_reverse_iterator crend() const { return publishers.crend(); } }; - - bool OscPublisherManager::OscPublisher::bUseBundle = false; }; -#undef type_ref #pragma mark - syntax sugars #pragma mark getter -using ofxOscPublisherManager = ofx::OscPublisherManager; -using ofxOscPublisher = ofxOscPublisherManager::OscPublisher; -using ofxOscPublisherIdentifier = ofxOscPublisherManager::Identifier; +using ofxOscPublisher = ofx::PubSubOsc::Publish::Publisher; +using ofxOscPublisherManager = ofx::PubSubOsc::Publish::PublisherManager; +using ofxOscPublisherIdentifier = ofx::PubSubOsc::Publish::PublishIdentifier; /// \brief get a OscPublisherManager. /// \returns ofxOscPublisherManager @@ -1107,9 +522,21 @@ inline ofxOscPublisher &ofxGetOscPublisher(const std::string &ip, int port) { /// \param whenValueIsChanged if this value to false, then we send value every update /// \returns ofxOscPublisherIdentifier -template -inline ofxOscPublisherIdentifier ofxPublishOsc(const std::string &ip, int port, const std::string &address, ValueRefOrGetterFunction &&valueRefOrGetterFunction, bool whenValueIsChanged = true) { - return ofxGetOscPublisher(ip, port).publish(address, valueRefOrGetterFunction, whenValueIsChanged); +struct explicit_bool { + explicit_bool() = delete; + explicit_bool(bool b) + : b(b) {} + template + explicit_bool(_) = delete; + operator bool() const { return b; }; + bool get() const { return b; }; + bool b; +}; + +template +inline ofxOscPublisherIdentifier ofxPublishOsc(const std::string &ip, int port, const std::string &address, ValueOrFunction &&valueOrFunction, explicit_bool whenValueIsChanged = true) +{ + return ofxGetOscPublisher(ip, port).publish(address, std::forward(valueOrFunction), whenValueIsChanged.get()); } /// \brief publish the value will be gave by function as an OSC message with an address pattern address to ip:port every time the value has changed. @@ -1123,9 +550,11 @@ inline ofxOscPublisherIdentifier ofxPublishOsc(const std::string &ip, int port, /// \param whenValueIsChanged if this value to false, then we send value every update /// \returns ofxOscPublisherIdentifier -template -inline ofxOscPublisherIdentifier ofxPublishOsc(const std::string &ip, int port, const std::string &address, ObjectPtrOrRef &&that, Method getter, bool whenValueIsChanged = true) { - return ofxGetOscPublisher(ip, port).publish(address, that, getter, whenValueIsChanged); +template +inline auto ofxPublishOsc(const std::string &ip, int port, const std::string &address, Object &&obj, Method &&meth, bool whenValueIsChanged = true) +-> ofx::PubSubOsc::enable_if_t::value, ofxOscPublisherIdentifier> +{ + return ofxGetOscPublisher(ip, port).publish(address, ofx::PubSubOsc::bind(std::forward(obj), std::forward(meth)), whenValueIsChanged); } template @@ -1136,21 +565,21 @@ inline void ofxPublishOsc(const std::string &ip, const std::initializer_list -inline void ofxPublishOsc(const std::initializer_list &ips, Args & ... args) { +inline void ofxPublishOsc(const std::initializer_list &ips, Args & ... args) { for(auto &ip : ips) { ofxPublishOsc(ip, args ...); } } template -inline void ofxPublishOsc(const std::initializer_list &targets, Args & ... args) { +inline void ofxPublishOsc(const std::initializer_list &targets, Args & ... args) { for(auto &target : targets) { ofxPublishOsc(target.ip, target.port, args ...); } } template -inline void ofxPublishOsc(const std::initializer_list &targets, Args & ... args) { +inline void ofxPublishOsc(const std::initializer_list &targets, Args & ... args) { for(auto &target : targets) { ofxPublishOsc(target.destination.ip, target.destination.port, target.address, args ...); } @@ -1218,7 +647,7 @@ inline void ofxUnpublishOsc(const std::string &ip, int port) { inline void ofxUnpublishOsc() { ofxOscPublisherManager &manager = ofxGetOscPublisherManager(); ofxOscPublisherManager::iterator it = manager.begin(), - end = manager.end(); + end = manager.end(); for(; it != end; it++) { it->second->unpublish(); } @@ -1280,7 +709,7 @@ inline void ofxUnregisterPublishingOsc(const std::string &ip, int port) { inline void ofxUnregisterPublishingOsc() { ofxOscPublisherManager &manager = ofxGetOscPublisherManager(); ofxOscPublisherManager::iterator it = manager.begin(), - end = manager.end(); + end = manager.end(); for(; it != end; it++) { it->second->unregister(); } @@ -1317,28 +746,29 @@ struct array_type { template typename array_type::type ofxPublishAsArray(T *ptr) { - return reinterpret_cast(reinterpret_cast(ptr[0])); + return reinterpret_cast(reinterpret_cast(ptr[0])); } template typename array_type::fun ofxPublishAsArray(T *(*getter)()) { return reinterpret_cast::type (*)()>( - reinterpret_cast(getter) + reinterpret_cast(getter) ); } template typename array_type::template meth::method ofxPublishAsArray(T *(U::*getter)()) { return reinterpret_cast::template meth::method>( - reinterpret_cast(getter) + reinterpret_cast(getter) ); } template typename array_type::template meth::const_method ofxPublishAsArray(T *(U::*getter)() const) { return reinterpret_cast::template meth::const_method>( - reinterpret_cast(getter) + reinterpret_cast(getter) ); } /// \} +#endif /* ofxPublisher_h */ diff --git a/src/ofxOscSubscriber.h b/src/ofxOscSubscriber.h index dd6c885..0ac9825 100644 --- a/src/ofxOscSubscriber.h +++ b/src/ofxOscSubscriber.h @@ -1,775 +1,354 @@ // // ofxOscSubscriber.h // -// Created by ISHII 2bit on 2015/05/10. +// Created by ISHII 2bit on 2016/05/29. // // #pragma once -#include "ofMain.h" -#include "ofxOsc.h" +#ifndef ofxOscSubscriber_h +#define ofxOscSubscriber_h -#include "details/ofxpubsubosc_settings.h" -#include "details/ofxpubsubosc_type_traits.h" +#define TYPE_DEBUG(T) -#include +#include "ofxOsc.h" -#if OFX_PUBSUBOSC_DEBUG -# define TYPE_DEBUG(type) ofLogNotice() << __func__ << ":" << __LINE__ << "[" << address << "], " << typeid(type).name(); -#else -# define TYPE_DEBUG(type) ; -#endif +#include "ofxOscSubscriberLoadImplementation.h" +#include "ofxOscSubscribeParameter.h" namespace ofx { - using namespace ofxpubsubosc; - - namespace { - template - using get_type = typename T::type; - - template - struct is_callable { - template - struct checker {}; - template static std::true_type test(checker *); - template static std::false_type test(...); - static constexpr bool value = decltype(test(nullptr))::value; - }; - - template - struct is_callable { - static constexpr bool value = true; - }; - - template - struct is_callable { - static constexpr bool value = true; - }; - - template - struct is_callable { - static constexpr bool value = true; - }; - - template - struct is_callable { - static constexpr bool value = true; - }; - - template - struct is_callable> { - static constexpr bool value = true; - }; - - template - struct function_info : public function_info {}; - - template - struct function_info { - static constexpr bool is_function = true; - static constexpr std::size_t arity = sizeof...(arguments); - using result_type = ret; - using arguments_types_tuple = std::tuple; - template - using argument_type = get_type>; - using function_type = std::function; - }; - - template - struct function_info { - static constexpr bool is_function = true; - static constexpr std::size_t arity = sizeof...(arguments); - using result_type = ret; - using arguments_types_tuple = std::tuple; - template - using argument_type = get_type>; - using function_type = std::function; - }; - - template - struct function_info { - static constexpr bool is_function = true; - static constexpr std::size_t arity = sizeof...(arguments); - using result_type = ret; - using arguments_types_tuple = std::tuple; - template - using argument_type = get_type>; - using function_type = std::function; - }; - - template - struct function_info { - static constexpr bool is_function = true; - static constexpr std::size_t arity = sizeof...(arguments); - using result_type = ret; - using arguments_types_tuple = std::tuple; - template - using argument_type = get_type>; - using function_type = std::function; - }; - - template - function_info get_function_info(T &t); // for decltype - }; - - class OscSubscriberManager { - public: - class OscSubscriber; - - private: - struct SetImplementation { - protected: -#define define_set_arithmetic(type) \ - inline void set(ofxOscMessage &m, type &v, std::size_t offset = 0) { \ - if(m.getArgType(offset) == OFXOSC_TYPE_INT32) v = m.getArgAsInt32(offset); \ - else if(m.getArgType(offset) == OFXOSC_TYPE_INT64) v = m.getArgAsInt64(offset); \ - else if(m.getArgType(offset) == OFXOSC_TYPE_FLOAT) v = m.getArgAsFloat(offset); \ - else if(m.getArgType(offset) == OFXOSC_TYPE_DOUBLE) v = m.getArgAsDouble(offset); \ - else if(m.getArgType(offset) == OFXOSC_TYPE_STRING) v = ofToDouble(m.getArgAsString(offset)); \ - } - - define_set_arithmetic(bool); - define_set_arithmetic(char); - define_set_arithmetic(unsigned char); - define_set_arithmetic(short); - define_set_arithmetic(unsigned short); - define_set_arithmetic(int); - define_set_arithmetic(unsigned int); - define_set_arithmetic(long); - define_set_arithmetic(unsigned long); - define_set_arithmetic(long long); - define_set_arithmetic(unsigned long long); - - define_set_arithmetic(float); - define_set_arithmetic(double); -#undef define_set_arithmetic - - inline void set(ofxOscMessage &m, std::string &v, std::size_t offset = 0) { - if(m.getArgType(offset) == OFXOSC_TYPE_STRING) v = m.getArgAsString(offset); - else if(m.getArgType(offset) == OFXOSC_TYPE_FLOAT) v = ofToString(m.getArgAsFloat(offset)); - else if(m.getArgType(offset) == OFXOSC_TYPE_DOUBLE) v = ofToString(m.getArgAsDouble(offset)); - else if(m.getArgType(offset) == OFXOSC_TYPE_INT32) v = ofToString(m.getArgAsInt32(offset)); - else if(m.getArgType(offset) == OFXOSC_TYPE_INT64) v = ofToString(m.getArgAsInt64(offset)); - else v = m.getArgAsString(offset); - } + namespace PubSubOsc { + namespace Subscribe { + using OscReceiverRef = std::shared_ptr; - inline void set(ofxOscMessage &m, ofBuffer &v, std::size_t offset = 0) { - v = m.getArgAsBlob(offset); - } + class SubscribeManager; - inline void set(ofxOscMessage &m, ofColor &v, std::size_t offset = 0) { setColor(m, v, 255, offset); } - inline void set(ofxOscMessage &m, ofShortColor &v, std::size_t offset = 0) { setColor(m, v, 65535, offset); } - inline void set(ofxOscMessage &m, ofFloatColor &v, std::size_t offset = 0) { setColor(m, v, 1.0f, offset); } - - template - inline void setColor(ofxOscMessage &m, ofColor_ &v, U defaultValue, std::size_t offset = 0) { - if(m.getNumArgs() == 1) { - set(m, v.r, offset); - set(m, v.g, offset); - set(m, v.b, offset); - v.a = defaultValue; - } else if(m.getNumArgs() == 3) { - set(m, v.r, offset + 0); - set(m, v.g, offset + 1); - set(m, v.b, offset + 2); - v.a = defaultValue; - } else { - set(m, v.r, offset + 0); - set(m, v.g, offset + 1); - set(m, v.b, offset + 2); - set(m, v.a, offset + 3); - } - } - - inline void set(ofxOscMessage &m, ofVec2f &v, std::size_t offset = 0) { setVec<2>(m, v, offset); } - inline void set(ofxOscMessage &m, ofVec3f &v, std::size_t offset = 0) { setVec<3>(m, v, offset); } - inline void set(ofxOscMessage &m, ofVec4f &v, std::size_t offset = 0) { setVec<4>(m, v, offset); } - inline void set(ofxOscMessage &m, ofQuaternion &v, std::size_t offset = 0) { setVec<4>(m, v, offset); } - inline void set(ofxOscMessage &m, ofMatrix3x3 &v, std::size_t offset = 0) { setVec<9>(m, v, offset); } - - template - inline void setVec(ofxOscMessage &m, U &v, std::size_t offset = 0) { - for(int i = 0; i < min(static_cast(m.getNumArgs() - offset), n); i++) { - set(m, v[i], offset + i); + class SubscribeIdentifier { + std::string address; + ParameterRef ref; + int key; + + void invalidate() { + address = ""; + ref = nullptr; + key = 0; } - } + public: + SubscribeIdentifier() : address(""), ref(nullptr) {} + SubscribeIdentifier(const std::string &address, const ParameterRef &ref, int key) + : address(address) + , ref(ref) + , key(key) {} + + SubscribeIdentifier(const SubscribeIdentifier &) = default; + SubscribeIdentifier(SubscribeIdentifier &&) = default; + + SubscribeIdentifier &operator=(const SubscribeIdentifier &) = default; + SubscribeIdentifier &operator=(SubscribeIdentifier &&) = default; + + const int getKey() const { return key; }; + bool isValid() const { return static_cast(ref); } + + friend class Subscriber; + }; - inline void set(ofxOscMessage &m, ofMatrix4x4 &v, std::size_t offset = 0) { - for(int j = 0; j < 4; j++) for(int i = 0; i < 4; i++) { - set(m, v(i, j), offset + 4 * j + i); + class Subscriber { + Targets::const_iterator findFromTargets(const SubscribeIdentifier &identifier, const Targets &targets) const { + if(!identifier.isValid()) return targets.end(); + Targets::const_iterator it = targets.find(identifier.address); + if(it != targets.end()) { + for(std::size_t i = 0, size = targets.count(identifier.address); i < size; ++i, ++it) { + if(it->second == identifier.ref) { + return it; + } + } + } + return targets.end(); } - } - - inline void set(ofxOscMessage &m, ofRectangle &v, std::size_t offset = 0) { - set(m, v.x, offset + 0); - set(m, v.y, offset + 1); - set(m, v.width, offset + 2); - set(m, v.height, offset + 3); - } - - template - inline void set(ofxOscMessage &m, U (&v)[size], std::size_t offset = 0) { - for(int i = 0; i < min(size, (m.getNumArgs() - offset) / ofxpubsubosc::type_traits::size); i++) { - set(m, v[i], offset + i * ofxpubsubosc::type_traits::size); + + inline Targets::const_iterator findSubscribed(const SubscribeIdentifier &identifier) const { + return findFromTargets(identifier, targets); } - } - - template - inline void set(ofxOscMessage &m, std::vector &v, std::size_t offset = 0) { - std::size_t num = (m.getNumArgs() - offset) / ofxpubsubosc::type_traits::size; - if(v.size() != num) v.resize(num); - for(int i = 0; i < num; i++) { - set(m, v[i], offset + i * ofxpubsubosc::type_traits::size); - } - } - -#pragma mark ofParameter / ofParameterGroup - - template - inline void set(ofxOscMessage &m, ofParameter &p, std::size_t offset = 0) { - U u; - set(m, u, offset); - p.set(u); - } - - inline void set(ofxOscMessage &m, ofAbstractParameter &p, std::size_t offset = 0) { -#define type_convert(type_) if(p.type() == typeid(ofParameter).name()) { set(m, p.cast(), offset); return; } - type_convert(float); - type_convert(double); - type_convert(int); - type_convert(unsigned int); - type_convert(long); - type_convert(unsigned long); - type_convert(ofColor); - type_convert(ofRectangle); - type_convert(ofVec2f); - type_convert(ofVec3f); - type_convert(ofVec4f); - type_convert(ofQuaternion); - type_convert(ofMatrix3x3); - type_convert(ofMatrix4x4); - - type_convert(ofFloatColor); - type_convert(ofShortColor); - - type_convert(bool); - type_convert(char); - type_convert(unsigned char); - type_convert(short); - type_convert(unsigned short); - type_convert(long long); - type_convert(unsigned long long); - type_convert(ofBuffer); - ofLogWarning("ofxOscSubscriber") << "ofAbstractParameter: Unknown type \"" << p.type() << "\", bind to " << m.getAddress() << ". we ignored."; -#undef type_convert - } - - inline void set(ofxOscMessage &m, ofParameterGroup &pg, std::size_t offset = 0) { - if(m.getArgType(0) == OFXOSC_TYPE_INT32) { - if(pg.size() <= m.getArgAsInt32(0)) { - ofLogWarning("ofxOscSubscriber") << "ofAbstractParameterGroup: not contain index \"" << m.getArgAsInt32(0) << "\""; - return; - } - set(m, pg.get(m.getArgAsInt32(0)), offset + 1); - } else if(m.getArgType(0) == OFXOSC_TYPE_INT64) { - if(pg.size() <= m.getArgAsInt64(0)) { - ofLogWarning("ofxOscSubscriber") << "ofAbstractParameterGroup: not contain index \"" << m.getArgAsInt64(0) << "\""; - return; - } - set(m, pg.get(m.getArgAsInt64(0)), offset + 1); - } else if(m.getArgType(0) == OFXOSC_TYPE_STRING) { - if(!pg.contains(m.getArgAsString(0))) { - ofLogWarning("ofxOscSubscriber") << "ofAbstractParameterGroup: not contain key \"" << m.getArgAsString(0) << "\""; - return; - } - set(m, pg.get(m.getArgAsString(0)), offset + 1); + + template + inline auto make_parameter_ref(T &value) + -> enable_if_t::value, ParameterRef> + { + return ParameterRef(new Parameter(value)); } - } - }; - -#pragma mark Parameter - - struct AbstractParameter { - virtual void read(ofxOscMessage &message) = 0; - }; - - template - struct Parameter : AbstractParameter, SetImplementation { - Parameter(T &t) : t(t) {} - virtual void read(ofxOscMessage &message) { set(message, t); } - - private: - - T &t; - }; - - template - struct SetterFunctionParameter : AbstractParameter, SetImplementation { - using Setter = std::function; - SetterFunctionParameter(Setter setter) : setter(setter) {}; - virtual void read(ofxOscMessage &message) { - typename remove_const_reference::type t; - set(message, t); - setter(t); - } - - private: - Setter setter; - }; - - template - struct SetterFunctionParameter : AbstractParameter, SetImplementation { - using Setter = std::function; - SetterFunctionParameter(Setter setter) : setter(setter) {}; - virtual void read(ofxOscMessage &message) { - setter(message); - } - - private: - Setter setter; - }; - - template - struct SetterFunctionParameter : AbstractParameter, SetImplementation { - using Setter = std::function; - SetterFunctionParameter(Setter setter) : setter(setter) {}; - virtual void read(ofxOscMessage &message) { - setter(); - } - - private: - Setter setter; - }; - - template - struct SetterMethodParameter : AbstractParameter, SetImplementation { - using Method = R (C::*)(T); - SetterMethodParameter(C &that, Method setter) - : that(that) - , setter(setter) {}; - - virtual void read(ofxOscMessage &message) { - typename remove_const_reference::type t; - set(message, t); - (that.*setter)(t); - } - - private: - C &that; - Method setter; - }; - - template - struct SetterMethodParameter : AbstractParameter, SetImplementation { - using Method = R (C::*)(ofxOscMessage &); - SetterMethodParameter(C &that, Method setter) - : that(that) - , setter(setter) {}; - - virtual void read(ofxOscMessage &message) { - (that.*setter)(message); - } - - private: - C &that; - Method setter; - }; - - template - struct SetterMethodParameter : AbstractParameter, SetImplementation { - using Method = R (C::*)(); - SetterMethodParameter(C &that, Method setter) - : that(that) - , setter(setter) {}; - - virtual void read(ofxOscMessage &message) { - (that.*setter)(); - } - - private: - C &that; - Method setter; - }; - - template - struct ConstSetterMethodParameter : AbstractParameter, SetImplementation { - using Method = R (C::*)(T) const; - ConstSetterMethodParameter(const C &that, Method setter) - : that(that) - , setter(setter) {}; - - virtual void read(ofxOscMessage &message) { - typename remove_const_reference::type t; - set(message, t); - (that.*setter)(t); - } - - private: - const C &that; - Method setter; - }; - - template - struct ConstSetterMethodParameter : AbstractParameter, SetImplementation { - using Method = R (C::*)(ofxOscMessage &) const; - ConstSetterMethodParameter(const C &that, Method setter) - : that(that) - , setter(setter) {}; - - virtual void read(ofxOscMessage &message) { - (that.*setter)(message); - } - - private: - const C &that; - Method setter; - }; - - template - struct ConstSetterMethodParameter : AbstractParameter, SetImplementation { - using Method = R (C::*)() const; - ConstSetterMethodParameter(const C &that, Method setter) - : that(that) - , setter(setter) {}; - - virtual void read(ofxOscMessage &message) { - (that.*setter)(); - } - - private: - const C &that; - Method setter; - }; - - using ParameterRef = std::shared_ptr; - using OscReceiverRef = std::shared_ptr; - using Targets = std::multimap; - - public: - class Identifier { - std::string address; - ParameterRef ref; - int key; - - void invalidate() { - address = ""; - ref = nullptr; - key = 0; - } - public: - Identifier() : address(""), ref(nullptr) {} - Identifier(const std::string &address, const ParameterRef &ref, int key) - : address(address) - , ref(ref) - , key(key) {} - - const int getKey() const { return key; }; - bool isValid() const { return static_cast(ref); } - - friend class OscSubscriber; - }; - - class OscSubscriber { - Targets::const_iterator findFromTargets(const Identifier &identifier, const Targets &targets) const { - if(!identifier.isValid()) return targets.end(); - Targets::const_iterator it = targets.find(identifier.address); - if(it != targets.end()) { - for(std::size_t i = 0, size = targets.count(identifier.address); i < size; ++i, ++it) { - if(it->second == identifier.ref) { - return it; - } - } + + template + inline ParameterRef make_parameter_ref(std::vector &&t) { + return ParameterRef(new TupleParameter(std::move(t))); } - return targets.end(); - } - - inline Targets::const_iterator findSubscribed(const Identifier &identifier) const { - return findFromTargets(identifier, targets); - } - - inline Identifier subscribe_impl(const std::string &address, ParameterRef ref) { - Targets::iterator it = targets.insert(std::make_pair(address, ref)); - return {address, ref, port}; - } - - public: - -#pragma mark subscribe - - template - inline auto subscribe(const std::string &address, T &value) - -> typename std::enable_if::value, Identifier>::type - { - return subscribe_impl(address, ParameterRef(new Parameter(value))); - } - - template - inline auto subscribe(const std::string &address, T &value) - -> typename std::enable_if::value, Identifier>::type - { - TYPE_DEBUG(T); - return subscribe(address, static_cast::function_type>(value)); - } - - template - inline auto subscribe(const std::string &address, T &&value) - -> typename std::enable_if::value, Identifier>::type - { - TYPE_DEBUG(T); - return subscribe(address, static_cast::function_type>(value)); - } - - template - inline auto subscribe(const std::string &address, T *value) - -> typename std::enable_if::value, Identifier>::type - { - TYPE_DEBUG(T); - return subscribe(address, static_cast::function_type>(value)); - } - + #pragma mark - #pragma mark setter function - - template - inline Identifier subscribe(const std::string &address, std::function setter) { - TYPE_DEBUG(T); - return subscribe_impl(address, ParameterRef(new SetterFunctionParameter(setter))); - } - - template - inline Identifier subscribe(const std::string &address, std::function setter) { - TYPE_DEBUG(T); - return subscribe_impl(address, ParameterRef(new SetterFunctionParameter(setter))); - } - - template - inline Identifier subscribe(const std::string &address, std::function setter) { - TYPE_DEBUG(T); - return subscribe_impl(address, ParameterRef(new SetterFunctionParameter(setter))); - } - -#pragma mark setter method - - template - inline Identifier subscribe(const std::string &address, C &that, R (C::*setter)(T)) { - return subscribe_impl(address, ParameterRef(new SetterMethodParameter(that, setter))); - } - - template - inline Identifier subscribe(const std::string &address, C *that, R (C::*setter)(T)) { - return subscribe_impl(address, ParameterRef(new SetterMethodParameter(*that, setter))); - } - - template - inline Identifier subscribe(const std::string &address, const C &that, R (C::*setter)(T) const) { - return subscribe_impl(address, ParameterRef(new ConstSetterMethodParameter(that, setter))); - } - - template - inline Identifier subscribe(const std::string &address, const C * const that, R (C::*setter)(T) const) { - return subscribe_impl(address, ParameterRef(new ConstSetterMethodParameter(*that, setter))); - } - + + template + inline ParameterRef make_parameter_ref(std::function setter) { + TYPE_DEBUG(T); + return ParameterRef(new SetterFunctionParameter(setter)); + } + + template + inline ParameterRef make_parameter_ref(std::function setter) { + TYPE_DEBUG(T); + return ParameterRef(new SetterFunctionParameter(setter)); + } + + template + inline ParameterRef make_parameter_ref(std::function setter) { + TYPE_DEBUG(T); + return ParameterRef(new SetterFunctionParameter(setter)); + } + +#pragma mark setter function for lambda and method + + template + inline auto make_parameter_ref(T &value) + -> enable_if_t::value, ParameterRef> + { + TYPE_DEBUG(T); + return make_parameter_ref(function_traits::cast(value)); + } + + template + inline auto make_parameter_ref(T &&value) + -> enable_if_t::value, ParameterRef> + { + TYPE_DEBUG(T); + return make_parameter_ref(function_traits::cast(value)); + } + + template + inline auto make_parameter_ref(T *value) + -> enable_if_t::value, ParameterRef> + { + TYPE_DEBUG(T); + return make_parameter_ref(function_traits::cast(value)); + } + + template + inline auto make_parameter_ref(Obj &&obj, Meth &&meth) + -> enable_if_t::value, ParameterRef> + { + TYPE_DEBUG(Obj); + TYPE_DEBUG(Meth); + return make_parameter_ref(bind(std::forward(obj), + std::forward(meth))); + } + + template + inline auto make_parameter_ref(T &&t, U &&u, Ts && ... ts) + -> enable_if_t::value, ParameterRef> + { + std::vector v{ + make_parameter_ref(std::forward(t)), + make_parameter_ref(std::forward(u)), + make_parameter_ref(std::forward(ts)) ... + }; + return make_parameter_ref(std::move(v)); + } + + public: + +#pragma mark subscribe + + template + inline SubscribeIdentifier subscribe(const std::string &address, Ts && ... values) { + ParameterRef ref = make_parameter_ref(std::forward(values) ...); + Targets::iterator it = targets.insert(std::make_pair(address, ref)); + return {address, ref, port}; + } + #pragma mark unscribe - - inline void unsubscribe(const std::string &address) { - targets.erase(address); - } - - inline void unsubscribe(Identifier &identifier) { - if(!identifier.isValid()) return; - Targets::const_iterator it{findSubscribed(identifier)}; - if(it != targets.end()) { - targets.erase(it); - } - identifier.invalidate(); - } - - inline void unsubscribe() { - targets.clear(); - } - -#pragma mark leakPicker - - inline void setLeakPicker(ParameterRef ref) { - leakPicker = ref; - } - - template - inline void setLeakPicker(std::function callback) { - setLeakPicker(ParameterRef(new SetterFunctionParameter(callback))); - } - - template - inline void setLeakPicker(C &that, R (C::*callback)(ofxOscMessage &)) { - setLeakPicker(ParameterRef(new SetterMethodParameter(that, callback))); - } - - template - inline void setLeakPicker(C *that, R (C::*callback)(ofxOscMessage &)) { - setLeakPicker(ParameterRef(new SetterMethodParameter(*that, callback))); - } - - template - inline void setLeakPicker(const C &that, R (C::*callback)(ofxOscMessage &) const) { - setLeakPicker(ParameterRef(new ConstSetterMethodParameter(that, callback))); - } - - template - inline void setLeakPicker(const C * const that, R (C::*callback)(ofxOscMessage &) const) { - setLeakPicker(ParameterRef(new ConstSetterMethodParameter(*that, callback))); - } - - - inline void removeLeakPicker() { - leakPicker.reset(); - } - - inline bool isSubscribed() const { - return !targets.empty(); - } - - inline bool isSubscribed(const std::string &address) const { - return isSubscribed() && (targets.find(address) != targets.end()); - } - - inline bool isLeakedOscCovered() const { - return static_cast(leakPicker); - } - - void clearLeakedOscMessages() { - std::queue empty; - std::swap(leakedOscMessages, empty); - } - - inline bool hasWaitingLeakedOscMessages() const { - return !static_cast(leakPicker) && !leakedOscMessages.empty(); - } - - inline bool getNextLeakedOscMessage(ofxOscMessage &m) { - if(hasWaitingLeakedOscMessages()) { - m.copy(leakedOscMessages.front()); - leakedOscMessages.pop(); - return true; - } else { - return false; - } - } - - void notify(ofxOscMessage & m) { - const std::string &address = m.getAddress(); - Targets::iterator it = targets.find(address); - if(it != targets.end()) { - for(std::size_t i = 0; i < targets.count(address); i++, ++it) { - it->second->read(m); + + inline void unsubscribe(const std::string &address) { + targets.erase(address); + } + + inline void unsubscribe(SubscribeIdentifier &identifier) { + if(!identifier.isValid()) return; + Targets::const_iterator it{findSubscribed(identifier)}; + if(it != targets.end()) { + targets.erase(it); } + identifier.invalidate(); } - } - - void notify(const Identifier &identifier, ofxOscMessage &m) { - if(!identifier.isValid()) return; - Targets::const_iterator it{findSubscribed(identifier)}; - if(it != targets.end() && it->first == m.getAddress()) { - it->second->read(m); + + inline void unsubscribe() { + targets.clear(); } - } - - using Ref = std::shared_ptr; - private: - OscSubscriber(int port) - : port(port) { - receiver.setup(port); - } - - void update() { - clearLeakedOscMessages(); - ofxOscMessage m; - while(receiver.hasWaitingMessages()) { - receiver.getNextMessage(m); + +#pragma mark leakPicker + + inline void setLeakPicker(ParameterRef ref) { + leakPicker = ref; + } + + template + inline void setLeakPicker(std::function callback) { + setLeakPicker(ParameterRef(new SetterFunctionParameter(callback))); + } + + template + inline void setLeakPicker(T &t) { + setLeakPicker(function_traits::cast(t)); + } + + inline void removeLeakPicker() { + leakPicker.reset(); + } + + inline bool isSubscribed() const { + return !targets.empty(); + } + + inline bool isSubscribed(const std::string &address) const { + return isSubscribed() && (targets.find(address) != targets.end()); + } + + inline bool isLeakedOscCovered() const { + return static_cast(leakPicker); + } + + void clearLeakedOscMessages() { + std::queue empty; + std::swap(leakedOscMessages, empty); + } + + inline bool hasWaitingLeakedOscMessages() const { + return !static_cast(leakPicker) && !leakedOscMessages.empty(); + } + + inline bool getNextLeakedOscMessage(ofxOscMessage &m) { + if(hasWaitingLeakedOscMessages()) { + m.copy(leakedOscMessages.front()); + leakedOscMessages.pop(); + return true; + } else { + return false; + } + } + + void notify(ofxOscMessage & m) { const std::string &address = m.getAddress(); Targets::iterator it = targets.find(address); if(it != targets.end()) { for(std::size_t i = 0; i < targets.count(address); i++, ++it) { it->second->read(m); } - } else { - if(leakPicker) { - leakPicker->read(m); + } + } + + void notify(const SubscribeIdentifier &identifier, ofxOscMessage &m) { + if(!identifier.isValid()) return; + Targets::const_iterator it{findSubscribed(identifier)}; + if(it != targets.end() && it->first == m.getAddress()) { + it->second->read(m); + } + } + + using Ref = std::shared_ptr; + private: + Subscriber(int port) + : port(port) { + receiver.setup(port); + } + + void update() { + clearLeakedOscMessages(); + ofxOscMessage m; + while(receiver.hasWaitingMessages()) { + receiver.getNextMessage(m); + const std::string &address = m.getAddress(); + Targets::iterator it = targets.find(address); + if(it != targets.end()) { + for(std::size_t i = 0; i < targets.count(address); i++, ++it) { + it->second->read(m); + } } else { - leakedOscMessages.push(m); + if(leakPicker) { + leakPicker->read(m); + } else { + leakedOscMessages.push(m); + } } } } - } - - int port; - ofxOscReceiver receiver; - Targets targets; - ParameterRef leakPicker; - std::queue leakedOscMessages; - - friend class OscSubscriberManager; - }; - - static OscSubscriberManager &getSharedInstance() { - static OscSubscriberManager *sharedInstance = new OscSubscriberManager; - return *sharedInstance; - } - - static OscSubscriber &getOscSubscriber(int port) { - OscSubscribers &managers = getSharedInstance().managers; - if(managers.find(port) == managers.end()) { - managers.insert(std::make_pair(port, OscSubscriber::Ref(new OscSubscriber(port)))); - } - return *(managers[port].get()); - } - - private: - using OscSubscribers = std::map; - void update(ofEventArgs &args) { - for(OscSubscribers::iterator it = managers.begin(); it != managers.end(); ++it) { - it->second->update(); - } - } - - OscSubscriberManager() { - ofAddListener(ofEvents().update, this, &OscSubscriberManager::update, OF_EVENT_ORDER_BEFORE_APP); - } - - virtual ~OscSubscriberManager() { - ofRemoveListener(ofEvents().update, this, &OscSubscriberManager::update, OF_EVENT_ORDER_BEFORE_APP); - } - OscSubscribers managers; - + + int port; + ofxOscReceiver receiver; + Targets targets; + ParameterRef leakPicker; + std::queue leakedOscMessages; + + friend class SubscriberManager; + }; + + class SubscriberManager { + public: + static SubscriberManager &getSharedInstance() { + static SubscriberManager *sharedInstance = new SubscriberManager; + return *sharedInstance; + } + + static Subscriber &getOscSubscriber(int port) { + Subscribers &managers = getSharedInstance().managers; + if(managers.find(port) == managers.end()) { + managers.insert(std::make_pair(port, Subscriber::Ref(new Subscriber(port)))); + } + return *(managers[port].get()); + } + private: + using Subscribers = std::map; + void update(ofEventArgs &args) { + for(Subscribers::iterator it = managers.begin(); it != managers.end(); ++it) { + it->second->update(); + } + } + + SubscriberManager() { + ofAddListener(ofEvents().update, this, &SubscriberManager::update, OF_EVENT_ORDER_BEFORE_APP); + } + + virtual ~SubscriberManager() { + ofRemoveListener(ofEvents().update, this, &SubscriberManager::update, OF_EVENT_ORDER_BEFORE_APP); + } + Subscribers managers; + #pragma mark iterator - public: - using iterator = OscSubscribers::iterator; - using const_iterator = OscSubscribers::const_iterator; - using reverse_iterator = OscSubscribers::reverse_iterator; - using const_reverse_iterator = OscSubscribers::const_reverse_iterator; - - iterator begin() { return managers.begin(); } - iterator end() { return managers.end(); } - - const_iterator begin() const { return managers.cbegin(); } - const_iterator end() const { return managers.cend(); } - const_iterator cbegin() const { return managers.cbegin(); } - const_iterator cend() const { return managers.cend(); } - - reverse_iterator rbegin() { return managers.rbegin(); } - reverse_iterator rend() { return managers.rend(); } - - const_reverse_iterator rbegin() const { return managers.crbegin(); } - const_reverse_iterator rend() const { return managers.crend(); } - const_reverse_iterator crbegin() const { return managers.crbegin(); } - const_reverse_iterator crend() const { return managers.crend(); } + public: + using iterator = Subscribers::iterator; + using const_iterator = Subscribers::const_iterator; + using reverse_iterator = Subscribers::reverse_iterator; + using const_reverse_iterator = Subscribers::const_reverse_iterator; + + iterator begin() { return managers.begin(); } + iterator end() { return managers.end(); } + + const_iterator begin() const { return managers.cbegin(); } + const_iterator end() const { return managers.cend(); } + const_iterator cbegin() const { return managers.cbegin(); } + const_iterator cend() const { return managers.cend(); } + + reverse_iterator rbegin() { return managers.rbegin(); } + reverse_iterator rend() { return managers.rend(); } + + const_reverse_iterator rbegin() const { return managers.crbegin(); } + const_reverse_iterator rend() const { return managers.crend(); } + const_reverse_iterator crbegin() const { return managers.crbegin(); } + const_reverse_iterator crend() const { return managers.crend(); } + }; + }; }; }; -using ofxOscSubscriberManager = ofx::OscSubscriberManager; -using ofxOscSubscriber = ofxOscSubscriberManager::OscSubscriber; -using ofxOscSubscriberIdentifier = ofxOscSubscriberManager::Identifier; +using ofxOscSubscriber = ofx::PubSubOsc::Subscribe::Subscriber; +using ofxOscSubscriberManager = ofx::PubSubOsc::Subscribe::SubscriberManager; +using ofxOscSubscriberIdentifier = ofx::PubSubOsc::Subscribe::SubscribeIdentifier; /// \brief get a OscSubscriberManager. /// \returns ofxOscSubscriberManager @@ -800,10 +379,19 @@ inline ofxOscSubscriber &ofxGetOscSubscriber(int port) { #pragma mark reference template -inline ofxOscSubscriberIdentifier ofxSubscribeOsc(int port, const std::string &address, T &&value) { +inline auto ofxSubscribeOsc(int port, const std::string &address, T &value) +-> ofx::PubSubOsc::enable_if_t::value, ofxOscSubscriberIdentifier> +{ return ofxGetOscSubscriber(port).subscribe(address, value); } +template +inline auto ofxSubscribeOsc(int port, const std::string &address, T callback) +-> ofx::PubSubOsc::enable_if_t::value, ofxOscSubscriberIdentifier> +{ + return ofxGetOscSubscriber(port).subscribe(address, ofx::PubSubOsc::function_traits::cast(callback)); +} + #pragma mark setter function/method /// \brief bind a callback to the OSC messages with an address pattern _address_ incoming to _port_. @@ -812,21 +400,24 @@ inline ofxOscSubscriberIdentifier ofxSubscribeOsc(int port, const std::string &a /// \param callback is kicked when receive a message to address /// \returns ofxOscSubscriberIdentifier -template -inline ofxOscSubscriberIdentifier ofxSubscribeOsc(int port, const std::string &address, std::function callback) { +template +inline ofxOscSubscriberIdentifier ofxSubscribeOsc(int port, const std::string &address, std::function callback) { return ofxGetOscSubscriber(port).subscribe(address, callback); } -/// \brief bind a callback to the OSC messages with an address pattern _address_ incoming to _port_. -/// \param port binded port is typed int -/// \param address osc address is typed const std::string & -/// \param that this object is typed ObjectRefOrPtr is reference or pointer of object, will bind with next argument of parameter method. is called as (that.*getter)(message) when receive a message. -/// \param callback is kicked when receive a message to address -/// \returns ofxOscSubscriberIdentifier +template +inline auto ofxSubscribeOsc(int port, const std::string &address, Obj &&obj, Meth &&meth) +-> ofx::PubSubOsc::enable_if_t::value, ofxOscSubscriberIdentifier> +{ + return ofxGetOscSubscriber(port).subscribe(address, ofx::PubSubOsc::bind(std::forward(obj), + std::forward(meth))); +} -template -inline ofxOscSubscriberIdentifier ofxSubscribeOsc(int port, const std::string &address, ObjectRefOrPtr &&that, Method callback) { - return ofxGetOscSubscriber(port).subscribe(address, that, callback); +template +inline auto ofxSubscribeOsc(int port, const std::string &address, T &&t, U &&u, Ts && ... values) +-> ofx::PubSubOsc::enable_if_t::value, ofxOscSubscriberIdentifier> +{ + return ofxGetOscSubscriber(port).subscribe(address, std::forward(t), std::forward(u), std::forward(values) ...); } #pragma mark subscribe multiple port at once @@ -891,7 +482,7 @@ inline void ofxUnsubscribeOsc(int port) { inline void ofxUnsubscribeOsc() { ofxOscSubscriberManager &manager = ofxGetOscSubscriberManager(); ofxOscSubscriberManager::iterator it = manager.begin(), - end = manager.end(); + end = manager.end(); for(; it != end; ++it) { it->second->unsubscribe(); } @@ -912,7 +503,7 @@ inline void ofxNotifyToSubscribedOsc(int port, ofxOscMessage &m) { inline void ofxNotifyToSubscribedOsc(ofxOscMessage &m) { ofxOscSubscriberManager &manager = ofxGetOscSubscriberManager(); ofxOscSubscriberManager::iterator it = manager.begin(), - end = manager.end(); + end = manager.end(); for(; it != end; ++it) { it->second->notify(m); } @@ -928,67 +519,30 @@ inline void ofxNotifyToSubscribedOsc(ofxOscMessage &m) { /// \callback is kicked when receive a leaked addresses /// \returns void -template -inline void ofxSetLeakedOscPicker(int port, Ret(*callback)(ofxOscMessage &)) { +template +inline void ofxSetLeakedOscPicker(int port, Callback callback) { ofxGetOscSubscriber(port).setLeakPicker(callback); } -/// \brief bind a callback to the OSC messages with are not match other patterns incoming to port. -/// \param port binded port is typed int -/// \param that this object is typed Obj&, will bind with next argument of parameter method. is called as (that.*getter)(message) when receive a message. -/// \callback is kicked when receive a leaked addresses -/// \returns void - -template -inline void ofxSetLeakedOscPicker(int port, Obj &that, Ret(Obj::*callback)(ofxOscMessage &)) { - ofxGetOscSubscriber(port).setLeakPicker(that, callback); -} - -/// \brief bind a callback to the OSC messages with are not match other patterns incoming to port. -/// \param port binded port is typed int -/// \param that this object is typed Obj*, will bind with next argument of parameter method. is called as (that->*getter)(message) when receive a message. -/// \callback is kicked when receive a leaked addresses -/// \returns void - -template -inline void ofxSetLeakedOscPicker(int port, Obj *that, Ret(Obj::*callback)(ofxOscMessage &)) { - ofxGetOscSubscriber(port).setLeakPicker(*that, callback); -} - -/// \brief bind a callback to the OSC messages with are not match other patterns incoming to port. -/// \param port binded port is typed int -/// \param that this object is typed Obj&, will bind with next argument of parameter method. is called as (that.*getter)(message) when receive a message. -/// \callback is kicked when receive a leaked addresses -/// \returns void - -template -inline void ofxSetLeakedOscPicker(int port, const Obj &that, Ret(Obj::*callback)(ofxOscMessage &) const) { - ofxGetOscSubscriber(port).setLeakPicker(that, callback); -} - -/// \brief bind a callback to the OSC messages with are not match other patterns incoming to port. -/// \param port binded port is typed int -/// \param that this object is typed Obj*, will bind with next argument of parameter method. is called as (that->*getter)(message) when receive a message. -/// \callback is kicked when receive a leaked addresses -/// \returns void - -template -inline void ofxSetLeakedOscPicker(int port, const Obj *that, Ret(Obj::*callback)(ofxOscMessage &) const) { - ofxGetOscSubscriber(port).setLeakPicker(*that, callback); +template +inline void ofxSetLeakedOscPicker(int port, Obj obj, Meth meth) { + ofxGetOscSubscriber(port).setLeakPicker(ofx::PubSubOsc::bind(obj, meth)); } -inline void ofxSetLeakedOscPicker(int port, const std::function &callback) { - ofxGetOscSubscriber(port).setLeakPicker(callback); -} #pragma mark leak picking all port -template -inline typename std::enable_if::value>::type ofxSetLeakedOscPickerAll(T &arg, Args & ... args) { +template +inline void ofxSetLeakedOscPickerAll(Callback callback) { for(auto subscriber : ofxGetOscSubscriberManager()) { - subscriber.second->setLeakPicker(arg, args ...); + subscriber.second->setLeakPicker(callback); } } +template +inline void ofxSetLeakedOscPickerAll(Obj obj, Meth meth) { + ofxSetLeakedOscPickerAll(ofx::PubSubOsc::bind(obj, meth)); +} + #pragma mark remove leaked osc picker(s) /// \brief remove a callback receives messages has leaked patterns incoming to port. @@ -1002,7 +556,7 @@ inline void ofxRemoveLeakedOscPicker(int port) { inline void ofxRemoveLeakedOscPicker() { ofxOscSubscriberManager &manager = ofxGetOscSubscriberManager(); ofxOscSubscriberManager::iterator it = manager.begin(), - end = manager.end(); + end = manager.end(); for(; it != end; ++it) { it->second->removeLeakPicker(); } @@ -1011,3 +565,5 @@ inline void ofxRemoveLeakedOscPicker() { /// \} #define SubscribeOsc(port, name) ofxSubscribeOsc(port, "/" #name, name) + +#endif /* ofxOscSubscriber_h */ diff --git a/src/ofxPubSubOsc.h b/src/ofxPubSubOsc.h index 8b36810..1d4359c 100644 --- a/src/ofxPubSubOsc.h +++ b/src/ofxPubSubOsc.h @@ -1,11 +1,22 @@ // // ofxPubSubOsc.h // -// Created by ISHII 2bit on 2015/05/11. +// Created by ISHII 2bit on 2016/05/29. // // #pragma once -#include "ofxOscPublisher.h" +#ifndef ofxPubSubOsc_h +#define ofxPubSubOsc_h + #include "ofxOscSubscriber.h" +#include "ofxOscPublisher.h" + +namespace ofx { + namespace PubSubOsc { + + }; +}; + +#endif /* ofxPubSubOsc_h */ From 4066b70b2051e86c6be03267cc60acd7af419423 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Thu, 2 Jun 2016 02:32:08 +0900 Subject: [PATCH 02/30] explicit_bool to more global --- src/details/ofxPubSubOscTypeUtils.h | 22 ++++++++++++++++++++++ src/ofxOscPublisher.h | 15 ++------------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/details/ofxPubSubOscTypeUtils.h b/src/details/ofxPubSubOscTypeUtils.h index 2ae71b4..e2778fd 100644 --- a/src/details/ofxPubSubOscTypeUtils.h +++ b/src/details/ofxPubSubOscTypeUtils.h @@ -363,4 +363,26 @@ bool operator!=(const ofBuffer &x, const ofBuffer &y) { return !operator==(x, y); } +#ifndef bbb_explicit_bool +#define bbb_explicit_bool + +namespace bbb { + struct explicit_bool { + explicit_bool() + : b(false) {} + explicit_bool(bool b) + : b(b) {} + template + explicit_bool(_) = delete; + bool &operator=(bool b) { this->b = b; } + + operator bool&() { return b; }; + operator bool() const { return b; }; + bool get() const { return b; }; + bool b; + }; +}; + +#endif + #endif /* ofxPubSubOscTypeUtils_h */ diff --git a/src/ofxOscPublisher.h b/src/ofxOscPublisher.h index 2d1afd9..27de923 100644 --- a/src/ofxOscPublisher.h +++ b/src/ofxOscPublisher.h @@ -522,19 +522,8 @@ inline ofxOscPublisher &ofxGetOscPublisher(const std::string &ip, int port) { /// \param whenValueIsChanged if this value to false, then we send value every update /// \returns ofxOscPublisherIdentifier -struct explicit_bool { - explicit_bool() = delete; - explicit_bool(bool b) - : b(b) {} - template - explicit_bool(_) = delete; - operator bool() const { return b; }; - bool get() const { return b; }; - bool b; -}; - template -inline ofxOscPublisherIdentifier ofxPublishOsc(const std::string &ip, int port, const std::string &address, ValueOrFunction &&valueOrFunction, explicit_bool whenValueIsChanged = true) +inline ofxOscPublisherIdentifier ofxPublishOsc(const std::string &ip, int port, const std::string &address, ValueOrFunction &&valueOrFunction, bbb::explicit_bool whenValueIsChanged = true) { return ofxGetOscPublisher(ip, port).publish(address, std::forward(valueOrFunction), whenValueIsChanged.get()); } @@ -551,7 +540,7 @@ inline ofxOscPublisherIdentifier ofxPublishOsc(const std::string &ip, int port, /// \returns ofxOscPublisherIdentifier template -inline auto ofxPublishOsc(const std::string &ip, int port, const std::string &address, Object &&obj, Method &&meth, bool whenValueIsChanged = true) +inline auto ofxPublishOsc(const std::string &ip, int port, const std::string &address, Object &&obj, Method &&meth, bbb::explicit_bool whenValueIsChanged = true) -> ofx::PubSubOsc::enable_if_t::value, ofxOscPublisherIdentifier> { return ofxGetOscPublisher(ip, port).publish(address, ofx::PubSubOsc::bind(std::forward(obj), std::forward(meth)), whenValueIsChanged); From 6ed9b33c0ab9fff6f824495e623cb506c9fd3bc3 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Thu, 2 Jun 2016 02:40:36 +0900 Subject: [PATCH 03/30] add ofxSendOsc --- .../ofxOscPublisherSetImplementation.h | 6 +++ src/ofxOscPublisher.h | 46 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/details/Publisher/ofxOscPublisherSetImplementation.h b/src/details/Publisher/ofxOscPublisherSetImplementation.h index 235403a..e613b8e 100644 --- a/src/details/Publisher/ofxOscPublisherSetImplementation.h +++ b/src/details/Publisher/ofxOscPublisherSetImplementation.h @@ -81,6 +81,12 @@ namespace ofx { for(int i = 0; i < v.size(); i++) { set(m, v[i]); } } + template + inline auto set(ofxOscMessage &m, Func f) + -> enable_if_t::value> { + set(m, f()); + } + #pragma mark ofParameter / ofParameterGroup template diff --git a/src/ofxOscPublisher.h b/src/ofxOscPublisher.h index 27de923..736c2e3 100644 --- a/src/ofxOscPublisher.h +++ b/src/ofxOscPublisher.h @@ -393,7 +393,46 @@ namespace ofx { return bUseBundle(); } + ofxOscSender &getSender() { return sender; } + +#pragma mark send + + template + void send(const std::string &address, Args && ... args) { + ofxOscMessage m = createMessage(address, std::forward(args) ...); + sender.sendMessage(m); + } + private: + template + void createMessageImpl(ofxOscMessage &m, Arg &&arg) { + set(m, std::forward(arg)); + } + + template + auto createMessageImpl(ofxOscMessage &m, Arg &&arg, Args && ... args) + -> enable_if_t<0 < sizeof...(Args), void> + { + set(m, std::forward(arg)); + createMessageImpl(m, std::forward(args) ...); + } + + template + auto createMessage(const std::string &address, Args && ... args) + -> enable_if_t<0 < sizeof...(Args), ofxOscMessage> + { + ofxOscMessage m; + m.setAddress(address); + createMessageImpl(m, std::forward(args) ...); + return m; + } + + ofxOscMessage createMessage(const std::string &address) { + ofxOscMessage m; + m.setAddress(address); + return m; + } + Publisher(const Destination &destination) : destination(destination) { sender.setup(destination.ip, destination.port); @@ -706,6 +745,13 @@ inline void ofxUnregisterPublishingOsc() { /// \} +#pragma mark send + +template +void ofxSendOsc(const std::string &ip, int port, const std::string &address, Args && ... args) { + ofxGetOscPublisher(ip, port).send(address, std::forward(args) ...); +} + #pragma mark using bundle option inline void ofxSetPublisherUsingBundle(bool bUseBundle) { From 1575e4b7e98b164ad3e5f8f2074b1ae991568694 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Mon, 5 Sep 2016 14:40:44 +0900 Subject: [PATCH 04/30] update README --- README.md | 63 +++++++++++++++++++++++-------------------------------- 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index baf6fb5..9bcf629 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,10 @@ unregister all the messages sending to _ip:port_. **NOTE**: registable type is same to `ofxPublishOsc`. see [more ofxPublishOsc](API_Reference.md#API_ofxPublishOsc). +### ofxSendOsc + +* void ofxSendOsc(const string &_ip_, int _port_, const string &_address_, Arguments && ... arguments) + ## Supported types * Arithmetic is any type of Int32, Int64 or Float @@ -189,13 +193,30 @@ if you use `vector vec;`, when `vec` will be resized every receiving O **NOTE**: do NOT use `vector>`, `vector[size]` ### Callback -* `T (\*callback)(ofxOscMessage &)`; -* pair of `U &that`, `T (U::\*callback)(ofxOscMessage &)`; -* pair of `U \*that`, `T (U::\*callback)(ofxOscMessage &)`; -* `std::function` + +#### Subscribe + +* `std::function`; +* `std::function` +* pair of `U &that`, `T (U::\*callback)(Arguments ...)`; +* pair of `U \*that`, `T (U::\*callback)(Arguments ...)`; + +`Arguments ...` are all of types we can use in + +#### Publish + +* `std::function`; +* pair of `U &that`, `T (U::\*callback)()`; +* pair of `U \*that`, `T (U::\*callback)()`; ## Update history +### 2016/06/XX ver 0.3.0 + +* refactor all for C++11 +* add `ofxSendOsc` +* ofxSubscribeOsc got more flexible. + ### 2016/01/25 [ver 0.2.2](../../releases/tag/v0_2_2) release * bugfix: about `ofQuaternion`'s `operator>>`, `operator<<` (issued by [musiko](https://github.com/musiko). thanks!!!) @@ -208,39 +229,6 @@ if you use `vector vec;`, when `vec` will be resized every receiving O * update exmaples (xcodeproj) for oF0.9.0 * some cleaning source and doxygen -### 2016/01/02 [ver 0.2.0](../../releases/tag/v0_2_0) release *(this version is broken)* - -* *after this release, we will only test on oF0.9.0~* -* new feature: multi-subscribe, multi-publish - * `ofxSubscribeOsc` returns `ofxSubscriberIdentifier` - * `ofxPublishOsc` returns `ofxPublisherIdentifier` - * TODO: API Reference -* add iterators to [ofxOscSubscriberManager](API_Reference.md#Advanced_ofxOscSubscriberManager) -* add iterators to [ofxOscPublisherManager](API_Reference.md#Advanced_ofxOscPublisherManager) -* add all port operation to ofxUnsubscribeOsc, ofxNotifyToSubscribedOsc, ofxRemoveLeakedOscPicker -* add ofxSetLeakedOscPickerAll -* add ofxSubscribeOsc with `std::initializer_list port` and `std::initializer_list addresses` -* add iterators to [ofxOscPublisherManager](API_Reference.md#Advanced_ofxOscPublisherManager) -* add all port operation to ofxUnpublishOsc, ofxUnregisterPublishingOsc -* add feature publishing r-value. (i.e., you can do `ofxPublishOsc(host, port, "/bar", "value!!")`) -* add `const` to lambda callback (proposed by [satoruhiga](https://github.com/satoruhiga). thanks!!) -* add useful macro `SubscribeOsc(port, name)` is same as `ofxSubscribeOsc(port, "/name", name)` (porposed by [hanasaan](https://github.com/hanasaan). thanks!!) -* add `std::` prefix -* cleaning up conditional macro about oF0.8.x -* some bugfix around lambda -* TODO: update some API Documentations - -### 2016/01/25 [ver 0.1.3](../../releases/tag/v0_1_3) release - -* bugfix: about `ofQuaternion`'s `operator>>`, `operator<<` (issued by [musiko](https://github.com/musiko). thanks!!!) - -### 2016/01/02 [ver 0.1.2](../../releases/tag/v0_1_2) release - -* this is *final update added new feature, with oF0.8.4 support* -* after this release, "ver 0.1.x will only bugfie about supporting oF0.8.4 -* add new feature ofxNotifyToSubscribedOsc (proposed by [satcy](https://github.com/satcy). thanks!!) -* some bugfix - ### [Older update histories](Update_History.md) @@ -268,6 +256,7 @@ MIT License. * [IWATANI Nariaki](https://github.com/nariakiiwatani) * [USAMI Takuto](https://github.com/usm916) * [HORII Satoshi](https://github.com/satcy) +* [Tomoto Yusuke](https://github.com/yusuketomoto) * [HANAI Yuuya](https://github.com/hanasaan) * [musiko](https://github.com/musiko) From 727a1a96ea8d499c14fbef4b08737bcc1e0ca508 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Mon, 5 Sep 2016 14:41:13 +0900 Subject: [PATCH 05/30] add implementation about std::array, std::deque --- .../ofxOscPublisherSetImplementation.h | 15 +++++++++++-- .../ofxOscSubscriberLoadImplementation.h | 22 ++++++++++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/details/Publisher/ofxOscPublisherSetImplementation.h b/src/details/Publisher/ofxOscPublisherSetImplementation.h index e613b8e..497c35c 100644 --- a/src/details/Publisher/ofxOscPublisherSetImplementation.h +++ b/src/details/Publisher/ofxOscPublisherSetImplementation.h @@ -71,13 +71,24 @@ namespace ofx { set(m, v.height); } +#pragma mark containerz + template + inline void set(ofxOscMessage &m, const std::array &v) { + for(int i = 0; i < size; i++) { set(m, v[i]); } + } + template inline void set(ofxOscMessage &m, const U (&v)[size]) { for(int i = 0; i < size; i++) { set(m, v[i]); } } - template - inline void set(ofxOscMessage &m, const std::vector &v) { + template + inline void set(ofxOscMessage &m, const std::vector &v) { + for(int i = 0; i < v.size(); i++) { set(m, v[i]); } + } + + template + inline void set(ofxOscMessage &m, const std::deque &v) { for(int i = 0; i < v.size(); i++) { set(m, v[i]); } } diff --git a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h index 598c276..14798d7 100644 --- a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h +++ b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h @@ -187,7 +187,14 @@ namespace ofx { } } -#pragma mark vector +#pragma mark container + template + inline void load(ofxOscMessage &m, std::array &v, std::size_t offset = 0) { + for(int i = 0; i < min(size, (m.getNumArgs() - offset) / type_traits::size); i++) { + load(m, v[i], offset + i * type_traits::size); + } + } + template inline void load(ofxOscMessage &m, U (&v)[size], std::size_t offset = 0) { for(int i = 0; i < min(size, (m.getNumArgs() - offset) / type_traits::size); i++) { @@ -195,8 +202,17 @@ namespace ofx { } } - template - inline void load(ofxOscMessage &m, std::vector &v, std::size_t offset = 0) { + template + inline void load(ofxOscMessage &m, std::vector &v, std::size_t offset = 0) { + std::size_t num = (m.getNumArgs() - offset) / type_traits::size; + if(v.size() != num) v.resize(num); + for(int i = 0; i < num; i++) { + load(m, v[i], offset + i * type_traits::size); + } + } + + template + inline void load(ofxOscMessage &m, std::deque &v, std::size_t offset = 0) { std::size_t num = (m.getNumArgs() - offset) / type_traits::size; if(v.size() != num) v.resize(num); for(int i = 0; i < num; i++) { From ddbdfd8b68986a8c5106e2b364994455df50a41e Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Mon, 6 Mar 2017 00:19:42 +0900 Subject: [PATCH 06/30] add ofxPublishOscManually --- .../Publisher/ofxOscPublishParameter.h | 24 ++++---- src/ofxOscPublisher.h | 55 +++++++++++++++++++ 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/src/details/Publisher/ofxOscPublishParameter.h b/src/details/Publisher/ofxOscPublishParameter.h index a77fad0..3434b09 100644 --- a/src/details/Publisher/ofxOscPublishParameter.h +++ b/src/details/Publisher/ofxOscPublishParameter.h @@ -23,7 +23,12 @@ namespace ofx { namespace Publish { struct AbstractParameter { AbstractParameter() : condition(new BasicCondition) {} - virtual bool write(ofxOscMessage &m, const std::string &address) = 0; + virtual bool write(ofxOscMessage &m, const std::string &address) { + if(!canPublish() || !isChanged()) return false; + writeForce(m, address); + return true; + } + virtual void writeForce(ofxOscMessage &m, const std::string &address) = 0; void setCondition(ConditionRef ref) { condition = ref; }; inline void setEnablePublish(bool bEnablePublish) { condition->setEnablePublish(bEnablePublish); }; @@ -32,6 +37,7 @@ namespace ofx { bool canPublish() { return condition->getCondition(); } + virtual bool isChanged() { return true; }; private: ConditionRef condition; }; @@ -43,11 +49,9 @@ namespace ofx { Parameter(T &t) : t(t) {} - virtual bool write(ofxOscMessage &m, const std::string &address) { - if(!canPublish() || !isChanged()) return false; + virtual void writeForce(ofxOscMessage &m, const std::string &address) { m.setAddress(address); set(m, get()); - return true; } protected: virtual bool isChanged() { return true; } @@ -79,11 +83,9 @@ namespace ofx { : t(t) { for(std::size_t i = 0; i < size; i++) old[i] = t[i]; } virtual ~Parameter() { }; - virtual bool write(ofxOscMessage &m, const std::string &address) { - if(!canPublish() || !isChanged()) return false; + virtual void writeForce(ofxOscMessage &m, const std::string &address) { m.setAddress(address); set(m, get()); - return true; } protected: @@ -114,11 +116,9 @@ namespace ofx { ConstParameter(const T &t) : t(t) {} - virtual bool write(ofxOscMessage &m, const std::string &address) { - if(!canPublish() || !isChanged()) return false; + virtual void writeForce(ofxOscMessage &m, const std::string &address) { m.setAddress(address); set(m, get()); - return true; } protected: virtual bool isChanged() { return true; } @@ -145,11 +145,9 @@ namespace ofx { ConstParameter(const Base (&t)[size]) : t(t) {} - virtual bool write(ofxOscMessage &m, const std::string &address) { - if(!canPublish() || !isChanged()) return false; + virtual void writeForce(ofxOscMessage &m, const std::string &address) { m.setAddress(address); set(m, get()); - return true; } protected: diff --git a/src/ofxOscPublisher.h b/src/ofxOscPublisher.h index 736c2e3..08a97d3 100644 --- a/src/ofxOscPublisher.h +++ b/src/ofxOscPublisher.h @@ -344,6 +344,45 @@ namespace ofx { registeredTargets.clear(); } + #pragma mark publishManually + + inline void publishManullay(const std::string &address) { + { + Targets::iterator it = registeredTargets.find(address); + if(it != registeredTargets.end()) { + ofxOscMessage m; + for(std::size_t i = 0, size = registeredTargets.count(address); i < size; i++, ++it) { + it->second->writeForce(m, it->first); + sender.sendMessage(m); + m.clear(); + } + } + } + + { + Targets::iterator it = targets.find(address); + if(it != targets.end()) { + ofxOscMessage m; + for(std::size_t i = 0, size = targets.count(address); i < size; i++, ++it) { + it->second->writeForce(m, it->first); + sender.sendMessage(m); + m.clear(); + } + } + } + } + + inline void publishManullay(const PublishIdentifier &identifier) { + if(!identifier.isValid()) return; + Targets::const_iterator it{findPublished(identifier)}; + if(it != targets.end()) { + ofxOscMessage m; + it->second->writeForce(m, it->first); + sender.sendMessage(m); + m.clear(); + } + } + #pragma mark status inline bool isPublished() const { @@ -745,6 +784,22 @@ inline void ofxUnregisterPublishingOsc() { /// \} +#pragma mark publish registered + +/// \name ofxPublishOscManually +/// \{ + +inline void ofxPublishOscManually(const std::string &ip, int port, const std::string &address) { + ofxGetOscPublisher(ip, port).publishManullay(address); +} + +inline void ofxPublishOscManually(const ofxOscPublisherIdentifier &identifier) { + if(!identifier.isValid()) return; + ofxGetOscPublisher(identifier.getKey().ip, identifier.getKey().port).publishManullay(identifier); +} + +/// \} + #pragma mark send template From cef07b1d0a68c3d2a9fa3f8fd2ed1de48f15d1cd Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Mon, 28 Nov 2016 23:27:30 +0900 Subject: [PATCH 07/30] add addon_config.mk --- addon_config.mk | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 addon_config.mk diff --git a/addon_config.mk b/addon_config.mk new file mode 100644 index 0000000..b8ee322 --- /dev/null +++ b/addon_config.mk @@ -0,0 +1,63 @@ +# All variables and this file are optional, if they are not present the PG and the +# makefiles will try to parse the correct values from the file system. +# +# Variables that specify exclusions can use % as a wildcard to specify that anything in +# that position will match. A partial path can also be specified to, for example, exclude +# a whole folder from the parsed paths from the file system +# +# Variables can be specified using = or += +# = will clear the contents of that variable both specified from the file or the ones parsed +# from the file system +# += will add the values to the previous ones in the file or the ones parsed from the file +# system +# +# The PG can be used to detect errors in this file, just create a new project with this addon +# and the PG will write to the console the kind of error and in which line it is + +meta: + ADDON_NAME = ofxPubSubOsc + ADDON_DESCRIPTION = bind OSC messages and values with only writing tiny code on setup once. + ADDON_AUTHOR = ISHII 2bit + ADDON_TAGS = "network" + ADDON_URL = http://github.com/2bbb/ofxPubSubOsc + ADDON_GIT_URL = git://github.com/2bbb/ofxPubSubOsc.git + ADDON_MINIMUM_OF_VERSION = 0.9.0 + +common: + # dependencies with other addons, a list of them separated by spaces + # or use += in several lines + ADDON_DEPENDENCIES = ofxOsc + + # include search paths, this will be usually parsed from the file system + # but if the addon or addon libraries need special search paths they can be + # specified here separated by spaces or one per line using += + # ADDON_INCLUDES = + + # any special flag that should be passed to the compiler when using this + # addon + # ADDON_CFLAGS = + + # any special flag that should be passed to the linker when using this + # addon, also used for system libraries with -lname + # ADDON_LDFLAGS = + + # linux only, any library that should be included in the project using + # pkg-config + # ADDON_PKG_CONFIG_LIBRARIES = + + # osx/iOS only, any framework that should be included in the project + # ADDON_FRAMEWORKS = + + # source files, these will be usually parsed from the file system looking + # in the src folders in libs and the root of the addon. if your addon needs + # to include files in different places or a different set of files per platform + # they can be specified here + # ADDON_SOURCES = + + # some addons need resources to be copied to the bin/data folder of the project + # specify here any files that need to be copied, you can use wildcards like * and ? + # ADDON_DATA = + + # when parsing the file system looking for libraries exclude this for all or + # a specific platform + # ADDON_LIBS_EXCLUDE = From d0ae0f02c794d94dd353c5c169e38fcd4cf7a9fb Mon Sep 17 00:00:00 2001 From: nariakiiwatani Date: Wed, 3 May 2017 23:10:36 +0900 Subject: [PATCH 08/30] decode true/false argument --- src/details/Subscriber/ofxOscSubscriberLoadImplementation.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h index 14798d7..eca8cda 100644 --- a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h +++ b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h @@ -25,6 +25,8 @@ namespace ofx { else if(m.getArgType(offset) == OFXOSC_TYPE_FLOAT) v = m.getArgAsFloat(offset); \ else if(m.getArgType(offset) == OFXOSC_TYPE_DOUBLE) v = m.getArgAsDouble(offset); \ else if(m.getArgType(offset) == OFXOSC_TYPE_STRING) v = ofToDouble(m.getArgAsString(offset)); \ + else if(m.getArgType(offset) == OFXOSC_TYPE_TRUE) v = true; \ + else if(m.getArgType(offset) == OFXOSC_TYPE_FALSE) v = false; \ } define_set_arithmetic(bool); From 1337e329732b58ad9eba425752fa4c16c82e20b4 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Fri, 12 May 2017 10:36:58 +0900 Subject: [PATCH 09/30] add: activate/deactivate subscribe * void ofxSetSubscriberActive(int port, bool bActive) * bool ofxGetSubscriberActive(int port) --- .../Subscriber/ofxOscSubscribeParameter.h | 4 +++ src/ofxOscSubscriber.h | 26 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/details/Subscriber/ofxOscSubscribeParameter.h b/src/details/Subscriber/ofxOscSubscribeParameter.h index 7d13631..5de3dfa 100644 --- a/src/details/Subscriber/ofxOscSubscribeParameter.h +++ b/src/details/Subscriber/ofxOscSubscribeParameter.h @@ -20,6 +20,10 @@ namespace ofx { struct AbstractParameter { virtual void read(ofxOscMessage &message, std::size_t offset = 0) = 0; virtual std::size_t size() const = 0; + void setEnable(bool bEnabled) { this->bEnabled = bEnabled; } + bool isEnabled() const { return bEnabled; } + protected: + bool bEnabled{true}; }; using ParameterRef = std::shared_ptr; diff --git a/src/ofxOscSubscriber.h b/src/ofxOscSubscriber.h index 0ac9825..fb2fbbf 100644 --- a/src/ofxOscSubscriber.h +++ b/src/ofxOscSubscriber.h @@ -251,6 +251,9 @@ namespace ofx { } } + void setEnable(bool bEnabled) { this->bEnabled = bEnabled; } + bool isEnabled() const { return bEnabled; } + using Ref = std::shared_ptr; private: Subscriber(int port) @@ -284,6 +287,7 @@ namespace ofx { Targets targets; ParameterRef leakPicker; std::queue leakedOscMessages; + bool bEnabled{true}; friend class SubscriberManager; }; @@ -302,11 +306,21 @@ namespace ofx { } return *(managers[port].get()); } + + void setEnable(int port, bool bEnabled) { + getOscSubscriber(port).setEnable(bEnabled); + } + + bool isEnabled(int port) const { + return getOscSubscriber(port).isEnabled(); + } private: using Subscribers = std::map; void update(ofEventArgs &args) { for(Subscribers::iterator it = managers.begin(); it != managers.end(); ++it) { - it->second->update(); + if(it->second->isEnabled()) { + it->second->update(); + } } } @@ -509,6 +523,16 @@ inline void ofxNotifyToSubscribedOsc(ofxOscMessage &m) { } } +#pragma mark activate / deactivate listening + +inline void ofxSetSubscriberActive(int port, bool bActive) { + ofxGetOscSubscriber(port).setEnable(bActive); +} + +inline bool ofxGetSubscriberActive(int port) { + return ofxGetOscSubscriber(port).isEnabled(); +} + #pragma mark interface about leaked osc /// \name ofxSetLeakedOscPicker From 4ff12b36549a624594b7c0f79f6b9117e84991fa Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Fri, 12 May 2017 10:38:58 +0900 Subject: [PATCH 10/30] rename: add Osc * void ofxSetOscSubscriberActive(int port, bool bActive); * bool ofxGetOscSubscriberActive(int port); --- src/ofxOscSubscriber.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ofxOscSubscriber.h b/src/ofxOscSubscriber.h index fb2fbbf..55e6bbe 100644 --- a/src/ofxOscSubscriber.h +++ b/src/ofxOscSubscriber.h @@ -525,11 +525,11 @@ inline void ofxNotifyToSubscribedOsc(ofxOscMessage &m) { #pragma mark activate / deactivate listening -inline void ofxSetSubscriberActive(int port, bool bActive) { +inline void ofxSetOscSubscriberActive(int port, bool bActive) { ofxGetOscSubscriber(port).setEnable(bActive); } -inline bool ofxGetSubscriberActive(int port) { +inline bool ofxGetOscSubscriberActive(int port) { return ofxGetOscSubscriber(port).isEnabled(); } From c33d65fc2051029ddf5c3cacfc46b0ecbee77d61 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Sun, 21 May 2017 16:57:39 +0900 Subject: [PATCH 11/30] resolve ambiguous --- src/details/ofxPubSubOscTypeUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/details/ofxPubSubOscTypeUtils.h b/src/details/ofxPubSubOscTypeUtils.h index e2778fd..415d9b0 100644 --- a/src/details/ofxPubSubOscTypeUtils.h +++ b/src/details/ofxPubSubOscTypeUtils.h @@ -43,7 +43,7 @@ namespace ofx { }; template - using remove_const_reference = get_type>; + using remove_const_reference = get_type>; template using remove_ref = get_type>; From 7937e5f6f3725b9ebc99814cd5f6cfa3878af04b Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Sun, 21 May 2017 16:59:59 +0900 Subject: [PATCH 12/30] replace binder test --- src/details/ofxPubSubOscTypeUtils.h | 112 +++++++++++++++------------- 1 file changed, 60 insertions(+), 52 deletions(-) diff --git a/src/details/ofxPubSubOscTypeUtils.h b/src/details/ofxPubSubOscTypeUtils.h index 415d9b0..dec6610 100644 --- a/src/details/ofxPubSubOscTypeUtils.h +++ b/src/details/ofxPubSubOscTypeUtils.h @@ -213,70 +213,78 @@ namespace ofx { #define P(n) std::placeholders:: _##n + template ()> + struct binder; + template - auto bind(obj o, meth m) - -> enable_if_t() == 0, typename function_traits::function_type> { - return std::bind(m, o); - } + struct binder { + using type = typename function_traits::function_type; + type bind(obj o, meth m) { return std::bind(m, o); } + }; template - auto bind(obj o, meth m) - -> enable_if_t() == 1, typename function_traits::function_type> { - return std::bind(m, o, P(1)); - } - + struct binder { + using type = typename function_traits::function_type; + type bind(obj o, meth m) { return std::bind(m, o, P(1)); } + }; + template - auto bind(obj o, meth m) - -> enable_if_t() == 2, typename function_traits::function_type> { - return std::bind(m, o, P(1), P(2)); - } - + struct binder { + using type = typename function_traits::function_type; + type bind(obj o, meth m) { return std::bind(m, o, P(1), P(2)); } + }; + template - auto bind(obj o, meth m) - -> enable_if_t() == 3, typename function_traits::function_type> { - return std::bind(m, o, P(1), P(2), P(3)); - } - + struct binder { + using type = typename function_traits::function_type; + type bind(obj o, meth m) { return std::bind(m, o, P(1), P(2), P(3)); } + }; + template - auto bind(obj o, meth m) - -> enable_if_t() == 4, typename function_traits::function_type> { - return std::bind(m, o, P(1), P(2), P(3), P(4)); - } - + struct binder { + using type = typename function_traits::function_type; + type bind(obj o, meth m) { return std::bind(m, o, P(1), P(2), P(3), P(4)); } + }; + template - auto bind(obj o, meth m) - -> enable_if_t() == 5, typename function_traits::function_type> { - return std::bind(m, o, P(1), P(2), P(3), P(4), P(5)); - } - + struct binder { + using type = typename function_traits::function_type; + type bind(obj o, meth m) { return std::bind(m, o, P(1), P(2), P(3), P(4), P(5)); } + }; + template - auto bind(obj o, meth m) - -> enable_if_t() == 6, typename function_traits::function_type> { - return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6)); - } - + struct binder { + using type = typename function_traits::function_type; + type bind(obj o, meth m) { return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6)); } + }; + template - auto bind(obj o, meth m) - -> enable_if_t() == 7, typename function_traits::function_type> { - return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6), P(7)); - } - + struct binder { + using type = typename function_traits::function_type; + type bind(obj o, meth m) { return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6), P(7)); } + }; + template - auto bind(obj o, meth m) - -> enable_if_t() == 8, typename function_traits::function_type> { - return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6), P(7), P(8)); - } - + struct binder { + using type = typename function_traits::function_type; + type bind(obj o, meth m) { return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6), P(7), P(8)); } + }; + template - auto bind(obj o, meth m) - -> enable_if_t() == 9, typename function_traits::function_type> { - return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6), P(7), P(8), P(9)); - } - + struct binder { + using type = typename function_traits::function_type; + type bind(obj o, meth m) { return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6), P(7), P(8), P(9)); } + }; + + template + struct binder { + using type = typename function_traits::function_type; + type bind(obj o, meth m) { return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6), P(7), P(8), P(9), P(10)); } + }; + template - auto bind(obj o, meth m) - -> enable_if_t() == 10, typename function_traits::function_type> { - return std::bind(m, o, P(1), P(2), P(3), P(4), P(5), P(6), P(7), P(8), P(9), P(10)); + typename binder::type bind(obj o, meth m) { + return binder::bind(o, m); } #undef P From 321c3ac96e1c5c82077ed69f06ca2621e47222b8 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Sun, 21 May 2017 17:04:39 +0900 Subject: [PATCH 13/30] fixed!! --- src/details/ofxPubSubOscTypeUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/details/ofxPubSubOscTypeUtils.h b/src/details/ofxPubSubOscTypeUtils.h index dec6610..d4d8480 100644 --- a/src/details/ofxPubSubOscTypeUtils.h +++ b/src/details/ofxPubSubOscTypeUtils.h @@ -213,7 +213,7 @@ namespace ofx { #define P(n) std::placeholders:: _##n - template ()> + template ()> struct binder; template From f77badf8cb110797ed0b4dbc9a7a222c6f9308b7 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Sun, 21 May 2017 17:13:22 +0900 Subject: [PATCH 14/30] sad mistake... --- src/details/ofxPubSubOscTypeUtils.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/details/ofxPubSubOscTypeUtils.h b/src/details/ofxPubSubOscTypeUtils.h index d4d8480..abd81d3 100644 --- a/src/details/ofxPubSubOscTypeUtils.h +++ b/src/details/ofxPubSubOscTypeUtils.h @@ -342,32 +342,32 @@ namespace ofx { }; -bool operator==(const ofMatrix3x3 &x, const ofMatrix3x3 &y) { +static inline bool operator==(const ofMatrix3x3 &x, const ofMatrix3x3 &y) { return (x.a == y.a) && (x.b == y.b) && (x.c == y.c) && (x.d == y.d) && (x.e == y.e) && (x.f == y.f) && (x.g == y.g) && (x.h == y.h) && (x.i == y.i); } -bool operator!=(const ofMatrix3x3 &x, const ofMatrix3x3 &y) { +static inline bool operator!=(const ofMatrix3x3 &x, const ofMatrix3x3 &y) { return !operator==(x, y); } -bool operator==(const ofMatrix4x4 &x, const ofMatrix4x4 &y) { +static inline bool operator==(const ofMatrix4x4 &x, const ofMatrix4x4 &y) { return (x._mat[0][0] == y._mat[0][0]) && (x._mat[0][1] == y._mat[0][1]) && (x._mat[0][2] == y._mat[0][2]) && (x._mat[0][3] == y._mat[0][3]) && (x._mat[1][0] == y._mat[1][0]) && (x._mat[1][1] == y._mat[1][1]) && (x._mat[1][2] == y._mat[1][2]) && (x._mat[1][3] == y._mat[1][3]) && (x._mat[2][0] == y._mat[2][0]) && (x._mat[2][1] == y._mat[2][1]) && (x._mat[2][2] == y._mat[2][2]) && (x._mat[2][3] == y._mat[2][3]) && (x._mat[3][0] == y._mat[3][0]) && (x._mat[3][1] == y._mat[3][1]) && (x._mat[3][2] == y._mat[3][2]) && (x._mat[3][3] == y._mat[3][3]); } -bool operator!=(const ofMatrix4x4 &x, const ofMatrix4x4 &y) { +static inline bool operator!=(const ofMatrix4x4 &x, const ofMatrix4x4 &y) { return !operator==(x, y); } -bool operator==(const ofBuffer &x, const ofBuffer &y) { +static inline bool operator==(const ofBuffer &x, const ofBuffer &y) { return (x.size() == y.size()) && (memcmp(x.getData(), y.getData(), x.size()) == 0); } -bool operator!=(const ofBuffer &x, const ofBuffer &y) { +static inline bool operator!=(const ofBuffer &x, const ofBuffer &y) { return !operator==(x, y); } From 1c31acb9154f24c17c924bbe5ce37c1247ca3c28 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Sun, 21 May 2017 17:21:26 +0900 Subject: [PATCH 15/30] type of port from int to std::uint16_t --- src/ofxOscPublisher.h | 49 ++++++++++++++++--------------- src/ofxOscSubscriber.h | 66 +++++++++++++++++++++--------------------- 2 files changed, 58 insertions(+), 57 deletions(-) diff --git a/src/ofxOscPublisher.h b/src/ofxOscPublisher.h index 08a97d3..8446e51 100644 --- a/src/ofxOscPublisher.h +++ b/src/ofxOscPublisher.h @@ -512,7 +512,7 @@ namespace ofx { return *sharedInstance; } - static Publisher &getOscPublisher(const std::string &ip, int port) { + static Publisher &getOscPublisher(const std::string &ip, std::uint16_t port) { Publishers &publishers = getSharedInstance().publishers; Destination destination(ip, port); if(publishers.find(destination) == publishers.end()) { @@ -568,7 +568,8 @@ namespace ofx { using ofxOscPublisher = ofx::PubSubOsc::Publish::Publisher; using ofxOscPublisherManager = ofx::PubSubOsc::Publish::PublisherManager; using ofxOscPublisherIdentifier = ofx::PubSubOsc::Publish::PublishIdentifier; - +using ofxOscPublisherDestination = ofx::PubSubOsc::Publish::Destination; + /// \brief get a OscPublisherManager. /// \returns ofxOscPublisherManager @@ -578,10 +579,10 @@ inline ofxOscPublisherManager &ofxGetOscPublisherManager() { /// \brief get a OscPublisher. /// \param ip target ip is typed const std::string & -/// \param port target port is typed int +/// \param port target port is typed std::uint16_t /// \returns ofxOscPublisher binded to ip & port -inline ofxOscPublisher &ofxGetOscPublisher(const std::string &ip, int port) { +inline ofxOscPublisher &ofxGetOscPublisher(const std::string &ip, std::uint16_t port) { return ofxOscPublisherManager::getOscPublisher(ip, port); } @@ -594,14 +595,14 @@ inline ofxOscPublisher &ofxGetOscPublisher(const std::string &ip, int port) { /// If whenValueIsChanged is set to false, then the binded value is sent every frame after App::update. /// template parameter T is suggested by value /// \param ip target ip is typed const std::string & -/// \param port target port is typed int +/// \param port target port is typed std::uint16_t /// \param address osc address is typed const std::string & /// \param value reference of value is typed T & /// \param whenValueIsChanged if this value to false, then we send value every update /// \returns ofxOscPublisherIdentifier template -inline ofxOscPublisherIdentifier ofxPublishOsc(const std::string &ip, int port, const std::string &address, ValueOrFunction &&valueOrFunction, bbb::explicit_bool whenValueIsChanged = true) +inline ofxOscPublisherIdentifier ofxPublishOsc(const std::string &ip, std::uint16_t port, const std::string &address, ValueOrFunction &&valueOrFunction, bbb::explicit_bool whenValueIsChanged = true) { return ofxGetOscPublisher(ip, port).publish(address, std::forward(valueOrFunction), whenValueIsChanged.get()); } @@ -610,7 +611,7 @@ inline ofxOscPublisherIdentifier ofxPublishOsc(const std::string &ip, int port, /// If whenValueIsChanged is set to false, then the binded value is sent every frame after App::update. /// template parameter ObjectPtrOrRef is suggested by that, and Method is suggested by getter. /// \param ip target ip is typed const std::string & -/// \param port target port is typed int +/// \param port target port is typed std::uint16_t /// \param address osc address is typed const std::string & /// \param that this object is typed ObjectPtrOrRef, will bind with next parameter method. is called as (that->*getter)() or (that.*getter)(). /// \param getter this method gives value, is typed T(C::*)() @@ -618,14 +619,14 @@ inline ofxOscPublisherIdentifier ofxPublishOsc(const std::string &ip, int port, /// \returns ofxOscPublisherIdentifier template -inline auto ofxPublishOsc(const std::string &ip, int port, const std::string &address, Object &&obj, Method &&meth, bbb::explicit_bool whenValueIsChanged = true) +inline auto ofxPublishOsc(const std::string &ip, std::uint16_t port, const std::string &address, Object &&obj, Method &&meth, bbb::explicit_bool whenValueIsChanged = true) -> ofx::PubSubOsc::enable_if_t::value, ofxOscPublisherIdentifier> { return ofxGetOscPublisher(ip, port).publish(address, ofx::PubSubOsc::bind(std::forward(obj), std::forward(meth)), whenValueIsChanged); } - + template -inline void ofxPublishOsc(const std::string &ip, const std::initializer_list ports, Args & ... args) { +inline void ofxPublishOsc(const std::string &ip, const std::initializer_list ports, Args & ... args) { for(auto port : ports) { ofxGetOscPublisher(ip, port).publish(args ...); } @@ -663,31 +664,31 @@ inline void ofxPublishOsc(const std::initializer_list -inline ofxOscPublisherIdentifier ofxPublishOscIf(ConditionValueRef &&condition, const std::string &ip, int port, const std::string &address, ValueRefOrGetterFunction &&valueRefOrGetterFunction) { +inline ofxOscPublisherIdentifier ofxPublishOscIf(ConditionValueRef &&condition, const std::string &ip, std::uint16_t port, const std::string &address, ValueRefOrGetterFunction &&valueRefOrGetterFunction) { return ofxGetOscPublisher(ip, port).publishIf(condition, address, valueRefOrGetterFunction); } template -inline ofxOscPublisherIdentifier ofxPublishOscIf(ConditionValueRef &&condition, const std::string &ip, int port, const std::string &address, ObjectPtrOrRef &&that, GetterMethod getter) { +inline ofxOscPublisherIdentifier ofxPublishOscIf(ConditionValueRef &&condition, const std::string &ip, std::uint16_t port, const std::string &address, ObjectPtrOrRef &&that, GetterMethod getter) { return ofxGetOscPublisher(ip, port).publishIf(condition, address, that, getter); } #pragma mark condition is method template -inline ofxOscPublisherIdentifier ofxPublishOscIf(ConditionObjectPtrOrRef &&condition, ConditionMethodReturnsBool method, const std::string &ip, int port, const std::string &address, ValueRefOrFunction &&valueRefOrGetterFunction) { +inline ofxOscPublisherIdentifier ofxPublishOscIf(ConditionObjectPtrOrRef &&condition, ConditionMethodReturnsBool method, const std::string &ip, std::uint16_t port, const std::string &address, ValueRefOrFunction &&valueRefOrGetterFunction) { return ofxGetOscPublisher(ip, port).publishIf(condition, method, address, valueRefOrGetterFunction); } template -inline ofxOscPublisherIdentifier ofxPublishOscIf(ConditionObjectPtrOrRef &&condition, ConditionMethodReturnsBool method, const std::string &ip, int port, const std::string &address, ObjectPtrOrRef &&that, GetterMethod getter) { +inline ofxOscPublisherIdentifier ofxPublishOscIf(ConditionObjectPtrOrRef &&condition, ConditionMethodReturnsBool method, const std::string &ip, std::uint16_t port, const std::string &address, ObjectPtrOrRef &&that, GetterMethod getter) { return ofxGetOscPublisher(ip, port).publishIf(condition, method, address, *that, getter); } @@ -703,11 +704,11 @@ inline void ofxUnpublishOsc(ofxOscPublisherIdentifier &identifier) { ofxGetOscPublisher(identifier.getKey().ip, identifier.getKey().port).unpublish(identifier); } -inline void ofxUnpublishOsc(const std::string &ip, int port, const std::string &address) { +inline void ofxUnpublishOsc(const std::string &ip, std::uint16_t port, const std::string &address) { ofxGetOscPublisher(ip, port).unpublish(address); } -inline void ofxUnpublishOsc(const std::string &ip, int port) { +inline void ofxUnpublishOsc(const std::string &ip, std::uint16_t port) { ofxGetOscPublisher(ip, port).unpublish(); } @@ -728,12 +729,12 @@ inline void ofxUnpublishOsc() { /// \{ template -inline ofxOscPublisherIdentifier ofxRegisterPublishingOsc(const std::string &ip, int port, const std::string &address, ValueOrGetterFunctionType &&valueOrGetterFunction) { +inline ofxOscPublisherIdentifier ofxRegisterPublishingOsc(const std::string &ip, std::uint16_t port, const std::string &address, ValueOrGetterFunctionType &&valueOrGetterFunction) { return ofxGetOscPublisher(ip, port).doRegister(address, valueOrGetterFunction); } template -inline ofxOscPublisherIdentifier ofxRegisterPublishingOsc(const std::string &ip, int port, const std::string &address, ObjectPtrOrRef &&that, GetterMethod &&getter) { +inline ofxOscPublisherIdentifier ofxRegisterPublishingOsc(const std::string &ip, std::uint16_t port, const std::string &address, ObjectPtrOrRef &&that, GetterMethod &&getter) { return ofxGetOscPublisher(ip, port).doRegister(address, that, getter); } @@ -744,7 +745,7 @@ inline ofxOscPublisherIdentifier ofxRegisterPublishingOsc(const std::string &ip, /// \name ofxPublishRegisteredOsc /// \{ -inline void ofxPublishRegisteredOsc(const std::string &ip, int port, const std::string &address) { +inline void ofxPublishRegisteredOsc(const std::string &ip, std::uint16_t port, const std::string &address) { ofxGetOscPublisher(ip, port).publishRegistered(address); } @@ -765,11 +766,11 @@ inline void ofxUnregisterPublishingOsc(ofxOscPublisherIdentifier &identifier) { ofxGetOscPublisher(identifier.getKey().ip, identifier.getKey().port).unregister(identifier); } -inline void ofxUnregisterPublishingOsc(const std::string &ip, int port, const std::string &address) { +inline void ofxUnregisterPublishingOsc(const std::string &ip, std::uint16_t port, const std::string &address) { ofxGetOscPublisher(ip, port).unregister(address); } -inline void ofxUnregisterPublishingOsc(const std::string &ip, int port) { +inline void ofxUnregisterPublishingOsc(const std::string &ip, std::uint16_t port) { ofxGetOscPublisher(ip, port).unregister(); } @@ -789,7 +790,7 @@ inline void ofxUnregisterPublishingOsc() { /// \name ofxPublishOscManually /// \{ -inline void ofxPublishOscManually(const std::string &ip, int port, const std::string &address) { +inline void ofxPublishOscManually(const std::string &ip, std::uint16_t port, const std::string &address) { ofxGetOscPublisher(ip, port).publishManullay(address); } @@ -803,7 +804,7 @@ inline void ofxPublishOscManually(const ofxOscPublisherIdentifier &identifier) { #pragma mark send template -void ofxSendOsc(const std::string &ip, int port, const std::string &address, Args && ... args) { +void ofxSendOsc(const std::string &ip, std::uint16_t port, const std::string &address, Args && ... args) { ofxGetOscPublisher(ip, port).send(address, std::forward(args) ...); } diff --git a/src/ofxOscSubscriber.h b/src/ofxOscSubscriber.h index 55e6bbe..5000806 100644 --- a/src/ofxOscSubscriber.h +++ b/src/ofxOscSubscriber.h @@ -27,7 +27,7 @@ namespace ofx { class SubscribeIdentifier { std::string address; ParameterRef ref; - int key; + std::uint16_t key; void invalidate() { address = ""; @@ -36,7 +36,7 @@ namespace ofx { } public: SubscribeIdentifier() : address(""), ref(nullptr) {} - SubscribeIdentifier(const std::string &address, const ParameterRef &ref, int key) + SubscribeIdentifier(const std::string &address, const ParameterRef &ref, std::uint16_t key) : address(address) , ref(ref) , key(key) {} @@ -47,7 +47,7 @@ namespace ofx { SubscribeIdentifier &operator=(const SubscribeIdentifier &) = default; SubscribeIdentifier &operator=(SubscribeIdentifier &&) = default; - const int getKey() const { return key; }; + const std::uint16_t getKey() const { return key; }; bool isValid() const { return static_cast(ref); } friend class Subscriber; @@ -256,7 +256,7 @@ namespace ofx { using Ref = std::shared_ptr; private: - Subscriber(int port) + Subscriber(std::uint16_t port) : port(port) { receiver.setup(port); } @@ -282,7 +282,7 @@ namespace ofx { } } - int port; + std::uint16_t port; ofxOscReceiver receiver; Targets targets; ParameterRef leakPicker; @@ -299,7 +299,7 @@ namespace ofx { return *sharedInstance; } - static Subscriber &getOscSubscriber(int port) { + static Subscriber &getOscSubscriber(std::uint16_t port) { Subscribers &managers = getSharedInstance().managers; if(managers.find(port) == managers.end()) { managers.insert(std::make_pair(port, Subscriber::Ref(new Subscriber(port)))); @@ -307,15 +307,15 @@ namespace ofx { return *(managers[port].get()); } - void setEnable(int port, bool bEnabled) { + void setEnable(std::uint16_t port, bool bEnabled) { getOscSubscriber(port).setEnable(bEnabled); } - bool isEnabled(int port) const { + bool isEnabled(std::uint16_t port) const { return getOscSubscriber(port).isEnabled(); } private: - using Subscribers = std::map; + using Subscribers = std::map; void update(ofEventArgs &args) { for(Subscribers::iterator it = managers.begin(); it != managers.end(); ++it) { if(it->second->isEnabled()) { @@ -372,10 +372,10 @@ inline ofxOscSubscriberManager &ofxGetOscSubscriberManager() { } /// \brief get a OscSubscriber. -/// \param port binded port is typed int +/// \param port binded port is typed std::uint16_t /// \returns ofxOscSubscriber binded to port -inline ofxOscSubscriber &ofxGetOscSubscriber(int port) { +inline ofxOscSubscriber &ofxGetOscSubscriber(std::uint16_t port) { return ofxOscSubscriberManager::getOscSubscriber(port); } @@ -385,7 +385,7 @@ inline ofxOscSubscriber &ofxGetOscSubscriber(int port) { /// \{ /// \brief bind a referece of value to the argument(s) of OSC messages with an address pattern _address_ incoming to _port_. -/// \param port binded port is typed int +/// \param port binded port is typed std::uint16_t /// \param address osc address is typed const std::string & /// \param value reference of value is typed T & /// \returns ofxOscSubscriberIdentifier @@ -393,14 +393,14 @@ inline ofxOscSubscriber &ofxGetOscSubscriber(int port) { #pragma mark reference template -inline auto ofxSubscribeOsc(int port, const std::string &address, T &value) +inline auto ofxSubscribeOsc(std::uint16_t port, const std::string &address, T &value) -> ofx::PubSubOsc::enable_if_t::value, ofxOscSubscriberIdentifier> { return ofxGetOscSubscriber(port).subscribe(address, value); } template -inline auto ofxSubscribeOsc(int port, const std::string &address, T callback) +inline auto ofxSubscribeOsc(std::uint16_t port, const std::string &address, T callback) -> ofx::PubSubOsc::enable_if_t::value, ofxOscSubscriberIdentifier> { return ofxGetOscSubscriber(port).subscribe(address, ofx::PubSubOsc::function_traits::cast(callback)); @@ -409,18 +409,18 @@ inline auto ofxSubscribeOsc(int port, const std::string &address, T callback) #pragma mark setter function/method /// \brief bind a callback to the OSC messages with an address pattern _address_ incoming to _port_. -/// \param port binded port is typed int +/// \param port binded port is typed std::uint16_t /// \param address osc address is typed const std::string & /// \param callback is kicked when receive a message to address /// \returns ofxOscSubscriberIdentifier template -inline ofxOscSubscriberIdentifier ofxSubscribeOsc(int port, const std::string &address, std::function callback) { +inline ofxOscSubscriberIdentifier ofxSubscribeOsc(std::uint16_t port, const std::string &address, std::function callback) { return ofxGetOscSubscriber(port).subscribe(address, callback); } template -inline auto ofxSubscribeOsc(int port, const std::string &address, Obj &&obj, Meth &&meth) +inline auto ofxSubscribeOsc(std::uint16_t port, const std::string &address, Obj &&obj, Meth &&meth) -> ofx::PubSubOsc::enable_if_t::value, ofxOscSubscriberIdentifier> { return ofxGetOscSubscriber(port).subscribe(address, ofx::PubSubOsc::bind(std::forward(obj), @@ -428,7 +428,7 @@ inline auto ofxSubscribeOsc(int port, const std::string &address, Obj &&obj, Met } template -inline auto ofxSubscribeOsc(int port, const std::string &address, T &&t, U &&u, Ts && ... values) +inline auto ofxSubscribeOsc(std::uint16_t port, const std::string &address, T &&t, U &&u, Ts && ... values) -> ofx::PubSubOsc::enable_if_t::value, ofxOscSubscriberIdentifier> { return ofxGetOscSubscriber(port).subscribe(address, std::forward(t), std::forward(u), std::forward(values) ...); @@ -437,14 +437,14 @@ inline auto ofxSubscribeOsc(int port, const std::string &address, T &&t, U &&u, #pragma mark subscribe multiple port at once template -inline void ofxSubscribeOsc(const std::initializer_list &ports, const std::string &address, Args & ... args) { +inline void ofxSubscribeOsc(const std::initializer_list &ports, const std::string &address, Args & ... args) { for(auto &port : ports) { ofxSubscribeOsc(port, address, args ...); } } template -inline void ofxSubscribeOsc(int port, const std::initializer_list &addresses, Args & ... args) { +inline void ofxSubscribeOsc(std::uint16_t port, const std::initializer_list &addresses, Args & ... args) { auto &subscriber = ofxGetOscSubscriber(port); for(auto &address : addresses) { subscriber.subscribe(address, args ...); @@ -452,7 +452,7 @@ inline void ofxSubscribeOsc(int port, const std::initializer_list -inline void ofxSubscribeOsc(const std::initializer_list &ports, const std::initializer_list &addresses, Args & ... args) { +inline void ofxSubscribeOsc(const std::initializer_list &ports, const std::initializer_list &addresses, Args & ... args) { for(auto &port : ports) { ofxSubscribeOsc(port, addresses, args ...); } @@ -474,19 +474,19 @@ inline void ofxUnsubscribeOsc(ofxOscSubscriberIdentifier &identifier) { /// \brief unbind from OSC messages with an address pattern _address_ incoming to _port_. -/// \param port binded port is typed int +/// \param port binded port is typed std::uint16_t /// \param address osc address is typed const std::string & /// \returns void -inline void ofxUnsubscribeOsc(int port, const std::string &address) { +inline void ofxUnsubscribeOsc(std::uint16_t port, const std::string &address) { ofxGetOscSubscriber(port).unsubscribe(address); } /// \brief unbind from OSC messages with any address patterns incoming to _port_. -/// \param port binded port is typed int +/// \param port binded port is typed std::uint16_t /// \returns void -inline void ofxUnsubscribeOsc(int port) { +inline void ofxUnsubscribeOsc(std::uint16_t port) { ofxGetOscSubscriber(port).unsubscribe(); } @@ -510,7 +510,7 @@ inline void ofxNotifyToSubscribedOsc(ofxOscSubscriberIdentifier &identifier, ofx ofxGetOscSubscriber(identifier.getKey()).notify(m); } -inline void ofxNotifyToSubscribedOsc(int port, ofxOscMessage &m) { +inline void ofxNotifyToSubscribedOsc(std::uint16_t port, ofxOscMessage &m) { ofxGetOscSubscriber(port).notify(m); } @@ -525,11 +525,11 @@ inline void ofxNotifyToSubscribedOsc(ofxOscMessage &m) { #pragma mark activate / deactivate listening -inline void ofxSetOscSubscriberActive(int port, bool bActive) { +inline void ofxSetOscSubscriberActive(std::uint16_t port, bool bActive) { ofxGetOscSubscriber(port).setEnable(bActive); } -inline bool ofxGetOscSubscriberActive(int port) { +inline bool ofxGetOscSubscriberActive(std::uint16_t port) { return ofxGetOscSubscriber(port).isEnabled(); } @@ -539,17 +539,17 @@ inline bool ofxGetOscSubscriberActive(int port) { /// \{ /// \brief bind a callback to the OSC messages with are not match other patterns incoming to port. -/// \param port binded port is typed int +/// \param port binded port is typed std::uint16_t /// \callback is kicked when receive a leaked addresses /// \returns void template -inline void ofxSetLeakedOscPicker(int port, Callback callback) { +inline void ofxSetLeakedOscPicker(std::uint16_t port, Callback callback) { ofxGetOscSubscriber(port).setLeakPicker(callback); } template -inline void ofxSetLeakedOscPicker(int port, Obj obj, Meth meth) { +inline void ofxSetLeakedOscPicker(std::uint16_t port, Obj obj, Meth meth) { ofxGetOscSubscriber(port).setLeakPicker(ofx::PubSubOsc::bind(obj, meth)); } @@ -570,10 +570,10 @@ inline void ofxSetLeakedOscPickerAll(Obj obj, Meth meth) { #pragma mark remove leaked osc picker(s) /// \brief remove a callback receives messages has leaked patterns incoming to port. -/// \param port binded port is typed int +/// \param port binded port is typed std::uint16_t /// \returns void -inline void ofxRemoveLeakedOscPicker(int port) { +inline void ofxRemoveLeakedOscPicker(std::uint16_t port) { ofxGetOscSubscriber(port).removeLeakPicker(); } From c7b2b4cacf04bb5db1a2fb99872800fd12019a05 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Sun, 21 May 2017 17:22:35 +0900 Subject: [PATCH 16/30] update README --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 9bcf629..2b86d81 100644 --- a/README.md +++ b/README.md @@ -263,4 +263,9 @@ MIT License. ## At the last Please create a new issue if there is a problem. + And please throw a pull request if you have a cool idea!! + +If you get happy with using this addon, and you're rich, please donation for support continuous development. + +Bitcoin: `386iAzZ7m99sMyUQjM7TrZg1Uft518zpgv` From bdd39a354211322f1ab0ee8f8b3261eff01746eb Mon Sep 17 00:00:00 2001 From: micuat Date: Sun, 21 May 2017 16:03:14 -0400 Subject: [PATCH 17/30] add namespace to other ambiguous "detail"s --- src/details/ofxPubSubOscTypeUtils.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/details/ofxPubSubOscTypeUtils.h b/src/details/ofxPubSubOscTypeUtils.h index abd81d3..45bacbd 100644 --- a/src/details/ofxPubSubOscTypeUtils.h +++ b/src/details/ofxPubSubOscTypeUtils.h @@ -121,27 +121,27 @@ namespace ofx { template struct function_traits - : detail::function_traits {}; + : PubSubOsc::detail::function_traits {}; template struct function_traits - : detail::function_traits {}; + : PubSubOsc::detail::function_traits {}; template struct function_traits - : detail::function_traits {}; + : PubSubOsc::detail::function_traits {}; template struct function_traits - : detail::function_traits {}; + : PubSubOsc::detail::function_traits {}; template struct function_traits - : detail::function_traits {}; + : PubSubOsc::detail::function_traits {}; template struct function_traits> - : detail::function_traits {}; + : PubSubOsc::detail::function_traits {}; template using result_type = typename function_traits::result_type; From fc0f6f8b72bb86fc00b11cdf6a7c203c8021f51d Mon Sep 17 00:00:00 2001 From: micuat Date: Sun, 21 May 2017 16:22:09 -0400 Subject: [PATCH 18/30] add namespace to help compiler find load(...) --- src/details/Subscriber/ofxOscSubscribeParameter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/details/Subscriber/ofxOscSubscribeParameter.h b/src/details/Subscriber/ofxOscSubscribeParameter.h index 5de3dfa..c51d4cb 100644 --- a/src/details/Subscriber/ofxOscSubscribeParameter.h +++ b/src/details/Subscriber/ofxOscSubscribeParameter.h @@ -32,7 +32,7 @@ namespace ofx { struct Parameter : AbstractParameter, type_traits { Parameter(T &t) : t(t) {} virtual void read(ofxOscMessage &message, std::size_t offset = 0) override - { load(message, t, offset); } + { PubSubOsc::load(message, t, offset); } virtual std::size_t size() const override { return type_traits::size; }; private: From 6de6c934fa444a1790fc66608d52f099af1f102c Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Fri, 22 Dec 2017 15:13:52 +0900 Subject: [PATCH 19/30] bugfix about unpublish issue #34 --- src/ofxOscPublisher.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ofxOscPublisher.h b/src/ofxOscPublisher.h index 8446e51..5b679e2 100644 --- a/src/ofxOscPublisher.h +++ b/src/ofxOscPublisher.h @@ -225,7 +225,7 @@ namespace ofx { #pragma mark unpublish void unpublish(const std::string &address) { - if(targets.find(address) == targets.end()) targets.erase(address); + if(targets.find(address) != targets.end()) targets.erase(address); } void unpublish(PublishIdentifier &identifier) { From 827928b84114616d53ab842d4a8cdf29012280fc Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Mon, 30 Apr 2018 06:46:41 +0900 Subject: [PATCH 20/30] a little fix, add ofxOscMessageEx --- .../Subscriber/ofxOscSubscribeParameter.h | 37 ++-- .../ofxOscSubscriberLoadImplementation.h | 53 +++--- src/details/ofxPubSubOscTypeTraits.h | 9 +- src/details/ofxPubSubOscTypeUtils.h | 16 +- src/ofxOscMessageEx.h | 166 ++++++++++++++++++ src/ofxOscSubscriber.h | 24 +-- 6 files changed, 251 insertions(+), 54 deletions(-) create mode 100644 src/ofxOscMessageEx.h diff --git a/src/details/Subscriber/ofxOscSubscribeParameter.h b/src/details/Subscriber/ofxOscSubscribeParameter.h index 5de3dfa..d178f45 100644 --- a/src/details/Subscriber/ofxOscSubscribeParameter.h +++ b/src/details/Subscriber/ofxOscSubscribeParameter.h @@ -12,13 +12,14 @@ #define ofxOscSubscribeParameter_h #include "ofxOscMessage.h" +#include "ofxOscMessageEx.h" #include "ofxOscSubscriberLoadImplementation.h" namespace ofx { namespace PubSubOsc { namespace Subscribe { struct AbstractParameter { - virtual void read(ofxOscMessage &message, std::size_t offset = 0) = 0; + virtual void read(ofxOscMessageEx &message, std::size_t offset = 0) = 0; virtual std::size_t size() const = 0; void setEnable(bool bEnabled) { this->bEnabled = bEnabled; } bool isEnabled() const { return bEnabled; } @@ -31,7 +32,7 @@ namespace ofx { template struct Parameter : AbstractParameter, type_traits { Parameter(T &t) : t(t) {} - virtual void read(ofxOscMessage &message, std::size_t offset = 0) override + virtual void read(ofxOscMessageEx &message, std::size_t offset = 0) override { load(message, t, offset); } virtual std::size_t size() const override { return type_traits::size; }; @@ -43,7 +44,7 @@ namespace ofx { template struct TupleParameter : AbstractParameter, type_traits> { TupleParameter(std::vector &&t) : t(std::move(t)) {} - virtual void read(ofxOscMessage &message, std::size_t offset = 0) override + virtual void read(ofxOscMessageEx &message, std::size_t offset = 0) override { load(message, t, offset); } virtual std::size_t size() const override { return type_traits>::size; }; @@ -55,7 +56,7 @@ namespace ofx { namespace detail { template void read_to_tuple(index_sequence &&, - ofxOscMessage &m, + ofxOscMessageEx &m, std::tuple &t, std::size_t offset) { std::size_t o{0}; @@ -63,7 +64,7 @@ namespace ofx { } template - void read_to_tuple(ofxOscMessage &m, std::tuple &t, std::size_t offset) { + void read_to_tuple(ofxOscMessageEx &m, std::tuple &t, std::size_t offset) { read_to_tuple(index_sequence_for(), m, t, offset); } }; @@ -73,7 +74,7 @@ namespace ofx { using Setter = std::function; SetterFunctionParameter(Setter setter) : setter(setter) {}; - virtual void read(ofxOscMessage &message, std::size_t offset = 0) override { + virtual void read(ofxOscMessageEx &message, std::size_t offset = 0) override { std::tuple ...> t; Subscribe::detail::read_to_tuple ...>(message, t, offset); apply(setter, t); @@ -84,12 +85,26 @@ namespace ofx { Setter setter; }; + template + struct SetterFunctionParameter : AbstractParameter, type_traits { + using Setter = std::function; + SetterFunctionParameter(Setter setter) : setter(setter) {}; + + virtual void read(ofxOscMessageEx &message, std::size_t offset = 0) override { + setter(message); + } + virtual std::size_t size() const override { return type_traits::size; }; + + private: + Setter setter; + }; + template struct SetterFunctionParameter : AbstractParameter, type_traits { using Setter = std::function; SetterFunctionParameter(Setter setter) : setter(setter) {}; - virtual void read(ofxOscMessage &message, std::size_t offset = 0) override { + virtual void read(ofxOscMessageEx &message, std::size_t offset = 0) override { setter(message); } virtual std::size_t size() const override { return type_traits::size; }; @@ -103,7 +118,7 @@ namespace ofx { using Setter = std::function; SetterFunctionParameter(Setter setter) : setter(setter) {}; - virtual void read(ofxOscMessage &message, std::size_t offset = 0) override { + virtual void read(ofxOscMessageEx &message, std::size_t offset = 0) override { std::tuple t; Subscribe::detail::read_to_tuple(message, t, offset); apply(setter, t); @@ -119,7 +134,7 @@ namespace ofx { using Setter = std::function; SetterFunctionParameter(Setter setter) : setter(setter) {}; - virtual void read(ofxOscMessage &message, std::size_t offset = 0) override { + virtual void read(ofxOscMessageEx &message, std::size_t offset = 0) override { setter(); } virtual std::size_t size() const override { return type_traits::size; }; @@ -130,11 +145,11 @@ namespace ofx { #pragma mark load for ParameterRef - inline void load(ofxOscMessage &m, ParameterRef &ref, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ParameterRef &ref, std::size_t offset = 0) { ref->read(m, offset); } - inline void load(ofxOscMessage &m, std::vector &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, std::vector &v, std::size_t offset = 0) { std::size_t o = 0; for(int i = 0; i < v.size(); i++) { if(m.getNumArgs() < offset + o + v[i]->size()) { diff --git a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h index eca8cda..7e7c2a8 100644 --- a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h +++ b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h @@ -10,7 +10,7 @@ #ifndef ofxOscSubscriberLoadImplementation_h #define ofxOscSubscriberLoadImplementation_h -#include "ofxOscMessage.h" +#include "ofxOscMessageEx.h" #include "ofxPubSubOscSettings.h" #include "ofxPubSubOscTypeUtils.h" @@ -19,7 +19,7 @@ namespace ofx { namespace PubSubOsc { #define define_set_arithmetic(type) \ - inline void load(ofxOscMessage &m, type &v, std::size_t offset = 0) { \ + inline void load(ofxOscMessageEx &m, type &v, std::size_t offset = 0) { \ if(m.getArgType(offset) == OFXOSC_TYPE_INT32) v = m.getArgAsInt32(offset); \ else if(m.getArgType(offset) == OFXOSC_TYPE_INT64) v = m.getArgAsInt64(offset); \ else if(m.getArgType(offset) == OFXOSC_TYPE_FLOAT) v = m.getArgAsFloat(offset); \ @@ -45,7 +45,7 @@ namespace ofx { define_set_arithmetic(double); #undef define_set_arithmetic - inline void load(ofxOscMessage &m, std::string &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, std::string &v, std::size_t offset = 0) { if(m.getArgType(offset) == OFXOSC_TYPE_STRING) v = m.getArgAsString(offset); else if(m.getArgType(offset) == OFXOSC_TYPE_FLOAT) v = ofToString(m.getArgAsFloat(offset)); else if(m.getArgType(offset) == OFXOSC_TYPE_DOUBLE) v = ofToString(m.getArgAsDouble(offset)); @@ -54,13 +54,20 @@ namespace ofx { else v = m.getArgAsString(offset); } - inline void load(ofxOscMessage &m, ofBuffer &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ofBuffer &v, std::size_t offset = 0) { v = m.getArgAsBlob(offset); } + inline void load(ofxOscMessageEx &m, ofxOscMessage &v, std::size_t offset = 0) { + v = m; + } + inline void load(ofxOscMessageEx &m, ofxOscMessageEx &v, std::size_t offset = 0) { + v = m; + } + #pragma mark ofColor_ template - inline void loadColor(ofxOscMessage &m, ofColor_ &v, U defaultValue, std::size_t offset = 0) { + inline void loadColor(ofxOscMessageEx &m, ofColor_ &v, U defaultValue, std::size_t offset = 0) { if(m.getNumArgs() == 1) { load(m, v.r, offset); load(m, v.g, offset); @@ -79,47 +86,47 @@ namespace ofx { } } - inline void load(ofxOscMessage &m, ofColor &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ofColor &v, std::size_t offset = 0) { loadColor(m, v, 255, offset); } - inline void load(ofxOscMessage &m, ofShortColor &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ofShortColor &v, std::size_t offset = 0) { loadColor(m, v, 65535, offset); } - inline void load(ofxOscMessage &m, ofFloatColor &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ofFloatColor &v, std::size_t offset = 0) { loadColor(m, v, 1.0f, offset); } #pragma mark oF container type template - inline void loadVec(ofxOscMessage &m, U &v, std::size_t offset = 0) { + inline void loadVec(ofxOscMessageEx &m, U &v, std::size_t offset = 0) { for(int i = 0; i < min(static_cast(m.getNumArgs() - offset), n); i++) { load(m, v[i], offset + i); } } - inline void load(ofxOscMessage &m, ofVec2f &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ofVec2f &v, std::size_t offset = 0) { loadVec<2>(m, v, offset); } - inline void load(ofxOscMessage &m, ofVec3f &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ofVec3f &v, std::size_t offset = 0) { loadVec<3>(m, v, offset); } - inline void load(ofxOscMessage &m, ofVec4f &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ofVec4f &v, std::size_t offset = 0) { loadVec<4>(m, v, offset); } - inline void load(ofxOscMessage &m, ofQuaternion &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ofQuaternion &v, std::size_t offset = 0) { loadVec<4>(m, v, offset); } - inline void load(ofxOscMessage &m, ofMatrix3x3 &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ofMatrix3x3 &v, std::size_t offset = 0) { loadVec<9>(m, v, offset); } - inline void load(ofxOscMessage &m, ofMatrix4x4 &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ofMatrix4x4 &v, std::size_t offset = 0) { for(int j = 0; j < 4; j++) for(int i = 0; i < 4; i++) { load(m, v(i, j), offset + 4 * j + i); } } - inline void load(ofxOscMessage &m, ofRectangle &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ofRectangle &v, std::size_t offset = 0) { load(m, v.x, offset + 0); load(m, v.y, offset + 1); load(m, v.width, offset + 2); @@ -129,13 +136,13 @@ namespace ofx { #pragma mark ofParameter / ofParameterGroup template - inline void load(ofxOscMessage &m, ofParameter &p, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ofParameter &p, std::size_t offset = 0) { U u; load(m, u, offset); p.set(u); } - inline void load(ofxOscMessage &m, ofAbstractParameter &p, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ofAbstractParameter &p, std::size_t offset = 0) { #define type_convert(type_) if(p.type() == typeid(ofParameter).name()) { load(m, p.cast(), offset); return; } type_convert(float); type_convert(double); @@ -167,7 +174,7 @@ namespace ofx { #undef type_convert } - inline void load(ofxOscMessage &m, ofParameterGroup &pg, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, ofParameterGroup &pg, std::size_t offset = 0) { if(m.getArgType(0) == OFXOSC_TYPE_INT32) { if(pg.size() <= m.getArgAsInt32(0)) { ofLogWarning("ofxOscSubscriber") << "ofAbstractParameterGroup: not contain index \"" << m.getArgAsInt32(0) << "\""; @@ -191,21 +198,21 @@ namespace ofx { #pragma mark container template - inline void load(ofxOscMessage &m, std::array &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, std::array &v, std::size_t offset = 0) { for(int i = 0; i < min(size, (m.getNumArgs() - offset) / type_traits::size); i++) { load(m, v[i], offset + i * type_traits::size); } } template - inline void load(ofxOscMessage &m, U (&v)[size], std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, U (&v)[size], std::size_t offset = 0) { for(int i = 0; i < min(size, (m.getNumArgs() - offset) / type_traits::size); i++) { load(m, v[i], offset + i * type_traits::size); } } template - inline void load(ofxOscMessage &m, std::vector &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, std::vector &v, std::size_t offset = 0) { std::size_t num = (m.getNumArgs() - offset) / type_traits::size; if(v.size() != num) v.resize(num); for(int i = 0; i < num; i++) { @@ -214,7 +221,7 @@ namespace ofx { } template - inline void load(ofxOscMessage &m, std::deque &v, std::size_t offset = 0) { + inline void load(ofxOscMessageEx &m, std::deque &v, std::size_t offset = 0) { std::size_t num = (m.getNumArgs() - offset) / type_traits::size; if(v.size() != num) v.resize(num); for(int i = 0; i < num; i++) { diff --git a/src/details/ofxPubSubOscTypeTraits.h b/src/details/ofxPubSubOscTypeTraits.h index 76bf34e..bb39b27 100644 --- a/src/details/ofxPubSubOscTypeTraits.h +++ b/src/details/ofxPubSubOscTypeTraits.h @@ -14,7 +14,7 @@ #include "ofVectorMath.h" #include "ofFileUtils.h" -#include "ofxOscMessage.h" +#include "ofxOscMessageEx.h" #include "ofxOscArrayPublisher.h" @@ -41,6 +41,13 @@ namespace ofx { static constexpr bool has_array_operator = false; }; + template <> + struct type_traits { + using inner_type = ofxOscMessageEx; + static constexpr std::size_t size = 0; + static constexpr bool has_array_operator = false; + }; + namespace detail { template struct size_sum { diff --git a/src/details/ofxPubSubOscTypeUtils.h b/src/details/ofxPubSubOscTypeUtils.h index abd81d3..220f3e5 100644 --- a/src/details/ofxPubSubOscTypeUtils.h +++ b/src/details/ofxPubSubOscTypeUtils.h @@ -121,27 +121,27 @@ namespace ofx { template struct function_traits - : detail::function_traits {}; + : PubSubOsc::detail::function_traits {}; template struct function_traits - : detail::function_traits {}; + : PubSubOsc::detail::function_traits {}; template struct function_traits - : detail::function_traits {}; + : PubSubOsc::detail::function_traits {}; template struct function_traits - : detail::function_traits {}; + : PubSubOsc::detail::function_traits {}; template struct function_traits - : detail::function_traits {}; + : PubSubOsc::detail::function_traits {}; template struct function_traits> - : detail::function_traits {}; + : PubSubOsc::detail::function_traits {}; template using result_type = typename function_traits::result_type; @@ -310,7 +310,7 @@ namespace ofx { }; template - using make_integer_sequence = get_type>; + using make_integer_sequence = get_type>; template using index_sequence = integer_sequence; @@ -382,7 +382,7 @@ namespace bbb { : b(b) {} template explicit_bool(_) = delete; - bool &operator=(bool b) { this->b = b; } + bool &operator=(bool b) { return this->b = b; ; } operator bool&() { return b; }; operator bool() const { return b; }; diff --git a/src/ofxOscMessageEx.h b/src/ofxOscMessageEx.h new file mode 100644 index 0000000..f040797 --- /dev/null +++ b/src/ofxOscMessageEx.h @@ -0,0 +1,166 @@ +// +// ofxOscMessageEx.h +// +// Created by ISHII 2bit on 2018/01/28. +// + +#ifndef ofxOscMessageEx_h +#define ofxOscMessageEx_h + +#include + +#include "ofxOscMessage.h" + +namespace ofx { + struct OscMessageEx : public ofxOscMessage { + struct OscArgConverter { + OscArgConverter(const OscMessageEx &m, std::size_t index) + : m(m) + , index(index) + {}; + + template + inline operator type() const { return as(); } + + template + auto as() const + -> typename std::enable_if::value, type>::type + { + switch(m.getArgType(index)) { + case OFXOSC_TYPE_INT32: return m.getArgAsInt32(index); + case OFXOSC_TYPE_INT64: return m.getArgAsInt64(index); + case OFXOSC_TYPE_FLOAT: return m.getArgAsFloat(index); + case OFXOSC_TYPE_DOUBLE: return m.getArgAsDouble(index); + case OFXOSC_TYPE_CHAR: return m.getArgAsChar(index); + case OFXOSC_TYPE_STRING: return std::stoll(m.getArgAsString(index)); + case OFXOSC_TYPE_SYMBOL: return std::stoll(m.getArgAsSymbol(index)); + case OFXOSC_TYPE_TRUE: return true; + case OFXOSC_TYPE_FALSE: return false; + default: { + ofLogWarning("ofxOscMessageEx::OscArgConverer") << "can't convert from " << m.getArgTypeName(index) << " to " << typeid(type).name(); + return type(); + } + } + }; + + template + auto as() const + -> typename std::enable_if::value, type>::type + { + switch(m.getArgType(index)) { + case OFXOSC_TYPE_INT32: return m.getArgAsInt32(index); + case OFXOSC_TYPE_INT64: return m.getArgAsInt64(index); + case OFXOSC_TYPE_FLOAT: return m.getArgAsFloat(index); + case OFXOSC_TYPE_DOUBLE: return m.getArgAsDouble(index); + case OFXOSC_TYPE_CHAR: return m.getArgAsChar(index); + case OFXOSC_TYPE_STRING: return std::stod(m.getArgAsString(index)); + case OFXOSC_TYPE_SYMBOL: return std::stod(m.getArgAsSymbol(index)); + case OFXOSC_TYPE_TRUE: return true; + case OFXOSC_TYPE_FALSE: return false; + default: { + ofLogWarning("ofxOscMessageEx::OscArgConverer") << "can't convert from " << m.getArgTypeName(index) << " to " << typeid(type).name(); + return type(); + } + } + }; + + template + auto as() const + -> typename std::enable_if::value, type>::type + { + switch(m.getArgType(index)) { + case OFXOSC_TYPE_INT32: return std::to_string(m.getArgAsInt32(index)); + case OFXOSC_TYPE_INT64: return std::to_string(m.getArgAsInt64(index)); + case OFXOSC_TYPE_FLOAT: return std::to_string(m.getArgAsFloat(index)); + case OFXOSC_TYPE_DOUBLE: return std::to_string(m.getArgAsDouble(index)); + case OFXOSC_TYPE_CHAR: return std::to_string(m.getArgAsChar(index)); + case OFXOSC_TYPE_STRING: return m.getArgAsString(index); + case OFXOSC_TYPE_SYMBOL: return m.getArgAsSymbol(index); + case OFXOSC_TYPE_TRUE: return "true"; + case OFXOSC_TYPE_FALSE: return "false"; + default: { + ofLogWarning("ofxOscMessageEx::OscArgConverer") << "can't convert from " << m.getArgTypeName(index) << " to std::string"; + return {}; + } + } + } + private: + const OscMessageEx &m; + std::size_t index; + }; + + using ofxOscMessage::ofxOscMessage; + using ofxOscMessage::operator=; + + OscMessageEx() {}; + OscMessageEx(const ofxOscMessage &m) + : ofxOscMessage(m) {}; + + OscArgConverter operator[](std::size_t index) const { + return {*this, index}; + } + + struct detail { + template + struct is_convertible_to_int32_t + : std::integral_constant< + bool, + std::is_integral::value + && sizeof(type) <= 4 && !std::is_same::value + > {}; + + template + struct is_convertible_to_int64_t + : std::integral_constant< + bool, + std::is_integral::value + && !is_convertible_to_int32_t::value + > {}; + }; + + OscMessageEx &add(float v) { + addFloatArg(v); + return *this; + } + + OscMessageEx &add(double v) { + addDoubleArg(v); + return *this; + } + + OscMessageEx &add(const std::string &v) { + addStringArg(v); + return *this; + } + + template + auto add(const type &v) + -> typename std::enable_if< + detail::is_convertible_to_int32_t::value, + OscMessageEx & + >::type + { + addInt32Arg(v); + return *this; + } + + template + auto add(const type &v) + -> typename std::enable_if< + detail::is_convertible_to_int64_t::value, + OscMessageEx & + >::type + { + addInt64Arg(v); + return *this; + } + + template + OscMessageEx &operator<<(const type &v) + { return add(v); } + }; +}; + +using ofxOscMessageEx = ofx::OscMessageEx; + +#endif /* ofxOscMessageEx_h */ diff --git a/src/ofxOscSubscriber.h b/src/ofxOscSubscriber.h index 5000806..49896d6 100644 --- a/src/ofxOscSubscriber.h +++ b/src/ofxOscSubscriber.h @@ -14,6 +14,8 @@ #include "ofxOsc.h" +#include "ofxOscMessageEx.h" + #include "ofxOscSubscriberLoadImplementation.h" #include "ofxOscSubscribeParameter.h" @@ -189,8 +191,8 @@ namespace ofx { } template - inline void setLeakPicker(std::function callback) { - setLeakPicker(ParameterRef(new SetterFunctionParameter(callback))); + inline void setLeakPicker(std::function callback) { + setLeakPicker(ParameterRef(new SetterFunctionParameter(callback))); } template @@ -215,7 +217,7 @@ namespace ofx { } void clearLeakedOscMessages() { - std::queue empty; + std::queue empty; std::swap(leakedOscMessages, empty); } @@ -223,7 +225,7 @@ namespace ofx { return !static_cast(leakPicker) && !leakedOscMessages.empty(); } - inline bool getNextLeakedOscMessage(ofxOscMessage &m) { + inline bool getNextLeakedOscMessage(ofxOscMessageEx &m) { if(hasWaitingLeakedOscMessages()) { m.copy(leakedOscMessages.front()); leakedOscMessages.pop(); @@ -233,7 +235,7 @@ namespace ofx { } } - void notify(ofxOscMessage & m) { + void notify(ofxOscMessageEx &m) { const std::string &address = m.getAddress(); Targets::iterator it = targets.find(address); if(it != targets.end()) { @@ -243,7 +245,7 @@ namespace ofx { } } - void notify(const SubscribeIdentifier &identifier, ofxOscMessage &m) { + void notify(const SubscribeIdentifier &identifier, ofxOscMessageEx &m) { if(!identifier.isValid()) return; Targets::const_iterator it{findSubscribed(identifier)}; if(it != targets.end() && it->first == m.getAddress()) { @@ -263,7 +265,7 @@ namespace ofx { void update() { clearLeakedOscMessages(); - ofxOscMessage m; + ofxOscMessageEx m; while(receiver.hasWaitingMessages()) { receiver.getNextMessage(m); const std::string &address = m.getAddress(); @@ -286,7 +288,7 @@ namespace ofx { ofxOscReceiver receiver; Targets targets; ParameterRef leakPicker; - std::queue leakedOscMessages; + std::queue leakedOscMessages; bool bEnabled{true}; friend class SubscriberManager; @@ -506,15 +508,15 @@ inline void ofxUnsubscribeOsc() { #pragma mark notify messages manually -inline void ofxNotifyToSubscribedOsc(ofxOscSubscriberIdentifier &identifier, ofxOscMessage &m) { +inline void ofxNotifyToSubscribedOsc(ofxOscSubscriberIdentifier &identifier, ofxOscMessageEx &m) { ofxGetOscSubscriber(identifier.getKey()).notify(m); } -inline void ofxNotifyToSubscribedOsc(std::uint16_t port, ofxOscMessage &m) { +inline void ofxNotifyToSubscribedOsc(std::uint16_t port, ofxOscMessageEx &m) { ofxGetOscSubscriber(port).notify(m); } -inline void ofxNotifyToSubscribedOsc(ofxOscMessage &m) { +inline void ofxNotifyToSubscribedOsc(ofxOscMessageEx &m) { ofxOscSubscriberManager &manager = ofxGetOscSubscriberManager(); ofxOscSubscriberManager::iterator it = manager.begin(), end = manager.end(); From 32fb53e2e8164db827b0256b43cad9fa2940b71a Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Mon, 30 Apr 2018 07:26:17 +0900 Subject: [PATCH 21/30] remove reimplementation, add const --- .../ofxOscSubscriberLoadImplementation.h | 51 +++--- src/details/ofxPubSubOscTypeTraits.h | 3 +- src/ofxOscMessageEx.h | 168 +++++------------- 3 files changed, 67 insertions(+), 155 deletions(-) diff --git a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h index 7e7c2a8..64da317 100644 --- a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h +++ b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h @@ -10,7 +10,7 @@ #ifndef ofxOscSubscriberLoadImplementation_h #define ofxOscSubscriberLoadImplementation_h -#include "ofxOscMessageEx.h" +#include "ofxOscMessage.h" #include "ofxPubSubOscSettings.h" #include "ofxPubSubOscTypeUtils.h" @@ -19,7 +19,7 @@ namespace ofx { namespace PubSubOsc { #define define_set_arithmetic(type) \ - inline void load(ofxOscMessageEx &m, type &v, std::size_t offset = 0) { \ + inline void load(const ofxOscMessage &m, type &v, std::size_t offset = 0) { \ if(m.getArgType(offset) == OFXOSC_TYPE_INT32) v = m.getArgAsInt32(offset); \ else if(m.getArgType(offset) == OFXOSC_TYPE_INT64) v = m.getArgAsInt64(offset); \ else if(m.getArgType(offset) == OFXOSC_TYPE_FLOAT) v = m.getArgAsFloat(offset); \ @@ -45,7 +45,7 @@ namespace ofx { define_set_arithmetic(double); #undef define_set_arithmetic - inline void load(ofxOscMessageEx &m, std::string &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, std::string &v, std::size_t offset = 0) { if(m.getArgType(offset) == OFXOSC_TYPE_STRING) v = m.getArgAsString(offset); else if(m.getArgType(offset) == OFXOSC_TYPE_FLOAT) v = ofToString(m.getArgAsFloat(offset)); else if(m.getArgType(offset) == OFXOSC_TYPE_DOUBLE) v = ofToString(m.getArgAsDouble(offset)); @@ -54,20 +54,17 @@ namespace ofx { else v = m.getArgAsString(offset); } - inline void load(ofxOscMessageEx &m, ofBuffer &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofBuffer &v, std::size_t offset = 0) { v = m.getArgAsBlob(offset); } - inline void load(ofxOscMessageEx &m, ofxOscMessage &v, std::size_t offset = 0) { - v = m; - } - inline void load(ofxOscMessageEx &m, ofxOscMessageEx &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofxOscMessage &v, std::size_t offset = 0) { v = m; } #pragma mark ofColor_ template - inline void loadColor(ofxOscMessageEx &m, ofColor_ &v, U defaultValue, std::size_t offset = 0) { + inline void loadColor(const ofxOscMessage &m, ofColor_ &v, U defaultValue, std::size_t offset = 0) { if(m.getNumArgs() == 1) { load(m, v.r, offset); load(m, v.g, offset); @@ -86,47 +83,47 @@ namespace ofx { } } - inline void load(ofxOscMessageEx &m, ofColor &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofColor &v, std::size_t offset = 0) { loadColor(m, v, 255, offset); } - inline void load(ofxOscMessageEx &m, ofShortColor &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofShortColor &v, std::size_t offset = 0) { loadColor(m, v, 65535, offset); } - inline void load(ofxOscMessageEx &m, ofFloatColor &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofFloatColor &v, std::size_t offset = 0) { loadColor(m, v, 1.0f, offset); } #pragma mark oF container type template - inline void loadVec(ofxOscMessageEx &m, U &v, std::size_t offset = 0) { + inline void loadVec(const ofxOscMessage &m, U &v, std::size_t offset = 0) { for(int i = 0; i < min(static_cast(m.getNumArgs() - offset), n); i++) { load(m, v[i], offset + i); } } - inline void load(ofxOscMessageEx &m, ofVec2f &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofVec2f &v, std::size_t offset = 0) { loadVec<2>(m, v, offset); } - inline void load(ofxOscMessageEx &m, ofVec3f &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofVec3f &v, std::size_t offset = 0) { loadVec<3>(m, v, offset); } - inline void load(ofxOscMessageEx &m, ofVec4f &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofVec4f &v, std::size_t offset = 0) { loadVec<4>(m, v, offset); } - inline void load(ofxOscMessageEx &m, ofQuaternion &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofQuaternion &v, std::size_t offset = 0) { loadVec<4>(m, v, offset); } - inline void load(ofxOscMessageEx &m, ofMatrix3x3 &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofMatrix3x3 &v, std::size_t offset = 0) { loadVec<9>(m, v, offset); } - inline void load(ofxOscMessageEx &m, ofMatrix4x4 &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofMatrix4x4 &v, std::size_t offset = 0) { for(int j = 0; j < 4; j++) for(int i = 0; i < 4; i++) { load(m, v(i, j), offset + 4 * j + i); } } - inline void load(ofxOscMessageEx &m, ofRectangle &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofRectangle &v, std::size_t offset = 0) { load(m, v.x, offset + 0); load(m, v.y, offset + 1); load(m, v.width, offset + 2); @@ -136,13 +133,13 @@ namespace ofx { #pragma mark ofParameter / ofParameterGroup template - inline void load(ofxOscMessageEx &m, ofParameter &p, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofParameter &p, std::size_t offset = 0) { U u; load(m, u, offset); p.set(u); } - inline void load(ofxOscMessageEx &m, ofAbstractParameter &p, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofAbstractParameter &p, std::size_t offset = 0) { #define type_convert(type_) if(p.type() == typeid(ofParameter).name()) { load(m, p.cast(), offset); return; } type_convert(float); type_convert(double); @@ -174,7 +171,7 @@ namespace ofx { #undef type_convert } - inline void load(ofxOscMessageEx &m, ofParameterGroup &pg, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, ofParameterGroup &pg, std::size_t offset = 0) { if(m.getArgType(0) == OFXOSC_TYPE_INT32) { if(pg.size() <= m.getArgAsInt32(0)) { ofLogWarning("ofxOscSubscriber") << "ofAbstractParameterGroup: not contain index \"" << m.getArgAsInt32(0) << "\""; @@ -198,21 +195,21 @@ namespace ofx { #pragma mark container template - inline void load(ofxOscMessageEx &m, std::array &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, std::array &v, std::size_t offset = 0) { for(int i = 0; i < min(size, (m.getNumArgs() - offset) / type_traits::size); i++) { load(m, v[i], offset + i * type_traits::size); } } template - inline void load(ofxOscMessageEx &m, U (&v)[size], std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, U (&v)[size], std::size_t offset = 0) { for(int i = 0; i < min(size, (m.getNumArgs() - offset) / type_traits::size); i++) { load(m, v[i], offset + i * type_traits::size); } } template - inline void load(ofxOscMessageEx &m, std::vector &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, std::vector &v, std::size_t offset = 0) { std::size_t num = (m.getNumArgs() - offset) / type_traits::size; if(v.size() != num) v.resize(num); for(int i = 0; i < num; i++) { @@ -221,7 +218,7 @@ namespace ofx { } template - inline void load(ofxOscMessageEx &m, std::deque &v, std::size_t offset = 0) { + inline void load(const ofxOscMessage &m, std::deque &v, std::size_t offset = 0) { std::size_t num = (m.getNumArgs() - offset) / type_traits::size; if(v.size() != num) v.resize(num); for(int i = 0; i < num; i++) { diff --git a/src/details/ofxPubSubOscTypeTraits.h b/src/details/ofxPubSubOscTypeTraits.h index bb39b27..bba98f4 100644 --- a/src/details/ofxPubSubOscTypeTraits.h +++ b/src/details/ofxPubSubOscTypeTraits.h @@ -14,11 +14,12 @@ #include "ofVectorMath.h" #include "ofFileUtils.h" -#include "ofxOscMessageEx.h" #include "ofxOscArrayPublisher.h" namespace ofx { + using ofxOscMessageEx = class OscMessageEx; + namespace PubSubOsc { template struct type_traits { diff --git a/src/ofxOscMessageEx.h b/src/ofxOscMessageEx.h index f040797..c6911f0 100644 --- a/src/ofxOscMessageEx.h +++ b/src/ofxOscMessageEx.h @@ -11,8 +11,37 @@ #include "ofxOscMessage.h" +#include "Publisher/ofxOscPublisherSetImplementation.h" +#include "Subscriber/ofxOscSubscriberLoadImplementation.h" + namespace ofx { struct OscMessageEx : public ofxOscMessage { + using ofxOscMessage::ofxOscMessage; + using ofxOscMessage::operator=; + + OscMessageEx() {}; + OscMessageEx(const ofxOscMessage &m) + : ofxOscMessage(m) {}; + template + OscMessageEx(const std::string &address, const arguments & ... args) { + setAddress(address); + const auto &_ = {add(args) ...}; + } + +#pragma mark add / operator<< + + template + OscMessageEx &add(const type &v) { + PubSubOsc::set(*this, v); + return *this; + } + + template + OscMessageEx &operator<<(const type &v) + { return add(v); } + +#pragma mark operator[] + struct OscArgConverter { OscArgConverter(const OscMessageEx &m, std::size_t index) : m(m) @@ -23,141 +52,26 @@ namespace ofx { inline operator type() const { return as(); } template - auto as() const - -> typename std::enable_if::value, type>::type - { - switch(m.getArgType(index)) { - case OFXOSC_TYPE_INT32: return m.getArgAsInt32(index); - case OFXOSC_TYPE_INT64: return m.getArgAsInt64(index); - case OFXOSC_TYPE_FLOAT: return m.getArgAsFloat(index); - case OFXOSC_TYPE_DOUBLE: return m.getArgAsDouble(index); - case OFXOSC_TYPE_CHAR: return m.getArgAsChar(index); - case OFXOSC_TYPE_STRING: return std::stoll(m.getArgAsString(index)); - case OFXOSC_TYPE_SYMBOL: return std::stoll(m.getArgAsSymbol(index)); - case OFXOSC_TYPE_TRUE: return true; - case OFXOSC_TYPE_FALSE: return false; - default: { - ofLogWarning("ofxOscMessageEx::OscArgConverer") << "can't convert from " << m.getArgTypeName(index) << " to " << typeid(type).name(); - return type(); - } - } - }; - - template - auto as() const - -> typename std::enable_if::value, type>::type + inline type as() const { - switch(m.getArgType(index)) { - case OFXOSC_TYPE_INT32: return m.getArgAsInt32(index); - case OFXOSC_TYPE_INT64: return m.getArgAsInt64(index); - case OFXOSC_TYPE_FLOAT: return m.getArgAsFloat(index); - case OFXOSC_TYPE_DOUBLE: return m.getArgAsDouble(index); - case OFXOSC_TYPE_CHAR: return m.getArgAsChar(index); - case OFXOSC_TYPE_STRING: return std::stod(m.getArgAsString(index)); - case OFXOSC_TYPE_SYMBOL: return std::stod(m.getArgAsSymbol(index)); - case OFXOSC_TYPE_TRUE: return true; - case OFXOSC_TYPE_FALSE: return false; - default: { - ofLogWarning("ofxOscMessageEx::OscArgConverer") << "can't convert from " << m.getArgTypeName(index) << " to " << typeid(type).name(); - return type(); - } - } + type v; + PubSubOsc::load(static_cast(m), v, index); + return v; }; - template - auto as() const - -> typename std::enable_if::value, type>::type - { - switch(m.getArgType(index)) { - case OFXOSC_TYPE_INT32: return std::to_string(m.getArgAsInt32(index)); - case OFXOSC_TYPE_INT64: return std::to_string(m.getArgAsInt64(index)); - case OFXOSC_TYPE_FLOAT: return std::to_string(m.getArgAsFloat(index)); - case OFXOSC_TYPE_DOUBLE: return std::to_string(m.getArgAsDouble(index)); - case OFXOSC_TYPE_CHAR: return std::to_string(m.getArgAsChar(index)); - case OFXOSC_TYPE_STRING: return m.getArgAsString(index); - case OFXOSC_TYPE_SYMBOL: return m.getArgAsSymbol(index); - case OFXOSC_TYPE_TRUE: return "true"; - case OFXOSC_TYPE_FALSE: return "false"; - default: { - ofLogWarning("ofxOscMessageEx::OscArgConverer") << "can't convert from " << m.getArgTypeName(index) << " to std::string"; - return {}; - } - } - } private: + OscArgConverter() = delete; + OscArgConverter(const OscArgConverter &) = delete; + OscArgConverter(OscArgConverter &&) = delete; + OscArgConverter &operator=(const OscArgConverter &) = delete; + OscArgConverter &operator=(OscArgConverter &&) = delete; const OscMessageEx &m; - std::size_t index; + const std::size_t index; }; - - using ofxOscMessage::ofxOscMessage; - using ofxOscMessage::operator=; - - OscMessageEx() {}; - OscMessageEx(const ofxOscMessage &m) - : ofxOscMessage(m) {}; - - OscArgConverter operator[](std::size_t index) const { + + inline OscArgConverter operator[](std::size_t index) const { return {*this, index}; } - - struct detail { - template - struct is_convertible_to_int32_t - : std::integral_constant< - bool, - std::is_integral::value - && sizeof(type) <= 4 && !std::is_same::value - > {}; - - template - struct is_convertible_to_int64_t - : std::integral_constant< - bool, - std::is_integral::value - && !is_convertible_to_int32_t::value - > {}; - }; - - OscMessageEx &add(float v) { - addFloatArg(v); - return *this; - } - - OscMessageEx &add(double v) { - addDoubleArg(v); - return *this; - } - - OscMessageEx &add(const std::string &v) { - addStringArg(v); - return *this; - } - - template - auto add(const type &v) - -> typename std::enable_if< - detail::is_convertible_to_int32_t::value, - OscMessageEx & - >::type - { - addInt32Arg(v); - return *this; - } - - template - auto add(const type &v) - -> typename std::enable_if< - detail::is_convertible_to_int64_t::value, - OscMessageEx & - >::type - { - addInt64Arg(v); - return *this; - } - - template - OscMessageEx &operator<<(const type &v) - { return add(v); } }; }; From e4fbe82cc47619af7f33c98a9cfaed946b3280b8 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Mon, 30 Apr 2018 07:32:15 +0900 Subject: [PATCH 22/30] add static_cast --- src/ofxOscMessageEx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ofxOscMessageEx.h b/src/ofxOscMessageEx.h index c6911f0..d824809 100644 --- a/src/ofxOscMessageEx.h +++ b/src/ofxOscMessageEx.h @@ -32,7 +32,7 @@ namespace ofx { template OscMessageEx &add(const type &v) { - PubSubOsc::set(*this, v); + PubSubOsc::set(static_cast(*this), v); return *this; } From 9560d4bc6ea0434ff168ead95cec8e0810d7f693 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Mon, 30 Apr 2018 07:54:08 +0900 Subject: [PATCH 23/30] a little fix for win --- src/details/Subscriber/ofxOscSubscribeParameter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/details/Subscriber/ofxOscSubscribeParameter.h b/src/details/Subscriber/ofxOscSubscribeParameter.h index dd5997b..5d1f1df 100644 --- a/src/details/Subscriber/ofxOscSubscribeParameter.h +++ b/src/details/Subscriber/ofxOscSubscribeParameter.h @@ -60,7 +60,7 @@ namespace ofx { std::tuple &t, std::size_t offset) { std::size_t o{0}; - std::vector{(load(m, std::get(t), offset + o), o += type_traits::size) ...}; + std::vector{(PubSubOsc::load(m, std::get(t), offset + o), o += type_traits::size) ...}; } template From 737f0ba713dd318446c3388f28708cbe2ffd084d Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Mon, 30 Apr 2018 09:59:23 +0900 Subject: [PATCH 24/30] implement utils about glm --- src/details/ofxPubSubOscTypeTraits.h | 28 +++++++++++++++- src/details/ofxPubSubOscTypeUtils.h | 49 ++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/details/ofxPubSubOscTypeTraits.h b/src/details/ofxPubSubOscTypeTraits.h index bba98f4..cc8fdcb 100644 --- a/src/details/ofxPubSubOscTypeTraits.h +++ b/src/details/ofxPubSubOscTypeTraits.h @@ -12,6 +12,8 @@ #include +#include + #include "ofVectorMath.h" #include "ofFileUtils.h" @@ -21,7 +23,7 @@ namespace ofx { using ofxOscMessageEx = class OscMessageEx; namespace PubSubOsc { - template + template struct type_traits { using inner_type = T; static constexpr std::size_t size = 1; @@ -124,6 +126,30 @@ namespace ofx { static constexpr bool has_array_operator = false; }; +#pragma mark glm +#ifdef GLM_VERSION + template + struct type_traits::value>> { + using inner_type = typename glm_vec_t::value_type; + static constexpr std::size_t size = get_glm_vec_size::value; + static constexpr bool has_array_operator = true; + }; + + template + struct type_traits::value>> { + using inner_type = typename glm_mat_t::col_type; + static constexpr std::size_t size = get_glm_vec_size::value; + static constexpr bool has_array_operator = true; + }; + + template + struct type_traits> { + using inner_type = T; + static constexpr std::size_t size = 4; + static constexpr bool has_array_operator = true; + }; +#endif + template <> struct type_traits { using inner_type = float; diff --git a/src/details/ofxPubSubOscTypeUtils.h b/src/details/ofxPubSubOscTypeUtils.h index 220f3e5..bd77f45 100644 --- a/src/details/ofxPubSubOscTypeUtils.h +++ b/src/details/ofxPubSubOscTypeUtils.h @@ -13,7 +13,10 @@ #include #include +#include + #include "ofxPubSubOscSettings.h" +#include "ofVectorMath.h" namespace ofx { namespace PubSubOsc { @@ -339,6 +342,52 @@ namespace ofx { }; using namespace applying; }; + +#pragma mark glm +#ifdef GLM_VERSION + template + struct is_glm_vec : std::false_type {}; + template + struct is_glm_vec> : std::true_type {}; + template + struct is_glm_vec> : std::true_type {}; + template + struct is_glm_vec> : std::true_type {}; + template + struct is_glm_vec> : std::true_type {}; + + template + struct get_glm_vec_size; + template + struct get_glm_vec_size> : std::integral_constant {}; + template + struct get_glm_vec_size> : std::integral_constant {}; + template + struct get_glm_vec_size> : std::integral_constant {}; + template + struct get_glm_vec_size> : std::integral_constant {}; + + template + struct is_glm_mat : std::false_type {}; + template + struct is_glm_mat> : std::true_type {}; + template + struct is_glm_mat> : std::true_type {}; + template + struct is_glm_mat> : std::true_type {}; + template + struct is_glm_mat> : std::true_type {}; + template + struct is_glm_mat> : std::true_type {}; + template + struct is_glm_mat> : std::true_type {}; + template + struct is_glm_mat> : std::true_type {}; + template + struct is_glm_mat> : std::true_type {}; + template + struct is_glm_mat> : std::true_type {}; +#endif }; From b4fbf36e5a9f7af1e815e243f9d370d242513f23 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Mon, 30 Apr 2018 10:00:37 +0900 Subject: [PATCH 25/30] implement set/load for tvecN, tmatMxN, tquat --- .../ofxOscPublisherSetImplementation.h | 26 +++++++++++++++++ .../ofxOscSubscriberLoadImplementation.h | 28 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/details/Publisher/ofxOscPublisherSetImplementation.h b/src/details/Publisher/ofxOscPublisherSetImplementation.h index 497c35c..6c8689a 100644 --- a/src/details/Publisher/ofxOscPublisherSetImplementation.h +++ b/src/details/Publisher/ofxOscPublisherSetImplementation.h @@ -10,6 +10,10 @@ #ifndef ofxOscPublisherSetImplementation_h #define ofxOscPublisherSetImplementation_h +#include + +#include + #include "ofxOscMessage.h" #include "ofxPubSubOscSettings.h" @@ -62,8 +66,30 @@ namespace ofx { inline void set(ofxOscMessage &m, const ofMatrix4x4 &v) { for(int j = 0; j < 4; j++) for(int i = 0; i < 4; i++) set(m, v(i, j)); +#pragma mark glm +#ifdef GLM_VERSION + template + inline auto set(ofxOscMessage &m, glm_vec_t &v) + -> PubSubOsc::enable_if_t::value> + { + setVec::value>(m, v); + } + + template + inline auto set(ofxOscMessage &m, glm_mat_t &v) + -> PubSubOsc::enable_if_t::value> + { + constexpr std::size_t row_length = get_glm_vec_size::value; + constexpr std::size_t col_length = get_glm_vec_size::value; + for(std::size_t i = 0; i < row_length; i++) setVec(m, v[i]); } + template + inline void set(ofxOscMessage &m, glm::tquat &v) { + setVec<4>(m, v); + } +#endif + inline void set(ofxOscMessage &m, const ofRectangle &v) { set(m, v.x); set(m, v.y); diff --git a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h index 64da317..1e65213 100644 --- a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h +++ b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h @@ -10,6 +10,10 @@ #ifndef ofxOscSubscriberLoadImplementation_h #define ofxOscSubscriberLoadImplementation_h +#include + +#include + #include "ofxOscMessage.h" #include "ofxPubSubOscSettings.h" @@ -123,6 +127,30 @@ namespace ofx { } } +#pragma mark glm +#ifdef GLM_VERSION + template + inline auto load(const ofxOscMessage &m, glm_vec_t &v, std::size_t offset = 0) + -> PubSubOsc::enable_if_t::value> + { + loadVec::value>(m, v, offset); + } + + template + inline auto load(const ofxOscMessage &m, glm_mat_t &v, std::size_t offset = 0) + -> PubSubOsc::enable_if_t::value> + { + constexpr std::size_t row_length = get_glm_vec_size::value; + constexpr std::size_t col_length = get_glm_vec_size::value; + for(std::size_t i = 0; i < row_length; i++) loadVec(m, v[i], offset + col_length * i); + } + + template + inline void load(ofxOscMessage &m, glm::tquat &v) { + loadVec<4>(m, v); + } +#endif + inline void load(const ofxOscMessage &m, ofRectangle &v, std::size_t offset = 0) { load(m, v.x, offset + 0); load(m, v.y, offset + 1); From b2aa017c587fb894de32c0f891be20e9bdbb69b5 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Mon, 30 Apr 2018 10:01:02 +0900 Subject: [PATCH 26/30] tiny refactoring --- src/details/Publisher/ofxOscPublishParameter.h | 4 ++-- .../Publisher/ofxOscPublisherSetImplementation.h | 16 +++++++++------- .../Subscriber/ofxOscSubscribeParameter.h | 2 +- .../ofxOscSubscriberLoadImplementation.h | 12 ++++++------ src/details/ofxOscArrayPublisher.h | 6 +++--- 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/details/Publisher/ofxOscPublishParameter.h b/src/details/Publisher/ofxOscPublishParameter.h index 3434b09..e7d0365 100644 --- a/src/details/Publisher/ofxOscPublishParameter.h +++ b/src/details/Publisher/ofxOscPublishParameter.h @@ -91,13 +91,13 @@ namespace ofx { protected: virtual bool isChanged() { bool isChange = false; - for(int i = 0; i < size; i++) { + for(std::size_t i = 0; i < size; i++) { isChange = isChange || (old[i] != get()[i]); if(isChange) break; } if(isChange) { - for(int i = 0; i < size; i++) { + for(std::size_t i = 0; i < size; i++) { old[i] = get()[i]; } return true; diff --git a/src/details/Publisher/ofxOscPublisherSetImplementation.h b/src/details/Publisher/ofxOscPublisherSetImplementation.h index 6c8689a..6200d1b 100644 --- a/src/details/Publisher/ofxOscPublisherSetImplementation.h +++ b/src/details/Publisher/ofxOscPublisherSetImplementation.h @@ -42,11 +42,11 @@ namespace ofx { template inline void setVec(ofxOscMessage &m, const T &v) { - for(int i = 0; i < n; i++) { set(m, v[i]); } + for(std::size_t i = 0; i < n; i++) { set(m, v[i]); } } template - inline void set(ofxOscMessage &m, const ofColor_ &v) { setVec<4>(m, v); } + inline void set(ofxOscMessage &m, const ofColor_ &v) { setVec<4>(m, v); } inline void set(ofxOscMessage &m, const ofVec2f &v) { setVec<2>(m, v); } inline void set(ofxOscMessage &m, const ofVec3f &v) { setVec<3>(m, v); } inline void set(ofxOscMessage &m, const ofVec4f &v) { setVec<4>(m, v); } @@ -65,7 +65,9 @@ namespace ofx { } inline void set(ofxOscMessage &m, const ofMatrix4x4 &v) { - for(int j = 0; j < 4; j++) for(int i = 0; i < 4; i++) set(m, v(i, j)); + for(std::size_t j = 0; j < 4; j++) for(std::size_t i = 0; i < 4; i++) set(m, v(i, j)); + } + #pragma mark glm #ifdef GLM_VERSION template @@ -100,22 +102,22 @@ namespace ofx { #pragma mark containerz template inline void set(ofxOscMessage &m, const std::array &v) { - for(int i = 0; i < size; i++) { set(m, v[i]); } + for(std::size_t i = 0; i < size; i++) { set(m, v[i]); } } template inline void set(ofxOscMessage &m, const U (&v)[size]) { - for(int i = 0; i < size; i++) { set(m, v[i]); } + for(std::size_t i = 0; i < size; i++) { set(m, v[i]); } } template inline void set(ofxOscMessage &m, const std::vector &v) { - for(int i = 0; i < v.size(); i++) { set(m, v[i]); } + for(std::size_t i = 0; i < v.size(); i++) { set(m, v[i]); } } template inline void set(ofxOscMessage &m, const std::deque &v) { - for(int i = 0; i < v.size(); i++) { set(m, v[i]); } + for(std::size_t i = 0; i < v.size(); i++) { set(m, v[i]); } } template diff --git a/src/details/Subscriber/ofxOscSubscribeParameter.h b/src/details/Subscriber/ofxOscSubscribeParameter.h index 5d1f1df..9646a85 100644 --- a/src/details/Subscriber/ofxOscSubscribeParameter.h +++ b/src/details/Subscriber/ofxOscSubscribeParameter.h @@ -151,7 +151,7 @@ namespace ofx { inline void load(ofxOscMessageEx &m, std::vector &v, std::size_t offset = 0) { std::size_t o = 0; - for(int i = 0; i < v.size(); i++) { + for(std::size_t i = 0; i < v.size(); i++) { if(m.getNumArgs() < offset + o + v[i]->size()) { ofLogWarning("ofxPubSubOsc::Subscriber") << "less args"; break; diff --git a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h index 1e65213..4d9423e 100644 --- a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h +++ b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h @@ -100,7 +100,7 @@ namespace ofx { #pragma mark oF container type template inline void loadVec(const ofxOscMessage &m, U &v, std::size_t offset = 0) { - for(int i = 0; i < min(static_cast(m.getNumArgs() - offset), n); i++) { + for(std::size_t i = 0; i < std::min(static_cast(m.getNumArgs() - offset), n); i++) { load(m, v[i], offset + i); } } @@ -122,7 +122,7 @@ namespace ofx { } inline void load(const ofxOscMessage &m, ofMatrix4x4 &v, std::size_t offset = 0) { - for(int j = 0; j < 4; j++) for(int i = 0; i < 4; i++) { + for(std::size_t j = 0; j < 4; j++) for(std::size_t i = 0; i < 4; i++) { load(m, v(i, j), offset + 4 * j + i); } } @@ -224,14 +224,14 @@ namespace ofx { #pragma mark container template inline void load(const ofxOscMessage &m, std::array &v, std::size_t offset = 0) { - for(int i = 0; i < min(size, (m.getNumArgs() - offset) / type_traits::size); i++) { + for(std::size_t i = 0; i < min(size, (m.getNumArgs() - offset) / type_traits::size); i++) { load(m, v[i], offset + i * type_traits::size); } } template inline void load(const ofxOscMessage &m, U (&v)[size], std::size_t offset = 0) { - for(int i = 0; i < min(size, (m.getNumArgs() - offset) / type_traits::size); i++) { + for(std::size_t i = 0; i < min(size, (m.getNumArgs() - offset) / type_traits::size); i++) { load(m, v[i], offset + i * type_traits::size); } } @@ -240,7 +240,7 @@ namespace ofx { inline void load(const ofxOscMessage &m, std::vector &v, std::size_t offset = 0) { std::size_t num = (m.getNumArgs() - offset) / type_traits::size; if(v.size() != num) v.resize(num); - for(int i = 0; i < num; i++) { + for(std::size_t i = 0; i < num; i++) { load(m, v[i], offset + i * type_traits::size); } } @@ -249,7 +249,7 @@ namespace ofx { inline void load(const ofxOscMessage &m, std::deque &v, std::size_t offset = 0) { std::size_t num = (m.getNumArgs() - offset) / type_traits::size; if(v.size() != num) v.resize(num); - for(int i = 0; i < num; i++) { + for(std::size_t i = 0; i < num; i++) { load(m, v[i], offset + i * type_traits::size); } } diff --git a/src/details/ofxOscArrayPublisher.h b/src/details/ofxOscArrayPublisher.h index b568374..4620901 100644 --- a/src/details/ofxOscArrayPublisher.h +++ b/src/details/ofxOscArrayPublisher.h @@ -179,9 +179,9 @@ namespace ofx { ArrayBuffer() : v(malloc(sizeof(T) * s)) {} virtual ~ArrayBuffer() { free(v); v = NULL; } - array_t operator=(const ArrayPublisher &arr) { for(int i = 0; i < size(); i++) v[i] = arr[i]; return get(); }; - bool operator!=(const ArrayPublisher &arr) const { for(int i = 0; i < size(); i++) if(v[i] != arr[i]) return true; return false; }; - bool operator==(const ArrayPublisher &arr) const { for(int i = 0; i < size(); i++) if(v[i] != arr[i]) return false; return true; }; + array_t operator=(const ArrayPublisher &arr) { for(std::size_t i = 0; i < size(); i++) v[i] = arr[i]; return get(); }; + bool operator!=(const ArrayPublisher &arr) const { for(std::size_t i = 0; i < size(); i++) if(v[i] != arr[i]) return true; return false; }; + bool operator==(const ArrayPublisher &arr) const { for(std::size_t i = 0; i < size(); i++) if(v[i] != arr[i]) return false; return true; }; T operator[](std::size_t n) const { return v[n]; }; T &operator[](std::size_t n) { return v[n]; }; From 71d96b0b429acb103bb738967d132a776dab9698 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Mon, 30 Apr 2018 10:07:30 +0900 Subject: [PATCH 27/30] update about including glm --- src/details/Publisher/ofxOscPublisherSetImplementation.h | 2 -- src/details/Subscriber/ofxOscSubscriberLoadImplementation.h | 2 -- src/details/ofxPubSubOscSettings.h | 4 ++++ src/details/ofxPubSubOscTypeTraits.h | 3 +-- src/details/ofxPubSubOscTypeUtils.h | 2 -- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/details/Publisher/ofxOscPublisherSetImplementation.h b/src/details/Publisher/ofxOscPublisherSetImplementation.h index 6200d1b..94b4e96 100644 --- a/src/details/Publisher/ofxOscPublisherSetImplementation.h +++ b/src/details/Publisher/ofxOscPublisherSetImplementation.h @@ -12,8 +12,6 @@ #include -#include - #include "ofxOscMessage.h" #include "ofxPubSubOscSettings.h" diff --git a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h index 4d9423e..0235745 100644 --- a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h +++ b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h @@ -12,8 +12,6 @@ #include -#include - #include "ofxOscMessage.h" #include "ofxPubSubOscSettings.h" diff --git a/src/details/ofxPubSubOscSettings.h b/src/details/ofxPubSubOscSettings.h index ce842c5..853e528 100644 --- a/src/details/ofxPubSubOscSettings.h +++ b/src/details/ofxPubSubOscSettings.h @@ -24,4 +24,8 @@ #define OFX_PUBSUBOSC_DEBUG 0 +#if 10 <= OF_VERSION_MINOR +# include +#endif + #endif diff --git a/src/details/ofxPubSubOscTypeTraits.h b/src/details/ofxPubSubOscTypeTraits.h index cc8fdcb..0ba6904 100644 --- a/src/details/ofxPubSubOscTypeTraits.h +++ b/src/details/ofxPubSubOscTypeTraits.h @@ -12,11 +12,10 @@ #include -#include - #include "ofVectorMath.h" #include "ofFileUtils.h" +#include "ofxPubSubOscSettings.h" #include "ofxOscArrayPublisher.h" namespace ofx { diff --git a/src/details/ofxPubSubOscTypeUtils.h b/src/details/ofxPubSubOscTypeUtils.h index bd77f45..de19aaa 100644 --- a/src/details/ofxPubSubOscTypeUtils.h +++ b/src/details/ofxPubSubOscTypeUtils.h @@ -13,8 +13,6 @@ #include #include -#include - #include "ofxPubSubOscSettings.h" #include "ofVectorMath.h" From 74e3bcfe944e32685d8b26768b39ba18dbb5babd Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Mon, 30 Apr 2018 10:31:08 +0900 Subject: [PATCH 28/30] update for the distant future. --- .../ofxOscPublisherSetImplementation.h | 17 +++++++++++++++++ .../ofxOscSubscriberLoadImplementation.h | 19 +++++++++++++++++++ src/details/ofxPubSubOscTypeTraits.h | 15 +++++++++++++++ src/details/ofxPubSubOscTypeUtils.h | 19 +++++++++++++++---- 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/details/Publisher/ofxOscPublisherSetImplementation.h b/src/details/Publisher/ofxOscPublisherSetImplementation.h index 94b4e96..95c4414 100644 --- a/src/details/Publisher/ofxOscPublisherSetImplementation.h +++ b/src/details/Publisher/ofxOscPublisherSetImplementation.h @@ -68,6 +68,7 @@ namespace ofx { #pragma mark glm #ifdef GLM_VERSION +# if GLM_VERSION < 990 template inline auto set(ofxOscMessage &m, glm_vec_t &v) -> PubSubOsc::enable_if_t::value> @@ -88,6 +89,22 @@ namespace ofx { inline void set(ofxOscMessage &m, glm::tquat &v) { setVec<4>(m, v); } +# else + template + inline void set(ofxOscMessage &m, glm::vec &v) { + setVec(m, v); + } + + template + inline void set(ofxOscMessage &m, glm::mat &v) { + for(std::size_t i = 0; i < M; i++) setVec(m, v[i]); + } + + template + inline void set(ofxOscMessage &m, glm::tquat &v) { + setVec<4>(m, v); + } +# endif #endif inline void set(ofxOscMessage &m, const ofRectangle &v) { diff --git a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h index 0235745..f48fd0f 100644 --- a/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h +++ b/src/details/Subscriber/ofxOscSubscriberLoadImplementation.h @@ -127,6 +127,7 @@ namespace ofx { #pragma mark glm #ifdef GLM_VERSION +# if GLM_VERSION < 990 template inline auto load(const ofxOscMessage &m, glm_vec_t &v, std::size_t offset = 0) -> PubSubOsc::enable_if_t::value> @@ -147,6 +148,24 @@ namespace ofx { inline void load(ofxOscMessage &m, glm::tquat &v) { loadVec<4>(m, v); } +# else + template + inline void load(const ofxOscMessage &m, glm::vec &v, std::size_t offset = 0) + { + loadVec(m, v, offset); + } + + template + inline void load(const ofxOscMessage &m, glm::mat &v, std::size_t offset = 0) + { + for(std::size_t i = 0; i < M; i++) loadVec(m, v[i], offset + N * i); + } + + template + inline void load(ofxOscMessage &m, glm::tquat &v) { + loadVec<4>(m, v); + } +# endif #endif inline void load(const ofxOscMessage &m, ofRectangle &v, std::size_t offset = 0) { diff --git a/src/details/ofxPubSubOscTypeTraits.h b/src/details/ofxPubSubOscTypeTraits.h index 0ba6904..abe2923 100644 --- a/src/details/ofxPubSubOscTypeTraits.h +++ b/src/details/ofxPubSubOscTypeTraits.h @@ -127,6 +127,7 @@ namespace ofx { #pragma mark glm #ifdef GLM_VERSION +# if GLM_VERSION < 990 template struct type_traits::value>> { using inner_type = typename glm_vec_t::value_type; @@ -140,7 +141,21 @@ namespace ofx { static constexpr std::size_t size = get_glm_vec_size::value; static constexpr bool has_array_operator = true; }; +# else + template + struct type_traits> { + using inner_type = T; + static constexpr std::size_t size = N; + static constexpr bool has_array_operator = true; + }; + template + struct type_traits> { + using inner_type = typename glm::mat::col_type; + static constexpr std::size_t size = M; + static constexpr bool has_array_operator = true; + }; +# endif template struct type_traits> { using inner_type = T; diff --git a/src/details/ofxPubSubOscTypeUtils.h b/src/details/ofxPubSubOscTypeUtils.h index de19aaa..c29de24 100644 --- a/src/details/ofxPubSubOscTypeUtils.h +++ b/src/details/ofxPubSubOscTypeUtils.h @@ -345,6 +345,11 @@ namespace ofx { #ifdef GLM_VERSION template struct is_glm_vec : std::false_type {}; + template + struct get_glm_vec_size; + template + struct is_glm_mat : std::false_type {}; +# if GLM_VERSION < 990 template struct is_glm_vec> : std::true_type {}; template @@ -354,8 +359,6 @@ namespace ofx { template struct is_glm_vec> : std::true_type {}; - template - struct get_glm_vec_size; template struct get_glm_vec_size> : std::integral_constant {}; template @@ -365,8 +368,6 @@ namespace ofx { template struct get_glm_vec_size> : std::integral_constant {}; - template - struct is_glm_mat : std::false_type {}; template struct is_glm_mat> : std::true_type {}; template @@ -385,6 +386,16 @@ namespace ofx { struct is_glm_mat> : std::true_type {}; template struct is_glm_mat> : std::true_type {}; +# else + template + struct is_glm_vec> : std::true_type {}; + + template + struct get_glm_vec_size> : std::integral_constant {}; + + template + struct is_glm_mat> : std::true_type {}; +# endif #endif }; From c5b182455e07ede1326d79c3e248da9ff473ce6e Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Tue, 1 May 2018 22:39:54 +0900 Subject: [PATCH 29/30] omg --- .../Publisher/ofxOscPublisherSetImplementation.h | 12 ++++++------ src/ofxOscMessageEx.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/details/Publisher/ofxOscPublisherSetImplementation.h b/src/details/Publisher/ofxOscPublisherSetImplementation.h index 95c4414..9a5289a 100644 --- a/src/details/Publisher/ofxOscPublisherSetImplementation.h +++ b/src/details/Publisher/ofxOscPublisherSetImplementation.h @@ -70,14 +70,14 @@ namespace ofx { #ifdef GLM_VERSION # if GLM_VERSION < 990 template - inline auto set(ofxOscMessage &m, glm_vec_t &v) + inline auto set(ofxOscMessage &m, const glm_vec_t &v) -> PubSubOsc::enable_if_t::value> { setVec::value>(m, v); } template - inline auto set(ofxOscMessage &m, glm_mat_t &v) + inline auto set(ofxOscMessage &m, const glm_mat_t &v) -> PubSubOsc::enable_if_t::value> { constexpr std::size_t row_length = get_glm_vec_size::value; @@ -86,22 +86,22 @@ namespace ofx { } template - inline void set(ofxOscMessage &m, glm::tquat &v) { + inline void set(ofxOscMessage &m, const glm::tquat &v) { setVec<4>(m, v); } # else template - inline void set(ofxOscMessage &m, glm::vec &v) { + inline void set(ofxOscMessage &m, const glm::vec &v) { setVec(m, v); } template - inline void set(ofxOscMessage &m, glm::mat &v) { + inline void set(ofxOscMessage &m, const glm::mat &v) { for(std::size_t i = 0; i < M; i++) setVec(m, v[i]); } template - inline void set(ofxOscMessage &m, glm::tquat &v) { + inline void set(ofxOscMessage &m, const glm::tquat &v) { setVec<4>(m, v); } # endif diff --git a/src/ofxOscMessageEx.h b/src/ofxOscMessageEx.h index d824809..4766029 100644 --- a/src/ofxOscMessageEx.h +++ b/src/ofxOscMessageEx.h @@ -25,7 +25,7 @@ namespace ofx { template OscMessageEx(const std::string &address, const arguments & ... args) { setAddress(address); - const auto &_ = {add(args) ...}; + const std::vector &_ = {add(args) ...}; } #pragma mark add / operator<< From 90c413f20730b6d70d5712a137baecec78cd6c14 Mon Sep 17 00:00:00 2001 From: ISHII 2bit Date: Tue, 8 May 2018 16:27:40 +0900 Subject: [PATCH 30/30] update README --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2b86d81..08a8dc3 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,11 @@ easy utility for publish/subscribe OSC message. ## Notice -* this addon is tested with oF0.9.0~ +* this addon is tested with oF0.9.8~ * if you use oF0.9.0~, then you can use `std::function`! detail: [API Reference](API_Reference.md#API_lambda_callback) * **if you use oF~0.8.4, then you can use [branch:v0_1_x_oF084](../../tree/v0_1_x_oF084)** -* if you have challange spirit, please use dev/main branch. -* if you want to join development ofxPubSubOsc, open the issue and post the PR for [dev/main](tree/dev/main). +* if you have challange spirit, please use dev/vX.Y.Z branch. +* if you want to join development ofxPubSubOsc, open the issue and post the PR for dev/vX.Y.Z. ## TOC @@ -72,6 +72,8 @@ public: ## Simple API Reference +_API Reference is imperfect now._ + #### If you want to use advanced features, see [Advanced](API_Reference.md) ### ofxSubscribeOsc @@ -211,11 +213,14 @@ if you use `vector vec;`, when `vec` will be resized every receiving O ## Update history -### 2016/06/XX ver 0.3.0 +### 2018/05/08 ver 0.3.0 * refactor all for C++11 * add `ofxSendOsc` * ofxSubscribeOsc got more flexible. + * multi arguments + * multi arguments callback +* add `ofxOscMessageEx` ### 2016/01/25 [ver 0.2.2](../../releases/tag/v0_2_2) release