From 0762af76c2537b4581531d6738b7799ab1205c10 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sun, 29 Apr 2018 21:52:56 +0100
Subject: [PATCH] Indexed-device config files for event-input layer

This allows multiple identical devices with event-input, using the
same syntax as for PLIB JS
---
 src/Input/FGEventInput.cxx | 27 ++++++++++++++++++++++++++-
 src/Input/FGEventInput.hxx |  3 +++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/Input/FGEventInput.cxx b/src/Input/FGEventInput.cxx
index f86fa3e1e..ad0e71cfa 100644
--- a/src/Input/FGEventInput.cxx
+++ b/src/Input/FGEventInput.cxx
@@ -363,6 +363,21 @@ void FGEventInput::update( double dt )
     }
 }
 
+std::string FGEventInput::computeDeviceIndexName(FGInputDevice* dev) const
+{
+    int count = 0;
+    const auto devName = dev->GetName();
+    for (auto it : input_devices) {
+        if (it.second->GetName() == devName) {
+            ++count;
+        }
+    }
+
+    std::ostringstream os;
+    os << devName << "_" << count;
+    return os.str();
+}
+
 unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice )
 {
   SGPropertyNode_ptr baseNode = fgGetNode( PROPERTY_ROOT, true );
@@ -371,7 +386,7 @@ unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice )
   const string deviceName = inputDevice->GetName();
   SGPropertyNode_ptr configNode;
   
-    // if we have a serial number set, tru using that to select a specfic configuration
+    // if we have a serial number set, try using that to select a specfic configuration
   if (!inputDevice->GetSerialNumber().empty()) {
     const string nameWithSerial = deviceName + "::" + inputDevice->GetSerialNumber();
     if (configMap.hasConfiguration(nameWithSerial)) {
@@ -380,6 +395,16 @@ unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice )
                << nameWithSerial << " : " << configNode->getStringValue("source"));
     }
   }
+
+  // try instanced (counted) name
+  if (configNode == nullptr) {
+      const auto nameWithIndex = computeDeviceIndexName(inputDevice);
+      if (configMap.hasConfiguration(nameWithIndex)) {
+          configNode = configMap.configurationForDeviceName(nameWithIndex);
+          SG_LOG(SG_INPUT, SG_INFO, "using instance-specific configuration for device "
+                 << nameWithIndex << " : " << configNode->getStringValue("source"));
+      }
+  }
   
     // otherwise try the unmodifed name for the device
   if (configNode == nullptr) {
diff --git a/src/Input/FGEventInput.hxx b/src/Input/FGEventInput.hxx
index f5bf9462f..9417807dd 100644
--- a/src/Input/FGEventInput.hxx
+++ b/src/Input/FGEventInput.hxx
@@ -309,6 +309,9 @@ protected:
   FGDeviceConfigurationMap configMap;
 
   SGPropertyNode_ptr nasalClose;
+
+private:
+  std::string computeDeviceIndexName(FGInputDevice *dev) const;
 };
 
 #endif