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"
28 #include "HLATypes.hxx"
34 class HLADataElementVisitor;
35 class HLAConstDataElementVisitor;
37 class HLADataElement : public SGReferenced {
39 virtual ~HLADataElement();
41 virtual void accept(HLADataElementVisitor& visitor) = 0;
42 virtual void accept(HLAConstDataElementVisitor& visitor) const = 0;
44 virtual bool encode(HLAEncodeStream& stream) const = 0;
45 virtual bool decode(HLADecodeStream& stream) = 0;
47 virtual const HLADataType* getDataType() const = 0;
48 virtual bool setDataType(const HLADataType* dataType) = 0;
50 bool setDataElement(const HLADataElementIndex& index, HLADataElement* dataElement)
51 { return setDataElement(index.begin(), index.end(), dataElement); }
52 HLADataElement* getDataElement(const HLADataElementIndex& index)
53 { return getDataElement(index.begin(), index.end()); }
54 const HLADataElement* getDataElement(const HLADataElementIndex& index) const
55 { return getDataElement(index.begin(), index.end()); }
57 virtual bool setDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end, HLADataElement* dataElement);
58 virtual HLADataElement* getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end);
59 virtual const HLADataElement* getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end) const;
61 /// Returns the time stamp if this data element.
62 /// Do not access this getter if the getTimeStampValid() method returns false.
63 const SGTimeStamp& getTimeStamp() const
64 { return _stamp->getTimeStamp(); }
65 void setTimeStamp(const SGTimeStamp& timeStamp);
67 bool getTimeStampValid() const
68 { if (!_stamp.valid()) return false; return _stamp->getTimeStampValid(); }
69 void setTimeStampValid(bool timeStampValid);
71 /// Convenience function that gives the time difference in seconds to a given timestamp
72 /// This function returns 0 if the timestamp is not valid.
73 double getTimeDifference(const SGTimeStamp& timeStamp) const;
75 /// Dirty tracking of the attribute/parameter that this data element belongs to
77 { if (!_stamp.valid()) return true; return _stamp->getDirty(); }
78 void setDirty(bool dirty)
79 { if (!_stamp.valid()) return; _stamp->setDirty(dirty); }
83 void attachStamp(HLADataElement& dataElement);
86 /// HLADataElements could be identified by path
87 /// These paths are composed of structure field names and array indices in the
88 /// order they appear while walking to the data element.
89 /// So provide here some tool functions to access these elements
90 /// Note that these functions are relatively expensive in execution time.
91 /// So only use them once at object creation time and store direct references to the values
95 PathElement(unsigned index) : _data(new IndexData(index)) {}
96 PathElement(const std::string& name) : _data(new FieldData(name)) {}
98 bool isFieldValue() const
99 { return _data->toFieldData(); }
100 bool isIndexValue() const
101 { return _data->toIndexData(); }
103 unsigned getIndexValue() const
105 const IndexData* indexData = _data->toIndexData();
108 return indexData->_index;
111 std::string getFieldValue() const
113 const FieldData* fieldData = _data->toFieldData();
115 return std::string();
116 return fieldData->_name;
119 // Want to be able to use that in std::map and std::set
120 bool operator<(const PathElement& pathElement) const
121 { return _data->less(pathElement._data.get()); }
122 bool operator==(const PathElement& pathElement) const
123 { return _data->equal(pathElement._data.get()); }
125 void append(std::string& s) const
126 { _data->append(s); }
131 struct Data : public SGReferenced {
133 virtual const FieldData* toFieldData() const;
134 virtual const IndexData* toIndexData() const;
135 virtual bool less(const Data*) const = 0;
136 virtual bool equal(const Data*) const = 0;
137 virtual void append(std::string&) const = 0;
139 struct FieldData : public Data {
140 FieldData(const std::string& name);
141 virtual ~FieldData();
142 virtual const FieldData* toFieldData() const;
143 virtual bool less(const Data* data) const;
144 virtual bool equal(const Data* data) const;
145 virtual void append(std::string& s) const;
148 struct IndexData : public Data {
149 IndexData(unsigned index);
150 virtual ~IndexData();
151 virtual const IndexData* toIndexData() const;
152 virtual bool less(const Data* data) const;
153 virtual bool equal(const Data* data) const;
154 virtual void append(std::string& s) const;
158 SGSharedPtr<Data> _data;
160 typedef std::list<PathElement> Path;
161 typedef std::pair<std::string, Path> StringPathPair;
162 typedef std::pair<unsigned, Path> IndexPathPair;
164 static std::string toString(const Path& path);
165 static std::string toString(const StringPathPair& path)
166 { return path.first + toString(path.second); }
167 static StringPathPair toStringPathPair(const std::string& s);
168 static Path toPath(const std::string& s)
169 { return toStringPathPair(s).second; }
172 // Container for the timestamp the originating attribute was last updated for
173 class Stamp : public SGReferenced {
175 Stamp() : _timeStampValid(false), _dirty(true)
178 const SGTimeStamp& getTimeStamp() const
179 { return _timeStamp; }
180 void setTimeStamp(const SGTimeStamp& timeStamp)
181 { _timeStamp = timeStamp; }
183 bool getTimeStampValid() const
184 { return _timeStampValid; }
185 void setTimeStampValid(bool timeStampValid)
186 { _timeStampValid = timeStampValid; }
188 bool getDirty() const
190 void setDirty(bool dirty)
194 SGTimeStamp _timeStamp;
195 bool _timeStampValid;
200 Stamp* _getStamp() const
201 { return _stamp.get(); }
203 virtual void _setStamp(Stamp* stamp);
206 SGSharedPtr<Stamp> _stamp;
209 class HLADataElementProvider {
211 class AbstractProvider : public SGReferenced {
213 virtual ~AbstractProvider() { }
214 virtual HLADataElement* getDataElement(const HLADataElement::Path& path) = 0;
215 // virtual HLADataElement* getDataElement(const HLADataElement::Path& path, const HLADataType* dataType)
217 // SGSharedPtr<HLADataElement> dataElement = getDataElement(path);
218 // if (!dataElement.valid())
220 // if (!dataElement->setDataType(dataType))
222 // return dataElement.release();
226 HLADataElementProvider()
228 HLADataElementProvider(HLADataElement* dataElement) :
229 _provider(new ConcreteProvider(dataElement))
231 HLADataElementProvider(const SGSharedPtr<HLADataElement>& dataElement) :
232 _provider(new ConcreteProvider(dataElement))
234 HLADataElementProvider(AbstractProvider* provider) :
238 HLADataElement* getDataElement(const HLADataElement::Path& path) const
240 if (!_provider.valid())
242 return _provider->getDataElement(path);
246 class ConcreteProvider : public AbstractProvider {
248 ConcreteProvider(const SGSharedPtr<HLADataElement>& dataElement) :
249 _dataElement(dataElement)
251 virtual HLADataElement* getDataElement(const HLADataElement::Path&)
252 { return _dataElement.get(); }
254 SGSharedPtr<HLADataElement> _dataElement;
257 SGSharedPtr<AbstractProvider> _provider;
260 typedef std::map<HLADataElement::Path, HLADataElementProvider> HLAPathElementMap;
261 typedef std::map<unsigned, HLAPathElementMap> HLAAttributePathElementMap;