Bonjour/Zeroconf event handling within a loop

hello everybody, I am quite new to Cinder but I am loving it :slight_smile: so maybe my question could look trivial but any help is very welcome.
so I need to find the IPAddress of the Kyma hardware via Bonjour/Zeroconf. I am good at handling the Bonjour/Zeroconf framework with a C select()loop or using the CFNetowrk and Cocoa APIs. but it is not clear yet what would be the best option inside a Cinder sketch. do I have a to create multiple threads? or is there any other convenient way to have loop and asynchronous calls?
thank you.
d

In the past I’ve run things like this with callbacks that run on the main thread via the app’s io_service. Here’s a very dirty example but it demonstrates the mechanisms involved, i.e std::thread, cinder Signals, async posting to an io_service etc.

#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
#include "cinder/Rand.h"

using namespace ci;
using namespace ci::app;
using namespace std;

std::mutex kLogMutex;
#define SHITTY_THREADSAFE_LOG(x) \
{ \
    std::lock_guard<std::mutex> lock{kLogMutex};\
    std::cout << x << std::endl;\
}\

struct SomeFakeService
{
    SomeFakeService ( )
    : _thread ( [=] { ThreadedFunc(); } )
    {
        SHITTY_THREADSAFE_LOG("Starting Threaded Service");
    }
    
    ~SomeFakeService ( )
    {
        if ( _thread.joinable() ) _thread.join();
        SHITTY_THREADSAFE_LOG("Killing Threaded Service");
    }
    
    signals::Signal<void(int)> OnSomeEvent;
    std::atomic_bool Running{true};
    
protected:
    
    void ThreadedFunc ( )
    {
        while ( Running )
        {
            // Simulate some latency
            std::this_thread::sleep_for( std::chrono::milliseconds ( randInt(10, 2000) ) );
            int someValue = randInt(1, 100);
            
            SHITTY_THREADSAFE_LOG("Sending " << someValue << " from thread " << std::this_thread::get_id() );
            // Emit callback on the main thread on the next call to App::update()
            App::get()->dispatchAsync( [=] { OnSomeEvent.emit( someValue ); } );
        }
    }
    
    std::thread _thread;
};

class TestApp : public App
{
public:
    
    SomeFakeService service;
    
    void setup ( ) override
    {
        service.OnSomeEvent.connect( [=] ( int someValue )
        {
            assert ( app::isMainThread() );
            SHITTY_THREADSAFE_LOG("Received " << someValue << " back on the main thread: " << std::this_thread::get_id() );
        } );
    }
    
    void draw ( ) override { gl::clear(); };
    void cleanup ( ) override { service.Running = false; }
};

CINDER_APP ( TestApp, RendererGl() );
1 Like

thanks Lithium, it was really helpful! you are the best :slight_smile: