MIDI2LR 6.2.0.1
MIDI2LR is an application that interfaces MIDI controllers with Lightroom 6+/CC Classic. It processes MIDI input into develop parameter updates and photo actions, and sends MIDI output when parameters are changed for motorized feedback (on controllers that have motorized faders). A listing of available LightRoom commands is in the Wiki. Assistance on the code and design is welcome.
Loading...
Searching...
No Matches
MIDI2LRApplication Class Referencefinal
+ Inheritance diagram for MIDI2LRApplication:

Public Member Functions

void anotherInstanceStarted (const juce::String &command_line) override
 
void anotherInstanceStarted (const juce::String &command_line) override
 
const juce::String getApplicationName () override
 
const juce::String getApplicationName () override
 
const juce::String getApplicationVersion () override
 
const juce::String getApplicationVersion () override
 
void initialise (const juce::String &command_line) override
 
void initialise (const juce::String &command_line) override
 
bool moreThanOneInstanceAllowed () noexcept override
 
bool moreThanOneInstanceAllowed () noexcept override
 
void shutdown () override
 
void shutdown () override
 
void systemRequestedQuit () override
 
void systemRequestedQuit () override
 
void unhandledException (const std::exception *e, const juce::String &source_filename, int line_number) override
 
void unhandledException (const std::exception *e, const juce::String &source_filename, int line_number) override
 

Private Member Functions

void DefaultProfileSave () noexcept
 
void DefaultProfileSave () noexcept
 
void InitializeThreads ()
 
void InitializeThreads ()
 
void LinkControlsModels () noexcept
 
void LinkControlsModels () noexcept
 
void LoadControlsModel ()
 
void LoadControlsModel ()
 
void SaveControlsModel () const noexcept
 
void SaveControlsModel () const noexcept
 
void SetAppFont () const noexcept
 
void SetAppFont () const noexcept
 
void SetupUi ()
 
void SetupUi ()
 
void StartServices ()
 
void StartServices ()
 
void StartThread (std::future< void > &thread, const char *threadName)
 
void StartThread (std::future< void > &thread, const char *threadName)
 
void StopServices ()
 
void StopServices ()
 

Private Attributes

const CommandSet command_set_ {}
 
ControlsModel controls_model_ {}
 
Devices devices_ {}
 
const LookAndFeelMIDI2LR dummy1_
 
const SetLogger dummy_ {}
 
asio::executor_work_guard< asio::io_context::executor_type > guard_
 
asio::io_context io_context_ {}
 
std::future< void > io_thread0_
 
std::future< void > io_thread1_
 
LrIpcIn lr_ipc_in_ {controls_model_, profile_manager_, profile_, midi_sender_, io_context_}
 
LrIpcOut lr_ipc_out_
 
std::unique_ptr< MainWindowmain_window_ {nullptr}
 
MidiReceiver midi_receiver_ {devices_}
 
MidiSender midi_sender_ {devices_}
 
Profile profile_ {command_set_}
 
ProfileManager profile_manager_ {controls_model_, profile_, lr_ipc_out_, midi_receiver_}
 
SettingsManager settings_manager_ {profile_manager_, lr_ipc_out_}
 
VersionChecker version_checker_ {settings_manager_}
 

Member Function Documentation

◆ anotherInstanceStarted() [1/2]

void MIDI2LRApplication::anotherInstanceStarted ( const juce::String &  command_line)
inlineoverride
268 {
269 if (command_line == kShutDownString) { systemRequestedQuit(); }
270 }
void systemRequestedQuit() override
Definition Main.cpp:242

◆ anotherInstanceStarted() [2/2]

void MIDI2LRApplication::anotherInstanceStarted ( const juce::String &  command_line)
inlineoverride
268 {
269 if (command_line == kShutDownString) { systemRequestedQuit(); }
270 }

◆ DefaultProfileSave() [1/2]

