Audacity  3.0.3
Namespaces | Classes | Typedefs | Functions | Variables
Journal Namespace Reference

Facilities for recording and playback of sequences of user interaction. More...

Namespaces

 anonymous_namespace{Journal.cpp}
 
 anonymous_namespace{JournalOutput.cpp}
 
 anonymous_namespace{JournalRegistry.cpp}
 
 Events
 
 WindowPaths
 

Classes

struct  RegisteredCommand
 
struct  RegisteredInitializer
 
class  SyncException
 

Typedefs

using InteractiveAction = std::function< int() >
 Function that returns a value which will be written to the journal. More...
 
using Dispatcher = std::function< bool(const wxArrayStringEx &fields) >
 
using Dictionary = std::unordered_map< wxString, Journal::Dispatcher >
 
using Initializer = std::function< bool() >
 
using Initializers = std::vector< Initializer >
 

Functions

bool RecordEnabled ()
 
bool SetRecordEnabled (bool value)
 
bool IsReplaying ()
 
void SetInputFileName (const wxString &path)
 
bool Begin (const FilePath &dataDir)
 
wxArrayStringEx GetTokens ()
 
bool Dispatch ()
 
void Sync (const wxString &string)
 
void Sync (const wxArrayString &strings)
 
void Sync (std::initializer_list< const wxString > strings)
 
int IfNotPlaying (const wxString &string, const InteractiveAction &action)
 Call action only if not replaying; synchronize on string and int values. More...
 
int GetExitCode ()
 
bool IsRecording ()
 
bool OpenOut (const wxString &fullPath)
 
void Output (const wxString &string)
 
void Output (const wxArrayString &strings)
 
void Output (std::initializer_list< const wxString > strings)
 
void Comment (const wxString &string)
 
bool GetError ()
 
void SetError ()
 
const DictionaryGetDictionary ()
 
static std::vector< Initializer > & sInitializers ()
 
const InitializersGetInitializers ()
 

Variables

constexpr auto SeparatorCharacter = ','
 
constexpr auto EscapeCharacter = '\\'
 
constexpr auto CommentCharacter = '#'
 

Detailed Description

Facilities for recording and playback of sequences of user interaction.

Typedef Documentation

◆ Dictionary

using Journal::Dictionary = typedef std::unordered_map< wxString, Journal::Dispatcher >

Definition at line 44 of file JournalRegistry.h.

◆ Dispatcher

using Journal::Dispatcher = typedef std::function< bool(const wxArrayStringEx &fields) >

Definition at line 33 of file JournalRegistry.h.

◆ Initializer

using Journal::Initializer = typedef std::function< bool() >

Definition at line 51 of file JournalRegistry.h.

◆ Initializers

using Journal::Initializers = typedef std::vector< Initializer >

Definition at line 59 of file JournalRegistry.h.

◆ InteractiveAction

using Journal::InteractiveAction = typedef std::function< int() >

Function that returns a value which will be written to the journal.

In future, might generalize to more return values and of other types

Definition at line 69 of file Journal.h.

Function Documentation

◆ Begin()

bool Journal::Begin ( const FilePath dataDir)

Definition at line 141 of file Journal.cpp.

142 {
143  if ( !GetError() && !sFileNameIn.empty() ) {
144  wxFileName fName{ sFileNameIn };
145  fName.MakeAbsolute( dataDir );
146  const auto path = fName.GetFullPath();
147  sFileIn.Open( path );
148  if ( !sFileIn.IsOpened() )
149  SetError();
150  else {
151  sLine = sFileIn.GetFirstLine();
152  sLineNumber = 0;
153 
154  auto tokens = PeekTokens();
155  NextIn();
156  if( !(
157  tokens.size() == 2 &&
158  tokens[0] == VersionToken &&
159  VersionCheck( tokens[1] )
160  ) )
161  SetError();
162  }
163  }
164 
165  if ( !GetError() && RecordEnabled() ) {
166  wxFileName fName{ dataDir, "journal", "txt" };
167  const auto path = fName.GetFullPath();
168  if ( !OpenOut( path ) )
169  SetError();
170  else {
171  // Generate a header
172  Comment( wxString::Format(
173  wxT("Journal recorded by %s on %s")
174  , wxGetUserName()
175  , wxDateTime::Now().Format()
176  ) );
178  }
179  }
180 
181  // Call other registered initialization steps
182  for (auto &initializer : GetInitializers()) {
183  if (initializer && !initializer()) {
184  SetError();
185  break;
186  }
187  }
188 
189  return !GetError();
190 }

