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
ProfileManager Class Referencefinal

#include <ProfileManager.h>

Inheritance diagram for ProfileManager:

Public Member Functions

 ProfileManager (const ProfileManager &other)=delete
 ProfileManager (ControlsModel &c_model, const Profile &profile, LrIpcOut &out, MidiReceiver &midi_receiver)
 ProfileManager (ProfileManager &&other)=delete
 ~ProfileManager ()=default
template<class T>
void AddCallback (_In_ T *const object, _In_ void(T::*const mf)(juce::XmlElement *, const juce::String &))
const juce::String & GetProfileDirectory () const noexcept
ProfileManageroperator= (const ProfileManager &other)=delete
ProfileManageroperator= (ProfileManager &&other)=delete
void SetProfileDirectory (const juce::File &directory)
void SwitchToProfile (const juce::String &profile)
void SwitchToProfile (int profile_index)

Private Types

enum class  SwitchState { kNone , kPrev , kNext }

Private Member Functions

void ConnectionCallback (bool, bool)
void handleAsyncUpdate () override
void MapCommand (rsj::MidiMessageId msg)
void MidiCmdCallback (rsj::MidiMessage mm)
void SwitchToNextProfile ()
void SwitchToPreviousProfile ()

Private Attributes

std::vector< std::function< void(juce::XmlElement *, const juce::String &)> > callbacks_
ControlsModelcontrols_model_
const Profilecurrent_profile_
int current_profile_index_ {0}
LrIpcOutlr_ipc_out_
juce::File profile_location_
std::vector< juce::String > profiles_
std::atomic< SwitchStateswitch_state_ {SwitchState::kNone}

Member Enumeration Documentation

◆ SwitchState

enum class ProfileManager::SwitchState
strongprivate
Enumerator
kNone 
kPrev 
kNext 
73 {
74 kNone,
75 kPrev,
76 kNext,
77 };

Constructor & Destructor Documentation

◆ ProfileManager() [1/3]

ProfileManager::ProfileManager ( ControlsModel & c_model,
const Profile & profile,
LrIpcOut & out,
MidiReceiver & midi_receiver )
34 : current_profile_ {profile}, controls_model_ {c_model}, lr_ipc_out_ {out}
35{
36 /* add ourselves as a listener to LR_IPC_OUT so that we can send plugin settings on connection */
37 midi_receiver.AddCallback(this, &ProfileManager::MidiCmdCallback);
39}
void AddCallback(_In_ T *const object, _In_ void(T::*const mf)(rsj::MidiMessage))
Definition MIDIReceiver.h:49
ControlsModel & controls_model_
Definition ProfileManager.h:80
LrIpcOut & lr_ipc_out_
Definition ProfileManager.h:83
const Profile & current_profile_
Definition ProfileManager.h:79
void MidiCmdCallback(rsj::MidiMessage mm)
Definition ProfileManager.cpp:144
void ConnectionCallback(bool, bool)
Definition ProfileManager.cpp:163

References current_profile_.

◆ ~ProfileManager()

ProfileManager::~ProfileManager ( )
default

◆ ProfileManager() [2/3]

ProfileManager::ProfileManager ( const ProfileManager & other)
delete

◆ ProfileManager() [3/3]

ProfileManager::ProfileManager ( ProfileManager && other)
delete

Member Function Documentation

◆ AddCallback()

template<class T>
void ProfileManager::AddCallback ( _In_ T *const object,
_In_ void(T::* mf )(juce::XmlElement *, const juce::String &) )
inline
52 {
53 if (object && mf) { callbacks_.emplace_back(std::bind_front(mf, object)); }
54 }
std::vector< std::function< void(juce::XmlElement *, const juce::String &)> > callbacks_
Definition ProfileManager.h:88

References callbacks_.

◆ ConnectionCallback()