void MIDI2LRApplication::DefaultProfileSave ( )
inlineprivatenoexcept
372 {
373 try {
374 const auto file_name {rsj::AppDataFilePath(kDefaultsFile)};
375 const auto profile_file {juce::File(file_name.data())};
376 profile_.ToXmlFile(profile_file);
377 rsj::Log(fmt::format(FMT_STRING("Default profile saved to {}."),
378 profile_file.getFullPathName().toStdString()),
379 std::source_location::current());
380 }
381 catch (const std::exception& e) {
382 rsj::ExceptionResponse(e, std::source_location::current());
383 }
384 }
Profile profile_
Definition Main.cpp:463
void ToXmlFile(const juce::File &file)
Definition Profile.cpp:240
void ExceptionResponse(gsl::czstring id, gsl::czstring fu, const std::exception &e) noexcept
std::string AppDataFilePath(const std::string &file_name)
void Log(const juce::String &info, const std::source_location &location=std::source_location::current()) noexcept
Definition Misc.cpp:113

◆ DefaultProfileSave() [2/2]

void MIDI2LRApplication::DefaultProfileSave ( )
inlineprivatenoexcept
372 {
373 try {
374 const auto file_name {rsj::AppDataFilePath(kDefaultsFile)};
375 const auto profile_file {juce::File(file_name.data())};
376 profile_.ToXmlFile(profile_file);
377 rsj::Log(fmt::format(FMT_STRING("Default profile saved to {}."),
378 profile_file.getFullPathName().toStdString()),
379 std::source_location::current());
380 }
381 catch (const std::exception& e) {
382 rsj::ExceptionResponse(e, std::source_location::current());
383 }
384 }

◆ getApplicationName() [1/2]

const juce::String MIDI2LRApplication::getApplicationName ( )
inlineoverride
190 {
191 return ProjectInfo::projectName;
192 }

◆ getApplicationName() [2/2]

const juce::String MIDI2LRApplication::getApplicationName ( )
inlineoverride
190 {
191 return ProjectInfo::projectName;
192 }

◆ getApplicationVersion() [1/2]

const juce::String MIDI2LRApplication::getApplicationVersion ( )
inlineoverride
196 {
197 return ProjectInfo::versionString;
198 }

◆ getApplicationVersion() [2/2]

const juce::String MIDI2LRApplication::getApplicationVersion ( )
inlineoverride
196 {
197 return ProjectInfo::versionString;
198 }

◆ initialise() [1/2]

void MIDI2LRApplication::initialise ( const juce::String &  command_line)
inlineoverride
203 {
204 /*Called when the application starts. This will be called once to let the application do
205 * whatever initialization it needs, create its windows, etc. After the method returns, the
206 * normal event - dispatch loop will be run, until the quit() method is called, at which
207 * point the shutdown() method will be called to let the application clear up anything it
208 * needs to delete. If during the initialise() method, the application decides not to
209 * start-up after all, it can just call the quit() method and the event loop won't be
210 * run. */
211 try {
212 if (command_line != kShutDownString) {
215 /* Need to start main window before ipc so it's already registered its callbacks and can
216 * receive messages */
217 SetupUi();
219 }
220 else {
221 quit();
222 }
223 }
224 catch (const std::exception& e) {
225 rsj::ExceptionResponse(e, std::source_location::current());
226 throw;
227 }
228 }
void LinkControlsModels() noexcept
Definition Main.cpp:335
void SetupUi()
Definition Main.cpp:341
void StartServices()
Definition Main.cpp:349
void InitializeThreads()
Definition Main.cpp:309

◆ initialise() [2/2]

void MIDI2LRApplication::initialise ( const juce::String &  command_line)
inlineoverride
203 {
204 /*Called when the application starts. This will be called once to let the application do
205 * whatever initialization it needs, create its windows, etc. After the method returns, the
206 * normal event - dispatch loop will be run, until the quit() method is called, at which
207 * point the shutdown() method will be called to let the application clear up anything it
208 * needs to delete. If during the initialise() method, the application decides not to
209 * start-up after all, it can just call the quit() method and the event loop won't be
210 * run. */
211 try {
212 if (command_line != kShutDownString) {
215 /* Need to start main window before ipc so it's already registered its callbacks and can
216 * receive messages */
217 SetupUi();
219 }
220 else {
221 quit();
222 }
223 }
224 catch (const std::exception& e) {
225 rsj::ExceptionResponse(e, std::source_location::current());
226 throw;
227 }
228 }

◆ InitializeThreads() [1/2]

