# include <config.h>
#endif
+#include <cstring>
#include "FGEventInput.hxx"
#include <Main/fg_props.hxx>
#include <simgear/io/sg_file.hxx>
+#include <simgear/props/props_io.hxx>
+#include <simgear/math/SGMath.hxx>
#include <Scripting/NasalSys.hxx>
+using simgear::PropertyList;
+using std::cout;
+using std::endl;
+using std::map;
+
FGEventSetting::FGEventSetting( SGPropertyNode_ptr base ) :
value(0.0)
{
static inline bool StartsWith( string & s, const char * cp )
{
- return s.compare( 0, strlen(cp), cp ) == 0;
+ return s.find( cp ) == 0;
}
FGInputEvent * FGInputEvent::NewObject( FGInputDevice * device, SGPropertyNode_ptr node )
return new FGButtonEvent( device, node );
if( StartsWith( name, "rel-" ) )
- return new FGAxisEvent( device, node );
+ return new FGRelAxisEvent( device, node );
if( StartsWith( name, "abs-" ) )
- return new FGAxisEvent( device, node );
+ return new FGAbsAxisEvent( device, node );
return new FGInputEvent( device, node );
}
read_bindings( node, bindings, KEYMOD_NONE, device->GetNasalModule() );
- vector<SGPropertyNode_ptr> settingNodes = node->getChildren("setting");
- for( vector<SGPropertyNode_ptr>::iterator it = settingNodes.begin(); it != settingNodes.end(); it++ )
+ PropertyList settingNodes = node->getChildren("setting");
+ for( PropertyList::iterator it = settingNodes.begin(); it != settingNodes.end(); ++it )
settings.push_back( new FGEventSetting( *it ) );
}
void FGInputEvent::update( double dt )
{
- for( setting_list_t::iterator it = settings.begin(); it != settings.end(); it++ ) {
+ for( setting_list_t::iterator it = settings.begin(); it != settings.end(); ++it ) {
if( (*it)->Test() ) {
double value = (*it)->GetValue();
if( value != lastSettingValue ) {
lastDt += eventData.dt;
if( lastDt >= intervalSec ) {
- for( binding_list_t::iterator it = bindings[eventData.modifiers].begin(); it != bindings[eventData.modifiers].end(); it++ )
- (*it)->fire( eventData.value, 1.0 );
+ for( binding_list_t::iterator it = bindings[eventData.modifiers].begin(); it != bindings[eventData.modifiers].end(); ++it )
+ fire( *it, eventData );
lastDt -= intervalSec;
}
}
+void FGInputEvent::fire( SGBinding * binding, FGEventData & eventData )
+{
+ binding->fire();
+}
+
+
+
FGAxisEvent::FGAxisEvent( FGInputDevice * device, SGPropertyNode_ptr node ) :
FGInputEvent( device, node )
{
tolerance = node->getDoubleValue("tolerance", 0.002);
- minRange = node->getDoubleValue("min-range", -1024.0);
- maxRange = node->getDoubleValue("max-range", 1024.0);
+ minRange = node->getDoubleValue("min-range", 0.0 );
+ maxRange = node->getDoubleValue("max-range", 0.0 );
center = node->getDoubleValue("center", 0.0);
deadband = node->getDoubleValue("dead-band", 0.0);
lowThreshold = node->getDoubleValue("low-threshold", -0.9);
if (fabs( eventData.value - lastValue) < tolerance)
return;
lastValue = eventData.value;
- FGInputEvent::fire( eventData );
+
+ // We need a copy of the FGEventData struct to set the new value and to avoid side effects
+ FGEventData ed = eventData;
+
+ if( fabs(ed.value) < deadband )
+ ed.value = 0.0;
+
+ if( minRange != maxRange )
+ ed.value = 2.0*(eventData.value-minRange)/(maxRange-minRange)-1.0;
+
+ FGInputEvent::fire( ed );
+}
+
+void FGAbsAxisEvent::fire( SGBinding * binding, FGEventData & eventData )
+{
+ // sets the "setting" node
+ binding->fire( eventData.value );
+}
+
+FGRelAxisEvent::FGRelAxisEvent( FGInputDevice * device, SGPropertyNode_ptr node ) :
+ FGAxisEvent( device, node )
+{
+ // relative axes can't use tolerance
+ tolerance = 0.0;
+}
+
+void FGRelAxisEvent::fire( SGBinding * binding, FGEventData & eventData )
+{
+ // sets the "offset" node
+ binding->fire( eventData.value, 1.0 );
}
FGButtonEvent::FGButtonEvent( FGInputDevice * device, SGPropertyNode_ptr node ) :
if( nasal ) {
SGPropertyNode_ptr nasalClose = nasal->getNode("close");
if (nasalClose) {
- const char *s = nasalClose->getStringValue();
- nas->createModule(nasalModule.c_str(), nasalModule.c_str(), s, strlen(s), deviceNode );
+ const string s = nasalClose->getStringValue();
+ nas->createModule(nasalModule.c_str(), nasalModule.c_str(), s.c_str(), s.length(), deviceNode );
}
}
nas->deleteModule(nasalModule.c_str());
nasalModule = string("__event:") + GetName();
- vector<SGPropertyNode_ptr> eventNodes = deviceNode->getChildren( "event" );
- for( vector<SGPropertyNode_ptr>::iterator it = eventNodes.begin(); it != eventNodes.end(); it++ )
+ PropertyList eventNodes = deviceNode->getChildren( "event" );
+ for( PropertyList::iterator it = eventNodes.begin(); it != eventNodes.end(); ++it )
AddHandledEvent( FGInputEvent::NewObject( this, *it ) );
debugEvents = deviceNode->getBoolValue("debug-events", debugEvents );
if (nasal) {
SGPropertyNode_ptr open = nasal->getNode("open");
if (open) {
- const char *s = open->getStringValue();
+ const string s = open->getStringValue();
FGNasalSys *nas = (FGNasalSys *)globals->get_subsystem("nasal");
if (nas)
- nas->createModule(nasalModule.c_str(), nasalModule.c_str(), s, strlen(s), deviceNode );
+ nas->createModule(nasalModule.c_str(), nasalModule.c_str(), s.c_str(), s.length(), deviceNode );
}
}
const char * FGEventInput::PROPERTY_ROOT = "/input/event";
FGEventInput::FGEventInput() :
- configMap( "Input/Event", fgGetNode( PROPERTY_ROOT, true ), "device-named" )
+ configMap( "Input/Event", fgGetNode(PROPERTY_ROOT, true), "device-named")
{
}
FGEventInput::~FGEventInput()
{
- for( map<int,FGInputDevice*>::iterator it = input_devices.begin(); it != input_devices.end(); it++ )
+ for( map<int,FGInputDevice*>::iterator it = input_devices.begin(); it != input_devices.end(); ++it )
delete (*it).second;
input_devices.clear();
}
void FGEventInput::update( double dt )
{
// call each associated device's update() method
- for( map<int,FGInputDevice*>::iterator it = input_devices.begin(); it != input_devices.end(); it++ )
+ for( map<int,FGInputDevice*>::iterator it = input_devices.begin(); it != input_devices.end(); ++it )
(*it).second->update( dt );
}
SGPropertyNode_ptr deviceNode = NULL;
// look for configuration in the device map
- if( configMap.count( inputDevice->GetName() ) > 0 ) {
+ if ( configMap.hasConfiguration( inputDevice->GetName() ) ) {
// found - copy to /input/event/device[n]
// find a free index
deviceNode = baseNode->getNode( "device", index, true );
// and copy the properties from the configuration tree
- copyProperties( configMap[ inputDevice->GetName() ], deviceNode );
+ copyProperties( configMap.configurationForDeviceName(inputDevice->GetName()), deviceNode );
}