It seems like shared_from_this may not be enabled when a unique_ptr is assigned to a shared_ptr (although it *should* be enabled when constructing a new shared_ptr from a unique_ptr). Functions that return objects that may need to use shared_from_this now return shared_ptr, just to be safe. Additionally, in some cases, shared_from_this was being called from Thread::run after the last reference to the shared object had been released. We now call shared_from_this during 'open', which will always run on the message thread while at least once reference to the shared object is alive.tags/2021-05-28
@@ -184,7 +184,7 @@ void FileChooser::launchAsync (int flags, std::function<void (const FileChooser& | |||||
} | } | ||||
std::unique_ptr<FileChooser::Pimpl> FileChooser::createPimpl (int flags, FilePreviewComponent* previewComp) | |||||
std::shared_ptr<FileChooser::Pimpl> FileChooser::createPimpl (int flags, FilePreviewComponent* previewComp) | |||||
{ | { | ||||
results.clear(); | results.clear(); | ||||
@@ -328,8 +328,8 @@ private: | |||||
std::shared_ptr<Pimpl> pimpl; | std::shared_ptr<Pimpl> pimpl; | ||||
//============================================================================== | //============================================================================== | ||||
std::unique_ptr<Pimpl> createPimpl (int, FilePreviewComponent*); | |||||
static std::unique_ptr<Pimpl> showPlatformDialog (FileChooser&, int, FilePreviewComponent*); | |||||
std::shared_ptr<Pimpl> createPimpl (int, FilePreviewComponent*); | |||||
static std::shared_ptr<Pimpl> showPlatformDialog (FileChooser&, int, FilePreviewComponent*); | |||||
class NonNative; | class NonNative; | ||||
friend class NonNative; | friend class NonNative; | ||||
@@ -219,11 +219,11 @@ private: | |||||
FileChooser::Native* FileChooser::Native::currentFileChooser = nullptr; | FileChooser::Native* FileChooser::Native::currentFileChooser = nullptr; | ||||
std::unique_ptr<FileChooser::Pimpl> FileChooser::showPlatformDialog (FileChooser& owner, int flags, | |||||
std::shared_ptr<FileChooser::Pimpl> FileChooser::showPlatformDialog (FileChooser& owner, int flags, | |||||
FilePreviewComponent*) | FilePreviewComponent*) | ||||
{ | { | ||||
if (FileChooser::Native::currentFileChooser == nullptr) | if (FileChooser::Native::currentFileChooser == nullptr) | ||||
return std::make_unique<FileChooser::Native> (owner, flags); | |||||
return std::make_shared<FileChooser::Native> (owner, flags); | |||||
// there can only be one file chooser on Android at a once | // there can only be one file chooser on Android at a once | ||||
jassertfalse; | jassertfalse; | ||||
@@ -379,10 +379,10 @@ bool FileChooser::isPlatformDialogAvailable() | |||||
#endif | #endif | ||||
} | } | ||||
std::unique_ptr<FileChooser::Pimpl> FileChooser::showPlatformDialog (FileChooser& owner, int flags, | |||||
std::shared_ptr<FileChooser::Pimpl> FileChooser::showPlatformDialog (FileChooser& owner, int flags, | |||||
FilePreviewComponent*) | FilePreviewComponent*) | ||||
{ | { | ||||
return std::make_unique<FileChooser::Native> (owner, flags); | |||||
return std::make_shared<FileChooser::Native> (owner, flags); | |||||
} | } | ||||
#if JUCE_DEPRECATION_IGNORED | #if JUCE_DEPRECATION_IGNORED | ||||
@@ -256,9 +256,9 @@ bool FileChooser::isPlatformDialogAvailable() | |||||
#endif | #endif | ||||
} | } | ||||
std::unique_ptr<FileChooser::Pimpl> FileChooser::showPlatformDialog (FileChooser& owner, int flags, FilePreviewComponent*) | |||||
std::shared_ptr<FileChooser::Pimpl> FileChooser::showPlatformDialog (FileChooser& owner, int flags, FilePreviewComponent*) | |||||
{ | { | ||||
return std::make_unique<Native> (owner, flags); | |||||
return std::make_shared<Native> (owner, flags); | |||||
} | } | ||||
} // namespace juce | } // namespace juce |
@@ -377,10 +377,10 @@ private: | |||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Native) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Native) | ||||
}; | }; | ||||
std::unique_ptr<FileChooser::Pimpl> FileChooser::showPlatformDialog (FileChooser& owner, int flags, | |||||
std::shared_ptr<FileChooser::Pimpl> FileChooser::showPlatformDialog (FileChooser& owner, int flags, | |||||
FilePreviewComponent* preview) | FilePreviewComponent* preview) | ||||
{ | { | ||||
return std::make_unique<FileChooser::Native> (owner, flags, preview); | |||||
return std::make_shared<FileChooser::Native> (owner, flags, preview); | |||||
} | } | ||||
bool FileChooser::isPlatformDialogAvailable() | bool FileChooser::isPlatformDialogAvailable() | ||||
@@ -82,6 +82,8 @@ public: | |||||
// the thread should not be running | // the thread should not be running | ||||
nativeDialogRef.set (nullptr); | nativeDialogRef.set (nullptr); | ||||
weakThis = shared_from_this(); | |||||
if (async) | if (async) | ||||
{ | { | ||||
jassert (! isThreadRunning()); | jassert (! isThreadRunning()); | ||||
@@ -140,6 +142,7 @@ private: | |||||
//============================================================================== | //============================================================================== | ||||
const Component::SafePointer<Component> owner; | const Component::SafePointer<Component> owner; | ||||
std::weak_ptr<Win32NativeFileChooser> weakThis; | |||||
String title, filtersString; | String title, filtersString; | ||||
std::unique_ptr<CustomComponentHolder> customComponent; | std::unique_ptr<CustomComponentHolder> customComponent; | ||||
String initialPath, returnedString; | String initialPath, returnedString; | ||||
@@ -481,11 +484,11 @@ private: | |||||
auto resultsCopy = openDialog (true); | auto resultsCopy = openDialog (true); | ||||
auto safeOwner = owner; | auto safeOwner = owner; | ||||
std::weak_ptr<Win32NativeFileChooser> weakThis = shared_from_this(); | |||||
auto weakThisCopy = weakThis; | |||||
MessageManager::callAsync ([resultsCopy, safeOwner, weakThis] | |||||
MessageManager::callAsync ([resultsCopy, safeOwner, weakThisCopy] | |||||
{ | { | ||||
if (auto locked = weakThis.lock()) | |||||
if (auto locked = weakThisCopy.lock()) | |||||
locked->results = resultsCopy; | locked->results = resultsCopy; | ||||
if (safeOwner != nullptr) | if (safeOwner != nullptr) | ||||
@@ -812,10 +815,10 @@ bool FileChooser::isPlatformDialogAvailable() | |||||
#endif | #endif | ||||
} | } | ||||
std::unique_ptr<FileChooser::Pimpl> FileChooser::showPlatformDialog (FileChooser& owner, int flags, | |||||
std::shared_ptr<FileChooser::Pimpl> FileChooser::showPlatformDialog (FileChooser& owner, int flags, | |||||
FilePreviewComponent* preview) | FilePreviewComponent* preview) | ||||
{ | { | ||||
return std::make_unique<FileChooser::Native> (owner, flags, preview); | |||||
return std::make_shared<FileChooser::Native> (owner, flags, preview); | |||||
} | } | ||||
} // namespace juce | } // namespace juce |