References Comment(), GetError(), GetInitializers(), Journal::Events::anonymous_namespace{JournalEvents.cpp}::initializer, Journal::anonymous_namespace{Journal.cpp}::NextIn(), OpenOut(), Output(), Journal::anonymous_namespace{Journal.cpp}::PeekTokens(), RecordEnabled(), SetError(), Journal::anonymous_namespace{Journal.cpp}::sFileIn, Journal::anonymous_namespace{Journal.cpp}::sFileNameIn, Journal::anonymous_namespace{Journal.cpp}::sLine, Journal::anonymous_namespace{Journal.cpp}::sLineNumber, Journal::anonymous_namespace{Journal.cpp}::VersionCheck(), Journal::anonymous_namespace{Journal.cpp}::VersionString(), and Journal::anonymous_namespace{Journal.cpp}::VersionToken.

Referenced by AudacityApp::InitPart2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Comment()

void Journal::Comment ( const wxString &  string)

Definition at line 62 of file JournalOutput.cpp.

63 {
64  if ( IsRecording() )
65  sFileOut.AddLine( CommentCharacter + string );
66 }

References CommentCharacter, IsRecording(), and Journal::anonymous_namespace{JournalOutput.cpp}::sFileOut.

Referenced by Begin().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Dispatch()

bool Journal::Dispatch ( )

Definition at line 202 of file Journal.cpp.

203 {
204  if ( GetError() )
205  // Don't repeatedly indicate error
206  // Do nothing
207  return false;
208 
209  if ( !IsReplaying() )
210  return false;
211 
212  // This will throw if no lines remain. A proper journal should exit the
213  // program before that happens.
214  auto words = GetTokens();
215 
216  // Lookup dispatch function by the first field of the line
217  auto &table = GetDictionary();
218  auto &name = words[0];
219  auto iter = table.find( name );
220  if ( iter == table.end() )
221  throw SyncException{};
222 
223  // Pass all the fields including the command name to the function
224  if ( !iter->second( words ) )
225  throw SyncException{};
226 
227  return true;
228 }

References GetDictionary(), GetError(), GetTokens(), IsReplaying(), and name.

Referenced by AudacityApp::OnExit(), and AudacityApp::OnIdle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetDictionary()

const Dictionary & Journal::GetDictionary ( )

Definition at line 53 of file JournalRegistry.cpp.

54 {
55  return sDictionary();
56 }

References Journal::anonymous_namespace{JournalRegistry.cpp}::sDictionary().

Referenced by Dispatch().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetError()

bool Journal::GetError ( )

Definition at line 30 of file JournalRegistry.cpp.

31 {
32  return sError;
33 }

References Journal::anonymous_namespace{JournalRegistry.cpp}::sError.

Referenced by Begin(), Dispatch(), and GetExitCode().

Here is the caller graph for this function:

◆ GetExitCode()

int Journal::GetExitCode ( )

Definition at line 288 of file Journal.cpp.

289 {
290  // Unconsumed commands remaining in the input file is also an error condition.
291  if( !GetError() && !PeekTokens().empty() ) {
292  NextIn();
293  SetError();
294  }
295  if ( GetError() ) {
296  // Return nonzero
297  // Returning the (1-based) line number at which the script failed is a
298  // simple way to communicate that information to the test driver script.
299  return sLineNumber ? sLineNumber : -1;
300  }
301 
302  // Return zero to mean all is well, the convention for command-line tools
303  return 0;
304 }

References GetError(), Journal::anonymous_namespace{Journal.cpp}::NextIn(), Journal::anonymous_namespace{Journal.cpp}::PeekTokens(), SetError(), and Journal::anonymous_namespace{Journal.cpp}::sLineNumber.

Referenced by AudacityApp::OnRun().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetInitializers()

const Initializers & Journal::GetInitializers ( )

Definition at line 69 of file JournalRegistry.cpp.

70 {
71  return sInitializers();
72 }

References sInitializers().

