Commit 76a09a24 authored by Bob Obara's avatar Bob Obara

ENH: Added ability to get owningItem and attribute of an item

Also added ability to get the items that reference an attribute
parent 876b222f
......@@ -26,13 +26,14 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#include "attribute/AttributeRefItem.h"
#include "attribute/Item.h"
#include "attribute/Definition.h"
#include "attribute/Manager.h"
#include <iostream>
using namespace slctk::attribute;
//----------------------------------------------------------------------------
Attribute::Attribute(const std::string &myName,
slctk::AttributeDefinitionPtr myDefinition,
unsigned long myId):
m_name(myName), m_definition(myDefinition), m_id(myId)
m_name(myName), m_definition(myDefinition), m_id(myId), m_aboutToBeDeleted(false)
{
this->m_definition->buildAttribute(this);
}
......@@ -40,16 +41,46 @@ Attribute::Attribute(const std::string &myName,
//----------------------------------------------------------------------------
Attribute::~Attribute()
{
this->m_aboutToBeDeleted = true;
std::cout << "Deleting Attribute " << this->name() << "\n";
this->removeAllAssociations();
// Clear all references to the attribute
std::map<slctk::attribute::AttributeRefItem *, std::set<int> >::iterator it;
for (it = this->m_references.begin(); it != this->m_references.end(); it++)
{
std::set<int>::iterator sit;
for (sit = it->second.begin(); sit != it->second.end(); sit++)
{
it->first->unset(*sit);
}
}
this->removeAllItems();
this->removeAllAssociations();
}
//----------------------------------------------------------------------------
void Attribute::removeAllItems()
{
// we need to detatch all items owned bu this attribute
std::size_t i, n = this->m_items.size();
for (i = 0; i < n; i++)
{
this->m_items[i]->detachOwningAttribute();
}
this->m_items.clear();
}
//----------------------------------------------------------------------------
void Attribute::references(std::vector<slctk::AttributeItemPtr> &list) const
{
list.clear();
std::map<slctk::attribute::AttributeRefItem *, std::set<int> >::const_iterator it;
for (it = this->m_references.begin(); it != this->m_references.end(); it++)
{
if (it->second.size())
{
list.push_back(it->first->pointer());
}
}
}
//----------------------------------------------------------------------------
const std::string &Attribute::type() const
{
return this->m_definition->type();
......@@ -87,6 +118,16 @@ Manager *Attribute::manager() const
return this->m_definition->manager();
}
//----------------------------------------------------------------------------
slctk::AttributePtr Attribute::pointer() const
{
Manager *m = this->manager();
if (m)
{
return m->findAttribute(this->m_name);
}
return slctk::AttributePtr();
}
//----------------------------------------------------------------------------
void Attribute::associateEntity(slctk::ModelEntity *entity)
{
if (this->isEntityAssociated(entity))
......
......@@ -51,6 +51,7 @@ namespace slctk
{
friend class slctk::attribute::Definition;
friend class slctk::attribute::Manager;
friend class slctk::attribute::AttributeRefItem;
public:
Attribute(const std::string &myName,
slctk::AttributeDefinitionPtr myDefinition, unsigned long myId);
......@@ -68,6 +69,11 @@ namespace slctk
slctk::AttributeDefinitionPtr definition() const
{return this->m_definition;}
// Return the public pointer for this attribute.
// If the attribute's manager has been deleted this can return an
// empty pointer
slctk::AttributePtr pointer() const;
bool isMemberOf(const std::string &category) const;
bool isMemberOf(const std::vector<std::string> &categories) const;
......@@ -83,6 +89,8 @@ namespace slctk
std::size_t numberOfItems() const
{return this->m_items.size();}
void references(std::vector<slctk::AttributeItemPtr> &list) const;
std::size_t numberOfAssociatedEntities() const
{ return this->m_entities.size();}
bool isEntityAssociated(slctk::ModelEntity *entity) const
......@@ -112,6 +120,8 @@ namespace slctk
{this->m_userData.erase(key);}
void clearAllUserData()
{this->m_userData.clear();}
bool isAboutToBeDeleted() const
{return this->m_aboutToBeDeleted;}
protected:
void removeAllItems();
......@@ -120,14 +130,27 @@ namespace slctk
void setName(const std::string &newname)
{this->m_name = newname;}
void addReference(slctk::attribute::AttributeRefItem *attRefItem, int pos)
{this->m_references[attRefItem].insert(pos);}
// This removes a specific ref item
void removeReference(slctk::attribute::AttributeRefItem *attRefItem, int pos)
{this->m_references[attRefItem].erase(pos);}
// This removes all references to a specific Ref Item
void removeReference(slctk::attribute::AttributeRefItem *attRefItem)
{this->m_references.erase(attRefItem);}
std::string m_name;
std::vector<slctk::AttributeItemPtr> m_items;
unsigned long m_id;
slctk::AttributeDefinitionPtr m_definition;
std::set<slctk::ModelEntity *> m_entities;
std::map<slctk::attribute::AttributeRefItem *, std::set<int> > m_references;
bool m_appliesToBoundaryNodes;
bool m_appliesToInteriorNodes;
std::map<std::string, void *> m_userData;
// We need something to indicate that the attribute is in process of
// being deleted - this is used skip certain clean up steps that
// would need to be done otherwise
bool m_aboutToBeDeleted;
private:
};
......
......@@ -30,7 +30,17 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
using namespace slctk::attribute;
//----------------------------------------------------------------------------
AttributeRefItem::AttributeRefItem()
AttributeRefItem::AttributeRefItem(Attribute *owningAttribute,
int itemPosition):
Item(owningAttribute, itemPosition)
{
}
//----------------------------------------------------------------------------
AttributeRefItem::AttributeRefItem(Item *owningItem,
int itemPosition,
int mySubGroupPosition):
Item(owningItem, itemPosition, mySubGroupPosition)
{
}
......@@ -60,6 +70,21 @@ setDefinition(slctk::ConstAttributeItemDefinitionPtr adef)
//----------------------------------------------------------------------------
AttributeRefItem::~AttributeRefItem()
{
this->clearAllReferences();
}
//----------------------------------------------------------------------------
void AttributeRefItem::clearAllReferences()
{
std::size_t i, n = this->m_values.size();
Attribute *att;
for (i = 0; i < n; i++)
{
att = this->m_values[i].lock().get();
if (att)
{
att->removeReference(this);
}
}
}
//----------------------------------------------------------------------------
Item::Type AttributeRefItem::type() const
......@@ -85,7 +110,13 @@ bool AttributeRefItem::setValue(int element, slctk::AttributePtr att)
static_cast<const AttributeRefItemDefinition *>(this->definition().get());
if (def->isValueValid(att))
{
Attribute *attPtr = this->m_values[element].lock().get();
if (attPtr != NULL)
{
attPtr->removeReference(this, element);
}
this->m_values[element] = att;
att->addReference(this, element);
return true;
}
return false;
......@@ -123,6 +154,7 @@ AttributeRefItem::appendValue(slctk::AttributePtr val)
if (def->isValueValid(val))
{
this->m_values.push_back(val);
val->addReference(this, this->m_values.size() - 1);
return true;
}
return false;
......@@ -139,6 +171,12 @@ AttributeRefItem::removeValue(int element)
{
return false; // The number of values is fixed
}
// Tell the attribute we are no longer referencing it (if needed)
Attribute *att = this->m_values[element].lock().get();
if (att != NULL)
{
att->removeReference(this, element);
}
this->m_values.erase(this->m_values.begin()+element);
return true;
}
......@@ -160,11 +198,40 @@ AttributeRefItem::setNumberOfValues(std::size_t newSize)
{
return false; // The number of values is fixed
}
if (newSize < n)
{
std::size_t i;
Attribute *att;
for (i = newSize; i < n; i++)
{
att = this->m_values[i].lock().get();
if (att != NULL)
{
att->removeReference(this, i);
}
}
}
this->m_values.resize(newSize);
return true;
}
//----------------------------------------------------------------------------
void
AttributeRefItem::unset(int element)
{
Attribute *att = this->m_values[element].lock().get();
if (att == NULL)
{
return;
}
this->m_values[element].reset();
// See if we need to tell the attribute we are no longer referencing it
if (!att->isAboutToBeDeleted())
{
att->removeReference(this, element);
}
}
//----------------------------------------------------------------------------
void
AttributeRefItem::reset()
{
const AttributeRefItemDefinition *def
......@@ -173,6 +240,7 @@ AttributeRefItem::reset()
int i, n = def->numberOfRequiredValues();
if (!n)
{
this->clearAllReferences();
this->m_values.clear();
return;
}
......
......@@ -40,8 +40,10 @@ namespace slctk
class AttributeRefItemDefinition;
class SLCTKATTRIBUTE_EXPORT AttributeRefItem : public Item
{
friend class Attribute;
public:
AttributeRefItem();
AttributeRefItem(Attribute *owningAttribute, int itemPosition);
AttributeRefItem(Item *owningItem, int myPosition, int mySubGroupPosition);
virtual ~AttributeRefItem();
virtual Item::Type type() const;
virtual bool setDefinition(slctk::ConstAttributeItemDefinitionPtr def);
......@@ -61,11 +63,11 @@ namespace slctk
{return this->valueAsString(0, format);}
virtual std::string valueAsString(int element, const std::string &format="") const;
virtual bool isSet(int element=0) const
{return this->m_values[element].lock() != NULL;}
virtual void unset(int element=0)
{this->m_values[element].reset();}
{return this->m_values[element].lock().get() != NULL;}
virtual void unset(int element=0);
protected:
void clearAllReferences();
std::vector<WeakAttributePtr>m_values;
private:
};
......
......@@ -62,9 +62,22 @@ AttributeRefItemDefinition::isValueValid(slctk::AttributePtr att) const
return true;
}
//----------------------------------------------------------------------------
slctk::AttributeItemPtr AttributeRefItemDefinition::buildItem() const
slctk::AttributeItemPtr
AttributeRefItemDefinition::buildItem(Attribute *owningAttribute,
int itemPosition) const
{
return slctk::AttributeItemPtr(new AttributeRefItem());
return slctk::AttributeItemPtr(new AttributeRefItem(owningAttribute,
itemPosition));
}
//----------------------------------------------------------------------------
slctk::AttributeItemPtr
AttributeRefItemDefinition::buildItem(Item *owningItem,
int itemPosition,
int subGroupPosition) const
{
return slctk::AttributeItemPtr(new AttributeRefItem(owningItem,
itemPosition,
subGroupPosition));
}
//----------------------------------------------------------------------------
void AttributeRefItemDefinition::setNumberOfRequiredValues(int esize)
......
......@@ -54,7 +54,11 @@ namespace slctk
bool isValueValid(slctk::AttributePtr att) const;
virtual slctk::AttributeItemPtr buildItem() const;
virtual slctk::AttributeItemPtr buildItem(Attribute *owningAttribute,
int itemPosition) const;
virtual slctk::AttributeItemPtr buildItem(Item *owningItem,
int position,
int subGroupPosition) const;
int numberOfRequiredValues() const
{return this->m_numberOfRequiredValues;}
void setNumberOfRequiredValues(int esize);
......
......@@ -138,10 +138,11 @@ void Definition::buildAttribute(Attribute *att) const
// Next - for each item definition we have build and add the appropriate
// item to the attribute
slctk::AttributeItemPtr comp;
std::size_t i, n = this->m_itemDefs.size();
for (i = 0; i < n; i++)
std::size_t i, j, n = this->m_itemDefs.size();
j = att->numberOfItems();
for (i = 0; i < n; i++, j++)
{
comp = this->m_itemDefs[i]->buildItem();
comp = this->m_itemDefs[i]->buildItem(att, j);
comp->setDefinition(this->m_itemDefs[i]);
att->addItem(comp);
}
......
......@@ -30,7 +30,17 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
using namespace slctk::attribute;
//----------------------------------------------------------------------------
DirectoryItem::DirectoryItem()
DirectoryItem::DirectoryItem(Attribute *owningAttribute,
int itemPosition):
Item(owningAttribute, itemPosition)
{
}
//----------------------------------------------------------------------------
DirectoryItem::DirectoryItem(Item *owningItem,
int itemPosition,
int subGroupPosition):
Item(owningItem, itemPosition, subGroupPosition)
{
}
......
......@@ -41,7 +41,8 @@ namespace slctk
class SLCTKATTRIBUTE_EXPORT DirectoryItem : public Item
{
public:
DirectoryItem();
DirectoryItem(Attribute *owningAttribute, int itemPosition);
DirectoryItem(Item *owningItem, int position, int subGroupPosition);
virtual ~DirectoryItem();
virtual bool setDefinition(slctk::ConstAttributeItemDefinitionPtr vdef);
virtual Item::Type type() const;
......
......@@ -53,9 +53,22 @@ DirectoryItemDefinition::isValueValid(const std::string &val) const
return true;
}
//----------------------------------------------------------------------------
slctk::AttributeItemPtr DirectoryItemDefinition::buildItem() const
slctk::AttributeItemPtr
DirectoryItemDefinition::buildItem(Attribute *owningAttribute,
int itemPosition) const
{
return slctk::AttributeItemPtr(new DirectoryItem());
return slctk::AttributeItemPtr(new DirectoryItem(owningAttribute,
itemPosition));
}
//----------------------------------------------------------------------------
slctk::AttributeItemPtr
DirectoryItemDefinition::buildItem(Item *owningItem,
int itemPosition,
int subGroupPosition) const
{
return slctk::AttributeItemPtr(new DirectoryItem(owningItem,
itemPosition,
subGroupPosition));
}
//----------------------------------------------------------------------------
void DirectoryItemDefinition::setNumberOfRequiredValues(int esize)
......
......@@ -48,7 +48,11 @@ namespace slctk
virtual Item::Type type() const;
bool isValueValid(const std::string &val) const;
virtual slctk::AttributeItemPtr buildItem() const;
virtual slctk::AttributeItemPtr buildItem(Attribute *owningAttribute,
int itemPosition) const;
virtual slctk::AttributeItemPtr buildItem(Item *owningItem,
int position,
int subGroupPosition) const;
int numberOfRequiredValues() const
{return this->m_numberOfRequiredValues;}
void setNumberOfRequiredValues(int esize);
......
......@@ -28,7 +28,17 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
using namespace slctk::attribute;
//----------------------------------------------------------------------------
DoubleItem::DoubleItem()
DoubleItem::DoubleItem(Attribute *owningAttribute,
int itemPosition):
ValueItemTemplate<double>(owningAttribute, itemPosition)
{
}
//----------------------------------------------------------------------------
DoubleItem::DoubleItem(Item *owningItem,
int itemPosition,
int mySubGroupPosition):
ValueItemTemplate<double>(owningItem, itemPosition, mySubGroupPosition)
{
}
......
......@@ -41,7 +41,8 @@ namespace slctk
{
friend class DoubleItemDefinition;
public:
DoubleItem();
DoubleItem(Attribute *owningAttribute, int itemPosition);
DoubleItem(Item *owningItem, int myPosition, int mySubGroupPosition);
virtual ~DoubleItem();
virtual Item::Type type() const;
protected:
......
......@@ -42,7 +42,20 @@ Item::Type DoubleItemDefinition::type() const
return Item::DOUBLE;
}
//----------------------------------------------------------------------------
slctk::AttributeItemPtr DoubleItemDefinition::buildItem() const
slctk::AttributeItemPtr
DoubleItemDefinition::buildItem(Attribute *owningAttribute,
int itemPosition) const
{
return slctk::AttributeItemPtr(new DoubleItem());
return slctk::AttributeItemPtr(new DoubleItem(owningAttribute,
itemPosition));
}
//----------------------------------------------------------------------------
slctk::AttributeItemPtr
DoubleItemDefinition::buildItem(Item *owningItem,
int itemPosition,
int subGroupPosition) const
{
return slctk::AttributeItemPtr(new DoubleItem(owningItem,
itemPosition,
subGroupPosition));
}
......@@ -40,7 +40,11 @@ namespace slctk
DoubleItemDefinition(const std::string &myName);
virtual ~DoubleItemDefinition();
virtual Item::Type type() const;
virtual slctk::AttributeItemPtr buildItem() const;
virtual slctk::AttributeItemPtr buildItem(Attribute *owningAttribute,
int itemPosition) const;
virtual slctk::AttributeItemPtr buildItem(Item *owningItem,
int position,
int subGroupPosition) const;
protected:
......
......@@ -30,7 +30,17 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
using namespace slctk::attribute;
//----------------------------------------------------------------------------
FileItem::FileItem()
FileItem::FileItem(Attribute *owningAttribute,
int itemPosition):
Item(owningAttribute, itemPosition)
{
}
//----------------------------------------------------------------------------
FileItem::FileItem(Item *owningItem,
int itemPosition,
int subGroupPosition):
Item(owningItem, itemPosition, subGroupPosition)
{
}
......
......@@ -41,7 +41,8 @@ namespace slctk
class SLCTKATTRIBUTE_EXPORT FileItem : public Item
{
public:
FileItem();
FileItem(Attribute *owningAttribute, int itemPosition);
FileItem(Item *owningItem, int position, int subGroupPosition);
virtual ~FileItem();
virtual bool setDefinition(slctk::ConstAttributeItemDefinitionPtr vdef);
virtual Item::Type type() const;
......
......@@ -53,9 +53,20 @@ FileItemDefinition::isValueValid(const std::string &val) const
return true;
}
//----------------------------------------------------------------------------
slctk::AttributeItemPtr FileItemDefinition::buildItem() const
slctk::AttributeItemPtr FileItemDefinition::buildItem(Attribute *owningAttribute,
int itemPosition) const
{
return slctk::AttributeItemPtr(new FileItem());
return slctk::AttributeItemPtr(new FileItem(owningAttribute,
itemPosition));
}
//----------------------------------------------------------------------------
slctk::AttributeItemPtr FileItemDefinition::buildItem(Item *owningItem,
int itemPosition,
int subGroupPosition) const
{
return slctk::AttributeItemPtr(new FileItem(owningItem,
itemPosition,
subGroupPosition));
}
//----------------------------------------------------------------------------
void FileItemDefinition::setNumberOfRequiredValues(int esize)
......
......@@ -48,7 +48,11 @@ namespace slctk
virtual Item::Type type() const;
bool isValueValid(const std::string &val) const;
virtual slctk::AttributeItemPtr buildItem() const;
virtual slctk::AttributeItemPtr buildItem(Attribute *owningAttribute,
int itemPosition) const;
virtual slctk::AttributeItemPtr buildItem(Item *owningItem,
int position,
int subGroupPosition) const;
int numberOfRequiredValues() const
{return this->m_numberOfRequiredValues;}
void setNumberOfRequiredValues(int esize);
......
......@@ -27,13 +27,42 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
using namespace slctk::attribute;
//----------------------------------------------------------------------------
GroupItem::GroupItem()
GroupItem::GroupItem(Attribute *owningAttribute,
int itemPosition):
Item(owningAttribute, itemPosition)
{
}
//----------------------------------------------------------------------------
GroupItem::GroupItem(Item *owningItem,
int itemPosition,
int mySubGroupPosition):
Item(owningItem, itemPosition, mySubGroupPosition)
{
}
//----------------------------------------------------------------------------
GroupItem::~GroupItem()
{
// This group is going away so make sure any items that are
// being held externally no longer think they are owned by it
this->detachAllItems();
}
//----------------------------------------------------------------------------
void GroupItem::detachAllItems()
{
// Detatch all top level items contained in this group
std::size_t i, j, n, m;
n = this->m_items.size();
for (i = 0; i < n; i++)
{
std::vector<slctk::AttributeItemPtr> &items = this->m_items[i];
m = items.size();
for (j = 0; j < m; j++)
{
items[j]->detachOwningItem();
}
}
}
//----------------------------------------------------------------------------
Item::Type GroupItem::type() const
......@@ -61,7 +90,7 @@ GroupItem::setDefinition(slctk::ConstAttributeItemDefinitionPtr gdef)
this->m_items.resize(n);
for (i = 0; i < n; i++)
{
def->buildGroup(this->m_items[i]);
def->buildGroup(this, i);
}
}
return true;
......@@ -74,6 +103,7 @@ void GroupItem::reset()
std::size_t i, n = def->numberOfRequiredGroups();
if (!n)
{
this->detachAllItems();
this->m_items.clear();
}
else
......@@ -116,7 +146,7 @@ bool GroupItem::appendGroup()
}
n = this->m_items.size();
this->m_items.resize(n+1);
def->buildGroup(this->m_items[n]);
def->buildGroup(this, n);
return true;
}
//----------------------------------------------------------------------------
......@@ -130,6 +160,12 @@ bool GroupItem::removeGroup(int element)
// Can not change the number of items
return false;
}
std::vector<slctk::AttributeItemPtr> &items = this->m_items[element];
std::size_t j, m = items.size();
for(j = 0; j < m; j++)
{
items[j]->detachOwningItem();
}
this->m_items.erase(this->m_items.begin() + element);
return true;
}
......@@ -150,10 +186,27 @@ bool GroupItem::setNumberOfGroups(std::size_t newSize)
{
return false; // The number of values is fixed
}
this->m_items.resize(newSize);
for (i = n; i < newSize; i++)
if (newSize < n)
{
def->buildGroup(this->m_items[i]);
// We need to detach all of the items we no longer need
std::size_t j, m;
for (i = newSize; i < n; i++)
{
std::vector<slctk::AttributeItemPtr> &items = this->m_items[i];
m = items.size();
for (j = 0; j < m; j++)
{
items[j]->detachOwningItem();
}
}
}
else
{
this->m_items.resize(newSize);
for (i = n; i < newSize; i++)
{
def->buildGroup(this, i);
}
}
return true;
}
......
......@@ -37,8 +37,10 @@ namespace slctk
class GroupItemDefinition;
class SLCTKATTRIBUTE_EXPORT GroupItem : public Item
{
friend class GroupItemDefinition;
public:
GroupItem();
GroupItem(Attribute *owningAttribute, int itemPosition);
GroupItem(Item *owningItem, int myPosition, int mySubGroupPosition);
virtual ~GroupItem();
virtual Item::Type type() const;
virtual bool setDefinition(slctk::ConstAttributeItemDefinitionPtr def);
......@@ -64,6 +66,9 @@ namespace slctk
virtual void reset();
protected:
// This method will detach all of the items directly owned by
// this group
void detachAllItems();
std::vector<std::vector<slctk::AttributeItemPtr> >m_items;
private:
......
......@@ -44,9 +44,22 @@ Item::Type GroupItemDefinition::type() const
return Item::GROUP;
}
//----------------------------------------------------------------------------
slctk::AttributeItemPtr GroupItemDefinition::buildItem() const
slctk::AttributeItemPtr
GroupItemDefinition::buildItem(Attribute *owningAttribute,
int itemPosition) const
{
return slctk::AttributeItemPtr(new GroupItem());
return slctk::AttributeItemPtr(new GroupItem(owningAttribute,
itemPosition));
}
//----------------------------------------------------------------------------
slctk::AttributeItemPtr
GroupItemDefinition::buildItem(Item *owningItem,
int itemPosition,
int subGroupPosition) const
{
return slctk::AttributeItemPtr(new GroupItem(owningItem,
itemPosition,
subGroupPosition));
}