Audacity  2.2.0
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 
22 class wxString;
23 
24 class AudacityException /* not final */
25 {
26 public:
28  virtual ~AudacityException() = 0;
29 
30  // This is intended as a "polymorphic move copy constructor"
31  // which leaves this "empty".
32  // We would not need this if we had std::exception_ptr
33  virtual std::unique_ptr< AudacityException > Move() = 0;
34 
35  // Action to do in the main thread at idle time of the event loop.
36  virtual void DelayedHandlerAction() = 0;
37 
38 protected:
39  // Make this protected to prevent slicing copies
41  AudacityException( const AudacityException& ) = default;
44 };
45 
46 // A subclass of AudacityException whose delayed handler action displays
47 // a message box. The message is specified by further subclasses.
48 // Not more than one message box will be displayed for each pass through
49 // the main event idle loop.
50 class MessageBoxException /* not final */ : public AudacityException
51 {
52  // Do not allow subclasses to change this behavior further, except
53  // by overriding ErrorMessage()
55  void DelayedHandlerAction() override;
56 
57 protected:
58  explicit MessageBoxException( const wxString &caption = wxString{} );
59  ~MessageBoxException() override;
60 
63 
64  // Format a default, internationalized error message for this exception.
65  virtual wxString ErrorMessage() const = 0;
66 
67 private:
68  wxString caption;
69  mutable bool moved { false };
70 };
71 
72 // MessageBoxException that shows a given, unvarying string.
73 class SimpleMessageBoxException /* not final */ : public MessageBoxException
74 {
75 public:
76  explicit SimpleMessageBoxException( const wxString &message_,
77  const wxString &caption = wxString{} )
78  : MessageBoxException{ caption }
79  , message{ message_ }
80  {}
81  ~SimpleMessageBoxException() override;
82 
86 
87  std::unique_ptr< AudacityException > Move() override;
88 
89  // Format a default, internationalized error message for this exception.
90  virtual wxString ErrorMessage() const override;
91 
92 private:
93  wxString message;
94 };
95 
97 {
98  void operator () (AudacityException *pException) const
99  {
100  if ( pException )
101  pException->DelayedHandlerAction();
102  }
103 };
104 
105 // Helpers for defining GuardedCall:
106 
107 // Call one function object,
108 // then another unless the first throws, return result of first
109 template <typename R> struct Sequencer {
110  template <typename F1, typename Argument, typename F2>
111  R operator () (const F1 &f1, Argument &&a, const F2 &f2)
112  {
113  auto result = f1( std::forward<Argument>(a) );
114  f2();
115  return result;
116  }
117 };
118 // template specialization to allow R to be void
119 template <> struct Sequencer<void> {
120  template <typename F1, typename Argument, typename F2>
121  void operator () (const F1 &f1, Argument &&a, const F2 &f2)
122  {
123  f1( std::forward<Argument>(a) );
124  f2();
125  }
126 };
127 
128 // Classes that can supply the second argument of GuardedCall:
129 // Frequently useful converter of all exceptions to some failure constant
130 template <typename R> struct SimpleGuard
131 {
132  explicit SimpleGuard( R value ) : m_value{ value } {}
133  R operator () ( AudacityException * ) const { return m_value; }
134  const R m_value;
135 };
136 
137 // Simple guard specialization that returns bool, and defines Default
138 template<> struct SimpleGuard<bool>
139 {
140  explicit SimpleGuard( bool value ) : m_value{ value } {}
141  bool operator () ( AudacityException * ) const { return m_value; }
143  { return SimpleGuard{ false }; }
144  const bool m_value;
145 };
146 
147 // Simple guard specialization that returns nothing, and defines Default
148 template<> struct SimpleGuard<void>
149 {
151  void operator () ( AudacityException * ) const {}
152  static SimpleGuard Default() { return {}; }
153 };
154 
155 template < typename R >
157 { return SimpleGuard< R >{ value }; }
158 
159 inline SimpleGuard< void > MakeSimpleGuard() { return {}; }
160 
172 template <
173  typename R, // return type
174 
175  typename F1, // function object with signature R()
176 
177  typename F2 = SimpleGuard< R >, // function object
178  // with signature R( AudacityException * )
179 
180  typename F3 =
181  DefaultDelayedHandlerAction // Any( AudacityException * ), ignore return
182 >
183 R GuardedCall
184  ( const F1 &body,
185  const F2 &handler = F2::Default(),
186  const F3 &delayedHandler = {} )
187 {
188  try { return body(); }
189  catch ( AudacityException &e ) {
190  return Sequencer<R>{}( handler, &e,
191  [&] {
192  auto pException =
193  std::shared_ptr< AudacityException > { e.Move().release() };
194  wxTheApp->CallAfter( [=] { // capture pException by value
195  delayedHandler( pException.get() );
196  } );
197  }
198  );
199  }
200  catch ( ... ) {
201  return handler( nullptr );
202  }
203 }
204 
205 #endif
#define PROHIBITED
Definition: Audacity.h:248
Definition: AudacityException.h:24
SimpleGuard()
Definition: AudacityException.h:150
Definition: AudacityException.h:109
virtual void DelayedHandlerAction()=0
AudacityException(AudacityException &&)
Definition: AudacityException.h:40
AudacityException()
Definition: AudacityException.h:27
SimpleGuard< R > MakeSimpleGuard(R value)
Definition: AudacityException.h:156
static SimpleGuard Default()
Definition: AudacityException.h:152
Definition: AudacityException.h:96
Definition: AudacityException.h:130
wxString caption
Definition: AudacityException.h:68
const bool m_value
Definition: AudacityException.h:144
SimpleGuard(R value)
Definition: AudacityException.h:132
virtual ~AudacityException()=0
Definition: AudacityException.cpp:7
R GuardedCall(const F1 &body, const F2 &handler=F2::Default(), const F3 &delayedHandler={})
Definition: AudacityException.h:184
SimpleGuard(bool value)
Definition: AudacityException.h:140
Definition: AudacityException.h:148
AudacityException & operator=(AudacityException &&)
Definition: AudacityException.h:42
static SimpleGuard Default()
Definition: AudacityException.h:142
const R m_value
Definition: AudacityException.h:134
virtual std::unique_ptr< AudacityException > Move()=0
SimpleMessageBoxException(const wxString &message_, const wxString &caption=wxString{})
Definition: AudacityException.h:76
Definition: AudacityException.h:73
Definition: AudacityException.h:50