rice 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Doxyfile +1 -1
- data/Makefile.in +3 -2
- data/README +247 -16
- data/aclocal.m4 +62 -51
- data/configure +1585 -1456
- data/extconf.rb +9 -1
- data/rice/Arg.hpp +8 -0
- data/rice/Arg_impl.hpp +124 -0
- data/rice/Arg_operators.cpp +21 -0
- data/rice/Arg_operators.hpp +19 -0
- data/rice/Constructor.hpp +150 -0
- data/rice/Data_Type.ipp +51 -6
- data/rice/Director.cpp +19 -0
- data/rice/Director.hpp +47 -0
- data/rice/Enum.hpp +2 -3
- data/rice/Enum.ipp +1 -1
- data/rice/Hash.hpp +1 -1
- data/rice/Makefile.am +7 -0
- data/rice/Makefile.in +18 -7
- data/rice/Module_impl.hpp +36 -3
- data/rice/Module_impl.ipp +56 -7
- data/rice/VM.cpp +2 -2
- data/rice/config.hpp +1 -1
- data/rice/detail/Arguments.hpp +118 -0
- data/rice/detail/Auto_Function_Wrapper.hpp +206 -96
- data/rice/detail/Auto_Function_Wrapper.ipp +1687 -144
- data/rice/detail/Auto_Member_Function_Wrapper.hpp +234 -123
- data/rice/detail/Auto_Member_Function_Wrapper.ipp +1133 -306
- data/rice/detail/Caster.hpp +3 -1
- data/rice/detail/creation_funcs.hpp +0 -8
- data/rice/detail/creation_funcs.ipp +1 -27
- data/rice/detail/define_method_and_auto_wrap.hpp +3 -1
- data/rice/detail/define_method_and_auto_wrap.ipp +4 -3
- data/rice/detail/object_call.ipp +1 -1
- data/rice/detail/ruby.hpp +1 -33
- data/rice/detail/wrap_function.hpp +103 -48
- data/rice/detail/wrap_function.ipp +154 -96
- data/rice/generate_code.rb +520 -55
- data/rice/global_function.hpp +12 -1
- data/rice/global_function.ipp +14 -2
- data/ruby/Makefile.in +5 -4
- data/ruby/lib/Makefile.in +4 -3
- data/ruby/lib/version.rb +1 -1
- data/sample/Makefile.in +4 -3
- data/test/Makefile.am +2 -0
- data/test/Makefile.in +32 -13
- data/test/test_Class.cpp +36 -14
- data/test/test_Constructor.cpp +176 -1
- data/test/test_Data_Type.cpp +121 -0
- data/test/test_Director.cpp +225 -0
- data/test/test_Enum.cpp +33 -0
- data/test/test_Module.cpp +175 -0
- data/test/test_global_functions.cpp +70 -1
- metadata +27 -7
data/extconf.rb
CHANGED
@@ -19,4 +19,12 @@ gem_name = "rice-#{Rice::VERSION}"
|
|
19
19
|
prefix_dir = File.join(Gem.default_dir, "gems", gem_name, "ruby", "lib")
|
20
20
|
with_ruby = File.join(Config::CONFIG["bindir"], Config::CONFIG["RUBY_INSTALL_NAME"])
|
21
21
|
|
22
|
-
|
22
|
+
other_opts = ""
|
23
|
+
env = ""
|
24
|
+
|
25
|
+
if RUBY_PLATFORM =~ /darwin10/
|
26
|
+
other_opts = "--disable-dependency-tracking"
|
27
|
+
env = "ARCHFLAGS='-arch x86_64'"
|
28
|
+
end
|
29
|
+
|
30
|
+
system "#{env} ./configure --with-ruby=#{with_ruby} --prefix=#{prefix_dir} #{other_opts}"
|
data/rice/Arg.hpp
ADDED
data/rice/Arg_impl.hpp
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
#ifndef Rice__Arg_Impl_hpp_
|
2
|
+
#define Rice__Arg_Impl_hpp_
|
3
|
+
|
4
|
+
namespace Rice {
|
5
|
+
|
6
|
+
//! Helper for defining default arguments of a method
|
7
|
+
/*! This class exposes the ability to define the default values of a
|
8
|
+
* wrapped method. Inspired by how Boost.Python handles keyword and
|
9
|
+
* default arguments, the syntax is simple:
|
10
|
+
*
|
11
|
+
* define_method(
|
12
|
+
* "method",
|
13
|
+
* &method,
|
14
|
+
* (Arg("arg1"), Arg("arg2") = 3, Arg("arg3") = true)
|
15
|
+
* );
|
16
|
+
*
|
17
|
+
* which means "for method &method, it takes 3 arguments
|
18
|
+
* [arg1, arg2, arg3]. Of these arguments, arg2's default is 3
|
19
|
+
* and arg3's default is true.
|
20
|
+
*
|
21
|
+
* It may be required to explicitly cast the type of the default
|
22
|
+
* value to prevent compilation errors.
|
23
|
+
*/
|
24
|
+
class Arg
|
25
|
+
{
|
26
|
+
public:
|
27
|
+
//! Initialize a new Arg with the name of the argument
|
28
|
+
/*! We require the name of the argument because 1) it makes code
|
29
|
+
* easier to read and 2) hopefully Ruby gets keyword arguments
|
30
|
+
* in the future and this means Rice will be ready for it.
|
31
|
+
*/
|
32
|
+
Arg(const char* name)
|
33
|
+
: name_(name)
|
34
|
+
, defaultValue(0)
|
35
|
+
{}
|
36
|
+
|
37
|
+
//! Copy Constructor
|
38
|
+
Arg(const Arg& other)
|
39
|
+
: name_(other.name()),
|
40
|
+
defaultValue(other.defaultValue ? other.defaultValue->clone() : 0)
|
41
|
+
{}
|
42
|
+
|
43
|
+
virtual ~Arg()
|
44
|
+
{
|
45
|
+
}
|
46
|
+
|
47
|
+
//! Set the default value for this Arg
|
48
|
+
/*! Set the default value for this argument.
|
49
|
+
* If this isn't called on this Arg, then this
|
50
|
+
* Arg is required in the method call.
|
51
|
+
*
|
52
|
+
* \param val the value to store as default
|
53
|
+
*/
|
54
|
+
template<typename Arg_Type>
|
55
|
+
Arg& operator=(Arg_Type const& val)
|
56
|
+
{
|
57
|
+
defaultValue = new type<Arg_Type>(val);
|
58
|
+
return *this;
|
59
|
+
}
|
60
|
+
|
61
|
+
//! Check if this Arg has a default value associated with it
|
62
|
+
bool hasDefaultValue() const {
|
63
|
+
return defaultValue != 0;
|
64
|
+
}
|
65
|
+
|
66
|
+
//! Return the default value associated with this Arg
|
67
|
+
/*! \return the type saved to this Arg
|
68
|
+
*/
|
69
|
+
template<typename Arg_Type>
|
70
|
+
Arg_Type getDefaultValue() const
|
71
|
+
{
|
72
|
+
return static_cast< type<Arg_Type>* >(defaultValue)->held;
|
73
|
+
}
|
74
|
+
|
75
|
+
//! Get the name of this Arg
|
76
|
+
const char* name() const
|
77
|
+
{
|
78
|
+
return name_;
|
79
|
+
}
|
80
|
+
|
81
|
+
private:
|
82
|
+
|
83
|
+
//! Name of the argument
|
84
|
+
const char* name_;
|
85
|
+
|
86
|
+
/**
|
87
|
+
* The following is a stripped down version of
|
88
|
+
* Boost.Any.
|
89
|
+
*/
|
90
|
+
|
91
|
+
class type_base
|
92
|
+
{
|
93
|
+
public:
|
94
|
+
virtual ~type_base() {}
|
95
|
+
virtual type_base* clone() const = 0;
|
96
|
+
};
|
97
|
+
|
98
|
+
template<typename Type>
|
99
|
+
class type : public type_base
|
100
|
+
{
|
101
|
+
public:
|
102
|
+
type(Type value)
|
103
|
+
:held(value)
|
104
|
+
{}
|
105
|
+
|
106
|
+
virtual ~type() { }
|
107
|
+
|
108
|
+
virtual type_base* clone() const
|
109
|
+
{
|
110
|
+
return new type(held);
|
111
|
+
}
|
112
|
+
|
113
|
+
Type held;
|
114
|
+
};
|
115
|
+
|
116
|
+
public:
|
117
|
+
|
118
|
+
//! Our saved default value
|
119
|
+
type_base* defaultValue;
|
120
|
+
};
|
121
|
+
|
122
|
+
}
|
123
|
+
|
124
|
+
#endif // Rice__Arg_Impl_hpp_
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#include "Arg_impl.hpp"
|
2
|
+
#include "detail/Arguments.hpp"
|
3
|
+
#include "Arg_operators.hpp"
|
4
|
+
|
5
|
+
namespace Rice {
|
6
|
+
|
7
|
+
Arguments* operator,(const Arg& arg1, const Arg& arg2)
|
8
|
+
{
|
9
|
+
Arguments* a = new Arguments();
|
10
|
+
a->add(arg1);
|
11
|
+
a->add(arg2);
|
12
|
+
return a;
|
13
|
+
}
|
14
|
+
|
15
|
+
Arguments* operator,(Arguments* arguments, const Arg& arg)
|
16
|
+
{
|
17
|
+
arguments->add(arg);
|
18
|
+
return arguments;
|
19
|
+
}
|
20
|
+
|
21
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#ifndef Rice__Arg_Operators_hpp_
|
2
|
+
#define Rice__Arg_Operators_hpp_
|
3
|
+
|
4
|
+
namespace Rice
|
5
|
+
{
|
6
|
+
|
7
|
+
//! Build the list of Arg objects into an Arguments object
|
8
|
+
/*! Take a list of Arg objects and build up a single Argument
|
9
|
+
* object used later in method dispatch
|
10
|
+
*/
|
11
|
+
Arguments* operator,(const Arg& arg1, const Arg& arg2);
|
12
|
+
|
13
|
+
/*! @see operator,(Arg, Arg)
|
14
|
+
*/
|
15
|
+
Arguments* operator,(Arguments* arguments, const Arg& arg);
|
16
|
+
|
17
|
+
}
|
18
|
+
|
19
|
+
#endif // Rice__Arg_Operators_hpp_
|
data/rice/Constructor.hpp
CHANGED
@@ -181,6 +181,156 @@ public:
|
|
181
181
|
}
|
182
182
|
};
|
183
183
|
|
184
|
+
template<typename T>
|
185
|
+
class Constructor<T, Object, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
|
186
|
+
{
|
187
|
+
public:
|
188
|
+
static void construct(Object self)
|
189
|
+
{
|
190
|
+
DATA_PTR(self.value()) = new T(self);
|
191
|
+
}
|
192
|
+
};
|
193
|
+
|
194
|
+
template<typename T, typename Arg1_T>
|
195
|
+
class Constructor<T, Object, Arg1_T, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
|
196
|
+
{
|
197
|
+
public:
|
198
|
+
static void construct(Object self, Arg1_T arg1)
|
199
|
+
{
|
200
|
+
DATA_PTR(self.value()) = new T(self, arg1);
|
201
|
+
}
|
202
|
+
};
|
203
|
+
|
204
|
+
template<typename T, typename Arg1_T, typename Arg2_T>
|
205
|
+
class Constructor<T, Object, Arg1_T, Arg2_T, void, void, void, void, void, void, void, void, void, void, void, void, void>
|
206
|
+
{
|
207
|
+
public:
|
208
|
+
static void construct(Object self, Arg1_T arg1, Arg2_T arg2)
|
209
|
+
{
|
210
|
+
DATA_PTR(self.value()) = new T(self, arg1, arg2);
|
211
|
+
}
|
212
|
+
};
|
213
|
+
|
214
|
+
template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T>
|
215
|
+
class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, void, void, void, void, void, void, void, void, void, void, void, void>
|
216
|
+
{
|
217
|
+
public:
|
218
|
+
static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3)
|
219
|
+
{
|
220
|
+
DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3);
|
221
|
+
}
|
222
|
+
};
|
223
|
+
|
224
|
+
template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T>
|
225
|
+
class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, void, void, void, void, void, void, void, void, void, void, void>
|
226
|
+
{
|
227
|
+
public:
|
228
|
+
static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4)
|
229
|
+
{
|
230
|
+
DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4);
|
231
|
+
}
|
232
|
+
};
|
233
|
+
|
234
|
+
template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T>
|
235
|
+
class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, void, void, void, void, void, void, void, void, void, void>
|
236
|
+
{
|
237
|
+
public:
|
238
|
+
static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5)
|
239
|
+
{
|
240
|
+
DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5);
|
241
|
+
}
|
242
|
+
};
|
243
|
+
|
244
|
+
template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T>
|
245
|
+
class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, void, void, void, void, void, void, void, void, void>
|
246
|
+
{
|
247
|
+
public:
|
248
|
+
static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6)
|
249
|
+
{
|
250
|
+
DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6);
|
251
|
+
}
|
252
|
+
};
|
253
|
+
|
254
|
+
template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T>
|
255
|
+
class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, void, void, void, void, void, void, void, void>
|
256
|
+
{
|
257
|
+
public:
|
258
|
+
static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7)
|
259
|
+
{
|
260
|
+
DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
261
|
+
}
|
262
|
+
};
|
263
|
+
|
264
|
+
template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T, typename Arg8_T>
|
265
|
+
class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, Arg8_T, void, void, void, void, void, void, void>
|
266
|
+
{
|
267
|
+
public:
|
268
|
+
static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8)
|
269
|
+
{
|
270
|
+
DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
271
|
+
}
|
272
|
+
};
|
273
|
+
|
274
|
+
template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T, typename Arg8_T, typename Arg9_T>
|
275
|
+
class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, Arg8_T, Arg9_T, void, void, void, void, void, void>
|
276
|
+
{
|
277
|
+
public:
|
278
|
+
static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8, Arg9_T arg9)
|
279
|
+
{
|
280
|
+
DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
|
281
|
+
}
|
282
|
+
};
|
283
|
+
|
284
|
+
template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T, typename Arg8_T, typename Arg9_T, typename Arg10_T>
|
285
|
+
class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, Arg8_T, Arg9_T, Arg10_T, void, void, void, void, void>
|
286
|
+
{
|
287
|
+
public:
|
288
|
+
static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8, Arg9_T arg9, Arg10_T arg10)
|
289
|
+
{
|
290
|
+
DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
|
291
|
+
}
|
292
|
+
};
|
293
|
+
|
294
|
+
template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T, typename Arg8_T, typename Arg9_T, typename Arg10_T, typename Arg11_T>
|
295
|
+
class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, Arg8_T, Arg9_T, Arg10_T, Arg11_T, void, void, void, void>
|
296
|
+
{
|
297
|
+
public:
|
298
|
+
static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8, Arg9_T arg9, Arg10_T arg10, Arg11_T arg11)
|
299
|
+
{
|
300
|
+
DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
|
301
|
+
}
|
302
|
+
};
|
303
|
+
|
304
|
+
template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T, typename Arg8_T, typename Arg9_T, typename Arg10_T, typename Arg11_T, typename Arg12_T>
|
305
|
+
class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, Arg8_T, Arg9_T, Arg10_T, Arg11_T, Arg12_T, void, void, void>
|
306
|
+
{
|
307
|
+
public:
|
308
|
+
static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8, Arg9_T arg9, Arg10_T arg10, Arg11_T arg11, Arg12_T arg12)
|
309
|
+
{
|
310
|
+
DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
|
311
|
+
}
|
312
|
+
};
|
313
|
+
|
314
|
+
template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T, typename Arg8_T, typename Arg9_T, typename Arg10_T, typename Arg11_T, typename Arg12_T, typename Arg13_T>
|
315
|
+
class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, Arg8_T, Arg9_T, Arg10_T, Arg11_T, Arg12_T, Arg13_T, void, void>
|
316
|
+
{
|
317
|
+
public:
|
318
|
+
static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8, Arg9_T arg9, Arg10_T arg10, Arg11_T arg11, Arg12_T arg12, Arg13_T arg13)
|
319
|
+
{
|
320
|
+
DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13);
|
321
|
+
}
|
322
|
+
};
|
323
|
+
|
324
|
+
template<typename T, typename Arg1_T, typename Arg2_T, typename Arg3_T, typename Arg4_T, typename Arg5_T, typename Arg6_T, typename Arg7_T, typename Arg8_T, typename Arg9_T, typename Arg10_T, typename Arg11_T, typename Arg12_T, typename Arg13_T, typename Arg14_T>
|
325
|
+
class Constructor<T, Object, Arg1_T, Arg2_T, Arg3_T, Arg4_T, Arg5_T, Arg6_T, Arg7_T, Arg8_T, Arg9_T, Arg10_T, Arg11_T, Arg12_T, Arg13_T, Arg14_T, void>
|
326
|
+
{
|
327
|
+
public:
|
328
|
+
static void construct(Object self, Arg1_T arg1, Arg2_T arg2, Arg3_T arg3, Arg4_T arg4, Arg5_T arg5, Arg6_T arg6, Arg7_T arg7, Arg8_T arg8, Arg9_T arg9, Arg10_T arg10, Arg11_T arg11, Arg12_T arg12, Arg13_T arg13, Arg14_T arg14)
|
329
|
+
{
|
330
|
+
DATA_PTR(self.value()) = new T(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14);
|
331
|
+
}
|
332
|
+
};
|
333
|
+
|
184
334
|
|
185
335
|
} // namespace Rice
|
186
336
|
|
data/rice/Data_Type.ipp
CHANGED
@@ -126,7 +126,7 @@ define_constructor(
|
|
126
126
|
check_is_bound();
|
127
127
|
|
128
128
|
// Normal constructor pattern with new/initialize
|
129
|
-
|
129
|
+
rb_define_alloc_func(
|
130
130
|
static_cast<VALUE>(*this),
|
131
131
|
detail::default_allocation_func<T>);
|
132
132
|
define_method("initialize", &Constructor_T::construct);
|
@@ -151,17 +151,62 @@ from_ruby(Object x)
|
|
151
151
|
return obj.get();
|
152
152
|
}
|
153
153
|
|
154
|
-
Data_Type_Base::Casters::const_iterator it(
|
155
|
-
|
156
|
-
|
154
|
+
Data_Type_Base::Casters::const_iterator it = Data_Type_Base::casters_.begin();
|
155
|
+
Data_Type_Base::Casters::const_iterator end = Data_Type_Base::casters_.end();
|
156
|
+
|
157
|
+
// Finding the bound type that relates to the given klass is
|
158
|
+
// a two step process. We iterate over the list of known type casters,
|
159
|
+
// looking for:
|
160
|
+
//
|
161
|
+
// 1) casters that handle this direct type
|
162
|
+
// 2) casters that handle types that are ancestors of klass
|
163
|
+
//
|
164
|
+
// Step 2 allows us to handle the case where a Rice-wrapped class
|
165
|
+
// is subclassed in Ruby but then an instance of that class is passed
|
166
|
+
// back into C++ (say, in a Listener / callback construction)
|
167
|
+
//
|
168
|
+
|
169
|
+
VALUE ancestors = rb_mod_ancestors(klass.value());
|
170
|
+
|
171
|
+
int earliest = RARRAY_LEN(ancestors) + 1;
|
172
|
+
|
173
|
+
int index;
|
174
|
+
VALUE indexFound;
|
175
|
+
Data_Type_Base::Casters::const_iterator toUse = end;
|
176
|
+
|
177
|
+
for(; it != end; it++) {
|
178
|
+
// Do we match directly?
|
179
|
+
if(klass.value() == it->first) {
|
180
|
+
toUse = it;
|
181
|
+
break;
|
182
|
+
}
|
183
|
+
|
184
|
+
// Check for ancestors. Trick is, we need to find the lowest
|
185
|
+
// ancestor that does have a Caster to make sure that we're casting
|
186
|
+
// to the closest C++ type that the Ruby class is subclassing.
|
187
|
+
// There might be multiple ancestors that are also wrapped in
|
188
|
+
// the extension, so find the earliest in the list and use that one.
|
189
|
+
indexFound = rb_funcall(ancestors, rb_intern("index"), 1, it->first);
|
190
|
+
|
191
|
+
if(indexFound != Qnil) {
|
192
|
+
index = NUM2INT(indexFound);
|
193
|
+
|
194
|
+
if(index < earliest) {
|
195
|
+
earliest = index;
|
196
|
+
toUse = it;
|
197
|
+
}
|
198
|
+
}
|
199
|
+
}
|
200
|
+
|
201
|
+
if(toUse == end)
|
157
202
|
{
|
158
|
-
std::string s = "
|
203
|
+
std::string s = "Class ";
|
159
204
|
s += klass.name().str();
|
160
205
|
s += " is not registered/bound in Rice";
|
161
206
|
throw std::runtime_error(s);
|
162
207
|
}
|
163
208
|
|
164
|
-
detail::Abstract_Caster * caster =
|
209
|
+
detail::Abstract_Caster * caster = toUse->second;
|
165
210
|
if(caster)
|
166
211
|
{
|
167
212
|
T * result = static_cast<T *>(caster->cast_to_base(v, klass_));
|
data/rice/Director.cpp
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#include "Director.hpp"
|
2
|
+
|
3
|
+
#include "detail/env.hpp"
|
4
|
+
|
5
|
+
namespace Rice {
|
6
|
+
|
7
|
+
Director::Director(Object self) {
|
8
|
+
self_ = self;
|
9
|
+
}
|
10
|
+
|
11
|
+
bool Director::callIsFromRuby(const char* methodName) const {
|
12
|
+
return (getSelf().value() == ruby_frame->self) && ( rb_id2name(ruby_frame->orig_func) != methodName );
|
13
|
+
}
|
14
|
+
|
15
|
+
void Director::raisePureVirtual() const {
|
16
|
+
rb_raise(rb_eNotImpError, "Cannot call super() into a pure-virtual C++ method");
|
17
|
+
}
|
18
|
+
|
19
|
+
}
|
data/rice/Director.hpp
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#ifndef Rice__Director__hpp_
|
2
|
+
#define Rice__Director__hpp_
|
3
|
+
|
4
|
+
#include "Object.hpp"
|
5
|
+
|
6
|
+
namespace Rice {
|
7
|
+
|
8
|
+
/**
|
9
|
+
* A Director works exactly as a SWIG %director works (thus the name).
|
10
|
+
* You use this class to help build proxy classes so that polymorphism
|
11
|
+
* works from C++ into Ruby.
|
12
|
+
*/
|
13
|
+
class Director
|
14
|
+
{
|
15
|
+
public:
|
16
|
+
//! Construct new Director. Needs the Ruby object so that the
|
17
|
+
// proxy class can call methods on that object.
|
18
|
+
Director(Object self);
|
19
|
+
|
20
|
+
virtual ~Director() { }
|
21
|
+
|
22
|
+
//! Is the current method call path coming from Ruby?
|
23
|
+
/*! This method allows one to choose the call chain according
|
24
|
+
* to the direction of the execution path. We need to do
|
25
|
+
* this to prevent infinite loops where super() calls could
|
26
|
+
* inadvertantly call methods back in Ruby
|
27
|
+
*/
|
28
|
+
bool callIsFromRuby(const char* methodName) const;
|
29
|
+
|
30
|
+
//! Raise a ruby exception when a call comes through for a pure virtual method
|
31
|
+
/*! If a Ruby script calls 'super' on a method that's otherwise a pure virtual
|
32
|
+
* method, use this method to throw an exception in this case.
|
33
|
+
*/
|
34
|
+
void raisePureVirtual() const;
|
35
|
+
|
36
|
+
//! Get the Ruby object linked to this C++ instance
|
37
|
+
Object getSelf() const { return self_; }
|
38
|
+
|
39
|
+
private:
|
40
|
+
|
41
|
+
// Save the Ruby object related to the instance of this class
|
42
|
+
Object self_;
|
43
|
+
|
44
|
+
};
|
45
|
+
}
|
46
|
+
|
47
|
+
#endif // Rice__Director__hpp_
|