1 // Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Library 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.
18 #ifndef HLADataElement_hxx
19 #define HLADataElement_hxx
23 #include <simgear/structure/SGReferenced.hxx>
24 #include <simgear/structure/SGSharedPtr.hxx>
25 #include <simgear/timing/timestamp.hxx>
26 #include "RTIData.hxx"
27 #include "HLADataType.hxx"
33 class HLADataElementVisitor;
34 class HLAConstDataElementVisitor;
36 class HLADataElement : public SGReferenced {
38 virtual ~HLADataElement();
40 virtual void accept(HLADataElementVisitor& visitor) = 0;
41 virtual void accept(HLAConstDataElementVisitor& visitor) const = 0;
43 virtual bool encode(HLAEncodeStream& stream) const = 0;
44 virtual bool decode(HLADecodeStream& stream) = 0;
46 virtual const HLADataType* getDataType() const = 0;
47 virtual bool setDataType(const HLADataType* dataType) = 0;
49 /// Returns the time stamp if this data element.
50 /// Do not access this getter if the getTimeStampValid() method returns false.
51 const SGTimeStamp& getTimeStamp() const
52 { return _stamp->getTimeStamp(); }
53 void setTimeStamp(const SGTimeStamp& timeStamp);
55 bool getTimeStampValid() const
56 { if (!_stamp.valid()) return false; return _stamp->getTimeStampValid(); }
57 void setTimeStampValid(bool timeStampValid);
59 /// Convenience function that gives the time difference in seconds to a given timestamp
60 /// This function returns 0 if the timestamp is not valid.
61 double getTimeDifference(const SGTimeStamp& timeStamp) const;
63 /// Dirty tracking of the attribute/parameter that this data element belongs to
65 { if (!_stamp.valid()) return true; return _stamp->getDirty(); }
66 void setDirty(bool dirty)
67 { if (!_stamp.valid()) return; _stamp->setDirty(dirty); }
71 void attachStamp(HLADataElement& dataElement);
74 /// HLADataElements could be identified by path
75 /// These paths are composed of structure field names and array indices in the
76 /// order they appear while walking to the data element.
77 /// So provide here some tool functions to access these elements
78 /// Note that these functions are relatively expensive in execution time.
79 /// So only use them once at object creation time and store direct references to the values
83 PathElement(unsigned index) : _data(new IndexData(index)) {}
84 PathElement(const std::string& name) : _data(new FieldData(name)) {}
86 bool isFieldValue() const
87 { return _data->toFieldData(); }
88 bool isIndexValue() const
89 { return _data->toIndexData(); }
91 unsigned getIndexValue() const
93 const IndexData* indexData = _data->toIndexData();
96 return indexData->_index;
99 std::string getFieldValue() const
101 const FieldData* fieldData = _data->toFieldData();
103 return std::string();
104 return fieldData->_name;
107 // Want to be able to use that in std::map and std::set
108 bool operator<(const PathElement& pathElement) const
109 { return _data->less(pathElement._data.get()); }
110 bool operator==(const PathElement& pathElement) const
111 { return _data->equal(pathElement._data.get()); }
113 void append(std::string& s) const
114 { _data->append(s); }
119 struct Data : public SGReferenced {
121 virtual const FieldData* toFieldData() const;
122 virtual const IndexData* toIndexData() const;
123 virtual bool less(const Data*) const = 0;
124 virtual bool equal(const Data*) const = 0;
125 virtual void append(std::string&) const = 0;
127 struct FieldData : public Data {
128 FieldData(const std::string& name);
129 virtual ~FieldData();
130 virtual const FieldData* toFieldData() const;
131 virtual bool less(const Data* data) const;
132 virtual bool equal(const Data* data) const;
133 virtual void append(std::string& s) const;
136 struct IndexData : public Data {
137 IndexData(unsigned index);
138 virtual ~IndexData();
139 virtual const IndexData* toIndexData() const;
140 virtual bool less(const Data* data) const;
141 virtual bool equal(const Data* data) const;
142 virtual void append(std::string& s) const;
146 SGSharedPtr<Data> _data;
148 typedef std::list<PathElement> Path;
149 typedef std::pair<std::string, Path> StringPathPair;
150 typedef std::pair<unsigned, Path> IndexPathPair;
152 static std::string toString(const Path& path);
153 static std::string toString(const StringPathPair& path)
154 { return path.first + toString(path.second); }
155 static StringPathPair toStringPathPair(const std::string& s);
156 static Path toPath(const std::string& s)
157 { return toStringPathPair(s).second; }
160 // Container for the timestamp the originating attribute was last updated for
161 class Stamp : public SGReferenced {
163 Stamp() : _timeStampValid(false), _dirty(true)
166 const SGTimeStamp& getTimeStamp() const
167 { return _timeStamp; }
168 void setTimeStamp(const SGTimeStamp& timeStamp)
169 { _timeStamp = timeStamp; }
171 bool getTimeStampValid() const
172 { return _timeStampValid; }
173 void setTimeStampValid(bool timeStampValid)
174 { _timeStampValid = timeStampValid; }
176 bool getDirty() const
178 void setDirty(bool dirty)
182 SGTimeStamp _timeStamp;
183 bool _timeStampValid;
188 Stamp* _getStamp() const
189 { return _stamp.get(); }
191 virtual void _setStamp(Stamp* stamp);
194 SGSharedPtr<Stamp> _stamp;
197 class HLADataElementProvider {
199 class AbstractProvider : public SGReferenced {
201 virtual ~AbstractProvider() { }
202 virtual HLADataElement* getDataElement(const HLADataElement::Path& path) = 0;
203 // virtual HLADataElement* getDataElement(const HLADataElement::Path& path, const HLADataType* dataType)
205 // SGSharedPtr<HLADataElement> dataElement = getDataElement(path);
206 // if (!dataElement.valid())
208 // if (!dataElement->setDataType(dataType))
210 // return dataElement.release();
214 HLADataElementProvider()
216 HLADataElementProvider(HLADataElement* dataElement) :
217 _provider(new ConcreteProvider(dataElement))
219 HLADataElementProvider(const SGSharedPtr<HLADataElement>& dataElement) :
220 _provider(new ConcreteProvider(dataElement))
222 HLADataElementProvider(AbstractProvider* provider) :
226 HLADataElement* getDataElement(const HLADataElement::Path& path) const
228 if (!_provider.valid())
230 return _provider->getDataElement(path);
234 class ConcreteProvider : public AbstractProvider {
236 ConcreteProvider(const SGSharedPtr<HLADataElement>& dataElement) :
237 _dataElement(dataElement)
239 virtual HLADataElement* getDataElement(const HLADataElement::Path&)
240 { return _dataElement.get(); }
242 SGSharedPtr<HLADataElement> _dataElement;
245 SGSharedPtr<AbstractProvider> _provider;
248 typedef std::map<HLADataElement::Path, HLADataElementProvider> HLAPathElementMap;
249 typedef std::map<unsigned, HLAPathElementMap> HLAAttributePathElementMap;