MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
track.h
1 // © Copyright 2010 - 2014 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _track_h
41 #define _track_h
42 
43 #include "exception.h"
44 #include "enumerations.h"
45 #include "interpolator.h"
46 #include "trackiterator.h"
47 
48 #ifndef SWIG // STD headers are bad for Swig
49  #include <cmath>
50  #include <iterator>
51 #endif
52 
53 namespace Mezzanine
54 {
55  /// @brief A base type that provides container features for different tracks
56  /// @details Tracks are containers of a Discrete set of points, that are presented as
57  /// a continuous range from 0 to 1. Interpolators are used to generate the data between
58  /// the points as it is needed. For example, lets say there is an interpolator provided
59  /// for integers and a track contains only two data points 0 and 100, requesting 0.5
60  /// might return 50.
61  /// @n @n
62  /// This uses std::vector underneath for its performance characteristics.
63  template <typename InterpolatorType>
64  class TrackBase
65  {
66  public:
67  /// @brief The type this class and the interpolator it uses works with.
68  typedef typename InterpolatorType::InterpolatableType InterpolatableType;
69 
70  /// @brief The type of the internal container storing the interpolatable data. This is a single point to change all the tracks.
71  /// @details If an interpolator requires a special container this can be re-implemented
72  /// to have the TrackBase use that instead. The type must implement at least:
73  /// - size()
74  /// - push_back(InterpolatableType)
75  /// - clear()
76  /// - A copy constructor
77  /// - A constructor that accepts an iterator range
78  /// - An iterator type
79  typedef typename InterpolatorType::Storage DataContainerType;
80 
81  /// @brief An iterator than can take an arbitrary amount of steps by interpolation.
83 
84  protected:
85  /// @brief The underlying container of Discrete datapoints
87 
88  public:
89  TrackBase(typename DataContainerType::iterator Begin,
90  typename DataContainerType::iterator End)
91  : DataPoints(Begin,End)
92  {}
93 
94  TrackBase(const DataContainerType& DataSet) : DataPoints(DataSet)
95  {}
96 
97  TrackBase()
98  {}
99 
100  /// @brief Get the amount of stored DataPoints
101  /// @note Name chosen to match standard containers
102  /// @return How many data points exist on this track
103  /// @note Name for compatibility with std templates
104  size_t size() const
105  { return DataPoints.size(); }
106  /// @brief Get the amount of stored DataPoints
107  /// @note Name chosen to match standard containers
108  /// @return How many data points exist on this track
109  /// @note Name for consistency with naming conventions and implemented in terms of size().
110  size_t Size() const
111  { return size(); }
112 
113  /// @brief Add another data point to the end of the track.
114  /// @param AddedValue The data point to add to theend of the track.
115  /// @note Name for compatibility with std templates.
116  virtual void push_back(const InterpolatableType& AddedValue)
117  { DataPoints.push_back(AddedValue); }
118  /// @brief Add another data point to the end of the track.
119  /// @param AddedValue The data point to add to theend of the track.
120  /// @note Name for consistency with naming conventions and implemented in terms of push_back().
121  virtual void Add(const InterpolatableType& AddedValue)
122  { push_back(AddedValue); }
123 
124  /// @brief Remove all the points from the track
125  void clear()
126  { DataPoints.clear(); }
127  /// @copydoc clear
128  void Clear()
129  { clear(); }
130 
131  /// @brief Get an Smooth iterator to the beginning of the track.
132  /// @details A Smooth iterator will take a fixed number of steps across
133  /// a data set, interpolating values not actually present.
134  /// @param Steps How many steps to take, defaults to 100.
135  virtual SmoothIteratorType begin(Integer Steps=100) const
136  {
137  return SmoothIteratorType(this, 0.0,
138  (Steps?(PreciseReal(1.0)/PreciseReal(Steps)):0.0)
139  );
140  }
141  /// @copydoc begin
142  virtual SmoothIteratorType Begin(Integer Steps=100) const
143  { return begin(Steps); }
144 
145 
146  /// @brief Get an Smooth iterator to the end (not one past) of the track.
147  /// @details A Smooth iterator will take a fixed number of steps across
148  /// a data set, interpolating values not actually present.
149  /// @param Steps How many steps to take if any, defaults to 0.
150  virtual SmoothIteratorType end(Integer Steps=0) const
151  {
152  return SmoothIteratorType(this, 1.0,
153  (Steps?(PreciseReal(1.0)/PreciseReal(Steps)):0.0)
154  );
155  }
156  /// @copydoc end
157  virtual SmoothIteratorType End(Integer Steps=0) const
158  { return end(Steps); }
159 
160  /// @brief Get a value between the beginning and the end
161  /// @details in derived classes this will perform some simple(hopefully fast) calculation to get
162  /// interpolated value between the beginning and the end fo the track. Depending on algorithm this
163  /// may or may not respect the nodes.
164  /// @param Percentage A value from 0 to 1 indicating when between the beginning and end the point should be.
165  /// @return An InterpolatableType
166  virtual InterpolatableType GetInterpolated(Real Percentage) const = 0;
167  };
168 
169  template <typename InterpolatorType>
170  class Track : public TrackBase<InterpolatorType>
171  {
172  protected:
174 
175  public:
176  /// @brief The type this class and the interpolator it uses works with.
177  typedef typename InterpolatorType::InterpolatableType InterpolatableType;
178 
179  /// @brief The type of the Container storing the interpolatable data. This is a single point to change all the tracks
180  typedef std::vector<InterpolatableType> DataContainerType;
181 
182  /// @brief An iterator than can take an arbitrary amount of steps by interpolation.
184 
185 
186  Track(typename DataContainerType::iterator Begin,
187  typename DataContainerType::iterator End)
188  : ParentType(Begin,End)
189  {}
190 
191  Track(const DataContainerType& DataSet)
192  : ParentType(DataSet)
193  {}
194 
195  Track()
196  {}
197 
198  virtual InterpolatableType GetInterpolated(Real Percentage) const
199  {
200  return InterpolatorType::Interpolate(
203  Percentage
204  );
205  }
206 
207  };
208 
209  /// @brief A track that keeps an extra data point in the track to make sure it loops.
210  /// @details when Add or push_back is called and there are 2 or more points the track,
211  /// this seamlessly adds a copy of the first data point to the end of the track. When
212  /// Iterating with a Smooth iterator this creates the impression of a loop.
213  template <typename InterpolatorType>
214  class TrackLooped : public Track<InterpolatorType>
215  {
216  protected:
217  /// @brief The immediate parent type of this class.
219  /// @brief The base most class of this type.
221 
222  public:
223  /// @brief The type this class and the interpolator it uses works with.
224  typedef typename InterpolatorType::InterpolatableType InterpolatableType;
225 
226  /// @brief The type of the Container storing the interpolatable data. This is a single point to change all the tracks
227  typedef std::vector<InterpolatableType> DataContainerType;
228 
229  /// @brief An iterator than can take an arbitrary amount of steps by interpolation.
231 
232  /// @brief
233  TrackLooped(typename DataContainerType::iterator Begin,
234  typename DataContainerType::iterator End)
235  : ParentType(Begin,End)
236  {}
237 
238  TrackLooped(const DataContainerType& DataSet)
239  : ParentType(DataSet)
240  {}
241 
242  TrackLooped()
243  {}
244 
245  virtual void push_back(const InterpolatableType& AddedValue)
246  {
247  if(BaseType::DataPoints.size()>1)
248  {
249  *(BaseType::DataPoints.end()-1) = AddedValue;
251  }else if(BaseType::DataPoints.size()==1){
252  BaseType::DataPoints.push_back(AddedValue);
254  }else{
255  BaseType::DataPoints.push_back(AddedValue);
256  }
257  }
258  };
259 
260 
261 }//Mezzanine
262 
263 #endif
264