-// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
+#ifdef HAVE_CONFIG_H
+# include <simgear_config.h>
+#endif
+
+#include <simgear/compiler.h>
+
#include "RTIObjectInstance.hxx"
#include "RTI13Ambassador.hxx"
namespace simgear {
-RTI13ObjectInstance::RTI13ObjectInstance(const RTI::ObjectHandle& handle, HLAObjectInstance* hlaObjectInstance,
- const RTI13ObjectClass* objectClass, RTI13Ambassador* ambassador, bool owned) :
- RTIObjectInstance(hlaObjectInstance),
+RTI13ObjectInstance::RTI13ObjectInstance(const RTI::ObjectHandle& handle, HLAObjectInstance* objectInstance,
+ const RTI13ObjectClass* objectClass, RTI13Ambassador* ambassador) :
+ RTIObjectInstance(objectInstance),
_handle(handle),
_objectClass(objectClass),
_ambassador(ambassador),
_attributeValuePairSet(RTI::AttributeSetFactory::create(objectClass->getNumAttributes()))
{
- updateAttributesFromClass(owned);
+ _setNumAttributes(getNumAttributes());
}
RTI13ObjectInstance::~RTI13ObjectInstance()
}
void
-RTI13ObjectInstance::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const RTIData& tag)
+RTI13ObjectInstance::reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList,
+ const RTIData& tag, HLAIndexList& indexPool)
{
- // Retrieve an empty update struct from the memory pool
- UpdateList updateList;
- getUpdateFromPool(updateList);
-
- RTI::ULong numAttribs = attributeValuePairSet.size();
- for (RTI::ULong i = 0; i < numAttribs; ++i) {
- unsigned index = getAttributeIndex(attributeValuePairSet.getHandle(i));
- // Get a RTIData from the data pool
- getDataFromPool(index, updateList.back()._indexDataPairList);
- RTI::ULong length = attributeValuePairSet.getValueLength(i);
- updateList.back()._indexDataPairList.back().second.resize(length);
- attributeValuePairSet.getValue(i, updateList.back()._indexDataPairList.back().second.data(), length);
- updateList.back()._tag = tag;
+ HLAIndexList reflectedIndices;
+ for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin();
+ i != attributeHandleDataPairList.end(); ++i) {
+ unsigned index = getAttributeIndex(i->first);
+ _attributeData[index]._data.swap(i->second);
+
+ if (indexPool.empty())
+ reflectedIndices.push_back(index);
+ else {
+ reflectedIndices.splice(reflectedIndices.end(), indexPool, indexPool.begin());
+ reflectedIndices.back() = index;
+ }
}
- RTIObjectInstance::reflectAttributeValues(updateList.front()._indexDataPairList, tag);
- // Return the update data back to the pool
- putUpdateToPool(updateList);
+ RTIObjectInstance::reflectAttributeValues(reflectedIndices, tag);
+
+ // Return the index list to the pool
+ indexPool.splice(indexPool.end(), reflectedIndices);
}
void
-RTI13ObjectInstance::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const SGTimeStamp& timeStamp, const RTIData& tag)
+RTI13ObjectInstance::reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList,
+ const SGTimeStamp& timeStamp, const RTIData& tag, HLAIndexList& indexPool)
{
- // Retrieve an empty update struct from the memory pool
- UpdateList updateList;
- getUpdateFromPool(updateList);
-
- RTI::ULong numAttribs = attributeValuePairSet.size();
- for (RTI::ULong i = 0; i < numAttribs; ++i) {
- unsigned index = getAttributeIndex(attributeValuePairSet.getHandle(i));
- // Get a RTIData from the data pool
- getDataFromPool(index, updateList.back()._indexDataPairList);
- RTI::ULong length = attributeValuePairSet.getValueLength(i);
- updateList.back()._indexDataPairList.back().second.resize(length);
- attributeValuePairSet.getValue(i, updateList.back()._indexDataPairList.back().second.data(), length);
- updateList.back()._tag = tag;
+ HLAIndexList reflectedIndices;
+ for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin();
+ i != attributeHandleDataPairList.end(); ++i) {
+ unsigned index = getAttributeIndex(i->first);
+ _attributeData[index]._data.swap(i->second);
+
+ if (indexPool.empty())
+ reflectedIndices.push_back(index);
+ else {
+ reflectedIndices.splice(reflectedIndices.end(), indexPool, indexPool.begin());
+ reflectedIndices.back() = index;
+ }
}
- scheduleUpdates(timeStamp, updateList);
+ RTIObjectInstance::reflectAttributeValues(reflectedIndices, timeStamp, tag);
+
+ // Return the index list to the pool
+ indexPool.splice(indexPool.end(), reflectedIndices);
}
void
-RTI13ObjectInstance::requestObjectAttributeValueUpdate()
+RTI13ObjectInstance::requestObjectAttributeValueUpdate(const HLAIndexList& indexList)
{
if (!_ambassador.valid()) {
SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
return;
}
+ if (indexList.empty())
+ return;
+
try {
unsigned numAttributes = getNumAttributes();
std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(numAttributes));
- for (unsigned i = 0; i < numAttributes; ++i) {
- if (!getRequestAttributeUpdate(i))
+ for (HLAIndexList::const_iterator i = indexList.begin(); i != indexList.end(); ++i) {
+ if (getAttributeOwned(*i)) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI13ObjectInstance::requestObjectAttributeValueUpdate(): "
+ "Invalid attribute index!");
continue;
- attributeHandleSet->add(getAttributeHandle(i));
+ }
+ attributeHandleSet->add(getAttributeHandle(*i));
}
if (!attributeHandleSet->size())
return;
_ambassador->requestObjectAttributeValueUpdate(_handle, *attributeHandleSet);
- for (unsigned i = 0; i < numAttributes; ++i)
- setRequestAttributeUpdate(i, false);
-
return;
} catch (RTI::ObjectNotKnown& e) {
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
}
void
-RTI13ObjectInstance::provideAttributeValueUpdate(const RTI::AttributeHandleSet& attributes)
+RTI13ObjectInstance::provideAttributeValueUpdate(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
{
// Called from the ambassador. Just marks some instance attributes dirty so that they are sent with the next update
- RTI::ULong numAttribs = attributes.size();
+ size_t numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
- unsigned index = getAttributeIndex(attributes.getHandle(i));
- setAttributeForceUpdate(index);
+ unsigned index = getAttributeIndex(attributeHandleSet[i]);
+ _attributeData[index]._dirty = true;
}
}
unsigned numAttributes = getNumAttributes();
for (unsigned i = 0; i < numAttributes; ++i) {
- if (!getAttributeEffectiveUpdateEnabled(i))
- continue;
- const HLADataElement* dataElement = getDataElement(i);
- if (!dataElement)
+ if (!_attributeData[i]._dirty)
continue;
- // FIXME cache somewhere
- RTIData data;
- HLAEncodeStream stream(data);
- dataElement->encode(stream);
+ const RTIData& data = _attributeData[i]._data;
_attributeValuePairSet->add(getAttributeHandle(i), data.data(), data.size());
}
_ambassador->updateAttributeValues(_handle, *_attributeValuePairSet, tag);
for (unsigned i = 0; i < numAttributes; ++i) {
- setAttributeUpdated(i);
+ _attributeData[i]._dirty = false;
}
} catch (RTI::ObjectNotKnown& e) {
unsigned numAttributes = getNumAttributes();
for (unsigned i = 0; i < numAttributes; ++i) {
- if (!getAttributeEffectiveUpdateEnabled(i))
+ if (!_attributeData[i]._dirty)
continue;
- const HLADataElement* dataElement = getDataElement(i);
- if (!dataElement)
- continue;
- // FIXME cache somewhere
- RTIData data;
- HLAEncodeStream stream(data);
- dataElement->encode(stream);
+ const RTIData& data = _attributeData[i]._data;
_attributeValuePairSet->add(getAttributeHandle(i), data.data(), data.size());
}
_ambassador->updateAttributeValues(_handle, *_attributeValuePairSet, timeStamp, tag);
for (unsigned i = 0; i < numAttributes; ++i) {
- setAttributeUpdated(i);
+ _attributeData[i]._dirty = false;
}
} catch (RTI::ObjectNotKnown& e) {
}
void
-RTI13ObjectInstance::attributesInScope(const RTI::AttributeHandleSet& attributeHandleSet)
+RTI13ObjectInstance::attributesInScope(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
{
- RTI::ULong numAttribs = attributeHandleSet.size();
+ size_t numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
- RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
+ RTI::AttributeHandle attributeHandle = attributeHandleSet[i];
setAttributeInScope(getAttributeIndex(attributeHandle), true);
}
}
void
-RTI13ObjectInstance::attributesOutOfScope(const RTI::AttributeHandleSet& attributeHandleSet)
+RTI13ObjectInstance::attributesOutOfScope(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
{
- RTI::ULong numAttribs = attributeHandleSet.size();
+ size_t numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
- RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
+ RTI::AttributeHandle attributeHandle = attributeHandleSet[i];
setAttributeInScope(getAttributeIndex(attributeHandle), false);
}
}
void
-RTI13ObjectInstance::turnUpdatesOnForObjectInstance(const RTI::AttributeHandleSet& attributeHandleSet)
+RTI13ObjectInstance::turnUpdatesOnForObjectInstance(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
{
- RTI::ULong numAttribs = attributeHandleSet.size();
+ size_t numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
- RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
+ RTI::AttributeHandle attributeHandle = attributeHandleSet[i];
setAttributeUpdateEnabled(getAttributeIndex(attributeHandle), true);
}
}
void
-RTI13ObjectInstance::turnUpdatesOffForObjectInstance(const RTI::AttributeHandleSet& attributeHandleSet)
+RTI13ObjectInstance::turnUpdatesOffForObjectInstance(const std::vector<RTI::AttributeHandle>& attributeHandleSet)
{
- RTI::ULong numAttribs = attributeHandleSet.size();
+ size_t numAttribs = attributeHandleSet.size();
for (RTI::ULong i = 0; i < numAttribs; ++i) {
- RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
+ RTI::AttributeHandle attributeHandle = attributeHandleSet[i];
setAttributeUpdateEnabled(getAttributeIndex(attributeHandle), false);
}
}
+bool
+RTI13ObjectInstance::isAttributeOwnedByFederate(unsigned index) const
+{
+ if (!_ambassador.valid()) {
+ SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
+ return false;
+ }
+ try {
+ RTI::AttributeHandle attributeHandle = getAttributeHandle(index);
+ return _ambassador->isAttributeOwnedByFederate(_handle, attributeHandle);
+ } catch (RTI::ObjectNotKnown& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query attribute ownership for index " << index << ": "
+ << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::AttributeNotDefined& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query attribute ownership for index " << index << ": "
+ << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::FederateNotExecutionMember& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query attribute ownership for index " << index << ": "
+ << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::ConcurrentAccessAttempted& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query attribute ownership for index " << index << ": "
+ << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::SaveInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query attribute ownership for index " << index << ": "
+ << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RestoreInProgress& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query attribute ownership for index " << index << ": "
+ << e._name << " " << e._reason);
+ return false;
+ } catch (RTI::RTIinternalError& e) {
+ SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query attribute ownership for index " << index << ": "
+ << e._name << " " << e._reason);
+ return false;
+ }
+ return false;
+ }
+
void
-RTI13ObjectInstance::requestAttributeOwnershipAssumption(const RTI::AttributeHandleSet& attributes, const RTIData& tag)
+RTI13ObjectInstance::requestAttributeOwnershipAssumption(const std::vector<RTI::AttributeHandle>& attributes, const RTIData& tag)
{
}
void
-RTI13ObjectInstance::attributeOwnershipDivestitureNotification(const RTI::AttributeHandleSet& attributes)
+RTI13ObjectInstance::attributeOwnershipDivestitureNotification(const std::vector<RTI::AttributeHandle>& attributes)
{
}
void
-RTI13ObjectInstance::attributeOwnershipAcquisitionNotification(const RTI::AttributeHandleSet& attributes)
+RTI13ObjectInstance::attributeOwnershipAcquisitionNotification(const std::vector<RTI::AttributeHandle>& attributes)
{
}
void
-RTI13ObjectInstance::attributeOwnershipUnavailable(const RTI::AttributeHandleSet& attributes)
+RTI13ObjectInstance::attributeOwnershipUnavailable(const std::vector<RTI::AttributeHandle>& attributes)
{
}
void
-RTI13ObjectInstance::requestAttributeOwnershipRelease(const RTI::AttributeHandleSet& attributes, const RTIData& tag)
+RTI13ObjectInstance::requestAttributeOwnershipRelease(const std::vector<RTI::AttributeHandle>& attributes, const RTIData& tag)
{
}
void
-RTI13ObjectInstance::confirmAttributeOwnershipAcquisitionCancellation(const RTI::AttributeHandleSet& attributes)
+RTI13ObjectInstance::confirmAttributeOwnershipAcquisitionCancellation(const std::vector<RTI::AttributeHandle>& attributes)
{
}