]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLADataElement.hxx
Merge branch 'timoore/optimizations' into next
[simgear.git] / simgear / hla / HLADataElement.hxx
1 // Copyright (C) 2009 - 2011  Mathias Froehlich - Mathias.Froehlich@web.de
2 //
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.
7 //
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.
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
18 #ifndef HLADataElement_hxx
19 #define HLADataElement_hxx
20
21 #include <list>
22 #include <map>
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
29 class SGTimeStamp;
30
31 namespace simgear {
32
33 class HLADataElementVisitor;
34 class HLAConstDataElementVisitor;
35
36 class HLADataElement : public SGReferenced {
37 public:
38     virtual ~HLADataElement();
39
40     virtual void accept(HLADataElementVisitor& visitor) = 0;
41     virtual void accept(HLAConstDataElementVisitor& visitor) const = 0;
42
43     virtual bool encode(HLAEncodeStream& stream) const = 0;
44     virtual bool decode(HLADecodeStream& stream) = 0;
45
46     virtual const HLADataType* getDataType() const = 0;
47     virtual bool setDataType(const HLADataType* dataType) = 0;
48
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);
54
55     bool getTimeStampValid() const
56     { if (!_stamp.valid()) return false; return _stamp->getTimeStampValid(); }
57     void setTimeStampValid(bool timeStampValid);
58
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;
62
63     /// Dirty tracking of the attribute/parameter that this data element belongs to
64     bool getDirty() const
65     { if (!_stamp.valid()) return true; return _stamp->getDirty(); }
66     void setDirty(bool dirty)
67     { if (!_stamp.valid()) return; _stamp->setDirty(dirty); }
68
69     /// Stamp handling
70     void createStamp();
71     void attachStamp(HLADataElement& dataElement);
72     void clearStamp();
73
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
80
81     class PathElement {
82     public:
83         PathElement(unsigned index) : _data(new IndexData(index)) {}
84         PathElement(const std::string& name) : _data(new FieldData(name)) {}
85
86         bool isFieldValue() const
87         { return _data->toFieldData(); }
88         bool isIndexValue() const
89         { return _data->toIndexData(); }
90
91         unsigned getIndexValue() const
92         {
93             const IndexData* indexData = _data->toIndexData();
94             if (!indexData)
95                 return ~unsigned(0);
96             return indexData->_index;
97         }
98
99         std::string getFieldValue() const
100         {
101             const FieldData* fieldData = _data->toFieldData();
102             if (!fieldData)
103                 return std::string();
104             return fieldData->_name;
105         }
106
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()); }
112
113         void append(std::string& s) const
114         { _data->append(s); }
115
116     private:
117         struct FieldData;
118         struct IndexData;
119         struct Data : public SGReferenced {
120             virtual ~Data();
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;
126         };
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;
134             std::string _name;
135         };
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;
143             unsigned _index;
144         };
145
146         SGSharedPtr<Data> _data;
147     };
148     typedef std::list<PathElement> Path;
149     typedef std::pair<std::string, Path> StringPathPair;
150     typedef std::pair<unsigned, Path> IndexPathPair;
151
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; }
158
159 protected:
160     // Container for the timestamp the originating attribute was last updated for
161     class Stamp : public SGReferenced {
162     public:
163         Stamp() : _timeStampValid(false), _dirty(true)
164         { }
165
166         const SGTimeStamp& getTimeStamp() const
167         { return _timeStamp; }
168         void setTimeStamp(const SGTimeStamp& timeStamp)
169         { _timeStamp = timeStamp; }
170
171         bool getTimeStampValid() const
172         { return _timeStampValid; }
173         void setTimeStampValid(bool timeStampValid)
174         { _timeStampValid = timeStampValid; }
175
176         bool getDirty() const
177         { return _dirty; }
178         void setDirty(bool dirty)
179         { _dirty = dirty; }
180
181     private:
182         SGTimeStamp _timeStamp;
183         bool _timeStampValid;
184         bool _dirty;
185     };
186
187     /// get the stamp
188     Stamp* _getStamp() const
189     { return _stamp.get(); }
190     /// Set the stamp
191     virtual void _setStamp(Stamp* stamp);
192
193 private:
194     SGSharedPtr<Stamp> _stamp;
195 };
196
197 class HLADataElementProvider {
198 public:
199     class AbstractProvider : public SGReferenced {
200     public:
201         virtual ~AbstractProvider() { }
202         virtual HLADataElement* getDataElement(const HLADataElement::Path& path) = 0;
203         // virtual HLADataElement* getDataElement(const HLADataElement::Path& path, const HLADataType* dataType)
204         // {
205         //     SGSharedPtr<HLADataElement> dataElement = getDataElement(path);
206         //     if (!dataElement.valid())
207         //         return 0;
208         //     if (!dataElement->setDataType(dataType))
209         //         return 0;
210         //     return dataElement.release();
211         // }
212     };
213
214     HLADataElementProvider()
215     { }
216     HLADataElementProvider(HLADataElement* dataElement) :
217         _provider(new ConcreteProvider(dataElement))
218     { }
219     HLADataElementProvider(const SGSharedPtr<HLADataElement>& dataElement) :
220         _provider(new ConcreteProvider(dataElement))
221     { }
222     HLADataElementProvider(AbstractProvider* provider) :
223         _provider(provider)
224     { }
225
226     HLADataElement* getDataElement(const HLADataElement::Path& path) const
227     {
228         if (!_provider.valid())
229             return 0;
230         return _provider->getDataElement(path);
231     }
232
233 private:
234     class ConcreteProvider : public AbstractProvider {
235     public:
236         ConcreteProvider(const SGSharedPtr<HLADataElement>& dataElement) :
237             _dataElement(dataElement)
238         { }
239         virtual HLADataElement* getDataElement(const HLADataElement::Path&)
240         { return _dataElement.get(); }
241     private:
242         SGSharedPtr<HLADataElement> _dataElement;
243     };
244
245     SGSharedPtr<AbstractProvider> _provider;
246 };
247
248 typedef std::map<HLADataElement::Path, HLADataElementProvider> HLAPathElementMap;
249 typedef std::map<unsigned, HLAPathElementMap> HLAAttributePathElementMap;
250
251 }
252
253 #endif