From 253b14a1cba0466b2354795d4843df211d0e2957 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer Date: Tue, 1 Jun 2010 22:08:42 +0200 Subject: [PATCH] Code cleanup, inherit JK, D and T from RS and a bugfix for the logic element - reuse code - undeclared inputs default to false where applicable - remove unused tInput - JK, D and T FF now inherit from RS with dominant R input, so they all have a R and a S input to preset the output - fix the nonfunctional element of the logic element --- src/Autopilot/xmlauto.cxx | 162 +++++++++++++------------------------- src/Autopilot/xmlauto.hxx | 3 +- 2 files changed, 54 insertions(+), 111 deletions(-) diff --git a/src/Autopilot/xmlauto.cxx b/src/Autopilot/xmlauto.cxx index 189100187..39fced0a1 100644 --- a/src/Autopilot/xmlauto.cxx +++ b/src/Autopilot/xmlauto.cxx @@ -910,87 +910,59 @@ void FGXMLAutoLogic::update(double dt) return; } - bool i = input->test(); + bool q = input->test(); + if( inverted ) q = !q; - if ( debug ) cout << "Updating " << get_name() << ": " << (inverted ? !i : i) << endl; + if ( debug ) cout << "Updating " << get_name() << ": " << q << endl; - set_output_value( i ); + set_output_value( q ); } class FGXMLAutoRSFlipFlop : public FGXMLAutoFlipFlop { private: - bool _rs; + bool _rIsDominant; public: - FGXMLAutoRSFlipFlop( SGPropertyNode * node ) : - FGXMLAutoFlipFlop( node ) { - // type exists here, otherwise we were not constructed - string val = node->getNode( "type" )->getStringValue(); - _rs = (val == "RS"); - } - - void updateState( double dt ) { - - if( sInput == NULL ) { - if ( debug ) cout << "No set (S) input for " << get_name() << endl; - return; - } + FGXMLAutoRSFlipFlop( SGPropertyNode * node, bool rIsDominant = true ) : + FGXMLAutoFlipFlop( node ) {} - if( rInput == NULL ) { - if ( debug ) cout << "No reset (R) input for " << get_name() << endl; - return; - } + bool getState( bool & q ) { - bool s = sInput->test(); - bool r = rInput->test(); + bool s = sInput ? sInput->test() : false; + bool r = rInput ? rInput->test() : false; // s == false && q == false: no change, keep state if( s || r ) { - bool q = false; - if( _rs ) { // RS: reset is dominant + if( _rIsDominant ) { // RS: reset is dominant if( s ) q = true; // set if( r ) q = false; // reset } else { // SR: set is dominant if( r ) q = false; // reset if( s ) q = true; // set } - if( inverted ) q = !q; - - if ( debug ) cout << "Updating " << get_name() << ":" - << " s=" << s - << ",r=" << r - << ",q=" << q << endl; - set_output_value( q ); - } else { - if ( debug ) cout << "Updating " << get_name() << ":" - << " s=" << s - << ",r=" << r - << ",q=unchanged" << endl; + return true; // signal state changed } + return false; // signal state unchagned } }; -class FGXMLAutoJKFlipFlop : public FGXMLAutoFlipFlop { +/* + JK flip-flop with set and reset input + */ +class FGXMLAutoJKFlipFlop : public FGXMLAutoRSFlipFlop { private: bool clock; public: FGXMLAutoJKFlipFlop( SGPropertyNode * node ) : - FGXMLAutoFlipFlop( node ), + FGXMLAutoRSFlipFlop( node ), clock(false) {} - void updateState( double dt ) { + bool getState( bool & q ) { - if( jInput == NULL ) { - if ( debug ) cout << "No set (j) input for " << get_name() << endl; - return; - } - - if( kInput == NULL ) { - if ( debug ) cout << "No reset (k) input for " << get_name() << endl; - return; - } + if( FGXMLAutoRSFlipFlop::getState(q ) ) + return true; - bool j = jInput->test(); - bool k = kInput->test(); + bool j = jInput ? jInput->test() : false; + bool k = kInput ? kInput->test() : false; /* if the user provided a clock input, use it. Otherwise use framerate as clock @@ -1000,9 +972,8 @@ public: bool raisingEdge = clockInput ? (c && !clock) : true; clock = c; - if( !raisingEdge ) return; + if( !raisingEdge ) return false; //signal no change - bool q = get_bool_output_value(); // j == false && k == false: no change, keep state if( (j || k) ) { if( j && k ) { @@ -1011,78 +982,56 @@ public: if( j ) q = true; // set if( k ) q = false; // reset } - if( inverted ) q = !q; - - if ( debug ) cout << "Updating " << get_name() << ":" - << " j=" << j - << ",k=" << k - << ",q=" << q << endl; - set_output_value( q ); - } else { - if ( debug ) cout << "Updating " << get_name() << ":" - << " j=" << j - << ",k=" << k - << ",q=unchanged" << endl; } + return true; // signal state changed } }; -class FGXMLAutoDFlipFlop : public FGXMLAutoFlipFlop { +class FGXMLAutoDFlipFlop : public FGXMLAutoRSFlipFlop { private: bool clock; public: FGXMLAutoDFlipFlop( SGPropertyNode * node ) : - FGXMLAutoFlipFlop( node ), + FGXMLAutoRSFlipFlop( node ), clock(false) {} - void updateState( double dt ) { + bool getState( bool & q ) { + + if( FGXMLAutoRSFlipFlop::getState(q ) ) + return true; if( clockInput == NULL ) { if ( debug ) cout << "No (clock) input for " << get_name() << endl; - return; - } - - if( dInput == NULL ) { - if ( debug ) cout << "No (D) input for " << get_name() << endl; - return; + return false; } - bool d = dInput->test(); - // check the clock - raising edge bool c = clockInput->test(); bool raisingEdge = c && !clock; clock = c; - if( raisingEdge ) { - bool q = d; - if( inverted ) q = !q; - - if ( debug ) cout << "Updating " << get_name() << ":" - << " d=" << d - << ",q=" << q << endl; - set_output_value( q ); - } else { - if ( debug ) cout << "Updating " << get_name() << ":" - << " d=" << d - << ",q=unchanged" << endl; - } + if( !raisingEdge ) return false; // signal state unchanged + q = dInput ? dInput->test() : false; + return true; } }; -class FGXMLAutoTFlipFlop : public FGXMLAutoFlipFlop { +class FGXMLAutoTFlipFlop : public FGXMLAutoRSFlipFlop { private: bool clock; public: FGXMLAutoTFlipFlop( SGPropertyNode * node ) : - FGXMLAutoFlipFlop( node ), + FGXMLAutoRSFlipFlop( node ), clock(false) {} - void updateState( double dt ) { + bool getState( bool & q ) { + + if( FGXMLAutoRSFlipFlop::getState(q ) ) + return true; if( clockInput == NULL ) { if ( debug ) cout << "No (clock) input for " << get_name() << endl; - return; + return false; } // check the clock - raising edge @@ -1090,17 +1039,9 @@ public: bool raisingEdge = c && !clock; clock = c; - if( raisingEdge ) { - bool q = !get_bool_output_value(); // toggle - if( inverted ) q = !q; // doesnt really make sense for a T-FF - - if ( debug ) cout << "Updating " << get_name() << ":" - << ",q=" << q << endl; - set_output_value( q ); - } else { - if ( debug ) cout << "Updating " << get_name() << ":" - << ",q=unchanged" << endl; - } + if( !raisingEdge ) return false; // signal state unchanged; + q = !q; // toggle + return true; } }; @@ -1121,8 +1062,6 @@ bool FGXMLAutoFlipFlop::parseNodeHook(const std::string& aName, SGPropertyNode* jInput = sgReadCondition( fgGetNode("/"), aNode ); } else if (aName == "K") { kInput = sgReadCondition( fgGetNode("/"), aNode ); - } else if (aName == "T") { - tInput = sgReadCondition( fgGetNode("/"), aNode ); } else if (aName == "D") { dInput = sgReadCondition( fgGetNode("/"), aNode ); } else if (aName == "clock") { @@ -1140,11 +1079,13 @@ bool FGXMLAutoFlipFlop::parseNodeHook(const std::string& aName, SGPropertyNode* void FGXMLAutoFlipFlop::update(double dt) { + bool q = get_bool_output_value(); + if ( isPropertyEnabled() ) { if ( !enabled ) { // we have just been enabled // initialize to a bool property - set_output_value( get_bool_output_value() ); + set_output_value( q ); } enabled = true; } else { @@ -1155,7 +1096,9 @@ void FGXMLAutoFlipFlop::update(double dt) if ( !enabled || dt < SGLimitsd::min() ) return; - updateState( dt ); + if( getState( q ) ) { + set_output_value( inverted ? !q : q ); + } } @@ -1384,7 +1327,8 @@ bool FGXMLAutopilot::build( SGPropertyNode_ptr config_props ) { string val; if( typeNode != NULL ) val = typeNode->getStringValue(); val = simgear::strutils::strip(val); - if( val == "RS" || val =="SR" ) flipFlop = new FGXMLAutoRSFlipFlop( node ); + if( val == "RS" ) flipFlop = new FGXMLAutoRSFlipFlop( node ); + else if( val == "SR" ) flipFlop = new FGXMLAutoRSFlipFlop( node, false ); else if( val == "JK" ) flipFlop = new FGXMLAutoJKFlipFlop( node ); else if( val == "T" ) flipFlop = new FGXMLAutoTFlipFlop( node ); else if( val == "D" ) flipFlop = new FGXMLAutoDFlipFlop( node ); diff --git a/src/Autopilot/xmlauto.hxx b/src/Autopilot/xmlauto.hxx index c1b49d23d..4aba66fc8 100644 --- a/src/Autopilot/xmlauto.hxx +++ b/src/Autopilot/xmlauto.hxx @@ -430,17 +430,16 @@ protected: SGSharedPtr clockInput; SGSharedPtr jInput; SGSharedPtr kInput; - SGSharedPtr tInput; SGSharedPtr dInput; bool inverted; FGXMLAutoFlipFlop( SGPropertyNode * node ); bool parseNodeHook(const std::string& aName, SGPropertyNode* aNode); void update( double dt ); - virtual void updateState( double dt ) = 0; public: ~FGXMLAutoFlipFlop() {}; + virtual bool getState( bool & result ) = 0; }; /** -- 2.39.5