void ProfileManager::ConnectionCallback ( bool connected,
bool blocked )
private
164{
165 try {
166 if (connected && !blocked) {
167 lr_ipc_out_.SendCommand(fmt::format("ChangedToDirectory {}\n",
168 juce::File::addTrailingSeparator(profile_location_.getFullPathName()).toStdString()));
169 }
170 }
171 catch (const std::exception& e) {
172 rsj::ExceptionResponse(e, std::source_location::current());
173 throw;
174 }
175}
juce::File profile_location_
Definition ProfileManager.h:82
void ExceptionResponse(gsl::czstring id, gsl::czstring fu, const std::exception &e) noexcept

◆ GetProfileDirectory()

const juce::String & ProfileManager::GetProfileDirectory ( ) const
inlinenodiscardnoexcept
57 {
58 return profile_location_.getFullPathName();
59 }

◆ handleAsyncUpdate()

void ProfileManager::handleAsyncUpdate ( )
overrideprivate
178{
179 try {
180 const auto state = switch_state_.load(std::memory_order_acquire);
181 switch (state) {
184 break;
187 break;
189 break;
190 }
191 switch_state_.store(SwitchState::kNone, std::memory_order_release);
192 }
193 catch (const std::exception& e) {
194 rsj::ExceptionResponse(e, std::source_location::current());
195 throw;
196 }
197}
void SwitchToNextProfile()
Definition ProfileManager.cpp:92
@ kNone
Definition ProfileManager.h:74
@ kNext
Definition ProfileManager.h:76
@ kPrev
Definition ProfileManager.h:75
std::atomic< SwitchState > switch_state_
Definition ProfileManager.h:90
void SwitchToPreviousProfile()
Definition ProfileManager.cpp:107

References kNext, kNone, kPrev, SwitchToNextProfile(), and SwitchToPreviousProfile().

◆ MapCommand()

void ProfileManager::MapCommand ( rsj::MidiMessageId msg)
private
123{
124 try {
125 using namespace std::string_literals;
126 const auto cmd {current_profile_.GetCommandForMessage(msg)};
127 if (cmd == "PrevPro"s) {
128 switch_state_.store(SwitchState::kPrev, std::memory_order_release);
129 triggerAsyncUpdate();
130 }
131 else if (cmd == "NextPro"s) {
132 switch_state_.store(SwitchState::kNext, std::memory_order_release);
133 triggerAsyncUpdate();
134 }
135 else { /* no action needed */
136 }
137 }
138 catch (const std::exception& e) {
139 rsj::ExceptionResponse(e, std::source_location::current());
140 throw;
141 }
142}

Referenced by MidiCmdCallback().

◆ MidiCmdCallback()

void ProfileManager::MidiCmdCallback ( rsj::MidiMessage mm)
private
145{
146 try {
147 const rsj::MidiMessageId cc {mm};
148 /* return if the value isn't high enough (notes may be < 1), or the command isn't a valid
149 * profile-related command */
150 if (controls_model_.ControllerToPlugin(mm, false) < 0.4
151 || !current_profile_.MessageExistsInMap(cc)) {
152 return;
153 }
154 MapCommand(cc);
155 }
156 catch (const std::exception& e) {
157 rsj::ExceptionResponse(e, std::source_location::current());
158 throw;
159 }
160}
void MapCommand(rsj::MidiMessageId msg)
Definition ProfileManager.cpp:122

References rsj::MidiMessageId::MidiMessageId(), ControlsModel::ControllerToPlugin(), controls_model_, current_profile_, MapCommand(), and Profile::MessageExistsInMap().

◆ operator=() [1/2]

ProfileManager & ProfileManager::operator= ( const ProfileManager & other)
delete

◆ operator=() [2/2]

ProfileManager & ProfileManager::operator= ( ProfileManager && other)
delete

◆ SetProfileDirectory()

void ProfileManager::SetProfileDirectory ( const juce::File & directory)
42{
43 try {
44 profile_location_ = directory;
45 auto file_array {directory.findChildFiles(juce::File::findFiles, false, "*.xml")};
46 file_array.sort();
47 profiles_.resize(file_array.size());
48 std::ranges::transform(file_array, profiles_.begin(),
49 [](const auto& file) { return file.getFileName(); });
50 }
51 catch (const std::exception& e) {
52 rsj::ExceptionResponse(e, std::source_location::current());
53 throw;
54 }
55}
std::vector< juce::String > profiles_
Definition ProfileManager.h:84

