MIDI2LR 6.3.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
void SaveControlsModel () const
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

References systemRequestedQuit().

◆ 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("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 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:112

Referenced by shutdown().

◆ 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("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

References InitializeThreads(), LinkControlsModels(), SetupUi(), and StartServices().

◆ 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

References io_thread0_, io_thread1_, and StartThread().

Referenced by initialise().

◆ 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 {
337 CCoptions::LinkToControlsModel(&controls_model_);
338 PWoptions::LinkToControlsModel(&controls_model_);
339 }
ControlsModel controls_model_
Definition Main.cpp:462

Referenced by initialise().

◆ LinkControlsModels() [2/2]

void MIDI2LRApplication::LinkControlsModels ( )
inlineprivatenoexcept
336 {
337 CCoptions::LinkToControlsModel(&controls_model_);
338 PWoptions::LinkToControlsModel(&controls_model_);
339 }

◆ 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("ControlsModel archive in Main loaded from {}.", px.string()),
417 std::source_location::current());
418 }
419 }
420 catch (const std::exception& e) {
421 rsj::ExceptionResponse(e, std::source_location::current());
422 throw;
423 }
424 }

Referenced by SetupUi().

◆ 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("ControlsModel archive in Main loaded from {}.", px.string()),
417 std::source_location::current());
418 }
419 }
420 catch (const std::exception& e) {
421 rsj::ExceptionResponse(e, std::source_location::current());
422 throw;
423 }
424 }

◆ 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
inlineprivate
387 {
388 try {
389 const fs::path p {rsj::AppDataFilePath(kSettingsFileX)};
390 fs::create_directories(p.parent_path()); // Ensure directoryexists
391 if (std::ofstream outfile {p, std::ios::trunc}; outfile.is_open()) {
392#pragma warning(suppress : 26414) /* too large to construct on stack */
393 const auto oarchive {std::make_unique<cereal::XMLOutputArchive>(outfile)};
394 (*oarchive)(controls_model_);
395 rsj::Log(fmt::format("ControlsModel archive in Main saved to {}.", 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:141

Referenced by shutdown().

◆ SaveControlsModel() [2/2]

void MIDI2LRApplication::SaveControlsModel ( ) const
inlineprivate
387 {
388 try {
389 const fs::path p {rsj::AppDataFilePath(kSettingsFileX)};
390 fs::create_directories(p.parent_path()); // Ensure directoryexists
391 if (std::ofstream outfile {p, std::ios::trunc}; outfile.is_open()) {
392#pragma warning(suppress : 26414) /* too large to construct on stack */
393 const auto oarchive {std::make_unique<cereal::XMLOutputArchive>(outfile)};
394 (*oarchive)(controls_model_);
395 rsj::Log(fmt::format("ControlsModel archive in Main saved to {}.", 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
427 {
428 try {
429 const auto& lang {rsj::ToLower(command_set_.GetLanguage())};
430 const std::unordered_map<std::string, std::pair<std::string, std::string>> font_map {
431 { "ko", {"NotoSansKR-Regular.otf", ""}},
432 { "zh_tw", {"NotoSansTC-Regular.otf", ""}},
433 { "zh_cn", {"NotoSansSC-Regular.otf", ""}},
434 { "ja", {"NotoSansJP-Regular.otf", ""}},
435 {"default", {"NotoSans-Regular-MIDI2LR.ttf", "NotoSans-Bold-MIDI2LR.ttf"}}
436 };
437 auto font_pair {font_map.find(lang)};
438 if (font_pair == font_map.end()) { font_pair = font_map.find("default"); }
439 const auto& primary_font_name {font_pair->second.first};
440 const auto& bold_font_name {font_pair->second.second};
441 LoadFont(primary_font_name, true);
442 if (!bold_font_name.empty()) { LoadFont(bold_font_name, false); }
443 }
444 catch (const std::exception& e) {
445 rsj::ExceptionResponse(e, std::source_location::current());
446 }
447 }
const CommandSet command_set_
Definition Main.cpp:461
std::string ToLower(std::string_view in)

Referenced by SetupUi().

◆ SetAppFont() [2/2]

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

◆ 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:426
void LoadControlsModel()
Definition Main.cpp:408

References LoadControlsModel(), and SetAppFont().

Referenced by initialise().

◆ 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 SaveControlsModel() const
Definition Main.cpp:386
void DefaultProfileSave() noexcept
Definition Main.cpp:371
void StopServices()
Definition Main.cpp:358

References DefaultProfileSave(), SaveControlsModel(), and StopServices().

◆ 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 {
351 midi_receiver_.Start();
352 midi_sender_.Start();
353 lr_ipc_out_.Start();
354 lr_ipc_in_.Start();
355 version_checker_.Start();
356 }
VersionChecker version_checker_
Definition Main.cpp:473
LrIpcIn lr_ipc_in_
Definition Main.cpp:469

Referenced by initialise().

◆ StartServices() [2/2]

void MIDI2LRApplication::StartServices ( )
inlineprivate
350 {
351 midi_receiver_.Start();
352 midi_sender_.Start();
353 lr_ipc_out_.Start();
354 lr_ipc_in_.Start();
355 version_checker_.Start();
356 }

◆ 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("{} ran {} handlers.", threadName, io_context_.run()),
330 std::source_location::current());
331 }
332 });
333 }
asio::io_context io_context_
Definition Main.cpp:455

References io_context_.

Referenced by InitializeThreads().

◆ 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("{} 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. */
364 midi_receiver_.Stop();
365 lr_ipc_in_.Stop();
366 lr_ipc_out_.Stop();
367 version_checker_.Stop();
368 io_context_.stop();
369 }

References io_context_.

Referenced by shutdown().

◆ 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. */
364 midi_receiver_.Stop();
365 lr_ipc_in_.Stop();
366 lr_ipc_out_.Stop();
367 version_checker_.Stop();
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] {
250 if (profile_.ProfileUnsaved() && main_window_) {
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 }

Referenced by anotherInstanceStarted().

◆ 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] {
250 if (profile_.ProfileUnsaved() && main_window_) {
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(fmt::runtime(msgt), e->what(),
284 source_filename.toStdString(), line_number,
285 std::uncaught_exceptions()),
286 fmt::format("Unhandled exception {}, {} line {}. Total uncaught {}.", e->what(),
287 source_filename.toStdString(), line_number, 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(fmt::runtime(msgt), source_filename.toStdString(),
294 line_number, std::uncaught_exceptions()),
295 fmt::format("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(fmt::runtime(msgt), e->what(),
284 source_filename.toStdString(), line_number,
285 std::uncaught_exceptions()),
286 fmt::format("Unhandled exception {}, {} line {}. Total uncaught {}.", e->what(),
287 source_filename.toStdString(), line_number, 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(fmt::runtime(msgt), source_filename.toStdString(),
294 line_number, std::uncaught_exceptions()),
295 fmt::format("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
453{};

◆ 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{};

Referenced by StartThread(), and StopServices().

◆ io_thread0_

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

Referenced by InitializeThreads().

◆ io_thread1_

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

Referenced by InitializeThreads().

◆ 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:
  • C:/Users/rsjaf/source/repos/MIDI2LR/src/application/Main.cpp