void MIDI2LRApplication::InitializeThreads ( )
inlineprivate
310 {
311 MIDI2LR_FAST_FLOATS;
312 rsj::LabelThread(MIDI2LR_UC_LITERAL("Main MIDI2LR thread"));
313 StartThread(io_thread0_, "io_thread0_");
314 StartThread(io_thread1_, "io_thread1_");
315 }
void StartThread(std::future< void > &thread, const char *threadName)
Definition Main.cpp:317
std::future< void > io_thread1_
Definition Main.cpp:457
std::future< void > io_thread0_
Definition Main.cpp:456
void LabelThread(gsl::czstring threadname)
Definition Misc.cpp:48

◆ InitializeThreads() [2/2]

void MIDI2LRApplication::InitializeThreads ( )
inlineprivate
310 {
311 MIDI2LR_FAST_FLOATS;
312 rsj::LabelThread(MIDI2LR_UC_LITERAL("Main MIDI2LR thread"));
313 StartThread(io_thread0_, "io_thread0_");
314 StartThread(io_thread1_, "io_thread1_");
315 }

◆ LinkControlsModels() [1/2]

void MIDI2LRApplication::LinkControlsModels ( )
inlineprivatenoexcept
336 {
339 }
static void LinkToControlsModel(_In_ ControlsModel *model) noexcept
Definition CCoptions.h:66
ControlsModel controls_model_
Definition Main.cpp:462
static void LinkToControlsModel(_In_ ControlsModel *model) noexcept
Definition PWoptions.h:63

◆ LinkControlsModels() [2/2]

void MIDI2LRApplication::LinkControlsModels ( )
inlineprivatenoexcept

◆ LoadControlsModel() [1/2]

void MIDI2LRApplication::LoadControlsModel ( )
inlineprivate
409 {
410 try {
411 const fs::path px {rsj::AppDataFilePath(kSettingsFileX)};
412 if (std::ifstream in_file {px}; in_file.is_open() && !in_file.eof()) {
413#pragma warning(suppress : 26414) /* too large to construct on stack */
414 const auto iarchive {std::make_unique<cereal::XMLInputArchive>(in_file)};
415 (*iarchive)(controls_model_);
416 rsj::Log(fmt::format(FMT_STRING("ControlsModel archive in Main loaded from {}."),
417 px.string()),
418 std::source_location::current());
419 }
420 }
421 catch (const std::exception& e) {
422 rsj::ExceptionResponse(e, std::source_location::current());
423 throw;
424 }
425 }

◆ LoadControlsModel() [2/2]

void MIDI2LRApplication::LoadControlsModel ( )
inlineprivate
409 {
410 try {
411 const fs::path px {rsj::AppDataFilePath(kSettingsFileX)};
412 if (std::ifstream in_file {px}; in_file.is_open() && !in_file.eof()) {
413#pragma warning(suppress : 26414) /* too large to construct on stack */
414 const auto iarchive {std::make_unique<cereal::XMLInputArchive>(in_file)};
415 (*iarchive)(controls_model_);
416 rsj::Log(fmt::format(FMT_STRING("ControlsModel archive in Main loaded from {}."),
417 px.string()),
418 std::source_location::current());
419 }
420 }
421 catch (const std::exception& e) {
422 rsj::ExceptionResponse(e, std::source_location::current());
423 throw;
424 }
425 }

◆ moreThanOneInstanceAllowed() [1/2]

bool MIDI2LRApplication::moreThanOneInstanceAllowed ( )
inlineoverridenoexcept
200{ return false; }

◆ moreThanOneInstanceAllowed() [2/2]

bool MIDI2LRApplication::moreThanOneInstanceAllowed ( )
inlineoverridenoexcept
200{ return false; }

◆ SaveControlsModel() [1/2]

void MIDI2LRApplication::SaveControlsModel ( ) const
inlineprivatenoexcept
387 {
388 try {
389 const fs::path p {rsj::AppDataFilePath(kSettingsFileX)};
390 if (std::ofstream outfile {p, std::ios::trunc}; outfile.is_open()) {
391#pragma warning(suppress : 26414) /* too large to construct on stack */
392 const auto oarchive {std::make_unique<cereal::XMLOutputArchive>(outfile)};
393 (*oarchive)(controls_model_);
394 rsj::Log(fmt::format(FMT_STRING("ControlsModel archive in Main saved to {}."),
395 p.string()),
396 std::source_location::current());
397 }
398 else {
399 rsj::LogAndAlertError(juce::translate("Unable to save settings.xml"),
400 "Unable to save settings.xml", std::source_location::current());
401 }
402 }
403 catch (const std::exception& e) {
404 rsj::ExceptionResponse(e, std::source_location::current());
405 }
406 }
void LogAndAlertError(const juce::String &error_text, const std::source_location &location=std::source_location::current()) noexcept
Definition Misc.cpp:142

◆ SaveControlsModel() [2/2]

void MIDI2LRApplication::SaveControlsModel ( ) const
inlineprivatenoexcept
387 {
388 try {
389 const fs::path p {rsj::AppDataFilePath(kSettingsFileX)};
390 if (std::ofstream outfile {p, std::ios::trunc}; outfile.is_open()) {
391#pragma warning(suppress : 26414) /* too large to construct on stack */
392 const auto oarchive {std::make_unique<cereal::XMLOutputArchive>(outfile)};
393 (*oarchive)(controls_model_);
394 rsj::Log(fmt::format(FMT_STRING("ControlsModel archive in Main saved to {}."),
395 p.string()),
396 std::source_location::current());
397 }
398 else {
399 rsj::LogAndAlertError(juce::translate("Unable to save settings.xml"),
400 "Unable to save settings.xml", std::source_location::current());
401 }
402 }
403 catch (const std::exception& e) {
404 rsj::ExceptionResponse(e, std::source_location::current());
405 }
406 }

◆ SetAppFont() [1/2]

void MIDI2LRApplication::SetAppFont ( ) const
inlineprivatenoexcept
428 {
429 try {
430 const auto& lang {rsj::ToLower(command_set_.GetLanguage())};
431 const std::unordered_map<std::string, std::pair<std::string, std::string>> font_map {
432 { "ko", {"NotoSansKR-Regular.otf", ""}},
433 { "zh_tw", {"NotoSansTC-Regular.otf", ""}},
434 { "zh_cn", {"NotoSansSC-Regular.otf", ""}},
435 { "ja", {"NotoSansJP-Regular.otf", ""}},
436 {"default", {"NotoSans-Regular-MIDI2LR.ttf", "NotoSans-Bold-MIDI2LR.ttf"}}
437 };
438 auto font_pair = font_map.find(lang);
439 if (font_pair == font_map.end()) { font_pair = font_map.find("default"); }
440 const auto& primary_font_name = font_pair->second.first;
441 const auto& bold_font_name = font_pair->second.second;
442 LoadFont(primary_font_name, true);
443 if (!bold_font_name.empty()) { LoadFont(bold_font_name, false); }
444 }
445 catch (const std::exception& e) {
446 rsj::ExceptionResponse(e, std::source_location::current());
447 }
448 }
const auto & GetLanguage() const noexcept
Definition CommandSet.h:54
const CommandSet command_set_
Definition Main.cpp:461
std::string ToLower(std::string_view in)

◆ SetAppFont() [2/2]

void MIDI2LRApplication::SetAppFont ( ) const
inlineprivatenoexcept
428 {
429 try {
430 const auto& lang {rsj::ToLower(command_set_.GetLanguage())};
431 const std::unordered_map<std::string, std::pair<std::string, std::string>> font_map {
432 { "ko", {"NotoSansKR-Regular.otf", ""}},
433 { "zh_tw", {"NotoSansTC-Regular.otf", ""}},
434 { "zh_cn", {"NotoSansSC-Regular.otf", ""}},
435 { "ja", {"NotoSansJP-Regular.otf", ""}},
436 {"default", {"NotoSans-Regular-MIDI2LR.ttf", "NotoSans-Bold-MIDI2LR.ttf"}}
437 };
438 auto font_pair = font_map.find(lang);
439 if (font_pair == font_map.end()) { font_pair = font_map.find("default"); }
440 const auto& primary_font_name = font_pair->second.first;
441 const auto& bold_font_name = font_pair->second.second;
442 LoadFont(primary_font_name, true);
443 if (!bold_font_name.empty()) { LoadFont(bold_font_name, false); }
444 }
445 catch (const std::exception& e) {
446 rsj::ExceptionResponse(e, std::source_location::current());
447 }
448 }

◆ SetupUi() [1/2]

void MIDI2LRApplication::SetupUi ( )
inlineprivate
342 {
343 SetAppFont();
345 main_window_ = std::make_unique<MainWindow>(getApplicationName(), command_set_, profile_,
347 }
MidiReceiver midi_receiver_
Definition Main.cpp:465
LrIpcOut lr_ipc_out_
Definition Main.cpp:466
std::unique_ptr< MainWindow > main_window_
Definition Main.cpp:472
SettingsManager settings_manager_
Definition Main.cpp:470
const juce::String getApplicationName() override
Definition Main.cpp:189
MidiSender midi_sender_
Definition Main.cpp:464
ProfileManager profile_manager_
Definition Main.cpp:468
void SetAppFont() const noexcept
Definition Main.cpp:427
void LoadControlsModel()
Definition Main.cpp:408

◆ SetupUi() [2/2]

void MIDI2LRApplication::SetupUi ( )
inlineprivate

◆ shutdown() [1/2]

void MIDI2LRApplication::shutdown ( )
inlineoverride
231 {
232 /*Called to allow the application to clear up before exiting. After JUCEApplication::quit()
233 * has been called, the event-dispatch loop will terminate, and this method will get called
234 * to allow the application to sort itself out. Be careful that nothing happens in this method
235 * that might rely on messages being sent, or any kind of window activity, because the message
236 * loop is no longer running at this point. */
237 StopServices();
240 }
void DefaultProfileSave() noexcept
Definition Main.cpp:371
void StopServices()
Definition Main.cpp:358
void SaveControlsModel() const noexcept
Definition Main.cpp:386

◆ shutdown() [2/2]

void MIDI2LRApplication::shutdown ( )
inlineoverride
231 {
232 /*Called to allow the application to clear up before exiting. After JUCEApplication::quit()
233 * has been called, the event-dispatch loop will terminate, and this method will get called
234 * to allow the application to sort itself out. Be careful that nothing happens in this method
235 * that might rely on messages being sent, or any kind of window activity, because the message
236 * loop is no longer running at this point. */
237 StopServices();
240 }

◆ StartServices() [1/2]

void MIDI2LRApplication::StartServices ( )
inlineprivate
350 {
356 }
void Start()
Definition LR_IPC_In.cpp:72
void Start()
Definition LR_IPC_Out.h:64
VersionChecker version_checker_
Definition Main.cpp:473
LrIpcIn lr_ipc_in_
Definition Main.cpp:469
void Start()
Definition MIDIReceiver.cpp:39
void Start()
Definition MIDISender.cpp:32
void Start()
Definition VersionChecker.cpp:50

◆ StartServices() [2/2]

void MIDI2LRApplication::StartServices ( )
inlineprivate

◆ StartThread() [1/2]

void MIDI2LRApplication::StartThread ( std::future< void > &  thread,
const char *  threadName 
)
inlineprivate
318 {
319 thread = std::async(std::launch::async, [this, threadName] {
320#ifdef _WIN32
321 const auto uwr = ww898::utf::convz<wchar_t>(threadName);
322 rsj::LabelThread(uwr.c_str());
323#else
324 rsj::LabelThread(threadName);
325#endif
326 MIDI2LR_FAST_FLOATS;
327 if constexpr (kNdebug) { io_context_.run(); }
328 else {
329 rsj::Log(fmt::format(FMT_STRING("{} ran {} handlers."), threadName, io_context_.run()),
330 std::source_location::current());
331 }
332 });
333 }
asio::io_context io_context_
Definition Main.cpp:455

◆ StartThread() [2/2]

void MIDI2LRApplication::StartThread ( std::future< void > &  thread,
const char *  threadName 
)
inlineprivate
318 {
319 thread = std::async(std::launch::async, [this, threadName] {
320#ifdef _WIN32
321 const auto uwr = ww898::utf::convz<wchar_t>(threadName);
322 rsj::LabelThread(uwr.c_str());
323#else
324 rsj::LabelThread(threadName);
325#endif
326 MIDI2LR_FAST_FLOATS;
327 if constexpr (kNdebug) { io_context_.run(); }
328 else {
329 rsj::Log(fmt::format(FMT_STRING("{} ran {} handlers."), threadName, io_context_.run()),
330 std::source_location::current());
331 }
332 });
333 }

◆ StopServices() [1/2]

void MIDI2LRApplication::StopServices ( )
inlineprivate
359 {
360 /*Primary goals: 1) remove callbacks in LR_IPC_Out and MIDIReceiver before the callee is
361 * destroyed, 2) stop additional threads in VersionChecker, LR_IPC_In, LR_IPC_Out and
362 * MIDIReceiver. Add to this list if new threads or callback lists are developed in this
363 * app. */
368 io_context_.stop();
369 }
void Stop()
Definition LR_IPC_In.cpp:89
void Stop()
Definition LR_IPC_Out.cpp:106
void Stop()
Definition MIDIReceiver.cpp:55
void Stop() noexcept
Definition VersionChecker.h:35

◆ StopServices() [2/2]

void MIDI2LRApplication::StopServices ( )
inlineprivate
359 {
360 /*Primary goals: 1) remove callbacks in LR_IPC_Out and MIDIReceiver before the callee is
361 * destroyed, 2) stop additional threads in VersionChecker, LR_IPC_In, LR_IPC_Out and
362 * MIDIReceiver. Add to this list if new threads or callback lists are developed in this
363 * app. */
368 io_context_.stop();
369 }

◆ systemRequestedQuit() [1/2]

void MIDI2LRApplication::systemRequestedQuit ( )
inlineoverride
243 {
244 /*This is called when the application is being asked to quit: you can ignore this request
245 * and let the application carry on running, or call quit() to allow the application to
246 * close. */
247 try {
248 constinit static std::once_flag of; /* function might be called twice during LR shutdown */
249 std::call_once(of, [this] {
251 if (juce::NativeMessageBox::showYesNoBox(juce::AlertWindow::WarningIcon,
252 juce::translate("MIDI2LR profiles"),
253 juce::translate("Profile changed. Do you want to save your changes? If you "
254 "continue without saving, your changes will be lost."))) {
255 main_window_->SaveProfile();
256 }
257 }
258 quit();
259 });
260 }
261 catch (const std::exception& e) {
262 rsj::ExceptionResponse(e, std::source_location::current());
263 throw;
264 }
265 }
bool ProfileUnsaved() const
Definition Profile.h:139

◆ systemRequestedQuit() [2/2]

void MIDI2LRApplication::systemRequestedQuit ( )
inlineoverride
243 {
244 /*This is called when the application is being asked to quit: you can ignore this request
245 * and let the application carry on running, or call quit() to allow the application to
246 * close. */
247 try {
248 constinit static std::once_flag of; /* function might be called twice during LR shutdown */
249 std::call_once(of, [this] {
251 if (juce::NativeMessageBox::showYesNoBox(juce::AlertWindow::WarningIcon,
252 juce::translate("MIDI2LR profiles"),
253 juce::translate("Profile changed. Do you want to save your changes? If you "
254 "continue without saving, your changes will be lost."))) {
255 main_window_->SaveProfile();
256 }
257 }
258 quit();
259 });
260 }
261 catch (const std::exception& e) {
262 rsj::ExceptionResponse(e, std::source_location::current());
263 throw;
264 }
265 }

◆ unhandledException() [1/2]

void MIDI2LRApplication::unhandledException ( const std::exception *  e,
const juce::String &  source_filename,
int  line_number 
)
inlineoverride
274 {
275 /* If any unhandled exceptions make it through to the message dispatch loop, this callback
276 * will be triggered, in case you want to log them or do some other type of error-handling. If
277 * the type of exception is derived from the std::exception class, the pointer passed-in will
278 * be valid. If the exception is of unknown type, this pointer will be null. */
279 try {
280 if (e) {
281 const auto msgt {juce::translate("unhandled exception").toStdString()
282 + " {}, {} line {}. Total uncaught {}."};
283 rsj::LogAndAlertError(fmt::format(msgt, e->what(), source_filename.toStdString(),
284 line_number, std::uncaught_exceptions()),
285 fmt::format(FMT_STRING("Unhandled exception {}, {} line {}. Total uncaught {}."),
286 e->what(), source_filename.toStdString(), line_number,
287 std::uncaught_exceptions()),
288 std::source_location::current());
289 }
290 else {
291 const auto msgt {juce::translate("unhandled exception").toStdString()
292 + " {} line {}. Total uncaught {}."};
293 rsj::LogAndAlertError(fmt::format(msgt, source_filename.toStdString(), line_number,
294 std::uncaught_exceptions()),
295 fmt::format(FMT_STRING("Unhandled exception {} line {}. Total uncaught {}."),
296 source_filename.toStdString(), line_number, std::uncaught_exceptions()),
297 std::source_location::current());
298 }
299 }
300 catch (...) {
301 /* we'll terminate anyway */
302 std::terminate();
303 }
304 /* can't go on with the program */
305 std::terminate();
306 }

◆ unhandledException() [2/2]

void MIDI2LRApplication::unhandledException ( const std::exception *  e,
const juce::String &  source_filename,
int  line_number 
)
inlineoverride
274 {
275 /* If any unhandled exceptions make it through to the message dispatch loop, this callback
276 * will be triggered, in case you want to log them or do some other type of error-handling. If
277 * the type of exception is derived from the std::exception class, the pointer passed-in will
278 * be valid. If the exception is of unknown type, this pointer will be null. */
279 try {
280 if (e) {
281 const auto msgt {juce::translate("unhandled exception").toStdString()
282 + " {}, {} line {}. Total uncaught {}."};
283 rsj::LogAndAlertError(fmt::format(msgt, e->what(), source_filename.toStdString(),
284 line_number, std::uncaught_exceptions()),
285 fmt::format(FMT_STRING("Unhandled exception {}, {} line {}. Total uncaught {}."),
286 e->what(), source_filename.toStdString(), line_number,
287 std::uncaught_exceptions()),
288 std::source_location::current());
289 }
290 else {
291 const auto msgt {juce::translate("unhandled exception").toStdString()
292 + " {} line {}. Total uncaught {}."};
293 rsj::LogAndAlertError(fmt::format(msgt, source_filename.toStdString(), line_number,
294 std::uncaught_exceptions()),
295 fmt::format(FMT_STRING("Unhandled exception {} line {}. Total uncaught {}."),
296 source_filename.toStdString(), line_number, std::uncaught_exceptions()),
297 std::source_location::current());
298 }
299 }
300 catch (...) {
301 /* we'll terminate anyway */
302 std::terminate();
303 }
304 /* can't go on with the program */
305 std::terminate();
306 }

Member Data Documentation

◆ command_set_

const CommandSet MIDI2LRApplication::command_set_ {}
private
461{};

◆ controls_model_

ControlsModel MIDI2LRApplication::controls_model_ {}
private
462{};

◆ devices_

Devices MIDI2LRApplication::devices_ {}
private
460{};

◆ dummy1_

const LookAndFeelMIDI2LR MIDI2LRApplication::dummy1_
private

◆ dummy_

const SetLogger MIDI2LRApplication::dummy_ {}
private
454{};

◆ guard_

asio::executor_work_guard< asio::io_context::executor_type > MIDI2LRApplication::guard_
private
Initial value:
{
asio::make_work_guard(io_context_)}
458 {
459 asio::make_work_guard(io_context_)};

◆ io_context_

asio::io_context MIDI2LRApplication::io_context_ {}
private
455{};

◆ io_thread0_

std::future< void > MIDI2LRApplication::io_thread0_
private

◆ io_thread1_

std::future< void > MIDI2LRApplication::io_thread1_
private

◆ lr_ipc_in_

◆ lr_ipc_out_

◆ main_window_

std::unique_ptr< MainWindow > MIDI2LRApplication::main_window_ {nullptr}
private
472{nullptr};

◆ midi_receiver_

MidiReceiver MIDI2LRApplication::midi_receiver_ {devices_}
private
465{devices_};
Devices devices_
Definition Main.cpp:460

◆ midi_sender_

MidiSender MIDI2LRApplication::midi_sender_ {devices_}
private
464{devices_};

◆ profile_

Profile MIDI2LRApplication::profile_ {command_set_}
private

◆ profile_manager_

◆ settings_manager_

SettingsManager MIDI2LRApplication::settings_manager_ {profile_manager_, lr_ipc_out_}
private

◆ version_checker_

VersionChecker MIDI2LRApplication::version_checker_ {settings_manager_}
private

The documentation for this class was generated from the following file: