176 lines
5.4 KiB
C++
176 lines
5.4 KiB
C++
// Copyright (C) 2009 - 2012 Mathias Froehlich
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License as
|
|
// published by the Free Software Foundation; either version 2 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful, but
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
#ifndef HLAObjectReferenceData_hxx
|
|
#define HLAObjectReferenceData_hxx
|
|
|
|
#include <simgear/hla/HLAArrayDataElement.hxx>
|
|
#include <simgear/hla/HLADataElement.hxx>
|
|
#include <simgear/hla/HLAFederate.hxx>
|
|
|
|
#include "HLAProxyDataElement.hxx"
|
|
|
|
namespace simgear {
|
|
|
|
/// Data element that references an other object instance by its name, or object instance handle?
|
|
/// Abstract variant that is object type independent and could be registered at the federate
|
|
/// if the object is not found immediately and might arrive later.
|
|
class HLAAbstractObjectReferenceDataElement : public HLAProxyDataElement {
|
|
public:
|
|
// FIXME drop the federate once we have a decode/encode visitor?!
|
|
HLAAbstractObjectReferenceDataElement(const SGWeakPtr<HLAFederate>& federate) :
|
|
_federate(federate)
|
|
{ }
|
|
|
|
virtual bool decode(HLADecodeStream& stream)
|
|
{
|
|
if (!HLAProxyDataElement::decode(stream))
|
|
return false;
|
|
|
|
// No change?
|
|
if (!_name.getDataElement()->getDirty())
|
|
return true;
|
|
_name.getDataElement()->setDirty(false);
|
|
|
|
return recheckObject();
|
|
}
|
|
|
|
/// Returns true if the object is correctly set
|
|
bool getComplete() const
|
|
{
|
|
if (HLAObjectInstance* objectInstance = _getObjectInstance()) {
|
|
return _name.getValue() == objectInstance->getName();
|
|
} else {
|
|
return _name.getValue().empty();
|
|
}
|
|
}
|
|
|
|
bool recheckObject()
|
|
{
|
|
HLAObjectInstance* objectInstance = _getObjectInstance();
|
|
if (objectInstance && _name.getValue() == objectInstance->getName())
|
|
return true;
|
|
|
|
if (_name.getValue().empty()) {
|
|
return _setObjectInstance(0);
|
|
} else {
|
|
// Get the object by its name from the federate
|
|
SGSharedPtr<HLAFederate> federate = _federate.lock();
|
|
if (!federate.valid())
|
|
return false;
|
|
SGSharedPtr<HLAObjectInstance> objectInstance;
|
|
objectInstance = federate->getObjectInstance(_name.getValue());
|
|
return _setObjectInstance(objectInstance.get());
|
|
}
|
|
}
|
|
|
|
protected:
|
|
virtual HLAStringDataElement* _getDataElement()
|
|
{ return _name.getDataElement(); }
|
|
virtual const HLAStringDataElement* _getDataElement() const
|
|
{ return _name.getDataElement(); }
|
|
|
|
virtual HLAObjectInstance* _getObjectInstance() const = 0;
|
|
virtual bool _setObjectInstance(HLAObjectInstance*) = 0;
|
|
|
|
void _setName(const HLAObjectInstance* objectInstance)
|
|
{
|
|
if (objectInstance)
|
|
_name.setValue(objectInstance->getName());
|
|
else
|
|
_name.setValue(std::string());
|
|
_name.getDataElement()->setDirty(true);
|
|
}
|
|
|
|
private:
|
|
HLAStringData _name;
|
|
SGWeakPtr<HLAFederate> _federate;
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
class HLAObjectReferenceDataElement : public HLAAbstractObjectReferenceDataElement {
|
|
public:
|
|
// FIXME drop the federate once we have a decode/encode visitor?!
|
|
HLAObjectReferenceDataElement(const SGWeakPtr<HLAFederate>& federate) :
|
|
HLAAbstractObjectReferenceDataElement(federate)
|
|
{ }
|
|
|
|
const SGSharedPtr<T>& getObject() const
|
|
{ return _object; }
|
|
void setObject(const SGSharedPtr<T>& object)
|
|
{
|
|
if (_object == object)
|
|
return;
|
|
_setName(object.get());
|
|
_object = object;
|
|
}
|
|
|
|
protected:
|
|
virtual HLAObjectInstance* _getObjectInstance() const
|
|
{
|
|
return _object.get();
|
|
}
|
|
virtual bool _setObjectInstance(HLAObjectInstance* objectInstance)
|
|
{
|
|
if (!objectInstance) {
|
|
_object.clear();
|
|
return true;
|
|
} else {
|
|
if (!dynamic_cast<T*>(objectInstance))
|
|
return false;
|
|
_object = static_cast<T*>(objectInstance);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private:
|
|
SGSharedPtr<T> _object;
|
|
};
|
|
|
|
template<typename T>
|
|
class HLAObjectReferenceData {
|
|
public:
|
|
typedef HLAObjectReferenceDataElement<T> DataElement;
|
|
|
|
HLAObjectReferenceData(const SGWeakPtr<HLAFederate>& federate) :
|
|
_dataElement(new DataElement(federate))
|
|
{ }
|
|
|
|
const HLADataElement* getDataElement() const
|
|
{ return _dataElement.get(); }
|
|
HLADataElement* getDataElement()
|
|
{ return _dataElement.get(); }
|
|
|
|
const SGSharedPtr<T>& getObject() const
|
|
{ return _dataElement->getObject(); }
|
|
void setObject(const SGSharedPtr<T>& object)
|
|
{ _dataElement->setObject(object); }
|
|
|
|
bool getComplete() const
|
|
{ return _dataElement->getComplete(); }
|
|
/// FIXME this must happen in the federate by registering object references
|
|
/// that still want to be resolved
|
|
bool recheckObject() const
|
|
{ return _dataElement->recheckObject(); }
|
|
|
|
private:
|
|
SGSharedPtr<DataElement> _dataElement;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|