mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Naming: Fix up naming of ChildProcessCoordinator and ChildProcessWorker
This commit is contained in:
parent
6ae1137d91
commit
b72b155443
13 changed files with 194 additions and 146 deletions
|
|
@ -97,7 +97,7 @@ public:
|
||||||
testResultsBox.setMultiLine (true);
|
testResultsBox.setMultiLine (true);
|
||||||
testResultsBox.setFont ({ Font::getDefaultMonospacedFontName(), 12.0f, Font::plain });
|
testResultsBox.setFont ({ Font::getDefaultMonospacedFontName(), 12.0f, Font::plain });
|
||||||
|
|
||||||
logMessage (String ("This demo uses the ChildProcessMaster and ChildProcessSlave classes to launch and communicate "
|
logMessage (String ("This demo uses the ChildProcessCoordinator and ChildProcessWorker classes to launch and communicate "
|
||||||
"with a child process, sending messages in the form of serialised ValueTree objects.") + newLine);
|
"with a child process, sending messages in the form of serialised ValueTree objects.") + newLine);
|
||||||
|
|
||||||
setSize (500, 500);
|
setSize (500, 500);
|
||||||
|
|
@ -105,7 +105,7 @@ public:
|
||||||
|
|
||||||
~ChildProcessDemo() override
|
~ChildProcessDemo() override
|
||||||
{
|
{
|
||||||
masterProcess.reset();
|
coordinatorProcess.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void paint (Graphics& g) override
|
void paint (Graphics& g) override
|
||||||
|
|
@ -134,11 +134,11 @@ public:
|
||||||
// invoked by the 'launch' button.
|
// invoked by the 'launch' button.
|
||||||
void launchChildProcess()
|
void launchChildProcess()
|
||||||
{
|
{
|
||||||
if (masterProcess.get() == nullptr)
|
if (coordinatorProcess.get() == nullptr)
|
||||||
{
|
{
|
||||||
masterProcess.reset (new DemoMasterProcess (*this));
|
coordinatorProcess.reset (new DemoCoordinatorProcess (*this));
|
||||||
|
|
||||||
if (masterProcess->launchSlaveProcess (File::getSpecialLocation (File::currentExecutableFile), demoCommandLineUID))
|
if (coordinatorProcess->launchWorkerProcess (File::getSpecialLocation (File::currentExecutableFile), demoCommandLineUID))
|
||||||
logMessage ("Child process started");
|
logMessage ("Child process started");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -146,8 +146,8 @@ public:
|
||||||
// invoked by the 'ping' button.
|
// invoked by the 'ping' button.
|
||||||
void pingChildProcess()
|
void pingChildProcess()
|
||||||
{
|
{
|
||||||
if (masterProcess.get() != nullptr)
|
if (coordinatorProcess.get() != nullptr)
|
||||||
masterProcess->sendPingMessageToSlave();
|
coordinatorProcess->sendPingMessageToWorker();
|
||||||
else
|
else
|
||||||
logMessage ("Child process is not running!");
|
logMessage ("Child process is not running!");
|
||||||
}
|
}
|
||||||
|
|
@ -155,45 +155,45 @@ public:
|
||||||
// invoked by the 'kill' button.
|
// invoked by the 'kill' button.
|
||||||
void killChildProcess()
|
void killChildProcess()
|
||||||
{
|
{
|
||||||
if (masterProcess.get() != nullptr)
|
if (coordinatorProcess.get() != nullptr)
|
||||||
{
|
{
|
||||||
masterProcess.reset();
|
coordinatorProcess.reset();
|
||||||
logMessage ("Child process killed");
|
logMessage ("Child process killed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// This class is used by the main process, acting as the master and receiving messages
|
// This class is used by the main process, acting as the coordinator and receiving messages
|
||||||
// from the slave process.
|
// from the worker process.
|
||||||
class DemoMasterProcess : public ChildProcessMaster,
|
class DemoCoordinatorProcess : public ChildProcessCoordinator,
|
||||||
private DeletedAtShutdown
|
private DeletedAtShutdown
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DemoMasterProcess (ChildProcessDemo& d) : demo (d) {}
|
DemoCoordinatorProcess (ChildProcessDemo& d) : demo (d) {}
|
||||||
|
|
||||||
// This gets called when a message arrives from the slave process..
|
// This gets called when a message arrives from the worker process..
|
||||||
void handleMessageFromSlave (const MemoryBlock& mb) override
|
void handleMessageFromWorker (const MemoryBlock& mb) override
|
||||||
{
|
{
|
||||||
auto incomingMessage = memoryBlockToValueTree (mb);
|
auto incomingMessage = memoryBlockToValueTree (mb);
|
||||||
|
|
||||||
demo.logMessage ("Received: " + valueTreeToString (incomingMessage));
|
demo.logMessage ("Received: " + valueTreeToString (incomingMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This gets called if the slave process dies.
|
// This gets called if the worker process dies.
|
||||||
void handleConnectionLost() override
|
void handleConnectionLost() override
|
||||||
{
|
{
|
||||||
demo.logMessage ("Connection lost to child process!");
|
demo.logMessage ("Connection lost to child process!");
|
||||||
demo.killChildProcess();
|
demo.killChildProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendPingMessageToSlave()
|
void sendPingMessageToWorker()
|
||||||
{
|
{
|
||||||
ValueTree message ("MESSAGE");
|
ValueTree message ("MESSAGE");
|
||||||
message.setProperty ("count", count++, nullptr);
|
message.setProperty ("count", count++, nullptr);
|
||||||
|
|
||||||
demo.logMessage ("Sending: " + valueTreeToString (message));
|
demo.logMessage ("Sending: " + valueTreeToString (message));
|
||||||
|
|
||||||
sendMessageToSlave (valueTreeToMemoryBlock (message));
|
sendMessageToWorker (valueTreeToMemoryBlock (message));
|
||||||
}
|
}
|
||||||
|
|
||||||
ChildProcessDemo& demo;
|
ChildProcessDemo& demo;
|
||||||
|
|
@ -201,7 +201,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
std::unique_ptr<DemoMasterProcess> masterProcess;
|
std::unique_ptr<DemoCoordinatorProcess> coordinatorProcess;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextButton launchButton { "Launch Child Process" };
|
TextButton launchButton { "Launch Child Process" };
|
||||||
|
|
@ -234,15 +234,15 @@ private:
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/* This class gets instantiated in the child process, and receives messages from
|
/* This class gets instantiated in the child process, and receives messages from
|
||||||
the master process.
|
the coordinator process.
|
||||||
*/
|
*/
|
||||||
class DemoSlaveProcess : public ChildProcessSlave,
|
class DemoWorkerProcess : public ChildProcessWorker,
|
||||||
private DeletedAtShutdown
|
private DeletedAtShutdown
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DemoSlaveProcess() {}
|
DemoWorkerProcess() = default;
|
||||||
|
|
||||||
void handleMessageFromMaster (const MemoryBlock& mb) override
|
void handleMessageFromCoordinator (const MemoryBlock& mb) override
|
||||||
{
|
{
|
||||||
ValueTree incomingMessage (memoryBlockToValueTree (mb));
|
ValueTree incomingMessage (memoryBlockToValueTree (mb));
|
||||||
|
|
||||||
|
|
@ -256,7 +256,7 @@ public:
|
||||||
ValueTree reply ("REPLY");
|
ValueTree reply ("REPLY");
|
||||||
reply.setProperty ("countPlusOne", static_cast<int> (incomingMessage["count"]) + 1, nullptr);
|
reply.setProperty ("countPlusOne", static_cast<int> (incomingMessage["count"]) + 1, nullptr);
|
||||||
|
|
||||||
sendMessageToMaster (valueTreeToMemoryBlock (reply));
|
sendMessageToCoordinator (valueTreeToMemoryBlock (reply));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleConnectionMade() override
|
void handleConnectionMade() override
|
||||||
|
|
@ -264,10 +264,10 @@ public:
|
||||||
// This method is called when the connection is established, and in response, we'll just
|
// This method is called when the connection is established, and in response, we'll just
|
||||||
// send off a message to say hello.
|
// send off a message to say hello.
|
||||||
ValueTree reply ("HelloWorld");
|
ValueTree reply ("HelloWorld");
|
||||||
sendMessageToMaster (valueTreeToMemoryBlock (reply));
|
sendMessageToCoordinator (valueTreeToMemoryBlock (reply));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If no pings are received from the master process for a number of seconds, then this will get invoked.
|
/* If no pings are received from the coordinator process for a number of seconds, then this will get invoked.
|
||||||
Typically you'll want to use this as a signal to kill the process as quickly as possible, as you
|
Typically you'll want to use this as a signal to kill the process as quickly as possible, as you
|
||||||
don't want to leave it hanging around as a zombie..
|
don't want to leave it hanging around as a zombie..
|
||||||
*/
|
*/
|
||||||
|
|
@ -284,11 +284,11 @@ public:
|
||||||
*/
|
*/
|
||||||
bool invokeChildProcessDemo (const String& commandLine)
|
bool invokeChildProcessDemo (const String& commandLine)
|
||||||
{
|
{
|
||||||
std::unique_ptr<DemoSlaveProcess> slave (new DemoSlaveProcess());
|
std::unique_ptr<DemoWorkerProcess> worker (new DemoWorkerProcess());
|
||||||
|
|
||||||
if (slave->initialiseFromCommandLine (commandLine, demoCommandLineUID))
|
if (worker->initialiseFromCommandLine (commandLine, demoCommandLineUID))
|
||||||
{
|
{
|
||||||
slave.release(); // allow the slave object to stay alive - it'll handle its own deletion.
|
worker.release(); // allow the worker object to stay alive - it'll handle its own deletion.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
#error "If you're building the audio plugin host, you probably want to enable VST and/or AU support"
|
#error "If you're building the audio plugin host, you probably want to enable VST and/or AU support"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class PluginScannerSubprocess : private ChildProcessSlave,
|
class PluginScannerSubprocess : private ChildProcessWorker,
|
||||||
private AsyncUpdater
|
private AsyncUpdater
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -40,10 +40,10 @@ public:
|
||||||
formatManager.addDefaultFormats();
|
formatManager.addDefaultFormats();
|
||||||
}
|
}
|
||||||
|
|
||||||
using ChildProcessSlave::initialiseFromCommandLine;
|
using ChildProcessWorker::initialiseFromCommandLine;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleMessageFromMaster (const MemoryBlock& mb) override
|
void handleMessageFromCoordinator (const MemoryBlock& mb) override
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock (mutex);
|
const std::lock_guard<std::mutex> lock (mutex);
|
||||||
|
|
@ -94,7 +94,7 @@ private:
|
||||||
xml.addChildElement (desc->createXml().release());
|
xml.addChildElement (desc->createXml().release());
|
||||||
|
|
||||||
const auto str = xml.toString();
|
const auto str = xml.toString();
|
||||||
sendMessageToMaster ({ str.toRawUTF8(), str.getNumBytesAsUTF8() });
|
sendMessageToCoordinator ({ str.toRawUTF8(), str.getNumBytesAsUTF8() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ public:
|
||||||
stream.writeString (format.getName());
|
stream.writeString (format.getName());
|
||||||
stream.writeString (fileOrIdentifier);
|
stream.writeString (fileOrIdentifier);
|
||||||
|
|
||||||
if (superprocess->sendMessageToSlave (block))
|
if (superprocess->sendMessageToWorker (block))
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock (mutex);
|
std::unique_lock<std::mutex> lock (mutex);
|
||||||
gotResponse = false;
|
gotResponse = false;
|
||||||
|
|
@ -123,17 +123,19 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Superprocess : public ChildProcessMaster
|
class Superprocess : private ChildProcessCoordinator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Superprocess (CustomPluginScanner& o)
|
explicit Superprocess (CustomPluginScanner& o)
|
||||||
: owner (o)
|
: owner (o)
|
||||||
{
|
{
|
||||||
launchSlaveProcess (File::getSpecialLocation (File::currentExecutableFile), processUID, 0, 0);
|
launchWorkerProcess (File::getSpecialLocation (File::currentExecutableFile), processUID, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using ChildProcessCoordinator::sendMessageToWorker;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleMessageFromSlave (const MemoryBlock& mb) override
|
void handleMessageFromWorker (const MemoryBlock& mb) override
|
||||||
{
|
{
|
||||||
auto xml = parseXML (mb.toString());
|
auto xml = parseXML (mb.toString());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ add_library( ${BINARY_NAME}
|
||||||
"../../../Source/Demos.h"
|
"../../../Source/Demos.h"
|
||||||
"../../../Source/Main.cpp"
|
"../../../Source/Main.cpp"
|
||||||
"../../../Source/MasterComponent.h"
|
"../../../Source/MasterComponent.h"
|
||||||
"../../../Source/SlaveComponent.h"
|
"../../../Source/ClientComponent.h"
|
||||||
"../../../Source/SharedCanvas.h"
|
"../../../Source/SharedCanvas.h"
|
||||||
"../../../Source/juce_icon.png"
|
"../../../Source/juce_icon.png"
|
||||||
"../../../../../modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h"
|
"../../../../../modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h"
|
||||||
|
|
@ -1623,7 +1623,7 @@ add_library( ${BINARY_NAME}
|
||||||
|
|
||||||
set_source_files_properties("../../../Source/Demos.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
set_source_files_properties("../../../Source/Demos.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
set_source_files_properties("../../../Source/MasterComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
set_source_files_properties("../../../Source/MasterComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
set_source_files_properties("../../../Source/SlaveComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
set_source_files_properties("../../../Source/ClientComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
set_source_files_properties("../../../Source/SharedCanvas.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
set_source_files_properties("../../../Source/SharedCanvas.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
set_source_files_properties("../../../Source/juce_icon.png" PROPERTIES HEADER_FILE_ONLY TRUE)
|
set_source_files_properties("../../../Source/juce_icon.png" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
set_source_files_properties("../../../../../modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
set_source_files_properties("../../../../../modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h" PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,6 @@
|
||||||
7BE6330821794919A88ED8ED /* include_juce_gui_extra.mm */ /* include_juce_gui_extra.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_gui_extra.mm; path = ../../JuceLibraryCode/include_juce_gui_extra.mm; sourceTree = SOURCE_ROOT; };
|
7BE6330821794919A88ED8ED /* include_juce_gui_extra.mm */ /* include_juce_gui_extra.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_gui_extra.mm; path = ../../JuceLibraryCode/include_juce_gui_extra.mm; sourceTree = SOURCE_ROOT; };
|
||||||
84B287BB2AD252B7D69AC47E /* include_juce_gui_basics.mm */ /* include_juce_gui_basics.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_gui_basics.mm; path = ../../JuceLibraryCode/include_juce_gui_basics.mm; sourceTree = SOURCE_ROOT; };
|
84B287BB2AD252B7D69AC47E /* include_juce_gui_basics.mm */ /* include_juce_gui_basics.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_gui_basics.mm; path = ../../JuceLibraryCode/include_juce_gui_basics.mm; sourceTree = SOURCE_ROOT; };
|
||||||
89583CD42AD218E9753DF11C /* juce_audio_devices */ /* juce_audio_devices */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_audio_devices; path = ../../../../modules/juce_audio_devices; sourceTree = SOURCE_ROOT; };
|
89583CD42AD218E9753DF11C /* juce_audio_devices */ /* juce_audio_devices */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_audio_devices; path = ../../../../modules/juce_audio_devices; sourceTree = SOURCE_ROOT; };
|
||||||
8E2F72AFA0CDA64F0C07F105 /* SlaveComponent.h */ /* SlaveComponent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SlaveComponent.h; path = ../../Source/SlaveComponent.h; sourceTree = SOURCE_ROOT; };
|
|
||||||
8EACAADD3A23DED3E252C92F /* juce_core */ /* juce_core */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_core; path = ../../../../modules/juce_core; sourceTree = SOURCE_ROOT; };
|
8EACAADD3A23DED3E252C92F /* juce_core */ /* juce_core */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_core; path = ../../../../modules/juce_core; sourceTree = SOURCE_ROOT; };
|
||||||
92800676AF753D1A60108F11 /* BinaryData.h */ /* BinaryData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BinaryData.h; path = ../../JuceLibraryCode/BinaryData.h; sourceTree = SOURCE_ROOT; };
|
92800676AF753D1A60108F11 /* BinaryData.h */ /* BinaryData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BinaryData.h; path = ../../JuceLibraryCode/BinaryData.h; sourceTree = SOURCE_ROOT; };
|
||||||
935CA85EF98714D3A17AE737 /* QuartzCore.framework */ /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
935CA85EF98714D3A17AE737 /* QuartzCore.framework */ /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||||
|
|
@ -83,6 +82,7 @@
|
||||||
AFF729977947528F3E4AAA96 /* include_juce_cryptography.mm */ /* include_juce_cryptography.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_cryptography.mm; path = ../../JuceLibraryCode/include_juce_cryptography.mm; sourceTree = SOURCE_ROOT; };
|
AFF729977947528F3E4AAA96 /* include_juce_cryptography.mm */ /* include_juce_cryptography.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_cryptography.mm; path = ../../JuceLibraryCode/include_juce_cryptography.mm; sourceTree = SOURCE_ROOT; };
|
||||||
B5433B00F012AD87AADBFCD6 /* juce_cryptography */ /* juce_cryptography */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_cryptography; path = ../../../../modules/juce_cryptography; sourceTree = SOURCE_ROOT; };
|
B5433B00F012AD87AADBFCD6 /* juce_cryptography */ /* juce_cryptography */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_cryptography; path = ../../../../modules/juce_cryptography; sourceTree = SOURCE_ROOT; };
|
||||||
B76F10A7778664E164A01934 /* juce_audio_basics */ /* juce_audio_basics */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_audio_basics; path = ../../../../modules/juce_audio_basics; sourceTree = SOURCE_ROOT; };
|
B76F10A7778664E164A01934 /* juce_audio_basics */ /* juce_audio_basics */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_audio_basics; path = ../../../../modules/juce_audio_basics; sourceTree = SOURCE_ROOT; };
|
||||||
|
B9B80E3572715F63FFC3678B /* ClientComponent.h */ /* ClientComponent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ClientComponent.h; path = ../../Source/ClientComponent.h; sourceTree = SOURCE_ROOT; };
|
||||||
BA2E40409255F1B078406221 /* juce_data_structures */ /* juce_data_structures */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_data_structures; path = ../../../../modules/juce_data_structures; sourceTree = SOURCE_ROOT; };
|
BA2E40409255F1B078406221 /* juce_data_structures */ /* juce_data_structures */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_data_structures; path = ../../../../modules/juce_data_structures; sourceTree = SOURCE_ROOT; };
|
||||||
C6E2284D86D93F1D9D5C7666 /* include_juce_audio_formats.mm */ /* include_juce_audio_formats.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_audio_formats.mm; path = ../../JuceLibraryCode/include_juce_audio_formats.mm; sourceTree = SOURCE_ROOT; };
|
C6E2284D86D93F1D9D5C7666 /* include_juce_audio_formats.mm */ /* include_juce_audio_formats.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_audio_formats.mm; path = ../../JuceLibraryCode/include_juce_audio_formats.mm; sourceTree = SOURCE_ROOT; };
|
||||||
C78806A6727F44EACFDED4A5 /* Cocoa.framework */ /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
C78806A6727F44EACFDED4A5 /* Cocoa.framework */ /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||||
|
|
@ -138,7 +138,7 @@
|
||||||
4FF648D72D6F1A78956CDA1B,
|
4FF648D72D6F1A78956CDA1B,
|
||||||
77C0AC21C1028911123844FC,
|
77C0AC21C1028911123844FC,
|
||||||
9982F39121710EFFD5FEEAEF,
|
9982F39121710EFFD5FEEAEF,
|
||||||
8E2F72AFA0CDA64F0C07F105,
|
B9B80E3572715F63FFC3678B,
|
||||||
25DEDA8C9F94A6C8DFC8E53E,
|
25DEDA8C9F94A6C8DFC8E53E,
|
||||||
);
|
);
|
||||||
name = Source;
|
name = Source;
|
||||||
|
|
|
||||||
|
|
@ -2174,7 +2174,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\Source\Demos.h"/>
|
<ClInclude Include="..\..\Source\Demos.h"/>
|
||||||
<ClInclude Include="..\..\Source\MasterComponent.h"/>
|
<ClInclude Include="..\..\Source\MasterComponent.h"/>
|
||||||
<ClInclude Include="..\..\Source\SlaveComponent.h"/>
|
<ClInclude Include="..\..\Source\ClientComponent.h"/>
|
||||||
<ClInclude Include="..\..\Source\SharedCanvas.h"/>
|
<ClInclude Include="..\..\Source\SharedCanvas.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_basics\audio_play_head\juce_AudioPlayHead.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_basics\audio_play_head\juce_AudioPlayHead.h"/>
|
||||||
<ClInclude Include="..\..\..\..\modules\juce_audio_basics\buffers\juce_AudioChannelSet.h"/>
|
<ClInclude Include="..\..\..\..\modules\juce_audio_basics\buffers\juce_AudioChannelSet.h"/>
|
||||||
|
|
|
||||||
|
|
@ -2667,7 +2667,7 @@
|
||||||
<ClInclude Include="..\..\Source\MasterComponent.h">
|
<ClInclude Include="..\..\Source\MasterComponent.h">
|
||||||
<Filter>NetworkGraphicsDemo\Source</Filter>
|
<Filter>NetworkGraphicsDemo\Source</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\Source\SlaveComponent.h">
|
<ClInclude Include="..\..\Source\ClientComponent.h">
|
||||||
<Filter>NetworkGraphicsDemo\Source</Filter>
|
<Filter>NetworkGraphicsDemo\Source</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\Source\SharedCanvas.h">
|
<ClInclude Include="..\..\Source\SharedCanvas.h">
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,6 @@
|
||||||
7BE6330821794919A88ED8ED /* include_juce_gui_extra.mm */ /* include_juce_gui_extra.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_gui_extra.mm; path = ../../JuceLibraryCode/include_juce_gui_extra.mm; sourceTree = SOURCE_ROOT; };
|
7BE6330821794919A88ED8ED /* include_juce_gui_extra.mm */ /* include_juce_gui_extra.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_gui_extra.mm; path = ../../JuceLibraryCode/include_juce_gui_extra.mm; sourceTree = SOURCE_ROOT; };
|
||||||
84B287BB2AD252B7D69AC47E /* include_juce_gui_basics.mm */ /* include_juce_gui_basics.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_gui_basics.mm; path = ../../JuceLibraryCode/include_juce_gui_basics.mm; sourceTree = SOURCE_ROOT; };
|
84B287BB2AD252B7D69AC47E /* include_juce_gui_basics.mm */ /* include_juce_gui_basics.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_gui_basics.mm; path = ../../JuceLibraryCode/include_juce_gui_basics.mm; sourceTree = SOURCE_ROOT; };
|
||||||
89583CD42AD218E9753DF11C /* juce_audio_devices */ /* juce_audio_devices */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_audio_devices; path = ../../../../modules/juce_audio_devices; sourceTree = SOURCE_ROOT; };
|
89583CD42AD218E9753DF11C /* juce_audio_devices */ /* juce_audio_devices */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_audio_devices; path = ../../../../modules/juce_audio_devices; sourceTree = SOURCE_ROOT; };
|
||||||
8E2F72AFA0CDA64F0C07F105 /* SlaveComponent.h */ /* SlaveComponent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SlaveComponent.h; path = ../../Source/SlaveComponent.h; sourceTree = SOURCE_ROOT; };
|
|
||||||
8EACAADD3A23DED3E252C92F /* juce_core */ /* juce_core */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_core; path = ../../../../modules/juce_core; sourceTree = SOURCE_ROOT; };
|
8EACAADD3A23DED3E252C92F /* juce_core */ /* juce_core */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_core; path = ../../../../modules/juce_core; sourceTree = SOURCE_ROOT; };
|
||||||
9193D2A3C463BEAA07FD424D /* CoreText.framework */ /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
|
9193D2A3C463BEAA07FD424D /* CoreText.framework */ /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
|
||||||
92800676AF753D1A60108F11 /* BinaryData.h */ /* BinaryData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BinaryData.h; path = ../../JuceLibraryCode/BinaryData.h; sourceTree = SOURCE_ROOT; };
|
92800676AF753D1A60108F11 /* BinaryData.h */ /* BinaryData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BinaryData.h; path = ../../JuceLibraryCode/BinaryData.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
|
@ -88,6 +87,7 @@
|
||||||
AFF729977947528F3E4AAA96 /* include_juce_cryptography.mm */ /* include_juce_cryptography.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_cryptography.mm; path = ../../JuceLibraryCode/include_juce_cryptography.mm; sourceTree = SOURCE_ROOT; };
|
AFF729977947528F3E4AAA96 /* include_juce_cryptography.mm */ /* include_juce_cryptography.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_cryptography.mm; path = ../../JuceLibraryCode/include_juce_cryptography.mm; sourceTree = SOURCE_ROOT; };
|
||||||
B5433B00F012AD87AADBFCD6 /* juce_cryptography */ /* juce_cryptography */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_cryptography; path = ../../../../modules/juce_cryptography; sourceTree = SOURCE_ROOT; };
|
B5433B00F012AD87AADBFCD6 /* juce_cryptography */ /* juce_cryptography */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_cryptography; path = ../../../../modules/juce_cryptography; sourceTree = SOURCE_ROOT; };
|
||||||
B76F10A7778664E164A01934 /* juce_audio_basics */ /* juce_audio_basics */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_audio_basics; path = ../../../../modules/juce_audio_basics; sourceTree = SOURCE_ROOT; };
|
B76F10A7778664E164A01934 /* juce_audio_basics */ /* juce_audio_basics */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_audio_basics; path = ../../../../modules/juce_audio_basics; sourceTree = SOURCE_ROOT; };
|
||||||
|
B9B80E3572715F63FFC3678B /* ClientComponent.h */ /* ClientComponent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ClientComponent.h; path = ../../Source/ClientComponent.h; sourceTree = SOURCE_ROOT; };
|
||||||
BA2E40409255F1B078406221 /* juce_data_structures */ /* juce_data_structures */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_data_structures; path = ../../../../modules/juce_data_structures; sourceTree = SOURCE_ROOT; };
|
BA2E40409255F1B078406221 /* juce_data_structures */ /* juce_data_structures */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_data_structures; path = ../../../../modules/juce_data_structures; sourceTree = SOURCE_ROOT; };
|
||||||
C6E2284D86D93F1D9D5C7666 /* include_juce_audio_formats.mm */ /* include_juce_audio_formats.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_audio_formats.mm; path = ../../JuceLibraryCode/include_juce_audio_formats.mm; sourceTree = SOURCE_ROOT; };
|
C6E2284D86D93F1D9D5C7666 /* include_juce_audio_formats.mm */ /* include_juce_audio_formats.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_audio_formats.mm; path = ../../JuceLibraryCode/include_juce_audio_formats.mm; sourceTree = SOURCE_ROOT; };
|
||||||
C821C5805007FFDC2636BBE6 /* OpenGLES.framework */ /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
|
C821C5805007FFDC2636BBE6 /* OpenGLES.framework */ /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
|
||||||
|
|
@ -147,7 +147,7 @@
|
||||||
4FF648D72D6F1A78956CDA1B,
|
4FF648D72D6F1A78956CDA1B,
|
||||||
77C0AC21C1028911123844FC,
|
77C0AC21C1028911123844FC,
|
||||||
9982F39121710EFFD5FEEAEF,
|
9982F39121710EFFD5FEEAEF,
|
||||||
8E2F72AFA0CDA64F0C07F105,
|
B9B80E3572715F63FFC3678B,
|
||||||
25DEDA8C9F94A6C8DFC8E53E,
|
25DEDA8C9F94A6C8DFC8E53E,
|
||||||
);
|
);
|
||||||
name = Source;
|
name = Source;
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
<FILE id="xdUc9q" name="Main.cpp" compile="1" resource="0" file="Source/Main.cpp"/>
|
<FILE id="xdUc9q" name="Main.cpp" compile="1" resource="0" file="Source/Main.cpp"/>
|
||||||
<FILE id="Vjuvqu" name="MasterComponent.h" compile="0" resource="0"
|
<FILE id="Vjuvqu" name="MasterComponent.h" compile="0" resource="0"
|
||||||
file="Source/MasterComponent.h"/>
|
file="Source/MasterComponent.h"/>
|
||||||
<FILE id="KbZNxO" name="SlaveComponent.h" compile="0" resource="0"
|
<FILE id="KbZNxO" name="ClientComponent.h" compile="0" resource="0"
|
||||||
file="Source/SlaveComponent.h"/>
|
file="Source/ClientComponent.h"/>
|
||||||
<FILE id="F7A4kl" name="SharedCanvas.h" compile="0" resource="0" file="Source/SharedCanvas.h"/>
|
<FILE id="F7A4kl" name="SharedCanvas.h" compile="0" resource="0" file="Source/SharedCanvas.h"/>
|
||||||
</GROUP>
|
</GROUP>
|
||||||
<FILE id="Ww6bQw" name="juce_icon.png" compile="0" resource="1" file="Source/juce_icon.png"/>
|
<FILE id="Ww6bQw" name="juce_icon.png" compile="0" resource="1" file="Source/juce_icon.png"/>
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This component runs in a slave process, draws the part of the canvas that this
|
This component runs in a client process, draws the part of the canvas that this
|
||||||
particular client covers, and updates itself when messages arrive from the master
|
particular client covers, and updates itself when messages arrive from the master
|
||||||
containing new canvas states.
|
containing new canvas states.
|
||||||
*/
|
*/
|
||||||
class SlaveCanvasComponent : public Component,
|
class ClientCanvasComponent : public Component,
|
||||||
private OSCSender,
|
private OSCSender,
|
||||||
private OSCReceiver,
|
private OSCReceiver,
|
||||||
private OSCReceiver::Listener<OSCReceiver::RealtimeCallback>,
|
private OSCReceiver::Listener<OSCReceiver::RealtimeCallback>,
|
||||||
|
|
@ -37,7 +37,7 @@ class SlaveCanvasComponent : public Component,
|
||||||
private Timer
|
private Timer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SlaveCanvasComponent (PropertiesFile& p, int windowIndex) : properties (p)
|
ClientCanvasComponent (PropertiesFile& p, int windowIndex) : properties (p)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
String uuidPropName ("UUID" + String (windowIndex));
|
String uuidPropName ("UUID" + String (windowIndex));
|
||||||
|
|
@ -65,7 +65,7 @@ public:
|
||||||
startTimer (2000);
|
startTimer (2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
~SlaveCanvasComponent() override
|
~ClientCanvasComponent() override
|
||||||
{
|
{
|
||||||
OSCReceiver::removeListener (this);
|
OSCReceiver::removeListener (this);
|
||||||
}
|
}
|
||||||
|
|
@ -220,5 +220,5 @@ private:
|
||||||
CriticalSection canvasLock;
|
CriticalSection canvasLock;
|
||||||
BlockPacketiser packetiser;
|
BlockPacketiser packetiser;
|
||||||
|
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SlaveCanvasComponent)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ClientCanvasComponent)
|
||||||
};
|
};
|
||||||
|
|
@ -41,7 +41,7 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "SharedCanvas.h"
|
#include "SharedCanvas.h"
|
||||||
#include "SlaveComponent.h"
|
#include "ClientComponent.h"
|
||||||
#include "Demos.h"
|
#include "Demos.h"
|
||||||
#include "MasterComponent.h"
|
#include "MasterComponent.h"
|
||||||
|
|
||||||
|
|
@ -107,7 +107,7 @@ public:
|
||||||
: DocumentWindow ("JUCE Networked Graphics Demo", Colours::black, DocumentWindow::allButtons)
|
: DocumentWindow ("JUCE Networked Graphics Demo", Colours::black, DocumentWindow::allButtons)
|
||||||
{
|
{
|
||||||
setUsingNativeTitleBar (true);
|
setUsingNativeTitleBar (true);
|
||||||
setContentOwned (new SlaveCanvasComponent (props, windowIndex), true);
|
setContentOwned (new ClientCanvasComponent (props, windowIndex), true);
|
||||||
setBounds (500, 100, getWidth(), getHeight());
|
setBounds (500, 100, getWidth(), getHeight());
|
||||||
setResizable (true, false);
|
setResizable (true, false);
|
||||||
setVisible (true);
|
setVisible (true);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
namespace juce
|
namespace juce
|
||||||
{
|
{
|
||||||
|
|
||||||
enum { magicMastSlaveConnectionHeader = 0x712baf04 };
|
enum { magicCoordWorkerConnectionHeader = 0x712baf04 };
|
||||||
|
|
||||||
static const char* startMessage = "__ipc_st";
|
static const char* startMessage = "__ipc_st";
|
||||||
static const char* killMessage = "__ipc_k_";
|
static const char* killMessage = "__ipc_k_";
|
||||||
|
|
@ -82,11 +82,11 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
struct ChildProcessMaster::Connection : public InterprocessConnection,
|
struct ChildProcessCoordinator::Connection : public InterprocessConnection,
|
||||||
private ChildProcessPingThread
|
private ChildProcessPingThread
|
||||||
{
|
{
|
||||||
Connection (ChildProcessMaster& m, const String& pipeName, int timeout)
|
Connection (ChildProcessCoordinator& m, const String& pipeName, int timeout)
|
||||||
: InterprocessConnection (false, magicMastSlaveConnectionHeader),
|
: InterprocessConnection (false, magicCoordWorkerConnectionHeader),
|
||||||
ChildProcessPingThread (timeout),
|
ChildProcessPingThread (timeout),
|
||||||
owner (m)
|
owner (m)
|
||||||
{
|
{
|
||||||
|
|
@ -103,7 +103,7 @@ private:
|
||||||
void connectionMade() override {}
|
void connectionMade() override {}
|
||||||
void connectionLost() override { owner.handleConnectionLost(); }
|
void connectionLost() override { owner.handleConnectionLost(); }
|
||||||
|
|
||||||
bool sendPingMessage (const MemoryBlock& m) override { return owner.sendMessageToSlave (m); }
|
bool sendPingMessage (const MemoryBlock& m) override { return owner.sendMessageToWorker (m); }
|
||||||
void pingFailed() override { connectionLost(); }
|
void pingFailed() override { connectionLost(); }
|
||||||
|
|
||||||
void messageReceived (const MemoryBlock& m) override
|
void messageReceived (const MemoryBlock& m) override
|
||||||
|
|
@ -111,25 +111,34 @@ private:
|
||||||
pingReceived();
|
pingReceived();
|
||||||
|
|
||||||
if (m.getSize() != specialMessageSize || ! isMessageType (m, pingMessage))
|
if (m.getSize() != specialMessageSize || ! isMessageType (m, pingMessage))
|
||||||
owner.handleMessageFromSlave (m);
|
owner.handleMessageFromWorker (m);
|
||||||
}
|
}
|
||||||
|
|
||||||
ChildProcessMaster& owner;
|
ChildProcessCoordinator& owner;
|
||||||
|
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Connection)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Connection)
|
||||||
};
|
};
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
ChildProcessMaster::ChildProcessMaster() {}
|
ChildProcessCoordinator::ChildProcessCoordinator() = default;
|
||||||
|
|
||||||
ChildProcessMaster::~ChildProcessMaster()
|
ChildProcessCoordinator::~ChildProcessCoordinator()
|
||||||
{
|
{
|
||||||
killSlaveProcess();
|
killWorkerProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChildProcessMaster::handleConnectionLost() {}
|
void ChildProcessCoordinator::handleConnectionLost() {}
|
||||||
|
|
||||||
bool ChildProcessMaster::sendMessageToSlave (const MemoryBlock& mb)
|
void ChildProcessCoordinator::handleMessageFromWorker (const MemoryBlock& mb)
|
||||||
|
{
|
||||||
|
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations")
|
||||||
|
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996)
|
||||||
|
handleMessageFromSlave (mb);
|
||||||
|
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||||
|
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChildProcessCoordinator::sendMessageToWorker (const MemoryBlock& mb)
|
||||||
{
|
{
|
||||||
if (connection != nullptr)
|
if (connection != nullptr)
|
||||||
return connection->sendMessage (mb);
|
return connection->sendMessage (mb);
|
||||||
|
|
@ -138,10 +147,10 @@ bool ChildProcessMaster::sendMessageToSlave (const MemoryBlock& mb)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChildProcessMaster::launchSlaveProcess (const File& executable, const String& commandLineUniqueID,
|
bool ChildProcessCoordinator::launchWorkerProcess (const File& executable, const String& commandLineUniqueID,
|
||||||
int timeoutMs, int streamFlags)
|
int timeoutMs, int streamFlags)
|
||||||
{
|
{
|
||||||
killSlaveProcess();
|
killWorkerProcess();
|
||||||
|
|
||||||
auto pipeName = "p" + String::toHexString (Random().nextInt64());
|
auto pipeName = "p" + String::toHexString (Random().nextInt64());
|
||||||
|
|
||||||
|
|
@ -157,7 +166,7 @@ bool ChildProcessMaster::launchSlaveProcess (const File& executable, const Strin
|
||||||
|
|
||||||
if (connection->isConnected())
|
if (connection->isConnected())
|
||||||
{
|
{
|
||||||
sendMessageToSlave ({ startMessage, specialMessageSize });
|
sendMessageToWorker ({ startMessage, specialMessageSize });
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,11 +176,11 @@ bool ChildProcessMaster::launchSlaveProcess (const File& executable, const Strin
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChildProcessMaster::killSlaveProcess()
|
void ChildProcessCoordinator::killWorkerProcess()
|
||||||
{
|
{
|
||||||
if (connection != nullptr)
|
if (connection != nullptr)
|
||||||
{
|
{
|
||||||
sendMessageToSlave ({ killMessage, specialMessageSize });
|
sendMessageToWorker ({ killMessage, specialMessageSize });
|
||||||
connection->disconnect();
|
connection->disconnect();
|
||||||
connection.reset();
|
connection.reset();
|
||||||
}
|
}
|
||||||
|
|
@ -180,11 +189,11 @@ void ChildProcessMaster::killSlaveProcess()
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
struct ChildProcessSlave::Connection : public InterprocessConnection,
|
struct ChildProcessWorker::Connection : public InterprocessConnection,
|
||||||
private ChildProcessPingThread
|
private ChildProcessPingThread
|
||||||
{
|
{
|
||||||
Connection (ChildProcessSlave& p, const String& pipeName, int timeout)
|
Connection (ChildProcessWorker& p, const String& pipeName, int timeout)
|
||||||
: InterprocessConnection (false, magicMastSlaveConnectionHeader),
|
: InterprocessConnection (false, magicCoordWorkerConnectionHeader),
|
||||||
ChildProcessPingThread (timeout),
|
ChildProcessPingThread (timeout),
|
||||||
owner (p)
|
owner (p)
|
||||||
{
|
{
|
||||||
|
|
@ -198,12 +207,12 @@ struct ChildProcessSlave::Connection : public InterprocessConnection,
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ChildProcessSlave& owner;
|
ChildProcessWorker& owner;
|
||||||
|
|
||||||
void connectionMade() override {}
|
void connectionMade() override {}
|
||||||
void connectionLost() override { owner.handleConnectionLost(); }
|
void connectionLost() override { owner.handleConnectionLost(); }
|
||||||
|
|
||||||
bool sendPingMessage (const MemoryBlock& m) override { return owner.sendMessageToMaster (m); }
|
bool sendPingMessage (const MemoryBlock& m) override { return owner.sendMessageToCoordinator (m); }
|
||||||
void pingFailed() override { connectionLost(); }
|
void pingFailed() override { connectionLost(); }
|
||||||
|
|
||||||
void messageReceived (const MemoryBlock& m) override
|
void messageReceived (const MemoryBlock& m) override
|
||||||
|
|
@ -219,20 +228,29 @@ private:
|
||||||
if (isMessageType (m, startMessage))
|
if (isMessageType (m, startMessage))
|
||||||
return owner.handleConnectionMade();
|
return owner.handleConnectionMade();
|
||||||
|
|
||||||
owner.handleMessageFromMaster (m);
|
owner.handleMessageFromCoordinator (m);
|
||||||
}
|
}
|
||||||
|
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Connection)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Connection)
|
||||||
};
|
};
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
ChildProcessSlave::ChildProcessSlave() {}
|
ChildProcessWorker::ChildProcessWorker() = default;
|
||||||
ChildProcessSlave::~ChildProcessSlave() {}
|
ChildProcessWorker::~ChildProcessWorker() = default;
|
||||||
|
|
||||||
void ChildProcessSlave::handleConnectionMade() {}
|
void ChildProcessWorker::handleConnectionMade() {}
|
||||||
void ChildProcessSlave::handleConnectionLost() {}
|
void ChildProcessWorker::handleConnectionLost() {}
|
||||||
|
|
||||||
bool ChildProcessSlave::sendMessageToMaster (const MemoryBlock& mb)
|
void ChildProcessWorker::handleMessageFromCoordinator (const MemoryBlock& mb)
|
||||||
|
{
|
||||||
|
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations")
|
||||||
|
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996)
|
||||||
|
handleMessageFromMaster (mb);
|
||||||
|
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||||
|
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChildProcessWorker::sendMessageToCoordinator (const MemoryBlock& mb)
|
||||||
{
|
{
|
||||||
if (connection != nullptr)
|
if (connection != nullptr)
|
||||||
return connection->sendMessage (mb);
|
return connection->sendMessage (mb);
|
||||||
|
|
@ -241,7 +259,7 @@ bool ChildProcessSlave::sendMessageToMaster (const MemoryBlock& mb)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChildProcessSlave::initialiseFromCommandLine (const String& commandLine,
|
bool ChildProcessWorker::initialiseFromCommandLine (const String& commandLine,
|
||||||
const String& commandLineUniqueID,
|
const String& commandLineUniqueID,
|
||||||
int timeoutMs)
|
int timeoutMs)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -25,47 +25,47 @@ namespace juce
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/**
|
/**
|
||||||
Acts as the slave end of a master/slave pair of connected processes.
|
Acts as the worker end of a coordinator/worker pair of connected processes.
|
||||||
|
|
||||||
The ChildProcessSlave and ChildProcessMaster classes make it easy for an app
|
The ChildProcessWorker and ChildProcessCoordinator classes make it easy for an app
|
||||||
to spawn a child process, and to manage a 2-way messaging connection to control it.
|
to spawn a child process, and to manage a 2-way messaging connection to control it.
|
||||||
|
|
||||||
To use the system, you need to create subclasses of both ChildProcessSlave and
|
To use the system, you need to create subclasses of both ChildProcessWorker and
|
||||||
ChildProcessMaster. To instantiate the ChildProcessSlave object, you must
|
ChildProcessCoordinator. To instantiate the ChildProcessWorker object, you must
|
||||||
add some code to your main() or JUCEApplication::initialise() function that
|
add some code to your main() or JUCEApplication::initialise() function that
|
||||||
calls the initialiseFromCommandLine() method to check the app's command-line
|
calls the initialiseFromCommandLine() method to check the app's command-line
|
||||||
parameters to see whether it's being launched as a child process. If this returns
|
parameters to see whether it's being launched as a child process. If this returns
|
||||||
true then the slave process can be allowed to run, and its handleMessageFromMaster()
|
true then the worker process can be allowed to run, and its handleMessageFromCoordinator()
|
||||||
method will be called whenever a message arrives.
|
method will be called whenever a message arrives.
|
||||||
|
|
||||||
The juce demo app has a good example of this class in action.
|
The juce demo app has a good example of this class in action.
|
||||||
|
|
||||||
@see ChildProcessMaster, InterprocessConnection, ChildProcess
|
@see ChildProcessCoordinator, InterprocessConnection, ChildProcess
|
||||||
|
|
||||||
@tags{Events}
|
@tags{Events}
|
||||||
*/
|
*/
|
||||||
class JUCE_API ChildProcessSlave
|
class JUCE_API ChildProcessWorker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Creates a non-connected slave process.
|
/** Creates a non-connected worker process.
|
||||||
Use initialiseFromCommandLine to connect to a master process.
|
Use initialiseFromCommandLine to connect to a coordinator process.
|
||||||
*/
|
*/
|
||||||
ChildProcessSlave();
|
ChildProcessWorker();
|
||||||
|
|
||||||
/** Destructor. */
|
/** Destructor. */
|
||||||
virtual ~ChildProcessSlave();
|
virtual ~ChildProcessWorker();
|
||||||
|
|
||||||
/** This checks some command-line parameters to see whether they were generated by
|
/** This checks some command-line parameters to see whether they were generated by
|
||||||
ChildProcessMaster::launchSlaveProcess(), and if so, connects to that master process.
|
ChildProcessCoordinator::launchWorkerProcess(), and if so, connects to that coordinator process.
|
||||||
|
|
||||||
In an exe that can be used as a child process, you should add some code to your
|
In an exe that can be used as a child process, you should add some code to your
|
||||||
main() or JUCEApplication::initialise() that calls this method.
|
main() or JUCEApplication::initialise() that calls this method.
|
||||||
|
|
||||||
The commandLineUniqueID should be a short alphanumeric identifier (no spaces!)
|
The commandLineUniqueID should be a short alphanumeric identifier (no spaces!)
|
||||||
that matches the string passed to ChildProcessMaster::launchSlaveProcess().
|
that matches the string passed to ChildProcessCoordinator::launchWorkerProcess().
|
||||||
|
|
||||||
The timeoutMs parameter lets you specify how long the child process is allowed
|
The timeoutMs parameter lets you specify how long the child process is allowed
|
||||||
to run without receiving a ping from the master before the master is considered to
|
to run without receiving a ping from the coordinator before the coordinator is considered to
|
||||||
have died, and handleConnectionLost() will be called. Passing <= 0 for this timeout
|
have died, and handleConnectionLost() will be called. Passing <= 0 for this timeout
|
||||||
makes it use a default value.
|
makes it use a default value.
|
||||||
|
|
||||||
|
|
@ -76,78 +76,86 @@ public:
|
||||||
int timeoutMs = 0);
|
int timeoutMs = 0);
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/** This will be called to deliver messages from the master process.
|
/** This will be called to deliver messages from the coordinator process.
|
||||||
The call will probably be made on a background thread, so be careful with your
|
The call will probably be made on a background thread, so be careful with your
|
||||||
thread-safety! You may want to respond by sending back a message with
|
thread-safety! You may want to respond by sending back a message with
|
||||||
sendMessageToMaster()
|
sendMessageToCoordinator()
|
||||||
*/
|
*/
|
||||||
virtual void handleMessageFromMaster (const MemoryBlock&) = 0;
|
virtual void handleMessageFromCoordinator (const MemoryBlock& mb);
|
||||||
|
|
||||||
/** This will be called when the master process finishes connecting to this slave.
|
[[deprecated ("Replaced by handleMessageFromCoordinator.")]]
|
||||||
|
virtual void handleMessageFromMaster (const MemoryBlock&) {}
|
||||||
|
|
||||||
|
/** This will be called when the coordinator process finishes connecting to this worker.
|
||||||
The call will probably be made on a background thread, so be careful with your thread-safety!
|
The call will probably be made on a background thread, so be careful with your thread-safety!
|
||||||
*/
|
*/
|
||||||
virtual void handleConnectionMade();
|
virtual void handleConnectionMade();
|
||||||
|
|
||||||
/** This will be called when the connection to the master process is lost.
|
/** This will be called when the connection to the coordinator process is lost.
|
||||||
The call may be made from any thread (including the message thread).
|
The call may be made from any thread (including the message thread).
|
||||||
Typically, if your process only exists to act as a slave, you should probably exit
|
Typically, if your process only exists to act as a worker, you should probably exit
|
||||||
when this happens.
|
when this happens.
|
||||||
*/
|
*/
|
||||||
virtual void handleConnectionLost();
|
virtual void handleConnectionLost();
|
||||||
|
|
||||||
/** Tries to send a message to the master process.
|
/** Tries to send a message to the coordinator process.
|
||||||
This returns true if the message was sent, but doesn't check that it actually gets
|
This returns true if the message was sent, but doesn't check that it actually gets
|
||||||
delivered at the other end. If successful, the data will emerge in a call to your
|
delivered at the other end. If successful, the data will emerge in a call to your
|
||||||
ChildProcessMaster::handleMessageFromSlave().
|
ChildProcessCoordinator::handleMessageFromWorker().
|
||||||
*/
|
*/
|
||||||
bool sendMessageToMaster (const MemoryBlock&);
|
bool sendMessageToCoordinator (const MemoryBlock&);
|
||||||
|
|
||||||
|
[[deprecated ("Replaced by sendMessageToCoordinator.")]]
|
||||||
|
bool sendMessageToMaster (const MemoryBlock& mb) { return sendMessageToCoordinator (mb); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Connection;
|
struct Connection;
|
||||||
std::unique_ptr<Connection> connection;
|
std::unique_ptr<Connection> connection;
|
||||||
|
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessSlave)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessWorker)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using ChildProcessSlave [[deprecated ("Replaced by ChildProcessWorker.")]] = ChildProcessWorker;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/**
|
/**
|
||||||
Acts as the master in a master/slave pair of connected processes.
|
Acts as the coordinator in a coordinator/worker pair of connected processes.
|
||||||
|
|
||||||
The ChildProcessSlave and ChildProcessMaster classes make it easy for an app
|
The ChildProcessWorker and ChildProcessCoordinator classes make it easy for an app
|
||||||
to spawn a child process, and to manage a 2-way messaging connection to control it.
|
to spawn a child process, and to manage a 2-way messaging connection to control it.
|
||||||
|
|
||||||
To use the system, you need to create subclasses of both ChildProcessSlave and
|
To use the system, you need to create subclasses of both ChildProcessWorker and
|
||||||
ChildProcessMaster. When you want your master process to launch the slave, you
|
ChildProcessCoordinator. When you want your coordinator process to launch the worker, you
|
||||||
just call launchSlaveProcess(), and it'll attempt to launch the executable that
|
just call launchWorkerProcess(), and it'll attempt to launch the executable that
|
||||||
you specify (which may be the same exe), and assuming it has been set-up to
|
you specify (which may be the same exe), and assuming it has been set-up to
|
||||||
correctly parse the command-line parameters (see ChildProcessSlave) then a
|
correctly parse the command-line parameters (see ChildProcessWorker) then a
|
||||||
two-way connection will be created.
|
two-way connection will be created.
|
||||||
|
|
||||||
The juce demo app has a good example of this class in action.
|
The juce demo app has a good example of this class in action.
|
||||||
|
|
||||||
@see ChildProcessSlave, InterprocessConnection, ChildProcess
|
@see ChildProcessWorker, InterprocessConnection, ChildProcess
|
||||||
|
|
||||||
@tags{Events}
|
@tags{Events}
|
||||||
*/
|
*/
|
||||||
class JUCE_API ChildProcessMaster
|
class JUCE_API ChildProcessCoordinator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Creates an uninitialised master process object.
|
/** Creates an uninitialised coordinator process object.
|
||||||
Use launchSlaveProcess to launch and connect to a child process.
|
Use launchWorkerProcess to launch and connect to a child process.
|
||||||
*/
|
*/
|
||||||
ChildProcessMaster();
|
ChildProcessCoordinator();
|
||||||
|
|
||||||
/** Destructor.
|
/** Destructor.
|
||||||
Note that the destructor calls killSlaveProcess(), but doesn't wait for
|
Note that the destructor calls killWorkerProcess(), but doesn't wait for
|
||||||
the child process to finish terminating.
|
the child process to finish terminating.
|
||||||
*/
|
*/
|
||||||
virtual ~ChildProcessMaster();
|
virtual ~ChildProcessCoordinator();
|
||||||
|
|
||||||
/** Attempts to launch and connect to a slave process.
|
/** Attempts to launch and connect to a worker process.
|
||||||
This will start the given executable, passing it a special command-line
|
This will start the given executable, passing it a special command-line
|
||||||
parameter based around the commandLineUniqueID string, which must be a
|
parameter based around the commandLineUniqueID string, which must be a
|
||||||
short alphanumeric string (no spaces!) that identifies your app. The exe
|
short alphanumeric string (no spaces!) that identifies your app. The exe
|
||||||
that gets launched must respond by calling ChildProcessSlave::initialiseFromCommandLine()
|
that gets launched must respond by calling ChildProcessWorker::initialiseFromCommandLine()
|
||||||
in its startup code, and must use a matching ID to commandLineUniqueID.
|
in its startup code, and must use a matching ID to commandLineUniqueID.
|
||||||
|
|
||||||
The timeoutMs parameter lets you specify how long the child process is allowed
|
The timeoutMs parameter lets you specify how long the child process is allowed
|
||||||
|
|
@ -156,37 +164,55 @@ public:
|
||||||
it use a default value.
|
it use a default value.
|
||||||
|
|
||||||
If this all works, the method returns true, and you can begin sending and
|
If this all works, the method returns true, and you can begin sending and
|
||||||
receiving messages with the slave process.
|
receiving messages with the worker process.
|
||||||
|
|
||||||
If a child process is already running, this will call killSlaveProcess() and
|
If a child process is already running, this will call killWorkerProcess() and
|
||||||
start a new one.
|
start a new one.
|
||||||
*/
|
*/
|
||||||
bool launchSlaveProcess (const File& executableToLaunch,
|
bool launchWorkerProcess (const File& executableToLaunch,
|
||||||
const String& commandLineUniqueID,
|
const String& commandLineUniqueID,
|
||||||
int timeoutMs = 0,
|
int timeoutMs = 0,
|
||||||
int streamFlags = ChildProcess::wantStdOut | ChildProcess::wantStdErr);
|
int streamFlags = ChildProcess::wantStdOut | ChildProcess::wantStdErr);
|
||||||
|
|
||||||
/** Sends a kill message to the slave, and disconnects from it.
|
[[deprecated ("Replaced by launchWorkerProcess.")]]
|
||||||
|
bool launchSlaveProcess (const File& executableToLaunch,
|
||||||
|
const String& commandLineUniqueID,
|
||||||
|
int timeoutMs = 0,
|
||||||
|
int streamFlags = ChildProcess::wantStdOut | ChildProcess::wantStdErr)
|
||||||
|
{
|
||||||
|
return launchWorkerProcess (executableToLaunch, commandLineUniqueID, timeoutMs, streamFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sends a kill message to the worker, and disconnects from it.
|
||||||
Note that this won't wait for it to terminate.
|
Note that this won't wait for it to terminate.
|
||||||
*/
|
*/
|
||||||
void killSlaveProcess();
|
void killWorkerProcess();
|
||||||
|
|
||||||
/** This will be called to deliver a message from the slave process.
|
[[deprecated ("Replaced by killWorkerProcess.")]]
|
||||||
|
void killSlaveProcess() { killWorkerProcess(); }
|
||||||
|
|
||||||
|
/** This will be called to deliver a message from the worker process.
|
||||||
The call will probably be made on a background thread, so be careful with your thread-safety!
|
The call will probably be made on a background thread, so be careful with your thread-safety!
|
||||||
*/
|
*/
|
||||||
virtual void handleMessageFromSlave (const MemoryBlock&) = 0;
|
virtual void handleMessageFromWorker (const MemoryBlock&);
|
||||||
|
|
||||||
/** This will be called when the slave process dies or is somehow disconnected.
|
[[deprecated ("Replaced by handleMessageFromWorker")]]
|
||||||
|
virtual void handleMessageFromSlave (const MemoryBlock&) {}
|
||||||
|
|
||||||
|
/** This will be called when the worker process dies or is somehow disconnected.
|
||||||
The call will probably be made on a background thread, so be careful with your thread-safety!
|
The call will probably be made on a background thread, so be careful with your thread-safety!
|
||||||
*/
|
*/
|
||||||
virtual void handleConnectionLost();
|
virtual void handleConnectionLost();
|
||||||
|
|
||||||
/** Attempts to send a message to the slave process.
|
/** Attempts to send a message to the worker process.
|
||||||
This returns true if the message was dispatched, but doesn't check that it actually
|
This returns true if the message was dispatched, but doesn't check that it actually
|
||||||
gets delivered at the other end. If successful, the data will emerge in a call to
|
gets delivered at the other end. If successful, the data will emerge in a call to
|
||||||
your ChildProcessSlave::handleMessageFromMaster().
|
your ChildProcessWorker::handleMessageFromCoordinator().
|
||||||
*/
|
*/
|
||||||
bool sendMessageToSlave (const MemoryBlock&);
|
bool sendMessageToWorker (const MemoryBlock&);
|
||||||
|
|
||||||
|
[[deprecated ("Replaced by sendMessageToWorker.")]]
|
||||||
|
bool sendMessageToSlave (const MemoryBlock& mb) { return sendMessageToWorker (mb); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<ChildProcess> childProcess;
|
std::unique_ptr<ChildProcess> childProcess;
|
||||||
|
|
@ -194,7 +220,9 @@ private:
|
||||||
struct Connection;
|
struct Connection;
|
||||||
std::unique_ptr<Connection> connection;
|
std::unique_ptr<Connection> connection;
|
||||||
|
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessMaster)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessCoordinator)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using ChildProcessMaster [[deprecated ("Replaced by ChildProcessCoordinator.")]] = ChildProcessCoordinator;
|
||||||
|
|
||||||
} // namespace juce
|
} // namespace juce
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue