#pragma once #include "fgc/CameraSettingsXml.h" #include #include #include namespace fgc { // One named camera profile: a VimbaX Viewer settings export, plus the generated // record beside it. // // A profile named X is /X.xml, and X.txt is a human-readable record // of what that XML contains. Only the XML is ever applied - the program hands // the path to the Vimba X SDK, so the camera receives exactly the combination // the Viewer validated. `settings` is parsed for display and diffing, never to // configure anything. struct CameraProfile { std::string name; // filename stem std::string xml_path; // what actually gets applied std::string txt_path; // the generated record CameraSettings settings; // parsed from the XML, for reading and diffing }; // What a load did, so the caller can report it. `first_run` distinguishes "there was no record to compare against" from "the // settings changed": on a first load every setting would otherwise be reported // as new, which for a real export is thousands of lines and no information. struct ProfileLoadResult { bool regenerated = false; bool first_run = false; // no previous record existed std::vector changes; // empty when first_run }; // Load a profile: hash the XML, compare against the hash recorded in the .txt, // and regenerate the record when they differ. // // Throws std::runtime_error if the XML is missing or unreadable. There is // deliberately no fallback to the .txt: it is a record, not a configuration // source, and applying one would defeat the point of the GUI validating the XML. CameraProfile loadCameraProfile(const std::string& profile_dir, const std::string& name, ProfileLoadResult& result); // Every *.xml in `dir`, keyed by profile name. Throws if the directory is // missing or holds no profiles, so a typo in a profile nobody is using today // still fails at startup rather than the first time someone switches to it. std::map loadCameraProfiles( const std::string& dir, std::map& results); } // namespace fgc