]> git.mxchange.org Git - flightgear.git/blob - utils/fgviewer/HLAObjectReferenceData.hxx
fgviewer: Import hla based viewer application.
[flightgear.git] / utils / fgviewer / HLAObjectReferenceData.hxx
1 // Copyright (C) 2009 - 2012  Mathias Froehlich
2 //
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.
7 //
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.
12 //
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.
16
17 #ifndef HLAObjectReferenceData_hxx
18 #define HLAObjectReferenceData_hxx
19
20 #include <simgear/hla/HLAArrayDataElement.hxx>
21 #include <simgear/hla/HLADataElement.hxx>
22 #include <simgear/hla/HLAFederate.hxx>
23
24 #include "HLAProxyDataElement.hxx"
25
26 namespace simgear {
27
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 {
32 public:
33     // FIXME drop the federate once we have a decode/encode visitor?!
34     HLAAbstractObjectReferenceDataElement(const SGWeakPtr<HLAFederate>& federate) :
35         _federate(federate)
36     { }
37
38     virtual bool decode(HLADecodeStream& stream)
39     {
40         if (!HLAProxyDataElement::decode(stream))
41             return false;
42
43         // No change?
44         if (!_name.getDataElement()->getDirty())
45             return true;
46         _name.getDataElement()->setDirty(false);
47
48         return recheckObject();
49     }
50
51     /// Returns true if the object is correctly set
52     bool getComplete() const
53     {
54         if (HLAObjectInstance* objectInstance = _getObjectInstance()) {
55             return _name.getValue() == objectInstance->getName();
56         } else {
57             return _name.getValue().empty();
58         }
59     }
60
61     bool recheckObject()
62     {
63         HLAObjectInstance* objectInstance = _getObjectInstance();
64         if (objectInstance && _name.getValue() == objectInstance->getName())
65             return true;
66
67         if (_name.getValue().empty()) {
68             return _setObjectInstance(0);
69         } else {
70             // Get the object by its name from the federate
71             SGSharedPtr<HLAFederate> federate = _federate.lock();
72             if (!federate.valid())
73                 return false;
74             SGSharedPtr<HLAObjectInstance> objectInstance;
75             objectInstance = federate->getObjectInstance(_name.getValue());
76             return _setObjectInstance(objectInstance.get());
77         }
78     }
79
80 protected:
81     virtual HLAStringDataElement* _getDataElement()
82     { return _name.getDataElement(); }
83     virtual const HLAStringDataElement* _getDataElement() const
84     { return _name.getDataElement(); }
85
86     virtual HLAObjectInstance* _getObjectInstance() const = 0;
87     virtual bool _setObjectInstance(HLAObjectInstance*) = 0;
88
89     void _setName(const HLAObjectInstance* objectInstance)
90     {
91         if (objectInstance)
92             _name.setValue(objectInstance->getName());
93         else
94             _name.setValue(std::string());
95         _name.getDataElement()->setDirty(true);
96     }
97
98 private:
99     HLAStringData _name;
100     SGWeakPtr<HLAFederate> _federate;
101 };
102
103
104 template<typename T>
105 class HLAObjectReferenceDataElement : public HLAAbstractObjectReferenceDataElement {
106 public:
107     // FIXME drop the federate once we have a decode/encode visitor?!
108     HLAObjectReferenceDataElement(const SGWeakPtr<HLAFederate>& federate) :
109         HLAAbstractObjectReferenceDataElement(federate)
110     { }
111
112     const SGSharedPtr<T>& getObject() const
113     { return _object; }
114     void setObject(const SGSharedPtr<T>& object)
115     {
116         if (_object == object)
117             return;
118         _setName(object.get());
119         _object = object;
120     }
121
122 protected:
123     virtual HLAObjectInstance* _getObjectInstance() const
124     {
125         return _object.get();
126     }
127     virtual bool _setObjectInstance(HLAObjectInstance* objectInstance)
128     {
129         if (!objectInstance) {
130             _object.clear();
131             return true;
132         } else {
133             if (!dynamic_cast<T*>(objectInstance))
134                 return false;
135             _object = static_cast<T*>(objectInstance);
136             return true;
137         }
138     }
139
140 private:
141     SGSharedPtr<T> _object;
142 };
143
144 template<typename T>
145 class HLAObjectReferenceData {
146 public:
147     typedef HLAObjectReferenceDataElement<T> DataElement;
148
149     HLAObjectReferenceData(const SGWeakPtr<HLAFederate>& federate) :
150         _dataElement(new DataElement(federate))
151     { }
152
153     const HLADataElement* getDataElement() const
154     { return _dataElement.get(); }
155     HLADataElement* getDataElement()
156     { return _dataElement.get(); }
157
158     const SGSharedPtr<T>& getObject() const
159     { return _dataElement->getObject(); }
160     void setObject(const SGSharedPtr<T>& object)
161     { _dataElement->setObject(object); }
162
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(); }
169
170 private:
171     SGSharedPtr<DataElement> _dataElement;
172 };
173
174 }
175
176 #endif