]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLADataElement.hxx
Add an initial implementation of a rti/hla dispatcher.
[simgear.git] / simgear / hla / HLADataElement.hxx
1 // Copyright (C) 2009 - 2010  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 HLADataElement : public SGReferenced {
34 public:
35     virtual ~HLADataElement();
36
37     virtual bool encode(HLAEncodeStream& stream) const = 0;
38     virtual bool decode(HLADecodeStream& stream) = 0;
39
40     virtual const HLADataType* getDataType() const = 0;
41     virtual bool setDataType(const HLADataType* dataType) = 0;
42
43     // Container for the timestamp the originating attribute was last updated for
44     // class TimeStamp : public SGReferenced {
45     // public:
46     //     const SGTimeStamp& getTimeStamp() const
47     //     { return _timeStamp; }
48     //     void setTimeStamp(const SGTimeStamp& timeStamp)
49     //     { _timeStamp = timeStamp; }
50     // private:
51     //     SGTimeStamp _timeStamp;
52     // };
53
54     // const TimeStamp* getTimeStamp() const
55     // { return _timeStamp.get(); }
56     // void setTimeStamp(const TimeStamp* timeStamp)
57     // { _timeStamp = timeStamp; }
58
59     // struct ChangeCount : public SGReferenced {
60     //     ChangeCount() : _value(0) {}
61     //     unsigned _value;
62     // };
63     // SGSharedPtr<ChangeCount> _changeCount;
64     // unsigned getChangeCount() const
65     // {
66     //     // If we don't have return allways the same
67     //     if (!_changeCount.valid())
68     //         return 0;
69     //     return _changeCount->_value;
70     // }
71
72     /// HLADataElements could be identified by path
73     /// These paths are composed of structure field names and array indices in the
74     /// order they appear while walking to the data element.
75     /// So provide here some tool functions to access these elements
76     /// Note that these functions are relatively expensive in execution time.
77     /// So only use them once at object creation time and store direct references to the values
78
79     class PathElement {
80     public:
81         PathElement(unsigned index) : _data(new IndexData(index)) {}
82         PathElement(const std::string& name) : _data(new FieldData(name)) {}
83
84         bool isFieldValue() const
85         { return _data->toFieldData(); }
86         bool isIndexValue() const
87         { return _data->toIndexData(); }
88
89         unsigned getIndexValue() const
90         {
91             const IndexData* indexData = _data->toIndexData();
92             if (!indexData)
93                 return ~unsigned(0);
94             return indexData->_index;
95         }
96
97         std::string getFieldValue() const
98         {
99             const FieldData* fieldData = _data->toFieldData();
100             if (!fieldData)
101                 return std::string();
102             return fieldData->_name;
103         }
104
105         // Want to be able to use that in std::map and std::set
106         bool operator<(const PathElement& pathElement) const
107         { return _data->less(pathElement._data.get()); }
108         bool operator==(const PathElement& pathElement) const
109         { return _data->equal(pathElement._data.get()); }
110
111         void append(std::string& s) const
112         { _data->append(s); }
113
114     private:
115         struct FieldData;
116         struct IndexData;
117         struct Data : public SGReferenced {
118             virtual ~Data();
119             virtual const FieldData* toFieldData() const;
120             virtual const IndexData* toIndexData() const;
121             virtual bool less(const Data*) const = 0;
122             virtual bool equal(const Data*) const = 0;
123             virtual void append(std::string&) const = 0;
124         };
125         struct FieldData : public Data {
126             FieldData(const std::string& name);
127             virtual ~FieldData();
128             virtual const FieldData* toFieldData() const;
129             virtual bool less(const Data* data) const;
130             virtual bool equal(const Data* data) const;
131             virtual void append(std::string& s) const;
132             std::string _name;
133         };
134         struct IndexData : public Data {
135             IndexData(unsigned index);
136             virtual ~IndexData();
137             virtual const IndexData* toIndexData() const;
138             virtual bool less(const Data* data) const;
139             virtual bool equal(const Data* data) const;
140             virtual void append(std::string& s) const;
141             unsigned _index;
142         };
143
144         SGSharedPtr<Data> _data;
145     };
146     typedef std::list<PathElement> Path;
147     typedef std::pair<std::string, Path> AttributePathPair;
148     typedef std::pair<unsigned, Path> IndexPathPair;
149
150     static std::string toString(const Path& path);
151     static std::string toString(const AttributePathPair& path)
152     { return path.first + toString(path.second); }
153     static AttributePathPair toAttributePathPair(const std::string& s);
154     static Path toPath(const std::string& s)
155     { return toAttributePathPair(s).second; }
156
157 private:
158     // SGSharedPtr<const TimeStamp> _timeStamp;
159 };
160
161 class HLADataElementProvider {
162 public:
163     class AbstractProvider : public SGReferenced {
164     public:
165         virtual ~AbstractProvider() { }
166         virtual HLADataElement* getDataElement(const HLADataElement::Path& path) = 0;
167         // virtual HLADataElement* getDataElement(const HLADataElement::Path& path, const HLADataType* dataType)
168         // {
169         //     SGSharedPtr<HLADataElement> dataElement = getDataElement(path);
170         //     if (!dataElement.valid())
171         //         return 0;
172         //     if (!dataElement->setDataType(dataType))
173         //         return 0;
174         //     return dataElement.release();
175         // }
176     };
177
178     HLADataElementProvider()
179     { }
180     HLADataElementProvider(HLADataElement* dataElement) :
181         _provider(new ConcreteProvider(dataElement))
182     { }
183     HLADataElementProvider(const SGSharedPtr<HLADataElement>& dataElement) :
184         _provider(new ConcreteProvider(dataElement))
185     { }
186     HLADataElementProvider(AbstractProvider* provider) :
187         _provider(provider)
188     { }
189
190     HLADataElement* getDataElement(const HLADataElement::Path& path) const
191     {
192         if (!_provider.valid())
193             return 0;
194         return _provider->getDataElement(path);
195     }
196
197 private:
198     class ConcreteProvider : public AbstractProvider {
199     public:
200         ConcreteProvider(const SGSharedPtr<HLADataElement>& dataElement) :
201             _dataElement(dataElement)
202         { }
203         virtual HLADataElement* getDataElement(const HLADataElement::Path&)
204         { return _dataElement.get(); }
205     private:
206         SGSharedPtr<HLADataElement> _dataElement;
207     };
208
209     SGSharedPtr<AbstractProvider> _provider;
210 };
211
212 typedef std::map<HLADataElement::Path, HLADataElementProvider> HLAPathElementMap;
213 typedef std::map<unsigned, HLAPathElementMap> HLAAttributePathElementMap;
214
215 }
216
217 #endif