LCOV - code coverage report
Current view: top level - src/midi - midi_manager_persist.cpp (source / functions) Coverage Total Hit
Test: merged.info Lines: 89.9 % 69 62
Test Date: 2026-06-01 11:15:25 Functions: 100.0 % 5 5

            Line data    Source code
       1              : #include "midi/midi_manager.h"
       2              : 
       3              : #include <nlohmann/json.hpp>
       4              : #include <fstream>
       5              : #include <filesystem>
       6              : #include <iostream>
       7              : 
       8              : namespace Amplitron {
       9              : 
      10              : // ---------------------------------------------------------------------------
      11              : // Persistence — midi_config.json
      12              : // ---------------------------------------------------------------------------
      13              : 
      14           42 : std::string MidiManager::get_config_path() {
      15              : #ifdef _WIN32
      16           14 :     const char* appdata = std::getenv("APPDATA");
      17           14 :     if (!appdata) return "midi_config.json";
      18           28 :     std::string dir = std::string(appdata) + "\\Amplitron";
      19           14 :     try {
      20           28 :         std::filesystem::create_directories(dir);
      21            0 :     } catch (...) {
      22              :         // Ignore errors — will fall back to local path if creation fails
      23            0 :     }
      24           14 :     return dir + "\\midi_config.json";
      25              : #else
      26           28 :     const char* home = std::getenv("HOME");
      27           28 :     if (!home) return "midi_config.json";
      28           28 :     std::string config_dir = std::string(home) + "/.config/amplitron";
      29              :     try {
      30           28 :         std::filesystem::create_directories(config_dir);
      31           14 :     } catch (...) {
      32              :         // Ignore errors — will fall back to local path if creation fails
      33            0 :     }
      34           28 :     return config_dir + "/midi_config.json";
      35              : #endif
      36           42 : }
      37              : 
      38            3 : std::string MidiManager::mappings_to_json() const {
      39            3 :     nlohmann::ordered_json root = nlohmann::ordered_json::object();
      40            3 :     nlohmann::ordered_json arr  = nlohmann::ordered_json::array();
      41              : 
      42            9 :     for (const auto& m : mappings_) {
      43            6 :         nlohmann::ordered_json jm = nlohmann::ordered_json::object();
      44            6 :         jm["cc"]      = m.cc_number;
      45            6 :         jm["channel"] = m.midi_channel;
      46            6 :         jm["target"]  = static_cast<int>(m.target_type);
      47            6 :         jm["mode"]    = static_cast<int>(m.mode);
      48            6 :         jm["effect"]  = m.effect_name;
      49            6 :         jm["param"]   = m.param_name;
      50            6 :         arr.push_back(std::move(jm));
      51            6 :     }
      52              : 
      53            3 :     root["mappings"] = std::move(arr);
      54            5 :     return root.dump(2) + "\n";
      55            3 : }
      56              : 
      57           39 : bool MidiManager::mappings_from_json(const std::string& json_str) {
      58           39 :     mappings_.clear();
      59              : 
      60           13 :     try {
      61           39 :         auto j = nlohmann::json::parse(json_str);
      62              : 
      63           39 :         if (!j.contains("mappings") || !j["mappings"].is_array()) {
      64            0 :             return false;
      65              :         }
      66              : 
      67          143 :         for (const auto& jm : j["mappings"]) {
      68           78 :             MidiMapping m;
      69           78 :             m.cc_number    = jm.value("cc",      0);
      70           78 :             m.midi_channel = jm.value("channel", -1);
      71           78 :             m.target_type  = static_cast<MidiTargetType>(jm.value("target", 0));
      72           78 :             m.mode         = static_cast<MidiMappingMode>(jm.value("mode",   0));
      73           78 :             m.effect_name  = jm.value("effect",  std::string{});
      74           78 :             m.param_name   = jm.value("param",   std::string{});
      75           78 :             mappings_.push_back(m);
      76           78 :         }
      77              : 
      78           39 :         return true;
      79           39 :     } catch (const nlohmann::json::exception& e) {
      80            0 :         std::cerr << "[midi_config] JSON parse error: " << e.what() << std::endl;
      81            0 :         return false;
      82            0 :     }
      83           13 : }
      84              : 
      85            3 : void MidiManager::save_config() const {
      86            3 :     std::string path = get_config_path();
      87            3 :     std::ofstream f(path);
      88            3 :     if (!f.is_open()) return;
      89            4 :     f << mappings_to_json();
      90            3 : }
      91              : 
      92           39 : void MidiManager::load_config() {
      93           39 :     std::string path = get_config_path();
      94           39 :     std::ifstream f(path);
      95           39 :     if (!f.is_open()) return;
      96              : 
      97           39 :     std::string content((std::istreambuf_iterator<char>(f)),
      98           52 :                          std::istreambuf_iterator<char>());
      99              : 
     100           39 :     mappings_from_json(content);
     101           39 : }
     102              : 
     103              : } // namespace Amplitron
     104              : 
        

Generated by: LCOV version 2.0-1