@@ -213,22 +213,21 @@ private: | |||||
updateLoginButtonStates (true); | updateLoginButtonStates (true); | ||||
WeakReference<Component> weakThis (this); | |||||
auto completionCallback = [this, weakThis] (const String& errorMessage) | |||||
auto completionCallback = [weakThis = SafePointer<LoginFormComponent> { this }] (const String& errorMessage) | |||||
{ | { | ||||
if (weakThis == nullptr) | if (weakThis == nullptr) | ||||
return; | return; | ||||
updateLoginButtonStates (false); | |||||
weakThis->updateLoginButtonStates (false); | |||||
if (errorMessage.isNotEmpty()) | if (errorMessage.isNotEmpty()) | ||||
{ | { | ||||
showErrorMessage (errorMessage); | |||||
weakThis->showErrorMessage (errorMessage); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
hideErrorMessage(); | |||||
mainWindow.hideLoginFormOverlay(); | |||||
weakThis->hideErrorMessage(); | |||||
weakThis->mainWindow.hideLoginFormOverlay(); | |||||
ProjucerApplication::getApp().getCommandManager().commandStatusChanged(); | ProjucerApplication::getApp().getCommandManager().commandStatusChanged(); | ||||
} | } | ||||
}; | }; | ||||
@@ -1113,8 +1113,7 @@ void ProjucerApplication::createNewProjectFromClipboard() | |||||
return; | return; | ||||
} | } | ||||
WeakReference<ProjucerApplication> parent { this }; | |||||
openFile (tempFile, [parent, cleanup] (bool openedSuccessfully) | |||||
openFile (tempFile, [parent = WeakReference<ProjucerApplication> { this }, cleanup] (bool openedSuccessfully) | |||||
{ | { | ||||
if (parent == nullptr) | if (parent == nullptr) | ||||
return; | return; | ||||
@@ -1172,8 +1171,7 @@ void ProjucerApplication::closeAllMainWindows (std::function<void (bool)> callba | |||||
void ProjucerApplication::closeAllMainWindowsAndQuitIfNeeded() | void ProjucerApplication::closeAllMainWindowsAndQuitIfNeeded() | ||||
{ | { | ||||
WeakReference<ProjucerApplication> parent; | |||||
closeAllMainWindows ([parent] (bool closedSuccessfully) | |||||
closeAllMainWindows ([parent = WeakReference<ProjucerApplication> { this }] (bool closedSuccessfully) | |||||
{ | { | ||||
#if JUCE_MAC | #if JUCE_MAC | ||||
ignoreUnused (parent, closedSuccessfully); | ignoreUnused (parent, closedSuccessfully); | ||||
@@ -346,9 +346,7 @@ void LatestVersionCheckerAndUpdater::addNotificationToOpenProjects (const Versio | |||||
{ | { | ||||
if (auto* project = window->getProject()) | if (auto* project = window->getProject()) | ||||
{ | { | ||||
Component::SafePointer<MainWindow> safeWindow (window); | |||||
auto ignore = [safeWindow] | |||||
auto ignore = [safeWindow = Component::SafePointer<MainWindow> { window }] | |||||
{ | { | ||||
if (safeWindow != nullptr) | if (safeWindow != nullptr) | ||||
safeWindow->getProject()->removeProjectMessage (ProjectMessages::Ids::newVersionAvailable); | safeWindow->getProject()->removeProjectMessage (ProjectMessages::Ids::newVersionAvailable); | ||||
@@ -247,9 +247,10 @@ void MainWindow::closeCurrentProject (OpenDocumentManager::SaveIfNeeded askUserT | |||||
pcc->hideEditor(); | pcc->hideEditor(); | ||||
} | } | ||||
SafePointer<MainWindow> parent { this }; | |||||
ProjucerApplication::getApp().openDocumentManager | ProjucerApplication::getApp().openDocumentManager | ||||
.closeAllDocumentsUsingProjectAsync (*currentProject, askUserToSave, [parent, askUserToSave, callback] (bool closedSuccessfully) | |||||
.closeAllDocumentsUsingProjectAsync (*currentProject, | |||||
askUserToSave, | |||||
[parent = SafePointer<MainWindow> { this }, askUserToSave, callback] (bool closedSuccessfully) | |||||
{ | { | ||||
if (parent == nullptr) | if (parent == nullptr) | ||||
return; | return; | ||||
@@ -291,8 +292,8 @@ void MainWindow::closeCurrentProject (OpenDocumentManager::SaveIfNeeded askUserT | |||||
void MainWindow::moveProject (File newProjectFileToOpen, OpenInIDE openInIDE) | void MainWindow::moveProject (File newProjectFileToOpen, OpenInIDE openInIDE) | ||||
{ | { | ||||
SafePointer<MainWindow> parent { this }; | |||||
closeCurrentProject (OpenDocumentManager::SaveIfNeeded::no, [parent, newProjectFileToOpen, openInIDE] (bool) | |||||
closeCurrentProject (OpenDocumentManager::SaveIfNeeded::no, | |||||
[parent = SafePointer<MainWindow> { this }, newProjectFileToOpen, openInIDE] (bool) | |||||
{ | { | ||||
if (parent == nullptr) | if (parent == nullptr) | ||||
return; | return; | ||||
@@ -360,9 +361,10 @@ void MainWindow::openFile (const File& file, std::function<void (bool)> callback | |||||
if (result.wasOk()) | if (result.wasOk()) | ||||
{ | { | ||||
SafePointer<MainWindow> parent { this }; | |||||
auto sharedDoc = std::make_shared<std::unique_ptr<Project>> (std::move (newDoc)); | |||||
closeCurrentProject (OpenDocumentManager::SaveIfNeeded::yes, [parent, sharedDoc, callback] (bool saveResult) | |||||
closeCurrentProject (OpenDocumentManager::SaveIfNeeded::yes, | |||||
[parent = SafePointer<MainWindow> { this }, | |||||
sharedDoc = std::make_shared<std::unique_ptr<Project>> (std::move (newDoc)), | |||||
callback] (bool saveResult) | |||||
{ | { | ||||
if (parent == nullptr) | if (parent == nullptr) | ||||
return; | return; | ||||
@@ -472,8 +474,7 @@ void MainWindow::openPIP (const File& pipFile, std::function<void (bool)> callba | |||||
return; | return; | ||||
} | } | ||||
SafePointer<MainWindow> parent { this }; | |||||
openFile (generator->getJucerFile(), [parent, generator, callback] (bool openedSuccessfully) | |||||
openFile (generator->getJucerFile(), [parent = SafePointer<MainWindow> { this }, generator, callback] (bool openedSuccessfully) | |||||
{ | { | ||||
if (parent == nullptr) | if (parent == nullptr) | ||||
return; | return; | ||||
@@ -768,18 +769,18 @@ void MainWindowList::closeWindow (MainWindow* w) | |||||
else | else | ||||
#endif | #endif | ||||
{ | { | ||||
WeakReference<MainWindowList> parent { this }; | |||||
w->closeCurrentProject (OpenDocumentManager::SaveIfNeeded::yes, [parent, w] (bool closedSuccessfully) | |||||
{ | |||||
if (parent == nullptr) | |||||
return; | |||||
if (closedSuccessfully) | |||||
{ | |||||
parent->windows.removeObject (w); | |||||
parent->saveCurrentlyOpenProjectList(); | |||||
} | |||||
}); | |||||
w->closeCurrentProject (OpenDocumentManager::SaveIfNeeded::yes, | |||||
[parent = WeakReference<MainWindowList> { this }, w] (bool closedSuccessfully) | |||||
{ | |||||
if (parent == nullptr) | |||||
return; | |||||
if (closedSuccessfully) | |||||
{ | |||||
parent->windows.removeObject (w); | |||||
parent->saveCurrentlyOpenProjectList(); | |||||
} | |||||
}); | |||||
} | } | ||||
} | } | ||||
@@ -176,7 +176,6 @@ void OpenDocumentManager::saveIfNeededAndUserAgrees (OpenDocumentManager::Docume | |||||
return; | return; | ||||
} | } | ||||
WeakReference<OpenDocumentManager> parent { this }; | |||||
AlertWindow::showYesNoCancelBox (AlertWindow::QuestionIcon, | AlertWindow::showYesNoCancelBox (AlertWindow::QuestionIcon, | ||||
TRANS("Closing document..."), | TRANS("Closing document..."), | ||||
TRANS("Do you want to save the changes to \"") | TRANS("Do you want to save the changes to \"") | ||||
@@ -185,7 +184,7 @@ void OpenDocumentManager::saveIfNeededAndUserAgrees (OpenDocumentManager::Docume | |||||
TRANS("Discard changes"), | TRANS("Discard changes"), | ||||
TRANS("Cancel"), | TRANS("Cancel"), | ||||
nullptr, | nullptr, | ||||
ModalCallbackFunction::create ([parent, doc, callback] (int r) | |||||
ModalCallbackFunction::create ([parent = WeakReference<OpenDocumentManager> { this }, doc, callback] (int r) | |||||
{ | { | ||||
if (parent == nullptr) | if (parent == nullptr) | ||||
return; | return; | ||||
@@ -241,8 +240,8 @@ void OpenDocumentManager::closeDocumentAsync (Document* doc, SaveIfNeeded saveIf | |||||
if (saveIfNeeded == SaveIfNeeded::yes) | if (saveIfNeeded == SaveIfNeeded::yes) | ||||
{ | { | ||||
WeakReference<OpenDocumentManager> parent { this }; | |||||
saveIfNeededAndUserAgrees (doc, [parent, doc, callback] (FileBasedDocument::SaveResult result) | |||||
saveIfNeededAndUserAgrees (doc, | |||||
[parent = WeakReference<OpenDocumentManager> { this }, doc, callback] (FileBasedDocument::SaveResult result) | |||||
{ | { | ||||
if (parent == nullptr) | if (parent == nullptr) | ||||
return; | return; | ||||
@@ -667,8 +667,8 @@ void CppCodeEditorComponent::insertComponentClass() | |||||
asyncAlertWindow->addButton (TRANS ("Insert Code"), 1, KeyPress (KeyPress::returnKey)); | asyncAlertWindow->addButton (TRANS ("Insert Code"), 1, KeyPress (KeyPress::returnKey)); | ||||
asyncAlertWindow->addButton (TRANS ("Cancel"), 0, KeyPress (KeyPress::escapeKey)); | asyncAlertWindow->addButton (TRANS ("Cancel"), 0, KeyPress (KeyPress::escapeKey)); | ||||
SafePointer<CppCodeEditorComponent> parent { this }; | |||||
asyncAlertWindow->enterModalState (true, ModalCallbackFunction::create ([parent, classNameField] (int result) | |||||
asyncAlertWindow->enterModalState (true, | |||||
ModalCallbackFunction::create ([parent = SafePointer<CppCodeEditorComponent> { this }, classNameField] (int result) | |||||
{ | { | ||||
if (parent == nullptr) | if (parent == nullptr) | ||||
return; | return; | ||||
@@ -262,10 +262,9 @@ public: | |||||
m.addSubMenu ("Relative to", compLayout->getRelativeTargetMenu (component, (int) dimension)); | m.addSubMenu ("Relative to", compLayout->getRelativeTargetMenu (component, (int) dimension)); | ||||
} | } | ||||
SafePointer<PositionPropertyBase> ref (this); | |||||
m.showMenuAsync (PopupMenu::Options().withTargetComponent (&button), | m.showMenuAsync (PopupMenu::Options().withTargetComponent (&button), | ||||
[ref, compLayout, callback, xAnchor, yAnchor, xMode, yMode, sizeW, sizeH, p, rpr] (int menuResult) mutable | |||||
[compLayout, callback, xAnchor, yAnchor, xMode, yMode, sizeW, sizeH, p, rpr, | |||||
ref = SafePointer<PositionPropertyBase> { this }] (int menuResult) mutable | |||||
{ | { | ||||
if (menuResult == 0 || ref == nullptr) | if (menuResult == 0 || ref == nullptr) | ||||
{ | { | ||||
@@ -694,8 +694,7 @@ public: | |||||
void saveAsync (std::function<void (bool)> callback) override | void saveAsync (std::function<void (bool)> callback) override | ||||
{ | { | ||||
WeakReference<JucerComponentDocument> parent { this }; | |||||
SourceCodeDocument::saveAsync ([parent, callback] (bool saveResult) | |||||
SourceCodeDocument::saveAsync ([parent = WeakReference<JucerComponentDocument> { this }, callback] (bool saveResult) | |||||
{ | { | ||||
if (parent == nullptr) | if (parent == nullptr) | ||||
return; | return; | ||||
@@ -720,8 +719,7 @@ public: | |||||
if (auto* header = odm.openFile (nullptr, getFile().withFileExtension (".h"))) | if (auto* header = odm.openFile (nullptr, getFile().withFileExtension (".h"))) | ||||
{ | { | ||||
WeakReference<JucerComponentDocument> parent { this }; | |||||
header->saveAsync ([parent, callback] (bool saveResult) | |||||
header->saveAsync ([parent = WeakReference<JucerComponentDocument> { this }, callback] (bool saveResult) | |||||
{ | { | ||||
if (parent == nullptr) | if (parent == nullptr) | ||||
return; | return; | ||||
@@ -78,25 +78,25 @@ public: | |||||
void deleteItem() override | void deleteItem() override | ||||
{ | { | ||||
WeakReference<ExporterItem> safeThis { this }; | |||||
auto resultCallback = [safeThis = WeakReference<ExporterItem> { this }] (int result) | |||||
{ | |||||
if (safeThis == nullptr || result == 0) | |||||
return; | |||||
safeThis->closeSettingsPage(); | |||||
auto parent = safeThis->exporter->settings.getParent(); | |||||
parent.removeChild (safeThis->exporter->settings, | |||||
safeThis->project.getUndoManagerFor (parent)); | |||||
}; | |||||
AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, | AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, | ||||
"Delete Exporter", | "Delete Exporter", | ||||
"Are you sure you want to delete this export target?", | "Are you sure you want to delete this export target?", | ||||
"", | "", | ||||
"", | "", | ||||
nullptr, | nullptr, | ||||
ModalCallbackFunction::create ([safeThis] (int result) | |||||
{ | |||||
if (safeThis == nullptr) | |||||
return; | |||||
if (result == 0) | |||||
return; | |||||
safeThis->closeSettingsPage(); | |||||
auto parent = safeThis->exporter->settings.getParent(); | |||||
parent.removeChild (safeThis->exporter->settings, safeThis->project.getUndoManagerFor (parent)); | |||||
})); | |||||
ModalCallbackFunction::create (std::move (resultCallback))); | |||||
} | } | ||||
void addSubItems() override | void addSubItems() override | ||||
@@ -244,14 +244,13 @@ public: | |||||
void deleteItem() override | void deleteItem() override | ||||
{ | { | ||||
WeakReference<ConfigItem> parent { this }; | |||||
AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, | AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, | ||||
"Delete Configuration", | "Delete Configuration", | ||||
"Are you sure you want to delete this configuration?", | "Are you sure you want to delete this configuration?", | ||||
"", | "", | ||||
"", | "", | ||||
nullptr, | nullptr, | ||||
ModalCallbackFunction::create ([parent] (int result) | |||||
ModalCallbackFunction::create ([parent = WeakReference<ConfigItem> { this }] (int result) | |||||
{ | { | ||||
if (parent == nullptr) | if (parent == nullptr) | ||||
return; | return; | ||||
@@ -538,14 +538,14 @@ public: | |||||
if (correspondingItem.isValid()) | if (correspondingItem.isValid()) | ||||
{ | { | ||||
WeakReference<SourceFileItem> parent { this }; | |||||
AlertWindow::showOkCancelBox (AlertWindow::NoIcon, | AlertWindow::showOkCancelBox (AlertWindow::NoIcon, | ||||
"File Rename", | "File Rename", | ||||
"Do you also want to rename the corresponding file \"" + correspondingFile.getFileName() + "\" to match?", | "Do you also want to rename the corresponding file \"" + correspondingFile.getFileName() + "\" to match?", | ||||
{}, | {}, | ||||
{}, | {}, | ||||
nullptr, | nullptr, | ||||
ModalCallbackFunction::create ([parent, oldFile, newFile, correspondingFile, correspondingItem] (int result) mutable | |||||
ModalCallbackFunction::create ([parent = WeakReference<SourceFileItem> { this }, | |||||
oldFile, newFile, correspondingFile, correspondingItem] (int result) mutable | |||||
{ | { | ||||
if (parent == nullptr || result == 0) | if (parent == nullptr || result == 0) | ||||
return; | return; | ||||
@@ -330,8 +330,7 @@ void ProjectContentComponent::saveDocumentAsync() | |||||
{ | { | ||||
if (currentDocument != nullptr) | if (currentDocument != nullptr) | ||||
{ | { | ||||
SafePointer<ProjectContentComponent> parent { this }; | |||||
currentDocument->saveAsync ([parent] (bool savedSuccessfully) | |||||
currentDocument->saveAsync ([parent = SafePointer<ProjectContentComponent> { this }] (bool savedSuccessfully) | |||||
{ | { | ||||
if (parent == nullptr) | if (parent == nullptr) | ||||
return; | return; | ||||
@@ -352,8 +351,7 @@ void ProjectContentComponent::saveAsAsync() | |||||
{ | { | ||||
if (currentDocument != nullptr) | if (currentDocument != nullptr) | ||||
{ | { | ||||
SafePointer<ProjectContentComponent> parent { this }; | |||||
currentDocument->saveAsAsync ([parent] (bool savedSuccessfully) | |||||
currentDocument->saveAsAsync ([parent = SafePointer<ProjectContentComponent> { this }] (bool savedSuccessfully) | |||||
{ | { | ||||
if (parent == nullptr) | if (parent == nullptr) | ||||
return; | return; | ||||
@@ -725,10 +725,9 @@ void Project::saveProject (Async async, | |||||
registerRecentFile (getFile()); | registerRecentFile (getFile()); | ||||
} | } | ||||
WeakReference<Project> ref (this); | |||||
saver = std::make_unique<ProjectSaver> (*this); | saver = std::make_unique<ProjectSaver> (*this); | ||||
saver->save (async, exporterToSave, [ref, onCompletion] (Result result) | |||||
saver->save (async, exporterToSave, [ref = WeakReference<Project> { this }, onCompletion] (Result result) | |||||
{ | { | ||||
if (ref == nullptr) | if (ref == nullptr) | ||||
return; | return; | ||||
@@ -1040,9 +1039,8 @@ void Project::saveAndMoveTemporaryProject (bool openInIDE) | |||||
// reload project from new location | // reload project from new location | ||||
if (auto* window = ProjucerApplication::getApp().mainWindowList.getMainWindowForFile (getFile())) | if (auto* window = ProjucerApplication::getApp().mainWindowList.getMainWindowForFile (getFile())) | ||||
{ | { | ||||
Component::SafePointer<MainWindow> safeWindow (window); | |||||
MessageManager::callAsync ([safeWindow, newDirectory, oldJucerFileName, openInIDE]() mutable | |||||
MessageManager::callAsync ([newDirectory, oldJucerFileName, openInIDE, | |||||
safeWindow = Component::SafePointer<MainWindow> { window }]() mutable | |||||
{ | { | ||||
if (safeWindow != nullptr) | if (safeWindow != nullptr) | ||||
safeWindow->moveProject (newDirectory.getChildFile (oldJucerFileName), | safeWindow->moveProject (newDirectory.getChildFile (oldJucerFileName), | ||||
@@ -54,8 +54,8 @@ void ProjectSaver::saveProjectAsync (ProjectExporter* exporterToSave, std::funct | |||||
{ | { | ||||
jassert (saveThread == nullptr); | jassert (saveThread == nullptr); | ||||
WeakReference<ProjectSaver> ref (this); | |||||
saveThread = std::make_unique<SaveThreadWithProgressWindow> (*this, exporterToSave, [ref, onCompletion] (Result result) | |||||
saveThread = std::make_unique<SaveThreadWithProgressWindow> (*this, exporterToSave, | |||||
[ref = WeakReference<ProjectSaver> { this }, onCompletion] (Result result) | |||||
{ | { | ||||
if (ref == nullptr) | if (ref == nullptr) | ||||
return; | return; | ||||
@@ -177,8 +177,7 @@ private: | |||||
asyncAlertWindow->addButton (TRANS ("Create Files"), 1, KeyPress (KeyPress::returnKey)); | asyncAlertWindow->addButton (TRANS ("Create Files"), 1, KeyPress (KeyPress::returnKey)); | ||||
asyncAlertWindow->addButton (TRANS ("Cancel"), 0, KeyPress (KeyPress::escapeKey)); | asyncAlertWindow->addButton (TRANS ("Cancel"), 0, KeyPress (KeyPress::escapeKey)); | ||||
WeakReference<NewComponentFileWizard> safeThis { this }; | |||||
asyncAlertWindow->enterModalState (true, ModalCallbackFunction::create ([safeThis, parent] (int result) | |||||
auto resultCallback = [safeThis = WeakReference<NewComponentFileWizard> { this }, parent] (int result) | |||||
{ | { | ||||
if (safeThis == nullptr) | if (safeThis == nullptr) | ||||
return; | return; | ||||
@@ -195,21 +194,24 @@ private: | |||||
if (className == build_tools::makeValidIdentifier (className, false, true, false)) | if (className == build_tools::makeValidIdentifier (className, false, true, false)) | ||||
{ | { | ||||
safeThis->askUserToChooseNewFile (className + ".h", "*.h;*.cpp", parent, [safeThis, parent, className] (File newFile) | |||||
{ | |||||
if (safeThis == nullptr) | |||||
return; | |||||
safeThis->askUserToChooseNewFile (className + ".h", "*.h;*.cpp", | |||||
parent, | |||||
[safeThis, parent, className] (File newFile) | |||||
{ | |||||
if (safeThis == nullptr) | |||||
return; | |||||
if (newFile != File()) | |||||
safeThis->createFiles (parent, className, newFile); | |||||
}); | |||||
if (newFile != File()) | |||||
safeThis->createFiles (parent, className, newFile); | |||||
}); | |||||
return; | return; | ||||
} | } | ||||
safeThis->createNewFileInternal (parent); | safeThis->createNewFileInternal (parent); | ||||
}; | |||||
}), false); | |||||
asyncAlertWindow->enterModalState (true, ModalCallbackFunction::create (std::move (resultCallback)), false); | |||||
} | } | ||||
std::unique_ptr<AlertWindow> asyncAlertWindow; | std::unique_ptr<AlertWindow> asyncAlertWindow; | ||||
@@ -2938,12 +2938,10 @@ public: | |||||
setScaleFactorAndDispatchMessage (peer->getPlatformScaleFactor()); | setScaleFactorAndDispatchMessage (peer->getPlatformScaleFactor()); | ||||
#if JUCE_LINUX || JUCE_BSD | #if JUCE_LINUX || JUCE_BSD | ||||
SafePointer<VSTPluginWindow> safeThis (this); | |||||
MessageManager::callAsync ([this, safeThis] | |||||
MessageManager::callAsync ([safeThis = SafePointer<VSTPluginWindow> { this }] | |||||
{ | { | ||||
if (safeThis != nullptr) | if (safeThis != nullptr) | ||||
componentMovedOrResized (true, true); | |||||
safeThis->componentMovedOrResized (true, true); | |||||
}); | }); | ||||
#else | #else | ||||
componentMovedOrResized (true, true); | componentMovedOrResized (true, true); | ||||
@@ -130,12 +130,10 @@ public: | |||||
static BluetoothMidiPairingWindowClass cls; | static BluetoothMidiPairingWindowClass cls; | ||||
window.reset (cls.createInstance()); | window.reset (cls.createInstance()); | ||||
WeakReference<BluetoothMidiSelectorWindowHelper> safeThis (this); | |||||
auto deletionCB = [=] | |||||
auto deletionCB = [safeThis = WeakReference<BluetoothMidiSelectorWindowHelper> { this }] | |||||
{ | { | ||||
if (auto* t = safeThis.get()) | |||||
delete t; | |||||
if (safeThis != nullptr) | |||||
delete safeThis.get(); | |||||
}; | }; | ||||
callbacks.reset (new BluetoothMidiPairingWindowClass::Callbacks { std::move (exitCB), | callbacks.reset (new BluetoothMidiPairingWindowClass::Callbacks { std::move (exitCB), | ||||
@@ -1753,12 +1753,10 @@ void Component::exitModalState (int returnValue) | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
WeakReference<Component> target (this); | |||||
MessageManager::callAsync ([=] | |||||
MessageManager::callAsync ([target = WeakReference<Component> { this }, returnValue] | |||||
{ | { | ||||
if (auto* c = target.get()) | |||||
c->exitModalState (returnValue); | |||||
if (target != nullptr) | |||||
target->exitModalState (returnValue); | |||||
}); | }); | ||||
} | } | ||||
} | } | ||||
@@ -2306,12 +2304,10 @@ void Component::internalModalInputAttempt() | |||||
//============================================================================== | //============================================================================== | ||||
void Component::postCommandMessage (int commandID) | void Component::postCommandMessage (int commandID) | ||||
{ | { | ||||
WeakReference<Component> target (this); | |||||
MessageManager::callAsync ([=] | |||||
MessageManager::callAsync ([target = WeakReference<Component> { this }, commandID] | |||||
{ | { | ||||
if (auto* c = target.get()) | |||||
c->handleCommandMessage (commandID); | |||||
if (target != nullptr) | |||||
target->handleCommandMessage (commandID); | |||||
}); | }); | ||||
} | } | ||||
@@ -207,7 +207,7 @@ void ModalComponentManager::handleAsyncUpdate() | |||||
Component::SafePointer<Component> compToDelete (item->autoDelete ? item->component : nullptr); | Component::SafePointer<Component> compToDelete (item->autoDelete ? item->component : nullptr); | ||||
for (int j = item->callbacks.size(); --j >= 0;) | for (int j = item->callbacks.size(); --j >= 0;) | ||||
item->callbacks.getUnchecked(j)->modalStateFinished (item->returnValue); | |||||
item->callbacks.getUnchecked (j)->modalStateFinished (item->returnValue); | |||||
compToDelete.deleteAndZero(); | compToDelete.deleteAndZero(); | ||||
} | } | ||||
@@ -198,7 +198,10 @@ public: | |||||
static ModalComponentManager::Callback* create (void (*functionToCall) (int, ParamType), | static ModalComponentManager::Callback* create (void (*functionToCall) (int, ParamType), | ||||
ParamType parameterValue) | ParamType parameterValue) | ||||
{ | { | ||||
return create ([=] (int r) { functionToCall (r, parameterValue); }); | |||||
return create ([functionToCall, parameterValue] (int r) | |||||
{ | |||||
functionToCall (r, parameterValue); | |||||
}); | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
@@ -228,7 +231,10 @@ public: | |||||
ParamType1 parameterValue1, | ParamType1 parameterValue1, | ||||
ParamType2 parameterValue2) | ParamType2 parameterValue2) | ||||
{ | { | ||||
return create ([=] (int r) { functionToCall (r, parameterValue1, parameterValue2); }); | |||||
return create ([functionToCall, parameterValue1, parameterValue2] (int r) | |||||
{ | |||||
functionToCall (r, parameterValue1, parameterValue2); | |||||
}); | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
@@ -258,8 +264,10 @@ public: | |||||
static ModalComponentManager::Callback* forComponent (void (*functionToCall) (int, ComponentType*), | static ModalComponentManager::Callback* forComponent (void (*functionToCall) (int, ComponentType*), | ||||
ComponentType* component) | ComponentType* component) | ||||
{ | { | ||||
WeakReference<Component> comp (component); | |||||
return create ([=] (int r) { functionToCall (r, static_cast<ComponentType*> (comp.get())); }); | |||||
return create ([functionToCall, comp = WeakReference<Component> { component }] (int r) | |||||
{ | |||||
functionToCall (r, static_cast<ComponentType*> (comp.get())); | |||||
}); | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
@@ -290,8 +298,10 @@ public: | |||||
ComponentType* component, | ComponentType* component, | ||||
ParamType param) | ParamType param) | ||||
{ | { | ||||
WeakReference<Component> comp (component); | |||||
return create ([=] (int r) { functionToCall (r, static_cast<ComponentType*> (comp.get()), param); }); | |||||
return create ([functionToCall, param, comp = WeakReference<Component> { component }] (int r) | |||||
{ | |||||
functionToCall (r, static_cast<ComponentType*> (comp.get()), param); | |||||
}); | |||||
} | } | ||||
private: | private: | ||||
@@ -192,8 +192,10 @@ void Desktop::handleAsyncUpdate() | |||||
{ | { | ||||
// The component may be deleted during this operation, but we'll use a SafePointer rather than a | // The component may be deleted during this operation, but we'll use a SafePointer rather than a | ||||
// BailOutChecker so that any remaining listeners will still get a callback (with a null pointer). | // BailOutChecker so that any remaining listeners will still get a callback (with a null pointer). | ||||
WeakReference<Component> currentFocus (Component::getCurrentlyFocusedComponent()); | |||||
focusListeners.call ([&] (FocusChangeListener& l) { l.globalFocusChanged (currentFocus.get()); }); | |||||
focusListeners.call ([currentFocus = WeakReference<Component> { Component::getCurrentlyFocusedComponent() }] (FocusChangeListener& l) | |||||
{ | |||||
l.globalFocusChanged (currentFocus.get()); | |||||
}); | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
@@ -392,8 +392,8 @@ void MultiDocumentPanel::closeDocumentAsync (Component* component, | |||||
{ | { | ||||
if (checkItsOkToCloseFirst) | if (checkItsOkToCloseFirst) | ||||
{ | { | ||||
SafePointer<MultiDocumentPanel> parent { this }; | |||||
tryToCloseDocumentAsync (component, [parent, component, callback] (bool closedSuccessfully) | |||||
tryToCloseDocumentAsync (component, | |||||
[parent = SafePointer<MultiDocumentPanel> { this }, component, callback] (bool closedSuccessfully) | |||||
{ | { | ||||
if (parent == nullptr) | if (parent == nullptr) | ||||
return; | return; | ||||
@@ -490,10 +490,10 @@ public: | |||||
auto chooserIntent = LocalRef<jobject> (env->CallStaticObjectMethod (AndroidIntent, AndroidIntent.createChooser, | auto chooserIntent = LocalRef<jobject> (env->CallStaticObjectMethod (AndroidIntent, AndroidIntent.createChooser, | ||||
intent.get(), javaString ("Choose share target").get())); | intent.get(), javaString ("Choose share target").get())); | ||||
WeakReference<ContentSharerNativeImpl> weakRef (this); | |||||
startAndroidActivityForResult (chooserIntent, 1003, | startAndroidActivityForResult (chooserIntent, 1003, | ||||
[weakRef] (int /*requestCode*/, int resultCode, LocalRef<jobject> /*intentData*/) mutable | |||||
[weakRef = WeakReference<ContentSharerNativeImpl> { this }] (int /*requestCode*/, | |||||
int resultCode, | |||||
LocalRef<jobject> /*intentData*/) mutable | |||||
{ | { | ||||
if (weakRef != nullptr) | if (weakRef != nullptr) | ||||
weakRef->sharingFinished (resultCode); | weakRef->sharingFinished (resultCode); | ||||
@@ -680,10 +680,11 @@ private: | |||||
AndroidIntent.createChooser, | AndroidIntent.createChooser, | ||||
intent.get(), | intent.get(), | ||||
javaString ("Choose share target").get())); | javaString ("Choose share target").get())); | ||||
WeakReference<ContentSharerNativeImpl> weakRef (this); | |||||
startAndroidActivityForResult (chooserIntent, 1003, | startAndroidActivityForResult (chooserIntent, 1003, | ||||
[weakRef] (int /*requestCode*/, int resultCode, LocalRef<jobject> /*intentData*/) mutable | |||||
[weakRef = WeakReference<ContentSharerNativeImpl> { this }] (int /*requestCode*/, | |||||
int resultCode, | |||||
LocalRef<jobject> /*intentData*/) mutable | |||||
{ | { | ||||
if (weakRef != nullptr) | if (weakRef != nullptr) | ||||
weakRef->sharingFinished (resultCode); | weakRef->sharingFinished (resultCode); | ||||
@@ -151,10 +151,8 @@ public: | |||||
if (currentFileChooser != nullptr) | if (currentFileChooser != nullptr) | ||||
{ | { | ||||
WeakReference<Native> myself (this); | |||||
startAndroidActivityForResult (LocalRef<jobject> (env->NewLocalRef (intent.get())), /*READ_REQUEST_CODE*/ 42, | startAndroidActivityForResult (LocalRef<jobject> (env->NewLocalRef (intent.get())), /*READ_REQUEST_CODE*/ 42, | ||||
[myself] (int requestCode, int resultCode, LocalRef<jobject> intentData) mutable | |||||
[myself = WeakReference<Native> { this }] (int requestCode, int resultCode, LocalRef<jobject> intentData) mutable | |||||
{ | { | ||||
if (myself != nullptr) | if (myself != nullptr) | ||||
myself->onActivityResult (requestCode, resultCode, intentData); | myself->onActivityResult (requestCode, resultCode, intentData); | ||||
@@ -680,12 +680,11 @@ private: | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
Component::SafePointer<FilePreviewComponent> safeComp (comp); | |||||
File selectedFile (path); | |||||
MessageManager::callAsync ([safeComp, selectedFile]() mutable | |||||
MessageManager::callAsync ([safeComp = Component::SafePointer<FilePreviewComponent> { comp }, | |||||
selectedFile = File { path }]() mutable | |||||
{ | { | ||||
safeComp->selectedFileChanged (selectedFile); | |||||
if (safeComp != nullptr) | |||||
safeComp->selectedFileChanged (selectedFile); | |||||
}); | }); | ||||
} | } | ||||
} | } | ||||
@@ -482,14 +482,11 @@ void ComboBox::showPopupIfNotActive() | |||||
{ | { | ||||
menuActive = true; | menuActive = true; | ||||
SafePointer<ComboBox> safePointer (this); | |||||
// as this method was triggered by a mouse event, the same mouse event may have | // as this method was triggered by a mouse event, the same mouse event may have | ||||
// exited the modal state of other popups currently on the screen. By calling | // exited the modal state of other popups currently on the screen. By calling | ||||
// showPopup asynchronously, we are giving the other popups a chance to properly | // showPopup asynchronously, we are giving the other popups a chance to properly | ||||
// close themselves | // close themselves | ||||
MessageManager::callAsync ([safePointer]() mutable { if (safePointer != nullptr) safePointer->showPopup(); }); | |||||
MessageManager::callAsync ([safePointer = SafePointer<ComboBox> { this }]() mutable { if (safePointer != nullptr) safePointer->showPopup(); }); | |||||
repaint(); | repaint(); | ||||
} | } | ||||
} | } | ||||
@@ -1875,10 +1875,8 @@ void TextEditor::mouseDown (const MouseEvent& e) | |||||
menuActive = true; | menuActive = true; | ||||
SafePointer<TextEditor> safeThis (this); | |||||
m.showMenuAsync (PopupMenu::Options(), | m.showMenuAsync (PopupMenu::Options(), | ||||
[safeThis] (int menuResult) | |||||
[safeThis = SafePointer<TextEditor> { this }] (int menuResult) | |||||
{ | { | ||||
if (auto* editor = safeThis.getComponent()) | if (auto* editor = safeThis.getComponent()) | ||||
{ | { | ||||
@@ -631,15 +631,14 @@ private: | |||||
auto options = Microsoft::WRL::Make<CoreWebView2EnvironmentOptions>(); | auto options = Microsoft::WRL::Make<CoreWebView2EnvironmentOptions>(); | ||||
WeakReference<WebView2> weakThis (this); | |||||
auto hr = createWebViewEnvironmentWithOptions (nullptr, | auto hr = createWebViewEnvironmentWithOptions (nullptr, | ||||
userDataFolder != File() ? userDataFolder.getFullPathName().toWideCharPointer() : nullptr, | userDataFolder != File() ? userDataFolder.getFullPathName().toWideCharPointer() : nullptr, | ||||
options.Get(), | options.Get(), | ||||
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>( | Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>( | ||||
[this, weakThis] (HRESULT, ICoreWebView2Environment* env) -> HRESULT | |||||
[weakThis = WeakReference<WebView2> { this }] (HRESULT, ICoreWebView2Environment* env) -> HRESULT | |||||
{ | { | ||||
if (weakThis != nullptr) | if (weakThis != nullptr) | ||||
webViewEnvironment = env; | |||||
weakThis->webViewEnvironment = env; | |||||
return S_OK; | return S_OK; | ||||
}).Get()); | }).Get()); | ||||
@@ -657,22 +656,22 @@ private: | |||||
webViewEnvironment->CreateCoreWebView2Controller ((HWND) peer->getNativeHandle(), | webViewEnvironment->CreateCoreWebView2Controller ((HWND) peer->getNativeHandle(), | ||||
Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler> ( | Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler> ( | ||||
[this, weakThis] (HRESULT, ICoreWebView2Controller* controller) -> HRESULT | |||||
[weakThis = WeakReference<WebView2> { this }] (HRESULT, ICoreWebView2Controller* controller) -> HRESULT | |||||
{ | { | ||||
if (weakThis != nullptr) | if (weakThis != nullptr) | ||||
{ | { | ||||
isCreating = false; | |||||
weakThis->isCreating = false; | |||||
if (controller != nullptr) | if (controller != nullptr) | ||||
{ | { | ||||
webViewController = controller; | |||||
controller->get_CoreWebView2 (webView.resetAndGetPointerAddress()); | |||||
weakThis->webViewController = controller; | |||||
controller->get_CoreWebView2 (weakThis->webView.resetAndGetPointerAddress()); | |||||
addEventHandlers(); | |||||
componentMovedOrResized (true, true); | |||||
weakThis->addEventHandlers(); | |||||
weakThis->componentMovedOrResized (true, true); | |||||
if (webView != nullptr && urlRequest.url.isNotEmpty()) | |||||
webView->Navigate (urlRequest.url.toWideCharPointer()); | |||||
if (weakThis->webView != nullptr && weakThis->urlRequest.url.isNotEmpty()) | |||||
weakThis->webView->Navigate (weakThis->urlRequest.url.toWideCharPointer()); | |||||
} | } | ||||
} | } | ||||
@@ -530,8 +530,8 @@ struct CameraDevice::Pimpl | |||||
if (cameraOpenCallback == nullptr || scopedCameraDevice != nullptr) | if (cameraOpenCallback == nullptr || scopedCameraDevice != nullptr) | ||||
return; | return; | ||||
WeakReference<Pimpl> safeThis (this); | |||||
RuntimePermissions::request (RuntimePermissions::camera, [safeThis] (bool granted) mutable | |||||
RuntimePermissions::request (RuntimePermissions::camera, | |||||
[safeThis = WeakReference<Pimpl> { this }] (bool granted) mutable | |||||
{ | { | ||||
if (safeThis != nullptr) | if (safeThis != nullptr) | ||||
safeThis->continueOpenRequest (granted); | safeThis->continueOpenRequest (granted); | ||||
@@ -1189,13 +1189,15 @@ private: | |||||
env->CallVoidMethod (jImage, AndroidImage.close); | env->CallVoidMethod (jImage, AndroidImage.close); | ||||
WeakReference<ImageReader> safeThis (this); | |||||
owner.callListeners (image); | owner.callListeners (image); | ||||
// Android may take multiple pictures before it handles a request to stop. | // Android may take multiple pictures before it handles a request to stop. | ||||
if (hasNotifiedListeners.compareAndSetBool (1, 0)) | if (hasNotifiedListeners.compareAndSetBool (1, 0)) | ||||
MessageManager::callAsync ([safeThis, image]() mutable { if (safeThis != nullptr) safeThis->owner.notifyPictureTaken (image); }); | |||||
MessageManager::callAsync ([safeThis = WeakReference<ImageReader> { this }, image]() mutable | |||||
{ | |||||
if (safeThis != nullptr) | |||||
safeThis->owner.notifyPictureTaken (image); | |||||
}); | |||||
} | } | ||||
struct ImageBuffer | struct ImageBuffer | ||||
@@ -2183,14 +2185,10 @@ private: | |||||
JUCE_CAMERA_LOG ("cameraCaptureSessionConfigureFailed()"); | JUCE_CAMERA_LOG ("cameraCaptureSessionConfigureFailed()"); | ||||
ignoreUnused (session); | ignoreUnused (session); | ||||
WeakReference<CaptureSession> weakRef (this); | |||||
MessageManager::callAsync ([this, weakRef]() | |||||
MessageManager::callAsync ([weakRef = WeakReference<CaptureSession> { this }] | |||||
{ | { | ||||
if (weakRef == nullptr) | |||||
return; | |||||
configuredCallback.captureSessionConfigured (nullptr); | |||||
if (weakRef != nullptr) | |||||
weakRef->configuredCallback.captureSessionConfigured (nullptr); | |||||
}); | }); | ||||
} | } | ||||
@@ -2218,17 +2216,18 @@ private: | |||||
captureSession = GlobalRef (session); | captureSession = GlobalRef (session); | ||||
} | } | ||||
WeakReference<CaptureSession> weakRef (this); | |||||
MessageManager::callAsync ([this, weakRef]() | |||||
MessageManager::callAsync ([weakRef = WeakReference<CaptureSession> { this }] | |||||
{ | { | ||||
if (weakRef == nullptr) | if (weakRef == nullptr) | ||||
return; | return; | ||||
stillPictureTaker.reset (new StillPictureTaker (captureSession, captureRequestBuilder, | |||||
previewCaptureRequest, handler, autoFocusMode)); | |||||
weakRef->stillPictureTaker.reset (new StillPictureTaker (weakRef->captureSession, | |||||
weakRef->captureRequestBuilder, | |||||
weakRef->previewCaptureRequest, | |||||
weakRef->handler, | |||||
weakRef->autoFocusMode)); | |||||
configuredCallback.captureSessionConfigured (this); | |||||
weakRef->configuredCallback.captureSessionConfigured (weakRef.get()); | |||||
}); | }); | ||||
} | } | ||||
@@ -2542,18 +2541,11 @@ private: | |||||
cameraLensFacing (cameraLensFacingToUse), | cameraLensFacing (cameraLensFacingToUse), | ||||
streamConfigurationMap (streamConfigurationMapToUse) | streamConfigurationMap (streamConfigurationMapToUse) | ||||
{ | { | ||||
WeakReference<CaptureSessionMode<Mode>> weakRef (this); | |||||
if (weakRef == nullptr) | |||||
return; | |||||
// async so that the object is fully constructed before the callback gets invoked | // async so that the object is fully constructed before the callback gets invoked | ||||
MessageManager::callAsync ([this, weakRef]() | |||||
MessageManager::callAsync ([weakRef = WeakReference<CaptureSessionMode<Mode>> { this }] | |||||
{ | { | ||||
if (weakRef == nullptr) | |||||
return; | |||||
previewDisplay.addListener (this); | |||||
if (weakRef != nullptr) | |||||
weakRef->previewDisplay.addListener (weakRef.get()); | |||||
}); | }); | ||||
} | } | ||||
@@ -1716,9 +1716,7 @@ private: | |||||
//============================================================================== | //============================================================================== | ||||
void systemVolumeChanged() | void systemVolumeChanged() | ||||
{ | { | ||||
WeakReference<SystemVolumeListener> weakThis (this); | |||||
MessageManager::callAsync ([weakThis]() mutable | |||||
MessageManager::callAsync ([weakThis = WeakReference<SystemVolumeListener> { this }]() mutable | |||||
{ | { | ||||
if (weakThis == nullptr) | if (weakThis == nullptr) | ||||
return; | return; | ||||
@@ -407,9 +407,7 @@ private: | |||||
if (error.isNotEmpty()) | if (error.isNotEmpty()) | ||||
{ | { | ||||
WeakReference<CaptureSession> weakRef (this); | |||||
MessageManager::callAsync ([weakRef, error]() mutable | |||||
MessageManager::callAsync ([weakRef = WeakReference<CaptureSession> { this }, error]() mutable | |||||
{ | { | ||||
if (weakRef != nullptr) | if (weakRef != nullptr) | ||||
weakRef->owner.cameraOpenCallback ({}, error); | weakRef->owner.cameraOpenCallback ({}, error); | ||||
@@ -423,9 +421,7 @@ private: | |||||
if (error.isNotEmpty()) | if (error.isNotEmpty()) | ||||
{ | { | ||||
WeakReference<CaptureSession> weakRef (this); | |||||
MessageManager::callAsync ([weakRef, error]() mutable | |||||
MessageManager::callAsync ([weakRef = WeakReference<CaptureSession> { this }, error]() mutable | |||||
{ | { | ||||
if (weakRef != nullptr) | if (weakRef != nullptr) | ||||
weakRef->owner.cameraOpenCallback ({}, error); | weakRef->owner.cameraOpenCallback ({}, error); | ||||
@@ -496,8 +496,7 @@ private: | |||||
{ | { | ||||
handleImageCapture (image); | handleImageCapture (image); | ||||
WeakReference<Pimpl> weakRef (this); | |||||
MessageManager::callAsync ([weakRef, image]() mutable | |||||
MessageManager::callAsync ([weakRef = WeakReference<Pimpl> { this }, image]() mutable | |||||
{ | { | ||||
if (weakRef != nullptr && weakRef->pictureTakenCallback != nullptr) | if (weakRef != nullptr && weakRef->pictureTakenCallback != nullptr) | ||||
weakRef->pictureTakenCallback (image); | weakRef->pictureTakenCallback (image); | ||||
@@ -435,9 +435,8 @@ private: | |||||
//============================================================================== | //============================================================================== | ||||
void notifyOwnerPreparationFinished (const URL& url, Result r, AVPlayer* preparedPlayer) | void notifyOwnerPreparationFinished (const URL& url, Result r, AVPlayer* preparedPlayer) | ||||
{ | { | ||||
WeakReference<PlayerAsyncInitialiser> safeThis (this); | |||||
MessageManager::callAsync ([safeThis, url, r, preparedPlayer]() mutable | |||||
MessageManager::callAsync ([url, preparedPlayer, r, | |||||
safeThis = WeakReference<PlayerAsyncInitialiser> { this }]() mutable | |||||
{ | { | ||||
if (safeThis != nullptr) | if (safeThis != nullptr) | ||||
safeThis->owner.playerPreparationFinished (url, r, preparedPlayer); | safeThis->owner.playerPreparationFinished (url, r, preparedPlayer); | ||||
@@ -530,9 +529,7 @@ private: | |||||
void playbackReachedEndTime() | void playbackReachedEndTime() | ||||
{ | { | ||||
WeakReference<PlayerControllerBase> safeThis (this); | |||||
MessageManager::callAsync ([safeThis]() mutable | |||||
MessageManager::callAsync ([safeThis = WeakReference<PlayerControllerBase> { this }]() mutable | |||||
{ | { | ||||
if (safeThis != nullptr) | if (safeThis != nullptr) | ||||
safeThis->owner.playbackReachedEndTime(); | safeThis->owner.playbackReachedEndTime(); | ||||
@@ -258,8 +258,7 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster | |||||
return; | return; | ||||
} | } | ||||
WeakReference<Pimpl> weakRef (this); | |||||
MessageManager::callAsync ([weakRef, image]() mutable | |||||
MessageManager::callAsync ([weakRef = WeakReference<Pimpl> { this }, image]() mutable | |||||
{ | { | ||||
if (weakRef == nullptr) | if (weakRef == nullptr) | ||||
return; | return; | ||||