From a24962151e5911504f6bb8f0abdcbecea698a5db Mon Sep 17 00:00:00 2001 From: jules Date: Fri, 28 Nov 2008 13:45:53 +0000 Subject: [PATCH] --- .../juce_win32_Windowing.cpp | 43 +++- .../src/host/InternalFilters.h | 1 + juce_amalgamated.cpp | 212 +++++++++++++----- juce_amalgamated.h | 29 ++- .../application/juce_Application.cpp | 10 +- .../application/juce_Application.h | 5 + .../formats/juce_AudioUnitPluginFormat.cpp | 52 ++++- .../formats/juce_AudioUnitPluginFormat.h | 1 + .../plugins/formats/juce_VSTPluginFormat.cpp | 19 +- .../plugins/formats/juce_VSTPluginFormat.h | 1 + .../audio/plugins/juce_AudioPluginFormat.h | 8 + .../plugins/juce_AudioPluginFormatManager.cpp | 12 +- .../plugins/juce_AudioPluginFormatManager.h | 6 + .../audio/plugins/juce_KnownPluginList.cpp | 17 +- .../audio/plugins/juce_PluginDescription.cpp | 12 +- .../audio/plugins/juce_PluginDescription.h | 9 +- .../plugins/juce_PluginListComponent.cpp | 8 +- 17 files changed, 332 insertions(+), 113 deletions(-) diff --git a/build/win32/platform_specific_code/juce_win32_Windowing.cpp b/build/win32/platform_specific_code/juce_win32_Windowing.cpp index c2f2df9d69..1297bb7b01 100644 --- a/build/win32/platform_specific_code/juce_win32_Windowing.cpp +++ b/build/win32/platform_specific_code/juce_win32_Windowing.cpp @@ -2028,7 +2028,9 @@ private: break; case WM_CLOSE: - handleUserClosingWindow(); + if (! component->isCurrentlyBlockedByAnotherModalComponent()) + handleUserClosingWindow(); + return 0; case WM_QUIT: @@ -2120,6 +2122,9 @@ private: switch (wParam & 0xfff0) { case SC_CLOSE: + if (sendInputAttemptWhenModalMessage()) + return 0; + if (hasTitleBar()) { PostMessage (h, WM_CLOSE, 0, 0); @@ -2128,16 +2133,25 @@ private: break; case SC_KEYMENU: + if (sendInputAttemptWhenModalMessage()) + return 0; + if (hasTitleBar() && h == GetCapture()) ReleaseCapture(); break; case SC_MAXIMIZE: + if (sendInputAttemptWhenModalMessage()) + return 0; + setFullScreen (true); return 0; case SC_MINIMIZE: + if (sendInputAttemptWhenModalMessage()) + return 0; + if (! hasTitleBar()) { setMinimised (true); @@ -2146,6 +2160,9 @@ private: break; case SC_RESTORE: + if (sendInputAttemptWhenModalMessage()) + return 0; + if (hasTitleBar()) { if (isFullScreen()) @@ -2179,14 +2196,7 @@ private: case WM_NCLBUTTONDOWN: case WM_NCRBUTTONDOWN: case WM_NCMBUTTONDOWN: - if (component->isCurrentlyBlockedByAnotherModalComponent()) - { - Component* const current = Component::getCurrentlyModalComponent(); - - if (current != 0) - current->inputAttemptWhenModal(); - } - + sendInputAttemptWhenModalMessage(); break; //case WM_IME_STARTCOMPOSITION; @@ -2206,6 +2216,21 @@ private: return DefWindowProc (h, message, wParam, lParam); } + bool sendInputAttemptWhenModalMessage() + { + if (component->isCurrentlyBlockedByAnotherModalComponent()) + { + Component* const current = Component::getCurrentlyModalComponent(); + + if (current != 0) + current->inputAttemptWhenModal(); + + return true; + } + + return false; + } + Win32ComponentPeer (const Win32ComponentPeer&); const Win32ComponentPeer& operator= (const Win32ComponentPeer&); }; diff --git a/extras/audio plugin host/src/host/InternalFilters.h b/extras/audio plugin host/src/host/InternalFilters.h index c853cd5803..6d3c489107 100644 --- a/extras/audio plugin host/src/host/InternalFilters.h +++ b/extras/audio plugin host/src/host/InternalFilters.h @@ -65,6 +65,7 @@ public: bool fileMightContainThisPluginType (const File&) { return false; } const FileSearchPath getDefaultLocationsToSearch() { return FileSearchPath(); } void findAllTypesForFile (OwnedArray &, const File&) {} + bool doesPluginStillExist (const PluginDescription&) { return true; } AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); //============================================================================== diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 2a31dc94e6..aa45f6470f 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -15226,6 +15226,9 @@ int JUCEApplication::main (String& commandLine, JUCEApplication* const app) jassert (appInstance == 0); appInstance = app; + app->commandLineParameters = commandLine.trim(); + commandLine = String::empty; + initialiseJuce_GUI(); InterProcessLock* appLock = 0; @@ -15236,11 +15239,10 @@ int JUCEApplication::main (String& commandLine, JUCEApplication* const app) if (! appLock->enter(0)) { - MessageManager::broadcastMessage (app->getApplicationName() + "/" + commandLine); + MessageManager::broadcastMessage (app->getApplicationName() + "/" + app->commandLineParameters); delete appInstance; appInstance = 0; - commandLine = String::empty; DBG ("Another instance is running - quitting..."); return 0; @@ -15252,9 +15254,7 @@ int JUCEApplication::main (String& commandLine, JUCEApplication* const app) juce_setCurrentThreadName ("Juce Message Thread"); // let the app do its setting-up.. - app->initialise (commandLine.trim()); - - commandLine = String::empty; + app->initialise (app->commandLineParameters); // register for broadcast new app messages MessageManager::getInstance()->registerBroadcastListener (app); @@ -26448,7 +26448,7 @@ AudioPluginInstance* AudioPluginFormatManager::createPluginInstance (const Plugi if (result == 0) { - if (description.file != File::nonexistent && ! description.file.exists()) + if (! doesPluginStillExist (description)) errorMessage = TRANS ("This plug-in file no longer exists"); else errorMessage = TRANS ("This plug-in failed to load correctly"); @@ -26457,6 +26457,15 @@ AudioPluginInstance* AudioPluginFormatManager::createPluginInstance (const Plugi return result; } +bool AudioPluginFormatManager::doesPluginStillExist (const PluginDescription& description) const +{ + for (int i = 0; i < formats.size(); ++i) + if (formats.getUnchecked(i)->getName() == description.pluginFormatName) + return formats.getUnchecked(i)->doesPluginStillExist (description); + + return false; +} + END_JUCE_NAMESPACE /********* End of inlined file: juce_AudioPluginFormatManager.cpp *********/ @@ -26500,7 +26509,7 @@ void KnownPluginList::clear() PluginDescription* KnownPluginList::getTypeForFile (const File& file) const throw() { for (int i = 0; i < types.size(); ++i) - if (types.getUnchecked(i)->file == file) + if (types.getUnchecked(i)->fileOrIdentifier == file.getFullPathName()) return types.getUnchecked(i); return 0; @@ -26550,7 +26559,7 @@ bool KnownPluginList::isListingUpToDate (const File& possiblePluginFile) const t { const PluginDescription* const d = types.getUnchecked(i); - if (d->file == possiblePluginFile + if (d->fileOrIdentifier == possiblePluginFile.getFullPathName() && d->lastFileModTime != possiblePluginFile.getLastModificationTime()) { return false; @@ -26575,7 +26584,7 @@ bool KnownPluginList::scanAndAddFile (const File& possiblePluginFile, { const PluginDescription* const d = types.getUnchecked(i); - if (d->file == possiblePluginFile) + if (d->fileOrIdentifier == possiblePluginFile.getFullPathName()) { if (d->lastFileModTime != possiblePluginFile.getLastModificationTime()) needsRescanning = true; @@ -26654,7 +26663,10 @@ public: else if (method == KnownPluginList::sortByManufacturer) diff = first->manufacturerName.compareLexicographically (second->manufacturerName); else if (method == KnownPluginList::sortByFileSystemLocation) - diff = first->file.getParentDirectory().getFullPathName().compare (second->file.getParentDirectory().getFullPathName()); + diff = first->fileOrIdentifier.replaceCharacter (T('\\'), T('/')) + .upToLastOccurrenceOf (T("/"), false, false) + .compare (second->fileOrIdentifier.replaceCharacter (T('\\'), T('/')) + .upToLastOccurrenceOf (T("/"), false, false)); if (diff == 0) diff = first->name.compareLexicographically (second->name); @@ -26764,13 +26776,13 @@ public: { for (int i = 0; i < allPlugins.size(); ++i) { - String path (allPlugins.getUnchecked(i)->file.getParentDirectory().getFullPathName()); + String path (allPlugins.getUnchecked(i) + ->fileOrIdentifier.replaceCharacter (T('\\'), T('/')) + .upToLastOccurrenceOf (T("/"), false, false)); if (path.substring (1, 2) == T(":")) path = path.substring (2); - path = path.replaceCharacter (T('\\'), T('/')); - addPlugin (allPlugins.getUnchecked(i), path); } @@ -26891,7 +26903,7 @@ PluginDescription::PluginDescription (const PluginDescription& other) throw() category (other.category), manufacturerName (other.manufacturerName), version (other.version), - file (other.file), + fileOrIdentifier (other.fileOrIdentifier), lastFileModTime (other.lastFileModTime), uid (other.uid), isInstrument (other.isInstrument), @@ -26907,7 +26919,7 @@ const PluginDescription& PluginDescription::operator= (const PluginDescription& category = other.category; manufacturerName = other.manufacturerName; version = other.version; - file = other.file; + fileOrIdentifier = other.fileOrIdentifier; uid = other.uid; isInstrument = other.isInstrument; lastFileModTime = other.lastFileModTime; @@ -26919,7 +26931,7 @@ const PluginDescription& PluginDescription::operator= (const PluginDescription& bool PluginDescription::isDuplicateOf (const PluginDescription& other) const { - return file == other.file + return fileOrIdentifier == other.fileOrIdentifier && uid == other.uid; } @@ -26927,7 +26939,7 @@ const String PluginDescription::createIdentifierString() const throw() { return pluginFormatName + T("-") + name - + T("-") + String::toHexString (file.getFileName().hashCode()) + + T("-") + String::toHexString (fileOrIdentifier.hashCode()) + T("-") + String::toHexString (uid); } @@ -26939,7 +26951,7 @@ XmlElement* PluginDescription::createXml() const e->setAttribute (T("category"), category); e->setAttribute (T("manufacturer"), manufacturerName); e->setAttribute (T("version"), version); - e->setAttribute (T("file"), file.getFullPathName()); + e->setAttribute (T("file"), fileOrIdentifier); e->setAttribute (T("uid"), String::toHexString (uid)); e->setAttribute (T("isInstrument"), isInstrument); e->setAttribute (T("fileTime"), String::toHexString (lastFileModTime.toMilliseconds())); @@ -26958,7 +26970,7 @@ bool PluginDescription::loadFromXml (const XmlElement& xml) category = xml.getStringAttribute (T("category")); manufacturerName = xml.getStringAttribute (T("manufacturer")); version = xml.getStringAttribute (T("version")); - file = File (xml.getStringAttribute (T("file"))); + fileOrIdentifier = xml.getStringAttribute (T("file")); uid = xml.getStringAttribute (T("uid")).getHexValue32(); isInstrument = xml.getBoolAttribute (T("isInstrument"), false); lastFileModTime = Time (xml.getStringAttribute (T("fileTime")).getHexValue64()); @@ -27251,14 +27263,16 @@ void PluginListComponent::buttonClicked (Button* b) const PluginDescription* const desc = list.getType (listBox->getSelectedRow()); if (desc != 0) - desc->file.getParentDirectory().startAsProcess(); + { + if (File (desc->fileOrIdentifier).existsAsFile()) + File (desc->fileOrIdentifier).getParentDirectory().startAsProcess(); + } } else if (r == 7) { for (int i = list.getNumTypes(); --i >= 0;) { - if (list.getType (i)->file != File::nonexistent - && ! list.getType (i)->file.exists()) + if (! AudioPluginFormatManager::getInstance()->doesPluginStillExist (*list.getType (i))) { list.removeType (i); } @@ -28155,22 +28169,45 @@ OSStatus AudioUnitPluginInstance::getTransportState (Boolean* outIsPlaying, if (ph != 0 && ph->getCurrentPosition (result)) { - *outIsPlaying = result.isPlaying; - *outTransportStateChanged = result.isPlaying != wasPlaying; + if (outIsPlaying != 0) + *outIsPlaying = result.isPlaying; + + if (outTransportStateChanged != 0) + *outTransportStateChanged = result.isPlaying != wasPlaying; + wasPlaying = result.isPlaying; - *outCurrentSampleInTimeLine = roundDoubleToInt (result.timeInSeconds * getSampleRate()); - *outIsCycling = false; - *outCycleStartBeat = 0; - *outCycleEndBeat = 0; + + if (outCurrentSampleInTimeLine != 0) + *outCurrentSampleInTimeLine = roundDoubleToInt (result.timeInSeconds * getSampleRate()); + + if (outIsCycling != 0) + *outIsCycling = false; + + if (outCycleStartBeat != 0) + *outCycleStartBeat = 0; + + if (outCycleEndBeat != 0) + *outCycleEndBeat = 0; } else { - *outIsPlaying = false; - *outTransportStateChanged = false; - *outCurrentSampleInTimeLine = 0; - *outIsCycling = false; - *outCycleStartBeat = 0; - *outCycleEndBeat = 0; + if (outIsPlaying != 0) + *outIsPlaying = false; + + if (outTransportStateChanged != 0) + *outTransportStateChanged = false; + + if (outCurrentSampleInTimeLine != 0) + *outCurrentSampleInTimeLine = 0; + + if (outIsCycling != 0) + *outIsCycling = false; + + if (outCycleStartBeat != 0) + *outCycleStartBeat = 0; + + if (outCycleEndBeat != 0) + *outCycleEndBeat = 0; } return noErr; @@ -28763,6 +28800,11 @@ bool AudioUnitPluginFormat::fileMightContainThisPluginType (const File& f) && f.isDirectory(); } +bool AudioUnitPluginFormat::doesPluginStillExist (const PluginDescription& desc) +{ + return File (desc.fileOrIdentifier).exists(); +} + const FileSearchPath AudioUnitPluginFormat::getDefaultLocationsToSearch() { return FileSearchPath ("~/Library/Audio/Plug-Ins/Components;/Library/Audio/Plug-Ins/Components"); @@ -29816,9 +29858,9 @@ public: void fillInPluginDescription (PluginDescription& desc) const { desc.name = name; - desc.file = module->file; + desc.fileOrIdentifier = module->file.getFullPathName(); desc.uid = getUID(); - desc.lastFileModTime = desc.file.getLastModificationTime(); + desc.lastFileModTime = module->file.getLastModificationTime(); desc.pluginFormatName = "VST"; desc.category = getCategory(); @@ -31985,7 +32027,7 @@ void VSTPluginFormat::findAllTypesForFile (OwnedArray & resul return; PluginDescription desc; - desc.file = file; + desc.fileOrIdentifier = file.getFullPathName(); desc.uid = 0; VSTPluginInstance* instance = dynamic_cast (createInstanceFromDescription (desc)); @@ -32063,12 +32105,14 @@ AudioPluginInstance* VSTPluginFormat::createInstanceFromDescription (const Plugi { VSTPluginInstance* result = 0; - if (fileMightContainThisPluginType (desc.file)) + File file (desc.fileOrIdentifier); + + if (fileMightContainThisPluginType (file)) { const File previousWorkingDirectory (File::getCurrentWorkingDirectory()); - desc.file.getParentDirectory().setAsCurrentWorkingDirectory(); + file.getParentDirectory().setAsCurrentWorkingDirectory(); - const ReferenceCountedObjectPtr module (ModuleHandle::findOrCreateModule (desc.file)); + const ReferenceCountedObjectPtr module (ModuleHandle::findOrCreateModule (file)); if (module != 0) { @@ -32126,6 +32170,11 @@ bool VSTPluginFormat::fileMightContainThisPluginType (const File& f) #endif } +bool VSTPluginFormat::doesPluginStillExist (const PluginDescription& desc) +{ + return File (desc.fileOrIdentifier).exists(); +} + const FileSearchPath VSTPluginFormat::getDefaultLocationsToSearch() { #if JUCE_MAC @@ -64756,12 +64805,16 @@ public: { Component* const over = dynamic_cast (currentlyOver); + // (note: use a local copy of the dragDesc member in case the callback runs + // a modal loop and deletes this object before the method completes) + const String dragDescLocal (dragDesc); + if (over != 0 && over->isValidComponent() && source->isValidComponent() - && currentlyOver->isInterestedInDragSource (dragDesc, source)) + && currentlyOver->isInterestedInDragSource (dragDescLocal, source)) { - currentlyOver->itemDragExit (dragDesc, source); + currentlyOver->itemDragExit (dragDescLocal, source); } } @@ -64802,11 +64855,15 @@ public: hit = hit->getComponentAt (rx, ry); } + // (note: use a local copy of the dragDesc member in case the callback runs + // a modal loop and deletes this object before the method completes) + const String dragDescLocal (dragDesc); + while (hit != 0) { DragAndDropTarget* const ddt = dynamic_cast (hit); - if (ddt != 0 && ddt->isInterestedInDragSource (dragDesc, source)) + if (ddt != 0 && ddt->isInterestedInDragSource (dragDescLocal, source)) { relX = screenX; relY = screenY; @@ -64868,7 +64925,13 @@ public: getParentComponent()->removeChildComponent (this); if (dropAccepted && ddt != 0) - ddt->itemDropped (dragDesc, source, relX, relY); + { + // (note: use a local copy of the dragDesc member in case the callback runs + // a modal loop and deletes this object before the method completes) + const String dragDescLocal (dragDesc); + + ddt->itemDropped (dragDescLocal, source, relX, relY); + } // careful - this object could now be deleted.. } @@ -64876,6 +64939,10 @@ public: void updateLocation (const bool canDoExternalDrag, int x, int y) { + // (note: use a local copy of the dragDesc member in case the callback runs + // a modal loop and deletes this object before it returns) + const String dragDescLocal (dragDesc); + int newX = x - xOff; int newY = y - yOff; @@ -64898,21 +64965,21 @@ public: if (over != 0 && over->isValidComponent() && ! (sourceWatcher->hasBeenDeleted()) - && currentlyOver->isInterestedInDragSource (dragDesc, source)) + && currentlyOver->isInterestedInDragSource (dragDescLocal, source)) { - currentlyOver->itemDragExit (dragDesc, source); + currentlyOver->itemDragExit (dragDescLocal, source); } currentlyOver = ddt; if (currentlyOver != 0 - && currentlyOver->isInterestedInDragSource (dragDesc, source)) - currentlyOver->itemDragEnter (dragDesc, source, relX, relY); + && currentlyOver->isInterestedInDragSource (dragDescLocal, source)) + currentlyOver->itemDragEnter (dragDescLocal, source, relX, relY); } if (currentlyOver != 0 - && currentlyOver->isInterestedInDragSource (dragDesc, source)) - currentlyOver->itemDragMove (dragDesc, source, relX, relY); + && currentlyOver->isInterestedInDragSource (dragDescLocal, source)) + currentlyOver->itemDragMove (dragDescLocal, source, relX, relY); if (currentlyOver == 0 && canDoExternalDrag @@ -64924,7 +64991,7 @@ public: StringArray files; bool canMoveFiles = false; - if (owner->shouldDropFilesWhenDraggedExternally (dragDesc, source, files, canMoveFiles) + if (owner->shouldDropFilesWhenDraggedExternally (dragDescLocal, source, files, canMoveFiles) && files.size() > 0) { ComponentDeletionWatcher cdw (this); @@ -242749,7 +242816,9 @@ private: break; case WM_CLOSE: - handleUserClosingWindow(); + if (! component->isCurrentlyBlockedByAnotherModalComponent()) + handleUserClosingWindow(); + return 0; case WM_QUIT: @@ -242839,6 +242908,9 @@ private: switch (wParam & 0xfff0) { case SC_CLOSE: + if (sendInputAttemptWhenModalMessage()) + return 0; + if (hasTitleBar()) { PostMessage (h, WM_CLOSE, 0, 0); @@ -242847,16 +242919,25 @@ private: break; case SC_KEYMENU: + if (sendInputAttemptWhenModalMessage()) + return 0; + if (hasTitleBar() && h == GetCapture()) ReleaseCapture(); break; case SC_MAXIMIZE: + if (sendInputAttemptWhenModalMessage()) + return 0; + setFullScreen (true); return 0; case SC_MINIMIZE: + if (sendInputAttemptWhenModalMessage()) + return 0; + if (! hasTitleBar()) { setMinimised (true); @@ -242865,6 +242946,9 @@ private: break; case SC_RESTORE: + if (sendInputAttemptWhenModalMessage()) + return 0; + if (hasTitleBar()) { if (isFullScreen()) @@ -242898,14 +242982,7 @@ private: case WM_NCLBUTTONDOWN: case WM_NCRBUTTONDOWN: case WM_NCMBUTTONDOWN: - if (component->isCurrentlyBlockedByAnotherModalComponent()) - { - Component* const current = Component::getCurrentlyModalComponent(); - - if (current != 0) - current->inputAttemptWhenModal(); - } - + sendInputAttemptWhenModalMessage(); break; //case WM_IME_STARTCOMPOSITION; @@ -242925,6 +243002,21 @@ private: return DefWindowProc (h, message, wParam, lParam); } + bool sendInputAttemptWhenModalMessage() + { + if (component->isCurrentlyBlockedByAnotherModalComponent()) + { + Component* const current = Component::getCurrentlyModalComponent(); + + if (current != 0) + current->inputAttemptWhenModal(); + + return true; + } + + return false; + } + Win32ComponentPeer (const Win32ComponentPeer&); const Win32ComponentPeer& operator= (const Win32ComponentPeer&); }; diff --git a/juce_amalgamated.h b/juce_amalgamated.h index ea0c08c7a6..8c6bfff3b1 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -23269,6 +23269,10 @@ public: */ int getApplicationReturnValue() const throw() { return appReturnValue; } + /** Returns the application's command line params. + */ + const String getCommandLineParameters() const throw() { return commandLineParameters; } + // These are used by the START_JUCE_APPLICATION() macro and aren't for public use. /** @internal */ @@ -23294,6 +23298,7 @@ public: private: + String commandLineParameters; int appReturnValue; bool stillInitialising; @@ -27828,8 +27833,13 @@ public: /** The version. This string doesn't have any particular format. */ String version; - /** The binary module file containing the plugin. */ - File file; + /** Either the file containing the plugin module, or some other unique way + of identifying it. + + E.g. for an AU, this would be the component ID, because not all AUs actually + live in a file... + */ + String fileOrIdentifier; /** The last time the plugin file was changed. This is handy when scanning for new or changed plugins. @@ -27971,6 +27981,13 @@ public: */ virtual bool fileMightContainThisPluginType (const File& file) = 0; + /** Checks whether this plugin could possibly be loaded. + + It doesn't actually need to load it, just to check whether the file or component + still exists. + */ + virtual bool doesPluginStillExist (const PluginDescription& desc) = 0; + /** Returns the typical places to look for this kind of plugin. Note that if this returns no paths, it means that the format can't be scanned-for @@ -28039,6 +28056,12 @@ public: AudioPluginInstance* createPluginInstance (const PluginDescription& description, String& errorMessage) const; + /** Checks that the file or component for this plugin actually still exists. + + (This won't try to load the plugin) + */ + bool doesPluginStillExist (const PluginDescription& description) const; + juce_UseDebuggingNewOperator private: @@ -34658,6 +34681,7 @@ public: void findAllTypesForFile (OwnedArray & results, const File& file); AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); bool fileMightContainThisPluginType (const File& file); + bool doesPluginStillExist (const PluginDescription& desc); const FileSearchPath getDefaultLocationsToSearch(); juce_UseDebuggingNewOperator @@ -34773,6 +34797,7 @@ public: void findAllTypesForFile (OwnedArray & results, const File& file); AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); bool fileMightContainThisPluginType (const File& file); + bool doesPluginStillExist (const PluginDescription& desc); const FileSearchPath getDefaultLocationsToSearch(); juce_UseDebuggingNewOperator diff --git a/src/juce_appframework/application/juce_Application.cpp b/src/juce_appframework/application/juce_Application.cpp index ecdaaa28c9..23017d7f85 100644 --- a/src/juce_appframework/application/juce_Application.cpp +++ b/src/juce_appframework/application/juce_Application.cpp @@ -167,6 +167,9 @@ int JUCEApplication::main (String& commandLine, JUCEApplication* const app) jassert (appInstance == 0); appInstance = app; + app->commandLineParameters = commandLine.trim(); + commandLine = String::empty; + initialiseJuce_GUI(); InterProcessLock* appLock = 0; @@ -177,11 +180,10 @@ int JUCEApplication::main (String& commandLine, JUCEApplication* const app) if (! appLock->enter(0)) { - MessageManager::broadcastMessage (app->getApplicationName() + "/" + commandLine); + MessageManager::broadcastMessage (app->getApplicationName() + "/" + app->commandLineParameters); delete appInstance; appInstance = 0; - commandLine = String::empty; DBG ("Another instance is running - quitting..."); return 0; @@ -193,9 +195,7 @@ int JUCEApplication::main (String& commandLine, JUCEApplication* const app) juce_setCurrentThreadName ("Juce Message Thread"); // let the app do its setting-up.. - app->initialise (commandLine.trim()); - - commandLine = String::empty; + app->initialise (app->commandLineParameters); // register for broadcast new app messages MessageManager::getInstance()->registerBroadcastListener (app); diff --git a/src/juce_appframework/application/juce_Application.h b/src/juce_appframework/application/juce_Application.h index 3e55a890df..7a77433be7 100644 --- a/src/juce_appframework/application/juce_Application.h +++ b/src/juce_appframework/application/juce_Application.h @@ -260,6 +260,10 @@ public: */ int getApplicationReturnValue() const throw() { return appReturnValue; } + /** Returns the application's command line params. + */ + const String getCommandLineParameters() const throw() { return commandLineParameters; } + //============================================================================== // These are used by the START_JUCE_APPLICATION() macro and aren't for public use. @@ -287,6 +291,7 @@ public: private: //============================================================================== + String commandLineParameters; int appReturnValue; bool stillInitialising; diff --git a/src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.cpp b/src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.cpp index 4d4dd37179..aac479768e 100644 --- a/src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.cpp +++ b/src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.cpp @@ -648,22 +648,45 @@ OSStatus AudioUnitPluginInstance::getTransportState (Boolean* outIsPlaying, if (ph != 0 && ph->getCurrentPosition (result)) { - *outIsPlaying = result.isPlaying; - *outTransportStateChanged = result.isPlaying != wasPlaying; + if (outIsPlaying != 0) + *outIsPlaying = result.isPlaying; + + if (outTransportStateChanged != 0) + *outTransportStateChanged = result.isPlaying != wasPlaying; + wasPlaying = result.isPlaying; - *outCurrentSampleInTimeLine = roundDoubleToInt (result.timeInSeconds * getSampleRate()); - *outIsCycling = false; - *outCycleStartBeat = 0; - *outCycleEndBeat = 0; + + if (outCurrentSampleInTimeLine != 0) + *outCurrentSampleInTimeLine = roundDoubleToInt (result.timeInSeconds * getSampleRate()); + + if (outIsCycling != 0) + *outIsCycling = false; + + if (outCycleStartBeat != 0) + *outCycleStartBeat = 0; + + if (outCycleEndBeat != 0) + *outCycleEndBeat = 0; } else { - *outIsPlaying = false; - *outTransportStateChanged = false; - *outCurrentSampleInTimeLine = 0; - *outIsCycling = false; - *outCycleStartBeat = 0; - *outCycleEndBeat = 0; + if (outIsPlaying != 0) + *outIsPlaying = false; + + if (outTransportStateChanged != 0) + *outTransportStateChanged = false; + + if (outCurrentSampleInTimeLine != 0) + *outCurrentSampleInTimeLine = 0; + + if (outIsCycling != 0) + *outIsCycling = false; + + if (outCycleStartBeat != 0) + *outCycleStartBeat = 0; + + if (outCycleEndBeat != 0) + *outCycleEndBeat = 0; } return noErr; @@ -1278,6 +1301,11 @@ bool AudioUnitPluginFormat::fileMightContainThisPluginType (const File& f) && f.isDirectory(); } +bool AudioUnitPluginFormat::doesPluginStillExist (const PluginDescription& desc) +{ + return File (desc.fileOrIdentifier).exists(); +} + const FileSearchPath AudioUnitPluginFormat::getDefaultLocationsToSearch() { return FileSearchPath ("~/Library/Audio/Plug-Ins/Components;/Library/Audio/Plug-Ins/Components"); diff --git a/src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.h b/src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.h index 175dbe22fc..812a6b4a39 100644 --- a/src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.h +++ b/src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.h @@ -52,6 +52,7 @@ public: void findAllTypesForFile (OwnedArray & results, const File& file); AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); bool fileMightContainThisPluginType (const File& file); + bool doesPluginStillExist (const PluginDescription& desc); const FileSearchPath getDefaultLocationsToSearch(); //============================================================================== diff --git a/src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.cpp b/src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.cpp index c6febe9724..c1a172c481 100644 --- a/src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.cpp +++ b/src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.cpp @@ -690,9 +690,9 @@ public: void fillInPluginDescription (PluginDescription& desc) const { desc.name = name; - desc.file = module->file; + desc.fileOrIdentifier = module->file.getFullPathName(); desc.uid = getUID(); - desc.lastFileModTime = desc.file.getLastModificationTime(); + desc.lastFileModTime = module->file.getLastModificationTime(); desc.pluginFormatName = "VST"; desc.category = getCategory(); @@ -2898,7 +2898,7 @@ void VSTPluginFormat::findAllTypesForFile (OwnedArray & resul return; PluginDescription desc; - desc.file = file; + desc.fileOrIdentifier = file.getFullPathName(); desc.uid = 0; VSTPluginInstance* instance = dynamic_cast (createInstanceFromDescription (desc)); @@ -2976,12 +2976,14 @@ AudioPluginInstance* VSTPluginFormat::createInstanceFromDescription (const Plugi { VSTPluginInstance* result = 0; - if (fileMightContainThisPluginType (desc.file)) + File file (desc.fileOrIdentifier); + + if (fileMightContainThisPluginType (file)) { const File previousWorkingDirectory (File::getCurrentWorkingDirectory()); - desc.file.getParentDirectory().setAsCurrentWorkingDirectory(); + file.getParentDirectory().setAsCurrentWorkingDirectory(); - const ReferenceCountedObjectPtr module (ModuleHandle::findOrCreateModule (desc.file)); + const ReferenceCountedObjectPtr module (ModuleHandle::findOrCreateModule (file)); if (module != 0) { @@ -3039,6 +3041,11 @@ bool VSTPluginFormat::fileMightContainThisPluginType (const File& f) #endif } +bool VSTPluginFormat::doesPluginStillExist (const PluginDescription& desc) +{ + return File (desc.fileOrIdentifier).exists(); +} + const FileSearchPath VSTPluginFormat::getDefaultLocationsToSearch() { #if JUCE_MAC diff --git a/src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.h b/src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.h index 92e8244628..e1e247b612 100644 --- a/src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.h +++ b/src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.h @@ -53,6 +53,7 @@ public: void findAllTypesForFile (OwnedArray & results, const File& file); AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); bool fileMightContainThisPluginType (const File& file); + bool doesPluginStillExist (const PluginDescription& desc); const FileSearchPath getDefaultLocationsToSearch(); //============================================================================== diff --git a/src/juce_appframework/audio/plugins/juce_AudioPluginFormat.h b/src/juce_appframework/audio/plugins/juce_AudioPluginFormat.h index 5be0ad90b6..c520e9a2fb 100644 --- a/src/juce_appframework/audio/plugins/juce_AudioPluginFormat.h +++ b/src/juce_appframework/audio/plugins/juce_AudioPluginFormat.h @@ -84,6 +84,14 @@ public: */ virtual bool fileMightContainThisPluginType (const File& file) = 0; + /** Checks whether this plugin could possibly be loaded. + + It doesn't actually need to load it, just to check whether the file or component + still exists. + */ + virtual bool doesPluginStillExist (const PluginDescription& desc) = 0; + + /** Returns the typical places to look for this kind of plugin. Note that if this returns no paths, it means that the format can't be scanned-for diff --git a/src/juce_appframework/audio/plugins/juce_AudioPluginFormatManager.cpp b/src/juce_appframework/audio/plugins/juce_AudioPluginFormatManager.cpp index ef3d851fb1..c2b1bb79df 100644 --- a/src/juce_appframework/audio/plugins/juce_AudioPluginFormatManager.cpp +++ b/src/juce_appframework/audio/plugins/juce_AudioPluginFormatManager.cpp @@ -126,7 +126,7 @@ AudioPluginInstance* AudioPluginFormatManager::createPluginInstance (const Plugi if (result == 0) { - if (description.file != File::nonexistent && ! description.file.exists()) + if (! doesPluginStillExist (description)) errorMessage = TRANS ("This plug-in file no longer exists"); else errorMessage = TRANS ("This plug-in failed to load correctly"); @@ -135,4 +135,14 @@ AudioPluginInstance* AudioPluginFormatManager::createPluginInstance (const Plugi return result; } +bool AudioPluginFormatManager::doesPluginStillExist (const PluginDescription& description) const +{ + for (int i = 0; i < formats.size(); ++i) + if (formats.getUnchecked(i)->getName() == description.pluginFormatName) + return formats.getUnchecked(i)->doesPluginStillExist (description); + + return false; +} + + END_JUCE_NAMESPACE diff --git a/src/juce_appframework/audio/plugins/juce_AudioPluginFormatManager.h b/src/juce_appframework/audio/plugins/juce_AudioPluginFormatManager.h index bfacbf3d9a..39b43f717c 100644 --- a/src/juce_appframework/audio/plugins/juce_AudioPluginFormatManager.h +++ b/src/juce_appframework/audio/plugins/juce_AudioPluginFormatManager.h @@ -92,6 +92,12 @@ public: AudioPluginInstance* createPluginInstance (const PluginDescription& description, String& errorMessage) const; + /** Checks that the file or component for this plugin actually still exists. + + (This won't try to load the plugin) + */ + bool doesPluginStillExist (const PluginDescription& description) const; + //============================================================================== juce_UseDebuggingNewOperator diff --git a/src/juce_appframework/audio/plugins/juce_KnownPluginList.cpp b/src/juce_appframework/audio/plugins/juce_KnownPluginList.cpp index 8b3308cf3a..7874b67493 100644 --- a/src/juce_appframework/audio/plugins/juce_KnownPluginList.cpp +++ b/src/juce_appframework/audio/plugins/juce_KnownPluginList.cpp @@ -58,7 +58,7 @@ void KnownPluginList::clear() PluginDescription* KnownPluginList::getTypeForFile (const File& file) const throw() { for (int i = 0; i < types.size(); ++i) - if (types.getUnchecked(i)->file == file) + if (types.getUnchecked(i)->fileOrIdentifier == file.getFullPathName()) return types.getUnchecked(i); return 0; @@ -108,7 +108,7 @@ bool KnownPluginList::isListingUpToDate (const File& possiblePluginFile) const t { const PluginDescription* const d = types.getUnchecked(i); - if (d->file == possiblePluginFile + if (d->fileOrIdentifier == possiblePluginFile.getFullPathName() && d->lastFileModTime != possiblePluginFile.getLastModificationTime()) { return false; @@ -133,7 +133,7 @@ bool KnownPluginList::scanAndAddFile (const File& possiblePluginFile, { const PluginDescription* const d = types.getUnchecked(i); - if (d->file == possiblePluginFile) + if (d->fileOrIdentifier == possiblePluginFile.getFullPathName()) { if (d->lastFileModTime != possiblePluginFile.getLastModificationTime()) needsRescanning = true; @@ -213,7 +213,10 @@ public: else if (method == KnownPluginList::sortByManufacturer) diff = first->manufacturerName.compareLexicographically (second->manufacturerName); else if (method == KnownPluginList::sortByFileSystemLocation) - diff = first->file.getParentDirectory().getFullPathName().compare (second->file.getParentDirectory().getFullPathName()); + diff = first->fileOrIdentifier.replaceCharacter (T('\\'), T('/')) + .upToLastOccurrenceOf (T("/"), false, false) + .compare (second->fileOrIdentifier.replaceCharacter (T('\\'), T('/')) + .upToLastOccurrenceOf (T("/"), false, false)); if (diff == 0) diff = first->name.compareLexicographically (second->name); @@ -325,13 +328,13 @@ public: { for (int i = 0; i < allPlugins.size(); ++i) { - String path (allPlugins.getUnchecked(i)->file.getParentDirectory().getFullPathName()); + String path (allPlugins.getUnchecked(i) + ->fileOrIdentifier.replaceCharacter (T('\\'), T('/')) + .upToLastOccurrenceOf (T("/"), false, false)); if (path.substring (1, 2) == T(":")) path = path.substring (2); - path = path.replaceCharacter (T('\\'), T('/')); - addPlugin (allPlugins.getUnchecked(i), path); } diff --git a/src/juce_appframework/audio/plugins/juce_PluginDescription.cpp b/src/juce_appframework/audio/plugins/juce_PluginDescription.cpp index 96d385f42e..3e855f0980 100644 --- a/src/juce_appframework/audio/plugins/juce_PluginDescription.cpp +++ b/src/juce_appframework/audio/plugins/juce_PluginDescription.cpp @@ -56,7 +56,7 @@ PluginDescription::PluginDescription (const PluginDescription& other) throw() category (other.category), manufacturerName (other.manufacturerName), version (other.version), - file (other.file), + fileOrIdentifier (other.fileOrIdentifier), lastFileModTime (other.lastFileModTime), uid (other.uid), isInstrument (other.isInstrument), @@ -72,7 +72,7 @@ const PluginDescription& PluginDescription::operator= (const PluginDescription& category = other.category; manufacturerName = other.manufacturerName; version = other.version; - file = other.file; + fileOrIdentifier = other.fileOrIdentifier; uid = other.uid; isInstrument = other.isInstrument; lastFileModTime = other.lastFileModTime; @@ -84,7 +84,7 @@ const PluginDescription& PluginDescription::operator= (const PluginDescription& bool PluginDescription::isDuplicateOf (const PluginDescription& other) const { - return file == other.file + return fileOrIdentifier == other.fileOrIdentifier && uid == other.uid; } @@ -92,7 +92,7 @@ const String PluginDescription::createIdentifierString() const throw() { return pluginFormatName + T("-") + name - + T("-") + String::toHexString (file.getFileName().hashCode()) + + T("-") + String::toHexString (fileOrIdentifier.hashCode()) + T("-") + String::toHexString (uid); } @@ -104,7 +104,7 @@ XmlElement* PluginDescription::createXml() const e->setAttribute (T("category"), category); e->setAttribute (T("manufacturer"), manufacturerName); e->setAttribute (T("version"), version); - e->setAttribute (T("file"), file.getFullPathName()); + e->setAttribute (T("file"), fileOrIdentifier); e->setAttribute (T("uid"), String::toHexString (uid)); e->setAttribute (T("isInstrument"), isInstrument); e->setAttribute (T("fileTime"), String::toHexString (lastFileModTime.toMilliseconds())); @@ -123,7 +123,7 @@ bool PluginDescription::loadFromXml (const XmlElement& xml) category = xml.getStringAttribute (T("category")); manufacturerName = xml.getStringAttribute (T("manufacturer")); version = xml.getStringAttribute (T("version")); - file = File (xml.getStringAttribute (T("file"))); + fileOrIdentifier = xml.getStringAttribute (T("file")); uid = xml.getStringAttribute (T("uid")).getHexValue32(); isInstrument = xml.getBoolAttribute (T("isInstrument"), false); lastFileModTime = Time (xml.getStringAttribute (T("fileTime")).getHexValue64()); diff --git a/src/juce_appframework/audio/plugins/juce_PluginDescription.h b/src/juce_appframework/audio/plugins/juce_PluginDescription.h index 9af83fa35c..43227c0358 100644 --- a/src/juce_appframework/audio/plugins/juce_PluginDescription.h +++ b/src/juce_appframework/audio/plugins/juce_PluginDescription.h @@ -74,8 +74,13 @@ public: /** The version. This string doesn't have any particular format. */ String version; - /** The binary module file containing the plugin. */ - File file; + /** Either the file containing the plugin module, or some other unique way + of identifying it. + + E.g. for an AU, this would be the component ID, because not all AUs actually + live in a file... + */ + String fileOrIdentifier; /** The last time the plugin file was changed. This is handy when scanning for new or changed plugins. diff --git a/src/juce_appframework/audio/plugins/juce_PluginListComponent.cpp b/src/juce_appframework/audio/plugins/juce_PluginListComponent.cpp index c781736f37..c515e131f5 100644 --- a/src/juce_appframework/audio/plugins/juce_PluginListComponent.cpp +++ b/src/juce_appframework/audio/plugins/juce_PluginListComponent.cpp @@ -190,14 +190,16 @@ void PluginListComponent::buttonClicked (Button* b) const PluginDescription* const desc = list.getType (listBox->getSelectedRow()); if (desc != 0) - desc->file.getParentDirectory().startAsProcess(); + { + if (File (desc->fileOrIdentifier).existsAsFile()) + File (desc->fileOrIdentifier).getParentDirectory().startAsProcess(); + } } else if (r == 7) { for (int i = list.getNumTypes(); --i >= 0;) { - if (list.getType (i)->file != File::nonexistent - && ! list.getType (i)->file.exists()) + if (! AudioPluginFormatManager::getInstance()->doesPluginStillExist (*list.getType (i))) { list.removeType (i); }