Referenced by Begin().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetTokens()

wxArrayStringEx Journal::GetTokens ( )

Definition at line 192 of file Journal.cpp.

193 {
194  auto result = PeekTokens();
195  if ( !result.empty() ) {
196  NextIn();
197  return result;
198  }
199  throw SyncException{};
200 }

References Journal::anonymous_namespace{Journal.cpp}::NextIn(), and Journal::anonymous_namespace{Journal.cpp}::PeekTokens().

Referenced by Dispatch(), IfNotPlaying(), and BasicMenu::anonymous_namespace{BasicMenu.cpp}::ReplayPopup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ IfNotPlaying()

int Journal::IfNotPlaying ( const wxString &  string,
const InteractiveAction action 
)

Call action only if not replaying; synchronize on string and int values.

If not replaying, call the function, and if recording, output the string and the return value.

If replaying, skip the action; Sync on the string; parse a value from the journal; throw SyncException if the value is ill-formed; otherwise output the value (if also recording), and return it

Definition at line 256 of file Journal.cpp.

258 {
259  // Special journal word
260  Sync(string);
261 
262  // Then read or write the return value on another journal line
263  if ( IsReplaying() ) {
264  auto tokens = GetTokens();
265  if ( tokens.size() == 1 ) {
266  try {
267  std::wstring str{ tokens[0].wc_str() };
268  size_t length = 0;
269  auto result = std::stoi(str, &length);
270  if (length == str.length()) {
271  if (IsRecording())
272  Journal::Output( std::to_wstring(result) );
273  return result;
274  }
275  }
276  catch ( const std::exception& ) {}
277  }
278  throw SyncException{};
279  }
280  else {
281  auto result = action ? action() : 0;
282  if ( IsRecording() )
283  Output( std::to_wstring( result ) );
284  return result;
285  }
286 }

References GetTokens(), IsRecording(), IsReplaying(), Output(), str, and Sync().

Referenced by AudacityMessageBox().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ IsRecording()

bool Journal::IsRecording ( )

Definition at line 28 of file JournalOutput.cpp.

29 {
30  return sFileOut.IsOpened();
31 }

References Journal::anonymous_namespace{JournalOutput.cpp}::sFileOut.

Referenced by Comment(), IfNotPlaying(), Output(), and Sync().

Here is the caller graph for this function:

◆ IsReplaying()

bool Journal::IsReplaying ( )

Definition at line 131 of file Journal.cpp.

132 {
133  return sFileIn.IsOpened();
134 }

References Journal::anonymous_namespace{Journal.cpp}::sFileIn.

Referenced by Dispatch(), IfNotPlaying(), Journal::anonymous_namespace{Journal.cpp}::PeekTokens(), BasicMenu::Handle::Popup(), and Sync().

Here is the caller graph for this function:

◆ OpenOut()

bool Journal::OpenOut ( const wxString &  fullPath)

Definition at line 33 of file JournalOutput.cpp.

34 {
35  sFileOut.Open( fullPath );
36  if ( sFileOut.IsOpened() )
37  sFileOut.Clear();
38  else {
39  sFileOut.Create();
40  sFileOut.Open( fullPath );
41  }
42  return sFileOut.IsOpened();
43 }

References Journal::anonymous_namespace{JournalOutput.cpp}::sFileOut.

Referenced by Begin().

Here is the caller graph for this function:

◆ Output() [1/3]

void Journal::Output ( const wxArrayString &  strings)

Definition at line 51 of file JournalOutput.cpp.

52 {
53  if ( IsRecording() )
54  Output( ::wxJoin( strings, SeparatorCharacter, EscapeCharacter ) );
55 }

References EscapeCharacter, IsRecording(), Output(), and SeparatorCharacter.

Here is the call graph for this function:

◆ Output() [2/3]

void Journal::Output ( const wxString &  string)

Definition at line 45 of file JournalOutput.cpp.

46 {
47  if ( IsRecording() )
48  sFileOut.AddLine( string );
49 }

References IsRecording(), and Journal::anonymous_namespace{JournalOutput.cpp}::sFileOut.

