LoginSignup
6
1

More than 5 years have passed since last update.

ofxPubSubOscの使い方 (ofxSubscribeOsc編)

Last updated at Posted at 2018-05-15

ofxPubSubOsc というoFのaddonを書いてまして, 最近やっとver0.3.0もリリースしたし, 今更ながら紹介記事を書いてみようと.

もう if(m.getAddress() == "/hoge") って書きたくない

// int hoge, fuga, piyo;
// receiver.setup(port);
void update() {
    ...

    ofxOscMessage m;
    while(receiver.hasWaitingMessages()) {
        receiver.getNextMessage(m);
        if(m.getAddress() == "/hoge") {
            hoge = m.getArgAsInt32(0);
        }
        else if(m.getAddress() == "/fuga") {
            fuga = m.getArgAsInt32(0);
        }
        else if(m.getAddress() == "/piyo") {
            piyo = m.getArgAsInt32(0);
        }
        ...
    }

    ...
}

こんなコード書いてますか?書いてますよね?
ofxPubSubOscを使うと

// int hoge, fuga, piyo;
void setup() {
    ...

    ofxSubScribeOsc(port, "/hoge", hoge);
    ofxSubScribeOsc(port, "/fuga", fuga);
    ofxSubScribeOsc(port, "/piyo", piyo);
    ...
}

すっきり.

値が変更されたときに何か処理したい

// int hoge;
ofxOscMessage m;
while(receiver.hasWaitingMessages()) {
    receiver.getNextMessage(m);
    if(m.getAddress() == "/hoge") {
        hoge = m.getArgAsInt32(0);
        doHoge(hoge);
    }
}

こういうときは無名関数を使って

// int hoge;
ofxSubscribeOsc(port, "/hoge", [=](int val) {
    hoge = val;
    doHoge(hoge);
});

OSC引数が複数ある場合

// int hoge1;
// std::string hoge2;
// bool hoge3;
if(m.getAddress() == "/hoge") {
    hoge1 = m.getArgAsInt32(0);
    hoge2 = m.getArgAsString(1);
    hoge3 = m.getArgAsBool(2);
}

複数引数にも対応.

// int hoge1;
// std::string hoge2;
// bool hoge3;
ofxSubscribeOsc(port, "/hoge", hoge1, hoge2, hoge3);

std::vector<float> とか

std::vector<float>

// std::vector<float> xs;
if(m.getAddress() == "/xs") {
    xs.resize(m.getNumArgs());
    for(std::size_t i = 0; i < xs.size(); i++) {
        xs[i] = m.getArgAsFloat(i);
    }
}
// std::vector<float> xs;
ofxSubscribeOsc(port, "/xs", xs);

ofVec4f

// ofVec4f v4;
if(m.getAddress() == "/vec") {
    for(std::size_t i = 0; i < 4; i++) {
        v4[i] = m.getArgAsFloat(i);
    }
}

そのまま渡すと

// ofVec4f v4;
ofxSubscribeOsc(port, "/vec", v4);

もっと複雑な使い方

受信時に追加で処理したいときは

// int hoge1;
// std::string hoge2;
// bool hoge3;
ofxSubscribeOsc(port, "/hoge", [=](int x, std::string y, bool z) {
    hoge1 = x;
    hoge2 = y;
    hoge3 = z;
    doHogehoge();
});

もっとスマートに

// int hoge1;
// std::string hoge2;
// bool hoge3;
ofxSubscribeOsc(port, "/hoge", hoge1, hoge2, hoge3, [=]{ doHogehoge(); });

前処理もしたい

受信時に追加で処理したいときは

// int hoge1;
// std::string hoge2;
// bool hoge3;
ofxSubscribeOsc(port, "/hoge", [=](int x, std::string y, bool z) {
    wilHogeHoge();
    hoge1 = x;
    hoge2 = y;
    hoge3 = z;
    doHogehoge();
});

もっとスマートに

// int hoge1;
// std::string hoge2;
// bool hoge3;
ofxSubscribeOsc(port, "/hoge", [=]{ willHogehoge(); }, hoge1, hoge2, hoge3, [=] { doHogehoge(); });

こんなコードが

class ofApp : public ofBaseApp {
    ofxOscReceiver receiver;
    ofVec3f position;
    ofColor bgColor;
    ofColor fgColor;

public:
    void setup() {
        receiver.setup(26666);
    }
    void update() {
        while(receiver.hasWaitingMessages()) {
            ofxOscMessage m;
            receiver.getNextMessage(m);

            std::string address = m.getAddress();
            if(address == "/position") {
                position.x = m.getArgAsFloat(0);
                position.y = m.getArgAsFloat(1);
                position.z = m.getArgAsFloat(2);
            }
            else if(address == "/bg_color") {
                bgColor.r = m.getArgAsInt32(0);
                bgColor.g = m.getArgAsInt32(1);
                bgColor.b = m.getArgAsInt32(2);
            }
            else if(address == "/fg_color") {
                fgColor.r = m.getArgAsInt32(0);
                fgColor.g = m.getArgAsInt32(1);
                fgColor.b = m.getArgAsInt32(2);
            }
            else if(address == "/bg_auto") {
                bool b = m.getArgAsBool(0);
                ofSetBackgroundAuto(b);
            }
        }
    }
};

こんな感じに

class ofApp : public ofBaseApp {
    ofxOscReceiver receiver;
    ofVec3f position;
    ofColor bgColor;
    ofColor fgColor;
    std::uint16_t port{26666};
public:
    void setup() {
        ofxSubscribeOsc(port, "/position", position);
        ofxSubscribeOsc(port, "/bg_color", bgColor);
        ofxSubscribeOsc(port, "/fg_color", fgColor);
        ofxSubscribeOsc(port, "/bg_auto", ofSetBackgroundAuto);
    }
    void update() {
    }
};

スマートでしょ?

飽きてきた

質問等のコメント付いたら答えます.

気が向いたら次は ofxPublishOsc について書きます.
といってももっぱら ofxSubscribeOsc の方がニーズがある気がするので書かないかも.

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1