1 // Copyright (C) 2009 - 2012 Mathias Froehlich
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License as
5 // published by the Free Software Foundation; either version 2 of the
6 // License, or (at your option) any later version.
8 // This program is distributed in the hope that it will be useful, but
9 // WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 #ifndef HLAObjectReferenceData_hxx
18 #define HLAObjectReferenceData_hxx
20 #include <simgear/hla/HLAArrayDataElement.hxx>
21 #include <simgear/hla/HLADataElement.hxx>
22 #include <simgear/hla/HLAFederate.hxx>
24 #include "HLAProxyDataElement.hxx"
28 /// Data element that references an other object instance by its name, or object instance handle?
29 /// Abstract variant that is object type independent and could be registered at the federate
30 /// if the object is not found immediately and might arrive later.
31 class HLAAbstractObjectReferenceDataElement : public HLAProxyDataElement {
33 // FIXME drop the federate once we have a decode/encode visitor?!
34 HLAAbstractObjectReferenceDataElement(const SGWeakPtr<HLAFederate>& federate) :
38 virtual bool decode(HLADecodeStream& stream)
40 if (!HLAProxyDataElement::decode(stream))
44 if (!_name.getDataElement()->getDirty())
46 _name.getDataElement()->setDirty(false);
48 return recheckObject();
51 /// Returns true if the object is correctly set
52 bool getComplete() const
54 if (HLAObjectInstance* objectInstance = _getObjectInstance()) {
55 return _name.getValue() == objectInstance->getName();
57 return _name.getValue().empty();
63 HLAObjectInstance* objectInstance = _getObjectInstance();
64 if (objectInstance && _name.getValue() == objectInstance->getName())
67 if (_name.getValue().empty()) {
68 return _setObjectInstance(0);
70 // Get the object by its name from the federate
71 SGSharedPtr<HLAFederate> federate = _federate.lock();
72 if (!federate.valid())
74 SGSharedPtr<HLAObjectInstance> objectInstance;
75 objectInstance = federate->getObjectInstance(_name.getValue());
76 return _setObjectInstance(objectInstance.get());
81 virtual HLAStringDataElement* _getDataElement()
82 { return _name.getDataElement(); }
83 virtual const HLAStringDataElement* _getDataElement() const
84 { return _name.getDataElement(); }
86 virtual HLAObjectInstance* _getObjectInstance() const = 0;
87 virtual bool _setObjectInstance(HLAObjectInstance*) = 0;
89 void _setName(const HLAObjectInstance* objectInstance)
92 _name.setValue(objectInstance->getName());
94 _name.setValue(std::string());
95 _name.getDataElement()->setDirty(true);
100 SGWeakPtr<HLAFederate> _federate;
105 class HLAObjectReferenceDataElement : public HLAAbstractObjectReferenceDataElement {
107 // FIXME drop the federate once we have a decode/encode visitor?!
108 HLAObjectReferenceDataElement(const SGWeakPtr<HLAFederate>& federate) :
109 HLAAbstractObjectReferenceDataElement(federate)
112 const SGSharedPtr<T>& getObject() const
114 void setObject(const SGSharedPtr<T>& object)
116 if (_object == object)
118 _setName(object.get());
123 virtual HLAObjectInstance* _getObjectInstance() const
125 return _object.get();
127 virtual bool _setObjectInstance(HLAObjectInstance* objectInstance)
129 if (!objectInstance) {
133 if (!dynamic_cast<T*>(objectInstance))
135 _object = static_cast<T*>(objectInstance);
141 SGSharedPtr<T> _object;
145 class HLAObjectReferenceData {
147 typedef HLAObjectReferenceDataElement<T> DataElement;
149 HLAObjectReferenceData(const SGWeakPtr<HLAFederate>& federate) :
150 _dataElement(new DataElement(federate))
153 const HLADataElement* getDataElement() const
154 { return _dataElement.get(); }
155 HLADataElement* getDataElement()
156 { return _dataElement.get(); }
158 const SGSharedPtr<T>& getObject() const
159 { return _dataElement->getObject(); }
160 void setObject(const SGSharedPtr<T>& object)
161 { _dataElement->setObject(object); }
163 bool getComplete() const
164 { return _dataElement->getComplete(); }
165 /// FIXME this must happen in the federate by registering object references
166 /// that still want to be resolved
167 bool recheckObject() const
168 { return _dataElement->recheckObject(); }
171 SGSharedPtr<DataElement> _dataElement;