Referenced by Begin(), Journal::Events::anonymous_namespace{JournalEvents.cpp}::Watcher::FilterEvent(), BasicMenu::anonymous_namespace{BasicMenu.cpp}::Watcher::FilterEvent(), CommandManager::HandleCommandEntry(), IfNotPlaying(), Output(), BasicMenu::Handle::Popup(), and Sync().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Output() [3/3]

void Journal::Output ( std::initializer_list< const wxString >  strings)

Definition at line 57 of file JournalOutput.cpp.

58 {
59  return Output( wxArrayStringEx( strings ) );
60 }

References Output().

Here is the call graph for this function:

◆ RecordEnabled()

bool Journal::RecordEnabled ( )

Definition at line 119 of file Journal.cpp.

120 {
121  return JournalEnabled.Read();
122 }

References Journal::anonymous_namespace{Journal.cpp}::JournalEnabled, and Setting< T >::Read().

Referenced by Begin(), PluginActions::Handler::OnWriteJournal(), and anonymous_namespace{PluginMenus.cpp}::ToolsMenu().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetError()

void Journal::SetError ( )

Definition at line 35 of file JournalRegistry.cpp.

36 {
37  sError = true;
38 }

References Journal::anonymous_namespace{JournalRegistry.cpp}::sError.

Referenced by Begin(), GetExitCode(), Journal::RegisteredCommand::RegisteredCommand(), and Journal::SyncException::SyncException().

Here is the caller graph for this function:

◆ SetInputFileName()

void Journal::SetInputFileName ( const wxString &  path)

Definition at line 136 of file Journal.cpp.

137 {
138  sFileNameIn = path;
139 }

References Journal::anonymous_namespace{Journal.cpp}::sFileNameIn.

Referenced by AudacityApp::InitPart2().

Here is the caller graph for this function:

◆ SetRecordEnabled()

bool Journal::SetRecordEnabled ( bool  value)

Definition at line 124 of file Journal.cpp.

125 {
126  auto result = JournalEnabled.Write(value);
127  gPrefs->Flush();
128  return result;
129 }

References FileConfig::Flush(), gPrefs, Journal::anonymous_namespace{Journal.cpp}::JournalEnabled, and Setting< T >::Write().

Referenced by PluginActions::Handler::OnWriteJournal().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sInitializers()

static std::vector<Initializer>& Journal::sInitializers ( )
static

Definition at line 58 of file JournalRegistry.cpp.

59 {
60  static std::vector<Initializer> sTheFunctions;
61  return sTheFunctions;
62 }

Referenced by GetInitializers(), and Journal::RegisteredInitializer::RegisteredInitializer().

Here is the caller graph for this function:

◆ Sync() [1/3]

void Journal::Sync ( const wxArrayString &  strings)

Definition at line 243 of file Journal.cpp.

244 {
245  if ( IsRecording() || IsReplaying() ) {
246  auto string = ::wxJoin( strings, SeparatorCharacter, EscapeCharacter );
247  Sync( string );
248  }
249 }

References EscapeCharacter, IsRecording(), IsReplaying(), SeparatorCharacter, and Sync().

Here is the call graph for this function:

◆ Sync() [2/3]

void Journal::Sync ( const wxString &  string)

Definition at line 230 of file Journal.cpp.

231 {
232  if ( IsRecording() || IsReplaying() ) {
233  if ( IsRecording() )
234  Output( string );
235  if ( IsReplaying() ) {
236  if ( sFileIn.Eof() || sLine != string )
237  throw SyncException{};
238  NextIn();
239  }
240  }
241 }

References IsRecording(), IsReplaying(), Journal::anonymous_namespace{Journal.cpp}::NextIn(), Output(), Journal::anonymous_namespace{Journal.cpp}::sFileIn, and Journal::anonymous_namespace{Journal.cpp}::sLine.

Referenced by IfNotPlaying(), and Sync().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Sync() [3/3]

void Journal::Sync ( std::initializer_list< const wxString >  strings)

Definition at line 251 of file Journal.cpp.

252 {
253  return Sync( wxArrayStringEx( strings ) );
254 }

References Sync().

Here is the call graph for this function:

Variable Documentation

◆ CommentCharacter

constexpr auto Journal::CommentCharacter = '#'
constexpr

◆ EscapeCharacter

constexpr auto Journal::EscapeCharacter = '\\'
constexpr

◆ SeparatorCharacter

