]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/cppbind/detail/to_nasal_helper.hxx
math/nasal: Add more SGRect members and nasal helper.
[simgear.git] / simgear / nasal / cppbind / detail / to_nasal_helper.hxx
1 ///@file
2 /// Conversion helpers used by to_nasal<T>(naContext, T)
3 ///
4 // Copyright (C) 2012  Thomas Geymayer <tomgey@gmail.com>
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Library General Public
8 // License as published by the Free Software Foundation; either
9 // version 2 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Library General Public License for more details.
15 //
16 // You should have received a copy of the GNU Library General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
19
20 #ifndef SG_TO_NASAL_HELPER_HXX_
21 #define SG_TO_NASAL_HELPER_HXX_
22
23 #include "nasal_traits.hxx"
24
25 #include <simgear/math/SGMath.hxx>
26 #include <simgear/math/SGRect.hxx>
27 #include <simgear/nasal/nasal.h>
28
29 #include <boost/function/function_fwd.hpp>
30 #include <boost/utility/enable_if.hpp>
31 #include <boost/call_traits.hpp>
32 #include <boost/type_traits.hpp>
33
34 #include <map>
35 #include <string>
36 #include <vector>
37
38 class SGGeod;
39 class SGPath;
40
41 namespace nasal
42 {
43   class CallContext;
44   class Hash;
45
46   typedef boost::function<naRef (CallContext)> free_function_t;
47
48   /**
49    * Convert std::string to Nasal string
50    */
51   naRef to_nasal_helper(naContext c, const std::string& str);
52
53   /**
54    * Convert C-string to Nasal string
55    */
56   // We need this to prevent the array overload of to_nasal being called
57   naRef to_nasal_helper(naContext c, const char* str);
58
59   /**
60    * Convert a nasal::Hash to a Nasal hash
61    */
62   naRef to_nasal_helper(naContext c, const Hash& hash);
63
64   /**
65    * Simple pass-through of naRef types to allow generic usage of to_nasal
66    */
67   naRef to_nasal_helper(naContext c, const naRef& ref);
68
69   naRef to_nasal_helper(naContext c, const SGGeod& pos);
70
71   naRef to_nasal_helper(naContext c, const SGPath& path);
72
73   /**
74    * Convert function pointer to Nasal function
75    */
76   naRef to_nasal_helper(naContext c, naCFunction func);
77
78   naRef to_nasal_helper(naContext c, const free_function_t& func);
79
80   /**
81    * Convert an enum value to the according numeric value
82    */
83   template<class T>
84   typename boost::enable_if< boost::is_enum<T>, naRef >::type
85   to_nasal_helper(naContext c, T val)
86   {
87     return naNum(val);
88   }
89
90   /**
91    * Convert a numeric type to Nasal number
92    */
93   template<class T>
94   typename boost::enable_if< boost::is_arithmetic<T>, naRef >::type
95   to_nasal_helper(naContext c, T num)
96   {
97     return naNum(num);
98   }
99
100   /**
101    * Convert a 2d vector to Nasal vector with 2 elements
102    */
103   template<class Vec2>
104   typename boost::enable_if<is_vec2<Vec2>, naRef>::type
105   to_nasal_helper(naContext c, const Vec2& vec);
106
107   /**
108    * Convert a std::map to a Nasal Hash
109    */
110   template<class Value>
111   naRef to_nasal_helper(naContext c, const std::map<std::string, Value>& map);
112
113   /**
114    * Convert a fixed size array to a Nasal vector
115    */
116   template<class T, size_t N>
117   naRef to_nasal_helper(naContext c, const T(&array)[N]);
118
119   /**
120    * Convert std::vector to Nasal vector
121    */
122   template< template<class T, class Alloc> class Vector,
123             class T,
124             class Alloc
125           >
126   typename boost::enable_if< boost::is_same< Vector<T,Alloc>,
127                                              std::vector<T,Alloc>
128                                            >,
129                              naRef
130                            >::type
131   to_nasal_helper(naContext c, const Vector<T, Alloc>& vec)
132   {
133     naRef ret = naNewVector(c);
134     naVec_setsize(c, ret, static_cast<int>(vec.size()));
135     for(int i = 0; i < static_cast<int>(vec.size()); ++i)
136       naVec_set(ret, i, to_nasal_helper(c, vec[i]));
137     return ret;
138   }
139
140   //----------------------------------------------------------------------------
141   template<class Vec2>
142   typename boost::enable_if<is_vec2<Vec2>, naRef>::type
143   to_nasal_helper(naContext c, const Vec2& vec)
144   {
145     // We take just double because in Nasal every number is represented as
146     // double
147     double nasal_vec[2] = {vec[0], vec[1]};
148     return to_nasal_helper(c, nasal_vec);
149   }
150
151   //----------------------------------------------------------------------------
152   template<class T>
153   naRef to_nasal_helper(naContext c, const SGRect<T>& rect)
154   {
155     std::vector<float> vec(4);
156     vec[0] = rect.l();
157     vec[1] = rect.t();
158     vec[2] = rect.r();
159     vec[3] = rect.b();
160
161     return to_nasal_helper(c, vec);
162   }
163
164   //----------------------------------------------------------------------------
165   template<class Value>
166   naRef to_nasal_helper(naContext c, const std::map<std::string, Value>& map)
167   {
168     naRef hash = naNewHash(c);
169
170     typedef typename boost::call_traits<Value>::param_type param_type;
171     typedef typename std::map<std::string, Value>::const_iterator map_iterator;
172
173     for( map_iterator it = map.begin(); it != map.end(); ++it )
174       naHash_set
175       (
176         hash,
177         to_nasal_helper(c, it->first),
178         to_nasal_helper(c, static_cast<param_type>(it->second))
179       );
180
181     return hash;
182   }
183
184   //----------------------------------------------------------------------------
185   template<class T, size_t N>
186   naRef to_nasal_helper(naContext c, const T(&array)[N])
187   {
188     naRef ret = naNewVector(c);
189     naVec_setsize(c, ret, static_cast<int>(N));
190     for(int i = 0; i < static_cast<int>(N); ++i)
191       naVec_set(ret, i, to_nasal_helper(c, array[i]));
192     return ret;
193   }
194
195 } // namespace nasal
196
197 #endif /* SG_TO_NASAL_HELPER_HXX_ */