Skip to content

Commit

Permalink
Improvements to Untie().
Browse files Browse the repository at this point in the history
* Add an assertion to check that we are not trying to untie a tied property.
* Add an overload to specify the property as a pointer in addition to specifying a property name.
  • Loading branch information
bcoconni committed Dec 18, 2021
1 parent 58e32fd commit edee663
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 35 deletions.
17 changes: 14 additions & 3 deletions src/input_output/FGPropertyManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

#include <assert.h>
#include "FGPropertyManager.h"

/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Expand Down Expand Up @@ -301,16 +302,26 @@ void FGPropertyNode::SetWritable (const string &name, bool state )

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void FGPropertyManager::Untie (const string &name)
void FGPropertyManager::Untie(const string &name)
{
SGPropertyNode* property = root->getNode(name.c_str());
if (!property) {
cerr << "Attempt to untie a non-existant property." << name << endl;
return;
}

vector <SGPropertyNode_ptr>::iterator it;
for (it = tied_properties.begin(); it != tied_properties.end(); ++it) {
Untie(property);
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void FGPropertyManager::Untie(SGPropertyNode *property)
{
const char *name = property->getName();

assert(property->isTied());

for (auto it = tied_properties.begin(); it != tied_properties.end(); ++it) {
if (*it == property) {
property->untie();
tied_properties.erase(it);
Expand Down
12 changes: 12 additions & 0 deletions src/input_output/FGPropertyManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,21 @@ class FGPropertyManager
*
* Classes should use this function to release control of any
* properties they are managing.
*
* @param name The property name to untie (full path).
*/
void Untie (const std::string &name);

/**
* Untie a property from an external data source.
*
* Classes should use this function to release control of any
* properties they are managing.
*
* @param property A pointer to the property to untie.
*/
void Untie (SGPropertyNode* property);

/**
* Unbind all properties bound by this manager to an external data source.
*
Expand Down
6 changes: 2 additions & 4 deletions src/math/FGFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -890,10 +890,8 @@ void FGFunction::Load(Element* el, FGPropertyValue* var, FGFDMExec* fdmex,

FGFunction::~FGFunction()
{
if (pNode && pNode->isTied()) {
string pName = pNode->GetFullyQualifiedName();
PropertyManager->Untie(pName);
}
if (pNode && pNode->isTied())
PropertyManager->Untie(pNode);

Debug(1);
}
Expand Down
48 changes: 22 additions & 26 deletions src/math/FGTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,8 +393,10 @@ FGTable::~FGTable()
// Untie the bound property so that it makes no further reference to this
// instance of FGTable after the destruction is completed.
if (!Name.empty() && !internal) {
string tmp = mkPropertyName(nullptr, "");
PropertyManager->Untie(tmp);
string tmp = PropertyManager->mkPropertyName(Name, false);
FGPropertyNode* node = PropertyManager->GetNode(tmp);
if (node && node->isTied())
PropertyManager->Untie(node);
}

if (nTables > 0) {
Expand Down Expand Up @@ -651,33 +653,26 @@ void FGTable::Print(void)

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

string FGTable::mkPropertyName(Element* el, const std::string& Prefix)
{
if (!Prefix.empty()) {
if (is_number(Prefix)) {
if (Name.find("#") != string::npos) { // if "#" is found
Name = replace(Name, "#", Prefix);
} else {
cerr << el->ReadFrom()
<< "Malformed table name with number: " << Prefix
<< " and property name: " << Name
<< " but no \"#\" sign for substitution." << endl;
}
} else {
Name = Prefix + "/" + Name;
}
}

return PropertyManager->mkPropertyName(Name, false);
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void FGTable::bind(Element* el, const string& Prefix)
{
typedef double (FGTable::*PMF)(void) const;

if ( !Name.empty() && !internal) {
string tmp = mkPropertyName(el, Prefix);
if (!Prefix.empty()) {
if (is_number(Prefix)) {
if (Name.find("#") != string::npos) { // if "#" is found
Name = replace(Name, "#", Prefix);
} else {
cerr << el->ReadFrom()
<< "Malformed table name with number: " << Prefix
<< " and property name: " << Name
<< " but no \"#\" sign for substitution." << endl;
}
} else {
Name = Prefix + "/" + Name;
}
}
string tmp = PropertyManager->mkPropertyName(Name, false);

if (PropertyManager->HasNode(tmp)) {
FGPropertyNode* _property = PropertyManager->GetNode(tmp);
Expand All @@ -687,7 +682,8 @@ void FGTable::bind(Element* el, const string& Prefix)
throw("Failed to bind the property to an existing already tied node.");
}
}
PropertyManager->Tie( tmp, this, (PMF)&FGTable::GetValue);

PropertyManager->Tie(tmp, this, (PMF)&FGTable::GetValue);
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Expand Down
2 changes: 0 additions & 2 deletions src/math/FGTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,6 @@ class FGTable : public FGParameter, public FGJSBBase
double** Allocate(void);
std::string Name;
void bind(Element* el, const std::string& Prefix);

std::string mkPropertyName(Element* el, const std::string& Prefix);
void Debug(int from);
};
}
Expand Down

1 comment on commit edee663

@bcoconni
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error in the commit message, you should read: "Add an assertion to check that we are not trying to untie a property that is not tied."

Please sign in to comment.