Simplify GuardedCall and default its return type to void

This commit is contained in:
Paul Licameli 2018-01-13 01:32:41 -05:00
parent 5407079c62
commit 8e0cffb7f2
11 changed files with 23 additions and 42 deletions

View File

@ -18,6 +18,7 @@
#include "MemoryX.h"
#include <wx/app.h>
#include <exception>
#include "Internat.h"
@ -105,29 +106,6 @@ struct DefaultDelayedHandlerAction
}
};
// Helpers for defining GuardedCall:
// Call one function object,
// then another unless the first throws, return result of first
template <typename R> struct Sequencer {
template <typename F1, typename Argument, typename F2>
R operator () (const F1 &f1, Argument &&a, const F2 &f2)
{
auto result = f1( std::forward<Argument>(a) );
f2();
return result;
}
};
// template specialization to allow R to be void
template <> struct Sequencer<void> {
template <typename F1, typename Argument, typename F2>
void operator () (const F1 &f1, Argument &&a, const F2 &f2)
{
f1( std::forward<Argument>(a) );
f2();
}
};
// Classes that can supply the second argument of GuardedCall:
// Frequently useful converter of all exceptions to some failure constant
template <typename R> struct SimpleGuard
@ -169,11 +147,11 @@ inline SimpleGuard< void > MakeSimpleGuard() { return {}; }
* for the guarded call or throw the same or another exception.
* It executes in the same thread as the body.
*
* If the handler catches non-null and does not throw, then delayedHandler
* If the handler is passed non-null and does not throw, then delayedHandler
* executes later in the main thread, in idle time of the event loop.
*/
template <
typename R, // return type
typename R = void, // return type
typename F1, // function object with signature R()
@ -190,15 +168,18 @@ R GuardedCall
{
try { return body(); }
catch ( AudacityException &e ) {
return Sequencer<R>{}( handler, &e,
[&] {
auto end = finally([&]{
if (!std::uncaught_exception()) {
auto pException =
std::shared_ptr< AudacityException > { e.Move().release() };
wxTheApp->CallAfter( [=] { // capture pException by value
delayedHandler( pException.get() );
} );
}
);
});
return handler( &e );
}
catch ( ... ) {
return handler( nullptr );

View File

@ -2724,7 +2724,7 @@ void AudioIO::StopStream()
// If the other track operations fail their strong guarantees, then
// the shift for latency correction may be skipped.
GuardedCall<void>( [&] {
GuardedCall( [&] {
WaveTrack* track = mCaptureTracks[i].get();
// use NOFAIL-GUARANTEE that track is flushed,
@ -3976,7 +3976,7 @@ void AudioIO::FillBuffers()
if (!mRecordingException &&
mCaptureTracks.size() > 0)
GuardedCall<void>( [&] {
GuardedCall( [&] {
// start record buffering
auto commonlyAvail = GetCommonlyAvailCapture();

View File

@ -1660,7 +1660,7 @@ _("Project check of \"%s\" folder \
// and don't try to recover other files but
// silence them too. GuardedCall will cause an appropriate
// error message for the user.
GuardedCall<void>(
GuardedCall(
[&] { ab->Recover(); },
[&] (AudacityException*) { action = 1; }
);
@ -1726,7 +1726,7 @@ _("Project check of \"%s\" folder \
// and don't try to recover other files but
// silence them too. GuardedCall will cause an appropriate
// error message for the user.
GuardedCall<void>(
GuardedCall(
[&] {
b->Recover();
nResult |= FSCKstatus_CHANGED;
@ -1800,7 +1800,7 @@ _("Project check of \"%s\" folder \
// and don't try to recover other files but
// silence them too. GuardedCall will cause an appropriate
// error message for the user.
GuardedCall<void>(
GuardedCall(
[&] {
//regenerate with zeroes
b->Recover();

View File

@ -502,7 +502,7 @@ bool ImportXMLTagHandler::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
// Guard this call so that C++ exceptions don't propagate through
// the expat library
GuardedCall< void >(
GuardedCall(
[&] { mProject->Import(strAttr, &trackArray); },
[&] (AudacityException*) { trackArray.clear(); }
);

View File

@ -1239,7 +1239,7 @@ void TagsEditor::OnSave(wxCommandEvent & WXUNUSED(event))
return;
}
GuardedCall< void >( [&] {
GuardedCall( [&] {
// Create/Open the file
XMLFileWriter writer{ fn, _("Error Saving Tags File") };

View File

@ -2513,7 +2513,7 @@ void Effect::Preview(bool dryOnly)
// was called.
if (!dryOnly) {
End();
GuardedCall< void >( [&]{ Init(); } );
GuardedCall( [&]{ Init(); } );
}
if (FocusDialog) {

View File

@ -1600,7 +1600,7 @@ void EffectEqualization::SaveCurves(const wxString &fileName)
else
fn = fileName;
GuardedCall< void >( [&] {
GuardedCall( [&] {
// Create/Open the file
const wxString fullPath{ fn.GetFullPath() };
XMLFileWriter eqFile{ fullPath, _("Error Saving Equalization Curves") };

View File

@ -494,7 +494,7 @@ FFmpegPresets::FFmpegPresets()
FFmpegPresets::~FFmpegPresets()
{
// We're in a destructor! Don't let exceptions out!
GuardedCall< void >( [&] {
GuardedCall( [&] {
wxFileName xmlFileName{ FileNames::DataDir(), wxT("ffmpeg_presets.xml") };
XMLFileWriter writer{
xmlFileName.GetFullPath(), _("Error Saving FFmpeg Presets") };
@ -520,7 +520,7 @@ void FFmpegPresets::ImportPresets(wxString &filename)
void FFmpegPresets::ExportPresets(wxString &filename)
{
GuardedCall< void >( [&] {
GuardedCall( [&] {
XMLFileWriter writer{ filename, _("Error Saving FFmpeg Presets") };
WriteXMLHeader(writer);
WriteXML(writer);

View File

@ -585,7 +585,7 @@ void ExportMultiple::OnExport(wxCommandEvent& WXUNUSED(event))
FileList += '\n';
}
GuardedCall<void>( [&] {
GuardedCall( [&] {
// This results dialog is a child of this dialog.
HelpSystem::ShowInfoDialog( this,
_("Export Multiple"),

View File

@ -377,7 +377,7 @@ void KeyConfigPrefs::OnExport(wxCommandEvent & WXUNUSED(event))
return;
}
GuardedCall< void >( [&] {
GuardedCall( [&] {
XMLFileWriter prefFile{ file, _("Error Exporting Keyboard Shortcuts") };
mManager->WriteXML(prefFile);
prefFile.Commit();

View File

@ -329,7 +329,7 @@ XMLFileWriter::XMLFileWriter
XMLFileWriter::~XMLFileWriter()
{
// Don't let a destructor throw!
GuardedCall< void >( [&] {
GuardedCall( [&] {
if (!mCommitted) {
auto fileName = GetName();
if ( IsOpened() )