◆ SwitchToNextProfile()

void ProfileManager::SwitchToNextProfile ( )
private
93{
94 try {
95 if (!profiles_.empty()) {
96 const auto profiles_size {gsl::narrow_cast<int>(profiles_.size())};
97 current_profile_index_ = (current_profile_index_ + 1) % profiles_size;
99 }
100 }
101 catch (const std::exception& e) {
102 rsj::ExceptionResponse(e, std::source_location::current());
103 throw;
104 }
105}
void SwitchToProfile(int profile_index)
Definition ProfileManager.cpp:57
int current_profile_index_
Definition ProfileManager.h:81

References current_profile_index_, and SwitchToProfile().

Referenced by handleAsyncUpdate().

◆ SwitchToPreviousProfile()

void ProfileManager::SwitchToPreviousProfile ( )
private
108{
109 try {
110 if (!profiles_.empty()) {
111 const auto profiles_size {gsl::narrow_cast<int>(profiles_.size())};
112 current_profile_index_ = (current_profile_index_ + profiles_size - 1) % profiles_size;
114 }
115 }
116 catch (const std::exception& e) {
117 rsj::ExceptionResponse(e, std::source_location::current());
118 throw;
119 }
120}

References current_profile_index_, and SwitchToProfile().

Referenced by handleAsyncUpdate().

◆ SwitchToProfile() [1/2]

void ProfileManager::SwitchToProfile ( const juce::String & profile)
73{
74 try {
75 const auto profile_file {profile_location_.getChildFile(profile)};
76 if (profile_file.exists()) {
77 if (const auto parsed {juce::parseXML(profile_file)}) {
78 for (const auto& cb : callbacks_) { cb(parsed.get(), profile); }
79 lr_ipc_out_.SendCommand(fmt::format("ChangedToDirectory {}\n",
80 juce::File::addTrailingSeparator(profile_location_.getFullPathName())
81 .toStdString()));
82 lr_ipc_out_.SendCommand(fmt::format("ChangedToFile {}\n", profile.toStdString()));
83 }
84 }
85 }
86 catch (const std::exception& e) {
87 rsj::ExceptionResponse(e, std::source_location::current());
88 throw;
89 }
90}

◆ SwitchToProfile() [2/2]

void ProfileManager::SwitchToProfile ( int profile_index)
58{
59 try {
60 if (profile_index >= 0 && std::cmp_less(profile_index, profiles_.size())) {
61 SwitchToProfile(profiles_.at(gsl::narrow_cast<size_t>(profile_index)));
62 current_profile_index_ = profile_index;
63 }
64 }
65 catch (const std::exception& e) {
66 rsj::ExceptionResponse(e, std::source_location::current());
67 throw;
68 }
69}

References current_profile_index_.

Referenced by MainContentComponent::Init(), LrIpcIn::ProcessLine(), SwitchToNextProfile(), and SwitchToPreviousProfile().

Member Data Documentation

◆ callbacks_

std::vector<std::function<void(juce::XmlElement*, const juce::String&)> > ProfileManager::callbacks_
private

Referenced by AddCallback().

◆ controls_model_

ControlsModel& ProfileManager::controls_model_
private

Referenced by MidiCmdCallback().

◆ current_profile_

const Profile& ProfileManager::current_profile_
private

Referenced by ProfileManager(), and MidiCmdCallback().

◆ current_profile_index_

int ProfileManager::current_profile_index_ {0}
private

◆ lr_ipc_out_

LrIpcOut& ProfileManager::lr_ipc_out_
private

◆ profile_location_

juce::File ProfileManager::profile_location_
private

◆ profiles_

std::vector<juce::String> ProfileManager::profiles_
private

◆ switch_state_

std::atomic<SwitchState> ProfileManager::switch_state_ {SwitchState::kNone}
private

The documentation for this class was generated from the following files:
  • C:/Users/rsjaf/source/repos/MIDI2LR/src/application/ProfileManager.h
  • C:/Users/rsjaf/source/repos/MIDI2LR/src/application/ProfileManager.cpp