Commit 9670c8d3 authored by Yumin Yuan's avatar Yumin Yuan
Browse files

Refactor APIs for association between Entity and Attribute.

Before this change, model manager had one and only one reference to an attribute system, so when we do entity assoication with attribute from different attribute system, such as model operators or simulation templates, we have to switch back and forth the attribute system of the model manager.
This added extra burden for application to manage the logic for switching the system, also could cause hard-to-find bugs if the application logic is not properly handled. So we removed the reference to attribute system from model manager, and changed the association api to include the attributesystem. The manager stills contains the map of entity and its associations for easy access from smtk, but now the association api eliminate the ambiguilty of which attribute system to use.
parent 1f967fd8
......@@ -464,16 +464,7 @@ smtk::attribute::ConstDefinitionPtr System::findIsUniqueBaseClass(
//----------------------------------------------------------------------------
void System::setRefModelManager(smtk::model::ManagerPtr refModelMgr)
{
smtk::model::ManagerPtr curManager = this->m_refModelMgr.lock();
if (curManager && curManager != refModelMgr)
{
curManager->setAttributeSystem(NULL, false);
}
this->m_refModelMgr = refModelMgr;
if (refModelMgr && this->m_refModelMgr.lock()->attributeSystem() != this)
{
refModelMgr->setAttributeSystem(this, false);
}
}
//----------------------------------------------------------------------------
void
......
......@@ -69,7 +69,7 @@ int main()
smtk::model::Vertex v0 = modelMgr->addVertex();
smtk::model::Vertex v1 = modelMgr->addVertex();
v0.associateAttribute(att->id());
v0.associateAttribute(att->system(), att->id());
test(
att->associatedModelEntityIds().count(v0.entity()) == 1,
"Could not associate a vertex to an attribute.");
......@@ -84,23 +84,23 @@ int main()
!v1.hasAttributes(),
"Disassociating a non-existent attribute appears to associate it.");
v1.associateAttribute(att->id());
v1.associateAttribute(att->system(), att->id());
att->removeAllAssociations();
test(
att->associatedModelEntityIds().empty(),
"Removing all attribute associations did not empty association list.");
smtk::model::Vertex v2 = modelMgr->addVertex();
v0.associateAttribute(att->id());
v1.associateAttribute(att->id());
v0.associateAttribute(att->system(), att->id());
v1.associateAttribute(att->system(), att->id());
test(
v2.associateAttribute(att->id()) == false,
v2.associateAttribute(att->system(), att->id()) == false,
"Should not have been able to associate more than 2 entities.");
att->removeAllAssociations();
smtk::model::Edge e0 = modelMgr->addEdge();
test(
e0.associateAttribute(att->id()) == false,
e0.associateAttribute(att->system(), att->id()) == false,
"Should not have been able to associate entity of wrong type.");
// ----
......@@ -110,12 +110,6 @@ int main()
test(
sys.refModelManager() == auxModelManager,
"Attribute system's modelMgr not changed.");
test(
auxModelManager->attributeSystem() == &sys,
"Second model manager's attribute system not changed.");
test(
modelMgr->attributeSystem() == NULL,
"Original model manager's attribute system not reset.");
return 0;
}
......@@ -762,7 +762,7 @@ void qtAssociationWidget::onDomainAssociationChanged()
AttributePtr attPtr = attSystem->findAttribute(attName.toStdString());
if(attPtr)
{
domainItem.associateAttribute(attPtr->id());
domainItem.associateAttribute(attSystem, attPtr->id());
emit this->attAssociationChanged();
}
else
......
......@@ -13,6 +13,7 @@
#include "smtk/model/DefaultSession.h"
#include "smtk/model/Entity.h"
#include "smtk/model/Events.h"
#include "smtk/model/Group.h"
#include "smtk/model/Manager.h"
#include "smtk/model/Model.h"
#include "smtk/model/Tessellation.h"
......@@ -661,18 +662,20 @@ bool EntityRef::hasAttributes() const
/**\brief Does the entityref have any attributes associated with it?
*/
bool EntityRef::associateAttribute(const smtk::common::UUID &attribId)
bool EntityRef::associateAttribute(smtk::attribute::System* sys,
const smtk::common::UUID &attribId)
{
ManagerPtr mgr = this->m_manager.lock();
return mgr->associateAttribute(attribId, this->m_entity);
return mgr->associateAttribute(sys, attribId, this->m_entity);
}
/**\brief Does the entityref have any attributes associated with it?
*/
bool EntityRef::disassociateAttribute(const smtk::common::UUID &attribId, bool reverse)
bool EntityRef::disassociateAttribute(smtk::attribute::System* sys,
const smtk::common::UUID &attribId, bool reverse)
{
ManagerPtr mgr = this->m_manager.lock();
return mgr->disassociateAttribute(attribId, this->m_entity, reverse);
return mgr->disassociateAttribute(sys, attribId, this->m_entity, reverse);
}
/**\brief Does the entityref have any attributes associated with it?
......@@ -1095,6 +1098,16 @@ Model EntityRef::owningModel() const
mgr->modelOwningEntity(this->m_entity));
}
/**\brief Return the Groups which contains this entity.
*
*/
Groups EntityRef::containingGroups() const
{
Groups result;
EntityRefArrangementOps::appendAllRelations(*this, SUBSET_OF, result);
return result;
}
/// A comparator provided so that entityrefs may be included in ordered sets.
bool EntityRef::operator == (const EntityRef& other) const
{
......
......@@ -65,6 +65,7 @@ class Tessellation;
// Use full names including namespace to make Shiboken less unhappy:
typedef std::set<smtk::model::EntityRef> EntityRefs;
typedef std::vector<smtk::model::EntityRef> EntityRefArray;
typedef std::vector<Group> Groups;
/**\brief A lightweight entityref pointing to a model entity's manager.
*
......@@ -174,8 +175,9 @@ public:
bool hasAttributes() const;
bool hasAttribute(const smtk::common::UUID &attribId) const;
bool associateAttribute(const smtk::common::UUID &attribId);
bool disassociateAttribute(const smtk::common::UUID &attribId, bool reverse = true);
bool associateAttribute(smtk::attribute::System* sys, const smtk::common::UUID &attribId);
bool disassociateAttribute(smtk::attribute::System* sys,
const smtk::common::UUID &attribId, bool reverse = true);
AttributeAssignments& attributes();
AttributeSet attributes() const;
......@@ -238,6 +240,7 @@ public:
template<typename T> T instances() const;
Model owningModel() const;
Groups containingGroups() const;
bool operator == (const EntityRef& other) const;
bool operator < (const EntityRef& other) const;
......
......@@ -63,7 +63,6 @@ Manager::Manager() :
m_analysisMesh(new UUIDsToTessellations),
m_attributeAssignments(new UUIDsToAttributeAssignments),
m_sessions(new UUIDsToSessions),
m_attributeSystem(NULL),
m_globalCounters(2,1) // first entry is session counter, second is model counter
{
// TODO: throw() when topology == NULL?
......@@ -86,7 +85,6 @@ Manager::Manager(
m_analysisMesh(mesh),
m_attributeAssignments(attribs),
m_sessions(new UUIDsToSessions),
m_attributeSystem(NULL),
m_globalCounters(2,1) // first entry is session counter, second is model counter
{
}
......@@ -102,7 +100,7 @@ Manager::~Manager()
// listeners that deletions are occurring.
this->unregisterSession(this->m_defaultSession, false);
}
this->setAttributeSystem(NULL, false);
this->m_attributeAssignments->clear();
}
//@}
......@@ -336,58 +334,6 @@ SessionInfoBits Manager::eraseModel(const Model& model, SessionInfoBits flags)
return true;
}
/**\brief Set the attribute manager.
*
* This is an error if the manager already has a non-null
* reference to a different model manager instance.
*
* If this manager is associated with a different attribute system,
* that attribute system is detached (its model manager reference
* set to null) and all attribute associations in the model manager
* are erased.
* This is not an error, but a warning message will be generated.
*
* On error, false is returned, an error message is generated,
* and no change is made to the attribute system.
*/
bool Manager::setAttributeSystem(smtk::attribute::System* attSys, bool reverse)
{
if (attSys)
{
smtk::model::Manager* attSysModelMgr = attSys->refModelManager().get();
if (attSysModelMgr && attSysModelMgr != this)
{
return false;
}
}
if (this->m_attributeSystem && this->m_attributeSystem != attSys)
{
// Only warn when (a) the new manager is non-NULL and (b) we
// have at least 1 attribute association.
if (!this->m_attributeAssignments->empty() && attSys)
{
smtkInfoMacro(this->m_log,
"WARNING: Changing attribute managers.\n"
" Current attribute associations cleared.\n");
this->m_attributeAssignments->clear();
}
if (reverse)
this->m_attributeSystem->setRefModelManager(ManagerPtr());
}
this->m_attributeSystem = attSys;
if (this->m_attributeSystem && reverse)
this->m_attributeSystem->setRefModelManager(shared_from_this());
return true;
}
/**\brief Return the attribute manager associated with this model manager.
*
*/
smtk::attribute::System* Manager::attributeSystem() const
{
return this->m_attributeSystem;
}
/// Entity construction
//@{
/// Return a currently-unused UUID (guaranteed not to collide if inserted immediately).
......@@ -2906,12 +2852,15 @@ bool Manager::hasAttribute(const UUID& attribId, const UUID& toEntity)
* valid (whether it was previously associated or not)
* and false otherwise.
*/
bool Manager::associateAttribute(const UUID& attribId, const UUID& toEntity)
bool Manager::associateAttribute(
smtk::attribute::System* sys,
const UUID& attribId,
const UUID& toEntity)
{
bool allowed = true;
if (this->m_attributeSystem)
if (sys)
{
attribute::AttributePtr att = this->m_attributeSystem->findAttribute(attribId);
attribute::AttributePtr att = sys->findAttribute(attribId);
if (!att || !att->associateEntity(toEntity))
allowed = false;
}
......@@ -2923,7 +2872,11 @@ bool Manager::associateAttribute(const UUID& attribId, const UUID& toEntity)
/**\brief Unassign an attribute from an entity.
*
*/
bool Manager::disassociateAttribute(const UUID& attribId, const UUID& fromEntity, bool reverse)
bool Manager::disassociateAttribute(
smtk::attribute::System* sys,
const UUID& attribId,
const UUID& fromEntity,
bool reverse)
{
bool didRemove = false;
UUIDWithAttributeAssignments ref = this->m_attributeAssignments->find(fromEntity);
......@@ -2943,18 +2896,15 @@ bool Manager::disassociateAttribute(const UUID& attribId, const UUID& fromEntit
}
#endif
// Notify the Attribute of the removal
if (reverse)
if (reverse && sys)
{
if (this->m_attributeSystem)
smtk::attribute::AttributePtr attrib =
sys->findAttribute(attribId);
// FIXME: Should we check that the manager's refManager
// is this Manager instance?
if (attrib)
{
smtk::attribute::AttributePtr attrib =
this->m_attributeSystem->findAttribute(attribId);
// FIXME: Should we check that the manager's refManager
// is this Manager instance?
if (attrib)
{
attrib->disassociateEntity(fromEntity, false);
}
attrib->disassociateEntity(fromEntity, false);
}
}
}
......
......@@ -123,8 +123,6 @@ public:
UUIDsToAttributeAssignments& attributeAssignments();
const UUIDsToAttributeAssignments& attributeAssignments() const;
smtk::attribute::System* attributeSystem() const;
BitFlags type(const smtk::common::UUID& ofEntity) const;
int dimension(const smtk::common::UUID& ofEntity) const;
std::string name(const smtk::common::UUID& ofEntity) const;
......@@ -300,8 +298,10 @@ public:
bool findOrAddEntityToGroup(const smtk::common::UUID& grp, const smtk::common::UUID& ent);
bool hasAttribute(const smtk::common::UUID& attribId, const smtk::common::UUID& toEntity);
bool associateAttribute(const smtk::common::UUID& attribId, const smtk::common::UUID& toEntity);
bool disassociateAttribute(const smtk::common::UUID& attribId, const smtk::common::UUID& fromEntity, bool reverse = true);
bool associateAttribute(smtk::attribute::System* sys,
const smtk::common::UUID& attribId, const smtk::common::UUID& toEntity);
bool disassociateAttribute(smtk::attribute::System* sys,
const smtk::common::UUID& attribId, const smtk::common::UUID& fromEntity, bool reverse = true);
Vertex insertVertex(const smtk::common::UUID& uid);
Edge insertEdge(const smtk::common::UUID& uid);
......@@ -395,7 +395,6 @@ protected:
std::string assignDefaultName(const smtk::common::UUID& uid, BitFlags entityFlags);
IntegerList& entityCounts(const smtk::common::UUID& modelId, BitFlags entityFlags);
void prepareForEntity(std::pair<smtk::common::UUID,Entity>& entry);
bool setAttributeSystem(smtk::attribute::System* sys, bool reverse = true);
// Below are all the different things that can be mapped to a UUID:
smtk::shared_ptr<UUIDsToEntities> m_topology;
......@@ -408,8 +407,6 @@ protected:
smtk::shared_ptr<UUIDsToAttributeAssignments> m_attributeAssignments;
smtk::shared_ptr<UUIDsToSessions> m_sessions;
smtk::attribute::System* m_attributeSystem; // Attribute systems may own a model
smtk::shared_ptr<Session> m_defaultSession;
smtk::common::UUIDGenerator m_uuidGenerator;
......
......@@ -19,7 +19,6 @@ class CellEntity;
class Group;
class Model;
typedef std::vector<CellEntity> CellEntities;
typedef std::vector<Group> Groups;
typedef std::vector<Model> Models;
/**\brief A entityref subclass that provides methods specific to models.
......
......@@ -401,10 +401,10 @@ int main(int argc, char* argv[])
aid1 = smtk::common::UUID::random();
aid2 = smtk::common::UUID::random();
test(!entity.hasAttributes(), "Detecting an un-associated attribute");
test( entity.associateAttribute(aid1), "Associating an attribute");
test( entity.associateAttribute(aid1), "Re-associating a repeated attribute");
test( entity.disassociateAttribute(aid1), "Disassociating an associated attribute");
test(!entity.disassociateAttribute(aid2), "Disassociating an un-associated attribute");
test( entity.associateAttribute(NULL, aid1), "Associating an attribute");
test( entity.associateAttribute(NULL, aid1), "Re-associating a repeated attribute");
test( entity.disassociateAttribute(NULL, aid1), "Disassociating an associated attribute");
test(!entity.disassociateAttribute(NULL, aid2), "Disassociating an un-associated attribute");
// Test that face entity was created with invalid (but present) face uses.
Face f(sm, uids[20]);
......
......@@ -190,11 +190,11 @@ int main(int argc, char* argv[])
smtk::common::UUID aid1, aid2;
aid1 = smtk::common::UUID::random();
aid2 = smtk::common::UUID::random();
test( sm->associateAttribute(/*attribId*/aid1, uids[0]), "Inserting a new attribute should succeed");
test( sm->associateAttribute(/*attribId*/aid2, uids[0]), "Inserting a new attribute should succeed");
test( sm->associateAttribute(/*attribId*/aid1, uids[0]), "Inserting an attribute twice should succeed");
test( sm->disassociateAttribute(/*attribId*/aid1, uids[0]), "Removing a non-existent attribute should fail");
test(!sm->disassociateAttribute(/*attribId*/aid1, uids[1]), "Removing a non-existent attribute should fail");
test( sm->associateAttribute(NULL, /*attribId*/aid1, uids[0]), "Inserting a new attribute should succeed");
test( sm->associateAttribute(NULL, /*attribId*/aid2, uids[0]), "Inserting a new attribute should succeed");
test( sm->associateAttribute(NULL, /*attribId*/aid1, uids[0]), "Inserting an attribute twice should succeed");
test( sm->disassociateAttribute(NULL, /*attribId*/aid1, uids[0]), "Removing a non-existent attribute should fail");
test(!sm->disassociateAttribute(NULL, /*attribId*/aid1, uids[1]), "Removing a non-existent attribute should fail");
// Test removal of arrangement information and entities.
// Remove a volume from its volume use and the model containing it.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment