Save AP_Var's initial value as a default value, and add a function for restoring the default value.

Fix the AP_Var::lookup cache, which was very busted.

git-svn-id: https://arducopter.googlecode.com/svn/trunk@1448 f9c3cf11-9bcb-44bc-f272-b75c42450872
This commit is contained in:
DrZiplok 2011-01-05 09:25:07 +00:00
parent 0e868ca343
commit c0de571afd
2 changed files with 63 additions and 40 deletions

View File

@ -11,9 +11,11 @@
#include "AP_Var.h"
const AP_Float AP_GainUnity(1.0);
const AP_Float AP_GainNegativeUnity(-1.0);
const AP_Float AP_Zero(0);
// Global constants exported
//
AP_Float AP_FloatUnity(1.0);
AP_Float AP_FloatNegativeUnity(-1.0);
AP_Float AP_FloatZero(0);
// Constructor
//
@ -24,11 +26,12 @@ AP_Var::AP_Var(AP_VarAddress address,
_name(name),
_scope(scope)
{
// if the variable is interesting, link it into the list
if (_name || (_address != AP_VarNoAddress)) {
_link = _variables;
_variables = this;
}
// link the variable into the list of known variables
_link = _variables;
_variables = this;
// reset the lookup cache
_lookupHintIndex = 0;
}
// Destructor
@ -37,30 +40,36 @@ AP_Var::AP_Var(AP_VarAddress address,
//
AP_Var::~AP_Var(void)
{
AP_Var *p;
// if we are at the head of the list - for variables
// recently constructed this is usually the case
if (_variables == this) {
// remove us from the head of the list
_variables = _link;
// only do this for variables that were considered interesting
if (_name || (_address != AP_VarNoAddress)) {
// if we are at the head of the list - for variables
// recently constructed this is usually the case
if (_variables == this) {
// remove us from the head of the list
_variables = _link;
} else {
// traverse the list looking for the entry that points to us
p = _variables;
while (p) {
// is it pointing at us?
if (p->_link == this) {
// make it point at what we point at, and done
p->_link = _link;
break;
}
// try the next one
p = p->_link;
} else {
// traverse the list looking for the entry that points to us
AP_Var *p = _variables;
while (p) {
// is it pointing at us?
if (p->_link == this) {
// make it point at what we point at, and done
p->_link = _link;
break;
}
// try the next one
p = p->_link;
}
}
// reset the lookup cache
_lookupHintIndex = 0;
}
void
AP_Var::set_default(void)
{
// Default implementation of ::set_default does nothing
}
// Copy the variable name to the provided buffer.
@ -172,12 +181,12 @@ AP_Var::lookup(int index)
}
// search
while (index-- && p) // count until we hit the index or the end of the list
while (i-- && p) // count until we hit the index or the end of the list
p = p->_link;
// update the cache on hit
if (p) {
_lookupHintIndex = i;
_lookupHintIndex = index;
_lookupHint = p;
}

View File

@ -65,12 +65,18 @@ public:
/// Destructor
///
/// Note that the linked-list removal can be inefficient when named variables
/// Note that the linked-list removal can be inefficient when variables
/// are destroyed in an order other than the reverse of the order in which
/// they are created.
/// they are created. This is not a major issue for variables created
/// and destroyed automatically at block boundaries, and the creation and
/// destruction of variables by hand is generally discouraged.
///
~AP_Var(void);
/// Set the variable to its default value
///
virtual void set_default(void);
/// Copy the variable's name, prefixed by any parent class names, to a buffer.
///
/// If the variable has no name, the buffer will contain an empty string.
@ -224,12 +230,13 @@ public:
/// @param name An optional name by which the variable may be known.
/// @param varClass An optional class that the variable may be a member of.
///
AP_VarT<T>(T initialValue = 0,
AP_VarT<T>(T defaultValue = 0,
AP_VarAddress address = AP_VarNoAddress,
const prog_char *name = NULL,
AP_VarScope *scope = NULL) :
AP_Var(address, name, scope),
_value(initialValue)
_value(defaultValue),
_defaultValue(defaultValue)
{
}
@ -249,6 +256,9 @@ public:
return sizeof(T);
}
/// Restore the variable to its default value
virtual void set_default(void) { _value = _defaultValue; }
/// Value getter
///
T get(void) const { return _value; }
@ -267,11 +277,12 @@ public:
///
AP_VarT<T>& operator=(AP_VarT<T>& v) { return v; }
/// Copy assignment from
/// Copy assignment from T
AP_VarT<T>& operator=(T v) { _value = v; return *this; }
protected:
T _value;
T _defaultValue;
};
@ -297,11 +308,11 @@ class AP_Float16 : public AP_Float
public:
/// Constructor mimics AP_Float::AP_Float()
///
AP_Float16(float initialValue = 0,
AP_Float16(float defaultValue = 0,
AP_VarAddress address = AP_VarNoAddress,
const prog_char *name = NULL,
AP_VarScope *scope = NULL) :
AP_Float(initialValue, address, name, scope)
AP_Float(defaultValue, address, name, scope)
{
}
@ -332,8 +343,11 @@ public:
};
/// Some convenient constant AP_Vars.
extern const AP_Float AP_FloatUnity;
extern const AP_Float AP_FloatNegativeUnity;
extern const AP_Float AP_FloatZero;
///
/// @todo Work out why these can't be const and fix if possible.
///
extern AP_Float AP_FloatUnity;
extern AP_Float AP_FloatNegativeUnity;
extern AP_Float AP_FloatZero;
#endif // AP_Var_H