Just for this thread to be somewhat useful to readers of the forum, here’s what worked for me.
The main program here is based on the main program in the juced tutorial, however I’ve omitted the code for the TextConsole component for the sake of brevity. It’s an on-screen text component that you can post text strings to, so nothing worth posting here, you can see it in the juced tutorial.
To the best of my understanding the code below is the minimum necessary to start a thread listening for UDP packets, and to communicate properly between the listener thread and the main application thread.
[code]#ifndef JUCER_HEADER_MAINCOMPONENT_MAINCOMPONENT_D0F6CD31
#define JUCER_HEADER_MAINCOMPONENT_MAINCOMPONENT_D0F6CD31
#include “…/Juce Library Code/JuceHeader.h”
#include “TextConsole.h”
#include “OSC\OSC_Listener.h”
class MainComponent : public Component
{
public:
MainComponent();
~MainComponent();
void resized();
void appendMessage (const String& message);
juce_UseDebuggingNewOperator
private:
OSC_Listener* m_OSCListener;
TextConsole* console;
// (prevent copy constructor and operator= being generated..)
MainComponent (const MainComponent&);
MainComponent& operator= (const MainComponent&);
};
#endif // JUCER_HEADER_MAINCOMPONENT_MAINCOMPONENT_D0F6CD31
[/code]
[code]#include “MainComponent.h”
MainComponent::MainComponent()
{
console = new TextConsole();
addAndMakeVisible(console);
setSize (580, 800);
m_OSCListener = new OSC_Listener(*this, 6666);
m_OSCListener->startThread();
}
void MainComponent::appendMessage(const String& message)
{
console->addLine(message);
}
MainComponent::~MainComponent()
{
delete m_OSCListener;
deleteAllChildren();
}
//==============================================================================
void MainComponent::resized()
{
console->setBounds (10, getHeight() - 500, getWidth() - 20, 490);
}
[/code]
[code]#ifndef OSC_LISTENER_H
#define OSC_LISTENER_H
#include “…/…/Juce Library Code/JuceHeader.h”
class MainComponent;
class OSC_Listener: public Thread, private MessageListener
{
public:
OSC_Listener::OSC_Listener(MainComponent& owner_, int port);
~OSC_Listener();
void handleMessage (const Message& message);
void run();
protected:
private:
int m_Port;
ScopedPointer <MemoryBlock> messageData;
ScopedPointer <DatagramSocket> socket;
MainComponent& owner;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSC_Listener);
};
#endif[/code]
[code]#include “OSC_Listener.h”
#include “…/MainComponent.h”
OSC_Listener::OSC_Listener(MainComponent& owner_, int port) : Thread (“OSC_Listener Thread”), owner (owner_), m_Port(port)
{
}
OSC_Listener::~OSC_Listener()
{
signalThreadShouldExit();
if (socket != 0)
socket->close();
// allow the thread 2 seconds to stop cleanly - should be plenty of time.
stopThread (2000);
}
void OSC_Listener::handleMessage (const Message& message)
{
if(message.intParameter1 == 1) // 1 means I’ve received stuff.
{
int length = message.intParameter2;
ScopedPointer <MemoryBlock> data (static_cast <MemoryBlock*> (message.pointerParameter));
// Here you can do whatever you see fit to the packet received.
// ProcessPacket(…);
// And here, just to demonstrate how this thread can then talk back to the thread where it was started, I create a String which could otherwise also have been derived from the received packet content…
String toPrint(“Here you can put the message you got”);
owner.appendMessage(toPrint);
}
}
void OSC_Listener::run()
{
messageData = new MemoryBlock(65535, true);
socket = new DatagramSocket(m_Port);
int readyForReading;
int bytesRead;
// threadShouldExit() returns true when the stopThread() method has been
// called, so we should check it often, and exit as soon as it gets flagged.
while (! threadShouldExit())
{
// What should I have as a timeout value here? -1 seems to work, but then "threadShouldExit()" is never checked. 1000 is probably a better choice.
readyForReading = socket->waitUntilReady( true , 1000 );
if(readyForReading>0)
{
bytesRead = socket->read(static_cast <char*> (messageData->getData()), 65535, false );
postMessage(new Message(1, bytesRead, 0, new MemoryBlock(*messageData)));
}
}
}
[/code]