31#include <simgear/debug/ErrorReportingCallback.hxx>
32#include <simgear/misc/sg_dir.hxx>
33#include <simgear/props/props_io.hxx>
34#include <simgear/structure/exception.hxx>
40using simgear::PropertyList;
49 SGPropertyNode* nodePath,
50 const std::string& nodeName)
53 for (
auto preloaded : nodePath->getChildren(nodeName)) {
54 std::string suffix = computeSuffix(preloaded);
55 for (
auto nameProp : preloaded->getChildren(
"name")) {
56 overrideDict[nameProp->getStringValue() + suffix] = preloaded;
64std::string FGDeviceConfigurationMap::computeSuffix(SGPropertyNode_ptr node)
66 if (node->hasChild(
"serial-number")) {
67 return std::string(
"::") + node->getStringValue(
"serial-number");
71 if (node->hasChild(
"device-number")) {
72 std::ostringstream os;
73 os <<
"_" << node->getIntValue(
"device-number");
87 auto j = overrideDict.find(
name);
88 if (j != overrideDict.end()) {
93 auto it = namePathMap.find(
name);
94 if (it == namePathMap.end()) {
98 SGPropertyNode_ptr result(
new SGPropertyNode);
100 readProperties(it->second, result);
101 result->setStringValue(
"source", it->second.utf8Str());
102 }
catch (sg_exception& e) {
103 simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::InputDeviceConfig,
104 "Failed to parse device configuration:" + e.getFormattedMessage(),
114 auto j = overrideDict.find(
name);
115 if (j != overrideDict.end()) {
119 return namePathMap.find(
name) != namePathMap.end();
122void FGDeviceConfigurationMap::scan_dir(
const SGPath & path)
124 SG_LOG(SG_INPUT, SG_DEBUG,
"Scanning " << path <<
" for input devices");
131 simgear::Dir dir(path);
132 simgear::PathList children = dir.children(simgear::Dir::TYPE_FILE |
133 simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT);
135 for (SGPath path : children) {
138 }
else if (path.extension() ==
"xml") {
140 refreshCacheForFile(path);
142 readCachedData(path);
150void FGDeviceConfigurationMap::readCachedData(
const SGPath& path)
157 if (namePathMap.find(s) == namePathMap.end()) {
158 namePathMap.insert(std::make_pair(s, path));
163void FGDeviceConfigurationMap::refreshCacheForFile(
const SGPath& path)
165 simgear::ErrorReportContext ectx(
"input-device", path.utf8Str());
167 SG_LOG(SG_INPUT, SG_DEBUG,
"Reading device file " << path);
168 SGPropertyNode_ptr n(
new SGPropertyNode);
170 readProperties(path, n);
171 }
catch (sg_exception& e) {
172 simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::InputDeviceConfig,
173 "Failed to load input device configuration:" + e.getFormattedMessage(),
178 std::string suffix = computeSuffix(n);
180 for (
auto nameProp : n->getChildren(
"name")) {
181 const string name = nameProp->getStringValue() + suffix;
182 names.push_back(
name);
184 if (namePathMap.find(
name) == namePathMap.end()) {
185 namePathMap.insert(std::make_pair(
name, path));
SGPropertyNode_ptr configurationForDeviceName(const std::string &name)
virtual ~FGDeviceConfigurationMap()
FGDeviceConfigurationMap()
bool hasConfiguration(const std::string &name) const
const SGPath & get_fg_home() const
const SGPath & get_fg_root() const
void stampCacheFile(const SGPath &path, const std::string &sha={})
string_list readStringListProperty(const std::string &key)
void writeStringListProperty(const std::string &key, const string_list &values)
static NavDataCache * instance()
bool isCachedFileModified(const SGPath &path) const
std::vector< std::string > string_list