constexpr auto Journal::SeparatorCharacter = ','
constexpr
Journal::anonymous_namespace{Journal.cpp}::JournalEnabled
BoolSetting JournalEnabled
Definition: Journal.cpp:39
Journal::GetDictionary
const Dictionary & GetDictionary()
Definition: JournalRegistry.cpp:53
Journal::anonymous_namespace{Journal.cpp}::VersionToken
constexpr auto VersionToken
Definition: Journal.cpp:67
Journal::OpenOut
bool OpenOut(const wxString &fullPath)
Definition: JournalOutput.cpp:33
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:70
str
#define str(a)
Definition: DBConnection.cpp:30
Journal::CommentCharacter
constexpr auto CommentCharacter
Definition: JournalOutput.h:24
Setting::Write
bool Write(const T &value)
Write value to config and return true if successful.
Definition: Prefs.h:172
Format
Abstract base class used in importing a file.
Journal::anonymous_namespace{Journal.cpp}::NextIn
void NextIn()
Definition: Journal.cpp:41
Journal::Sync
void Sync(std::initializer_list< const wxString > strings)
Definition: Journal.cpp:251
Journal::SeparatorCharacter
constexpr auto SeparatorCharacter
Definition: JournalOutput.h:22
Journal::anonymous_namespace{JournalOutput.cpp}::sFileOut
Journal::anonymous_namespace{JournalOutput.cpp}::FlushingTextFile sFileOut
wxArrayStringEx
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
Definition: wxArrayStringEx.h:18
Journal::anonymous_namespace{Journal.cpp}::sLine
wxString sLine
Definition: Journal.cpp:34
Journal::anonymous_namespace{JournalRegistry.cpp}::sDictionary
static Dictionary & sDictionary()
Definition: JournalRegistry.cpp:22
Setting::Read
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:128
Journal::anonymous_namespace{Journal.cpp}::sFileNameIn
wxString sFileNameIn
Definition: Journal.cpp:31
Journal::anonymous_namespace{Journal.cpp}::VersionString
wxString VersionString()
Definition: Journal.cpp:74
Journal::Output
void Output(const wxString &string)
Definition: JournalOutput.cpp:45
Journal::GetError
bool GetError()
Definition: JournalRegistry.cpp:30
Journal::anonymous_namespace{Journal.cpp}::sFileIn
wxTextFile sFileIn
Definition: Journal.cpp:32
Journal::IsRecording
bool IsRecording()
Definition: JournalOutput.cpp:28
Journal::anonymous_namespace{Journal.cpp}::PeekTokens
wxArrayStringEx PeekTokens()
Definition: Journal.cpp:49
Journal::SetError
void SetError()
Definition: JournalRegistry.cpp:35
Journal::sInitializers
static std::vector< Initializer > & sInitializers()
Definition: JournalRegistry.cpp:58
Journal::Output
void Output(std::initializer_list< const wxString > strings)
Definition: JournalOutput.cpp:57
name
const TranslatableString name
Definition: Distortion.cpp:98
Journal::Comment
void Comment(const wxString &string)
Definition: JournalOutput.cpp:62
Journal::GetTokens
wxArrayStringEx GetTokens()
Definition: Journal.cpp:192
Journal::RecordEnabled
bool RecordEnabled()
Definition: Journal.cpp:119
Journal::IsReplaying
bool IsReplaying()
Definition: Journal.cpp:131
Journal::anonymous_namespace{JournalRegistry.cpp}::sError
bool sError
Definition: JournalRegistry.cpp:20
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
Journal::EscapeCharacter
constexpr auto EscapeCharacter
Definition: JournalOutput.h:23
Journal::anonymous_namespace{Journal.cpp}::VersionCheck
bool VersionCheck(const wxString &value)
True if value is an acceptable journal version number to be rerun.
Definition: Journal.cpp:85
Journal::Events::anonymous_namespace{JournalEvents.cpp}::initializer
RegisteredInitializer initializer
Definition: JournalEvents.cpp:449
Journal::GetInitializers
const Initializers & GetInitializers()
Definition: JournalRegistry.cpp:69
Journal::anonymous_namespace{Journal.cpp}::sLineNumber
int sLineNumber
Definition: Journal.cpp:37