upgrade to JUCE 5.4.3. Remove (probably) unused JUCE modules. Remove VST2 target (it's been end-of-life'd by Steinberg and by JUCE)
This commit is contained in:
@ -94,7 +94,7 @@ struct ChildProcessMaster::Connection : public InterprocessConnection,
|
||||
startThread (4);
|
||||
}
|
||||
|
||||
~Connection()
|
||||
~Connection() override
|
||||
{
|
||||
stopThread (10000);
|
||||
}
|
||||
@ -192,7 +192,7 @@ struct ChildProcessSlave::Connection : public InterprocessConnection,
|
||||
startThread (4);
|
||||
}
|
||||
|
||||
~Connection()
|
||||
~Connection() override
|
||||
{
|
||||
stopThread (10000);
|
||||
}
|
||||
|
@ -104,8 +104,6 @@ public:
|
||||
|
||||
private:
|
||||
struct Connection;
|
||||
friend struct Connection;
|
||||
friend struct ContainerDeletePolicy<Connection>;
|
||||
std::unique_ptr<Connection> connection;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessSlave)
|
||||
@ -194,8 +192,6 @@ private:
|
||||
std::unique_ptr<ChildProcess> childProcess;
|
||||
|
||||
struct Connection;
|
||||
friend struct Connection;
|
||||
friend struct ContainerDeletePolicy<Connection>;
|
||||
std::unique_ptr<Connection> connection;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessMaster)
|
||||
|
@ -59,6 +59,7 @@ bool InterprocessConnection::connectToSocket (const String& hostName,
|
||||
|
||||
if (socket->connect (hostName, portNumber, timeOutMillisecs))
|
||||
{
|
||||
threadIsRunning = true;
|
||||
connectionMadeInt();
|
||||
thread->startThread();
|
||||
return true;
|
||||
@ -130,7 +131,7 @@ bool InterprocessConnection::isConnected() const
|
||||
|
||||
return ((socket != nullptr && socket->isConnected())
|
||||
|| (pipe != nullptr && pipe->isOpen()))
|
||||
&& thread->isThreadRunning();
|
||||
&& threadIsRunning;
|
||||
}
|
||||
|
||||
String InterprocessConnection::getConnectedHostName() const
|
||||
@ -179,6 +180,8 @@ void InterprocessConnection::initialiseWithSocket (StreamingSocket* newSocket)
|
||||
{
|
||||
jassert (socket == nullptr && pipe == nullptr);
|
||||
socket.reset (newSocket);
|
||||
|
||||
threadIsRunning = true;
|
||||
connectionMadeInt();
|
||||
thread->startThread();
|
||||
}
|
||||
@ -187,6 +190,8 @@ void InterprocessConnection::initialiseWithPipe (NamedPipe* newPipe)
|
||||
{
|
||||
jassert (socket == nullptr && pipe == nullptr);
|
||||
pipe.reset (newPipe);
|
||||
|
||||
threadIsRunning = true;
|
||||
connectionMadeInt();
|
||||
thread->startThread();
|
||||
}
|
||||
@ -366,6 +371,8 @@ void InterprocessConnection::runThread()
|
||||
if (thread->threadShouldExit() || ! readNextMessage())
|
||||
break;
|
||||
}
|
||||
|
||||
threadIsRunning = false;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@ -197,9 +197,9 @@ private:
|
||||
int readData (void*, int);
|
||||
|
||||
struct ConnectionThread;
|
||||
friend struct ConnectionThread;
|
||||
friend struct ContainerDeletePolicy<ConnectionThread>;
|
||||
std::unique_ptr<ConnectionThread> thread;
|
||||
std::atomic<bool> threadIsRunning { false };
|
||||
|
||||
void runThread();
|
||||
int writeData (void*, int);
|
||||
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
InterprocessConnectionServer();
|
||||
|
||||
/** Destructor. */
|
||||
~InterprocessConnectionServer();
|
||||
~InterprocessConnectionServer() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Starts an internal thread which listens on the given port number.
|
||||
|
@ -0,0 +1,190 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
NetworkServiceDiscovery::Advertiser::Advertiser (const String& serviceTypeUID,
|
||||
const String& serviceDescription,
|
||||
int broadcastPortToUse, int connectionPort,
|
||||
RelativeTime minTimeBetweenBroadcasts)
|
||||
: Thread ("Discovery_broadcast"),
|
||||
message (serviceTypeUID), broadcastPort (broadcastPortToUse),
|
||||
minInterval (minTimeBetweenBroadcasts)
|
||||
{
|
||||
message.setAttribute ("id", Uuid().toString());
|
||||
message.setAttribute ("name", serviceDescription);
|
||||
message.setAttribute ("address", String());
|
||||
message.setAttribute ("port", connectionPort);
|
||||
|
||||
startThread (2);
|
||||
}
|
||||
|
||||
NetworkServiceDiscovery::Advertiser::~Advertiser()
|
||||
{
|
||||
stopThread (2000);
|
||||
socket.shutdown();
|
||||
}
|
||||
|
||||
void NetworkServiceDiscovery::Advertiser::run()
|
||||
{
|
||||
if (! socket.bindToPort (0))
|
||||
{
|
||||
jassertfalse;
|
||||
return;
|
||||
}
|
||||
|
||||
while (! threadShouldExit())
|
||||
{
|
||||
sendBroadcast();
|
||||
wait ((int) minInterval.inMilliseconds());
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkServiceDiscovery::Advertiser::sendBroadcast()
|
||||
{
|
||||
auto localAddress = IPAddress::getLocalAddress();
|
||||
message.setAttribute ("address", localAddress.toString());
|
||||
auto broadcastAddress = IPAddress::getInterfaceBroadcastAddress (localAddress);
|
||||
auto data = message.createDocument ({}, true, false);
|
||||
socket.write (broadcastAddress.toString(), broadcastPort, data.toRawUTF8(), (int) data.getNumBytesAsUTF8());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
NetworkServiceDiscovery::AvailableServiceList::AvailableServiceList (const String& serviceType, int broadcastPort)
|
||||
: Thread ("Discovery_listen"), serviceTypeUID (serviceType)
|
||||
{
|
||||
socket.bindToPort (broadcastPort);
|
||||
startThread (2);
|
||||
}
|
||||
|
||||
NetworkServiceDiscovery::AvailableServiceList::~AvailableServiceList()
|
||||
{
|
||||
socket.shutdown();
|
||||
stopThread (2000);
|
||||
}
|
||||
|
||||
void NetworkServiceDiscovery::AvailableServiceList::run()
|
||||
{
|
||||
while (! threadShouldExit())
|
||||
{
|
||||
if (socket.waitUntilReady (true, 200) == 1)
|
||||
{
|
||||
char buffer[1024];
|
||||
auto bytesRead = socket.read (buffer, sizeof (buffer) - 1, false);
|
||||
|
||||
if (bytesRead > 10)
|
||||
if (auto xml = parseXML (String (CharPointer_UTF8 (buffer),
|
||||
CharPointer_UTF8 (buffer + bytesRead))))
|
||||
if (xml->hasTagName (serviceTypeUID))
|
||||
handleMessage (*xml);
|
||||
}
|
||||
|
||||
removeTimedOutServices();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<NetworkServiceDiscovery::Service> NetworkServiceDiscovery::AvailableServiceList::getServices() const
|
||||
{
|
||||
const ScopedLock sl (listLock);
|
||||
auto listCopy = services;
|
||||
return listCopy;
|
||||
}
|
||||
|
||||
void NetworkServiceDiscovery::AvailableServiceList::handleAsyncUpdate()
|
||||
{
|
||||
if (onChange != nullptr)
|
||||
onChange();
|
||||
}
|
||||
|
||||
void NetworkServiceDiscovery::AvailableServiceList::handleMessage (const XmlElement& xml)
|
||||
{
|
||||
Service service;
|
||||
service.instanceID = xml.getStringAttribute ("id");
|
||||
|
||||
if (service.instanceID.trim().isNotEmpty())
|
||||
{
|
||||
service.description = xml.getStringAttribute ("name");
|
||||
service.address = IPAddress (xml.getStringAttribute ("address"));
|
||||
service.port = xml.getIntAttribute ("port");
|
||||
service.lastSeen = Time::getCurrentTime();
|
||||
|
||||
handleMessage (service);
|
||||
}
|
||||
}
|
||||
|
||||
static void sortServiceList (std::vector<NetworkServiceDiscovery::Service>& services)
|
||||
{
|
||||
auto compareServices = [] (const NetworkServiceDiscovery::Service& s1,
|
||||
const NetworkServiceDiscovery::Service& s2)
|
||||
{
|
||||
return s1.instanceID < s2.instanceID;
|
||||
};
|
||||
|
||||
std::sort (services.begin(), services.end(), compareServices);
|
||||
}
|
||||
|
||||
void NetworkServiceDiscovery::AvailableServiceList::handleMessage (const Service& service)
|
||||
{
|
||||
const ScopedLock sl (listLock);
|
||||
|
||||
for (auto& s : services)
|
||||
{
|
||||
if (s.instanceID == service.instanceID)
|
||||
{
|
||||
if (s.description != service.description
|
||||
|| s.address != service.address
|
||||
|| s.port != service.port)
|
||||
{
|
||||
s = service;
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
|
||||
s.lastSeen = service.lastSeen;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
services.push_back (service);
|
||||
sortServiceList (services);
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
|
||||
void NetworkServiceDiscovery::AvailableServiceList::removeTimedOutServices()
|
||||
{
|
||||
const double timeoutSeconds = 5.0;
|
||||
auto oldestAllowedTime = Time::getCurrentTime() - RelativeTime::seconds (timeoutSeconds);
|
||||
|
||||
const ScopedLock sl (listLock);
|
||||
|
||||
auto oldEnd = std::end (services);
|
||||
auto newEnd = std::remove_if (std::begin (services), oldEnd,
|
||||
[=] (const Service& s) { return s.lastSeen < oldestAllowedTime; });
|
||||
|
||||
if (newEnd != oldEnd)
|
||||
{
|
||||
services.erase (newEnd, oldEnd);
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace juce
|
128
modules/juce_events/interprocess/juce_NetworkServiceDiscovery.h
Normal file
128
modules/juce_events/interprocess/juce_NetworkServiceDiscovery.h
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
The code included in this file is provided under the terms of the ISC license
|
||||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
without fee is hereby granted provided that the above copyright notice and
|
||||
this permission notice appear in all copies.
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Contains classes that implement a simple protocol for broadcasting the availability
|
||||
and location of a discoverable service on the local network, and for maintaining a
|
||||
list of known services.
|
||||
*/
|
||||
struct NetworkServiceDiscovery
|
||||
{
|
||||
/** An object which runs a thread to repeatedly broadcast the existence of a
|
||||
discoverable service.
|
||||
|
||||
To use, simply create an instance of an Advertiser and it'll broadcast until
|
||||
you delete it.
|
||||
*/
|
||||
struct Advertiser : private Thread
|
||||
{
|
||||
/** Creates and starts an Advertiser thread, broadcasting with the given properties.
|
||||
@param serviceTypeUID A user-supplied string to define the type of service this represents
|
||||
@param serviceDescription A description string that will appear in the Service::description field for clients
|
||||
@param broadcastPort The port number on which to broadcast the service discovery packets
|
||||
@param connectionPort The port number that will be sent to appear in the Service::port field
|
||||
@param minTimeBetweenBroadcasts The interval to wait between sending broadcast messages
|
||||
*/
|
||||
Advertiser (const String& serviceTypeUID,
|
||||
const String& serviceDescription,
|
||||
int broadcastPort,
|
||||
int connectionPort,
|
||||
RelativeTime minTimeBetweenBroadcasts = RelativeTime::seconds (1.5));
|
||||
|
||||
/** Destructor */
|
||||
~Advertiser() override;
|
||||
|
||||
private:
|
||||
XmlElement message;
|
||||
const int broadcastPort;
|
||||
const RelativeTime minInterval;
|
||||
DatagramSocket socket { true };
|
||||
|
||||
void run() override;
|
||||
void sendBroadcast();
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Contains information about a service that has been found on the network.
|
||||
@see AvailableServiceList, Advertiser
|
||||
*/
|
||||
struct Service
|
||||
{
|
||||
String instanceID; /**< A UUID that identifies the particular instance of the Advertiser class. */
|
||||
String description; /**< The service description as sent by the Advertiser */
|
||||
IPAddress address; /**< The IP address of the advertiser */
|
||||
int port; /**< The port number of the advertiser */
|
||||
Time lastSeen; /**< The time of the last ping received from the advertiser */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Watches the network for broadcasts from Advertiser objects, and keeps a list of
|
||||
all the currently active instances.
|
||||
|
||||
Just create an instance of AvailableServiceList and it will start listening - you
|
||||
can register a callback with its onChange member to find out when services
|
||||
appear/disappear, and you can call getServices() to find out the current list.
|
||||
@see Service, Advertiser
|
||||
*/
|
||||
struct AvailableServiceList : private Thread,
|
||||
private AsyncUpdater
|
||||
{
|
||||
/** Creates an AvailableServiceList that will bind to the given port number and watch
|
||||
the network for Advertisers broadcasting the given service type.
|
||||
|
||||
This will only detect broadcasts from an Advertiser object with a matching
|
||||
serviceTypeUID value, and where the broadcastPort matches.
|
||||
*/
|
||||
AvailableServiceList (const String& serviceTypeUID, int broadcastPort);
|
||||
|
||||
/** Destructor */
|
||||
~AvailableServiceList() override;
|
||||
|
||||
/** A lambda that can be set to recieve a callback when the list changes */
|
||||
std::function<void()> onChange;
|
||||
|
||||
/** Returns a list of the currently known services. */
|
||||
std::vector<Service> getServices() const;
|
||||
|
||||
private:
|
||||
DatagramSocket socket { true };
|
||||
String serviceTypeUID;
|
||||
CriticalSection listLock;
|
||||
std::vector<Service> services;
|
||||
|
||||
void run() override;
|
||||
void handleAsyncUpdate() override;
|
||||
void handleMessage (const XmlElement&);
|
||||
void handleMessage (const Service&);
|
||||
void removeTimedOutServices();
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AvailableServiceList)
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace juce
|
Reference in New Issue
Block a user