Audacity  2.2.2
AudacityException.h
Go to the documentation of this file.
1 #ifndef __AUDACITY_EXCEPTION__
2 #define __AUDACITY_EXCEPTION__
3 
4 /**********************************************************************
5 
6  Audacity: A Digital Audio Editor
7 
8  AudacityException.h
9 
10  Paul Licameli
11 
12  Define the root of a hierarchy of classes that are thrown and caught
13  by Audacity.
14 
15  Define some subclasses. Not all subclasses need be defined here.
16 
17  **********************************************************************/
18 
19 #include "MemoryX.h"
20 #include <wx/app.h>
21 #include <exception>
22 
23 #include "Internat.h"
24 
25 class wxString;
26 
27 class AudacityException /* not final */
28 {
29 public:
31  virtual ~AudacityException() = 0;
32 
33  // This is intended as a "polymorphic move copy constructor"
34  // which leaves this "empty".
35  // We would not need this if we had std::exception_ptr
36  virtual std::unique_ptr< AudacityException > Move() = 0;
37 
38  // Action to do in the main thread at idle time of the event loop.
39  virtual void DelayedHandlerAction() = 0;
40 
41 protected:
42  // Make this protected to prevent slicing copies
44  AudacityException( const AudacityException& ) = default;
47 };
48 
49 // A subclass of AudacityException whose delayed handler action displays
50 // a message box. The message is specified by further subclasses.
51 // Not more than one message box will be displayed for each pass through
52 // the main event idle loop.
53 class MessageBoxException /* not final */ : public AudacityException
54 {
55  // Do not allow subclasses to change this behavior further, except
56  // by overriding ErrorMessage()
58  void DelayedHandlerAction() override;
59 
60 protected:
61  // If default-constructed with empty caption, it makes no message box.
62  explicit MessageBoxException( const wxString &caption = wxString{} );
63  ~MessageBoxException() override;
64 
67 
68  // Format a default, internationalized error message for this exception.
69  virtual wxString ErrorMessage() const = 0;
70 
71 private:
72  wxString caption;
73  mutable bool moved { false };
74 };
75 
76 // MessageBoxException that shows a given, unvarying string.
77 class SimpleMessageBoxException /* not final */ : public MessageBoxException
78 {
79 public:
80  explicit SimpleMessageBoxException( const wxString &message_,
81  const wxString &caption = _("Message") )
82  : MessageBoxException{ caption }
83  , message{ message_ }
84  {}
85  ~SimpleMessageBoxException() override;
86 
90 
91  std::unique_ptr< AudacityException > Move() override;
92 
93  // Format a default, internationalized error message for this exception.
94  virtual wxString ErrorMessage() const override;
95 
96 private:
97  wxString message;
98 };
99 
101 {
102  void operator () (AudacityException *pException) const
103  {
104  if ( pException )
105  pException->DelayedHandlerAction();
106  }
107 };
108 
109 // Classes that can supply the second argument of GuardedCall:
110 // Frequently useful converter of all exceptions to some failure constant
111 template <typename R> struct SimpleGuard
112 {
113  explicit SimpleGuard( R value ) : m_value{ value } {}
114  R operator () ( AudacityException * ) const { return m_value; }
115  const R m_value;
116 };
117 
118 // Simple guard specialization that returns bool, and defines Default
119 template<> struct SimpleGuard<bool>
120 {
121  explicit SimpleGuard( bool value ) : m_value{ value } {}
122  bool operator () ( AudacityException * ) const { return m_value; }
124  { return SimpleGuard{ false }; }
125  const bool m_value;
126 };
127 
128 // Simple guard specialization that returns nothing, and defines Default
129 template<> struct SimpleGuard<void>
130 {
132  void operator () ( AudacityException * ) const {}
133  static SimpleGuard Default() { return {}; }
134 };
135 
136 template < typename R >
138 { return SimpleGuard< R >{ value }; }
139 
140 inline SimpleGuard< void > MakeSimpleGuard() { return {}; }
141 
153 template <
154  typename R = void, // return type
155 
156  typename F1, // function object with signature R()
157 
158  typename F2 = SimpleGuard< R >, // function object
159  // with signature R( AudacityException * )
160 
161  typename F3 =
162  DefaultDelayedHandlerAction // Any( AudacityException * ), ignore return
163 >
164 R GuardedCall
165  ( const F1 &body,
166  const F2 &handler = F2::Default(),
167  const F3 &delayedHandler = {} )
168 {
169  try { return body(); }
170  catch ( AudacityException &e ) {
171 
172  auto end = finally([&]{
173  if (!std::uncaught_exception()) {
174  auto pException =
175  std::shared_ptr< AudacityException > { e.Move().release() };
176  wxTheApp->CallAfter( [=] { // capture pException by value
177  delayedHandler( pException.get() );
178  } );
179  }
180  });
181 
182  return handler( &e );
183  }
184  catch ( ... ) {
185  return handler( nullptr );
186  }
187 }
188 
189 #endif
#define PROHIBITED
Definition: Audacity.h:217
root of a hierarchy of classes that are thrown and caught by Audacity.
SimpleMessageBoxException(const wxString &message_, const wxString &caption=_("Message"))
virtual void DelayedHandlerAction()=0
AudacityException(AudacityException &&)
SimpleGuard< R > MakeSimpleGuard(R value)
static SimpleGuard Default()
SimpleGuard(R value)
virtual ~AudacityException()=0
R GuardedCall(const F1 &body, const F2 &handler=F2::Default(), const F3 &delayedHandler={})
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
AudacityException & operator=(AudacityException &&)
static SimpleGuard Default()
virtual std::unique_ptr< AudacityException > Move()=0
an AudacityException that pops up a single message box even if there were multiple exceptions of the ...