rbplusplus 0.9.1 → 1.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.
Files changed (53) hide show
  1. data/Rakefile +4 -9
  2. data/lib/rbplusplus/builders/allocation_strategy.rb +0 -7
  3. data/lib/rbplusplus/builders/base.rb +11 -5
  4. data/lib/rbplusplus/builders/class.rb +5 -14
  5. data/lib/rbplusplus/builders/const.rb +1 -1
  6. data/lib/rbplusplus/builders/constructor.rb +1 -1
  7. data/lib/rbplusplus/builders/director.rb +13 -13
  8. data/lib/rbplusplus/builders/enumeration.rb +2 -2
  9. data/lib/rbplusplus/builders/helpers/class.rb +17 -2
  10. data/lib/rbplusplus/builders/helpers/implicit_caster.rb +0 -0
  11. data/lib/rbplusplus/builders/implicit_caster.rb +24 -0
  12. data/lib/rbplusplus/builders/instance_variable.rb +4 -4
  13. data/lib/rbplusplus/builders/method_base.rb +8 -7
  14. data/lib/rbplusplus/builders/module.rb +1 -1
  15. data/lib/rbplusplus/logger.rb +13 -4
  16. data/lib/rbplusplus/transformers/class.rb +43 -34
  17. data/lib/rbplusplus/transformers/constructor.rb +30 -0
  18. data/lib/rbplusplus/transformers/function.rb +3 -3
  19. data/lib/rbplusplus/transformers/method.rb +2 -2
  20. data/lib/rbplusplus/transformers/node.rb +10 -17
  21. data/lib/rbplusplus/writers/multiple_files_writer.rb +8 -6
  22. data/lib/rbplusplus.rb +2 -1
  23. data/test/allocation_strategies_test.rb +21 -14
  24. data/test/class_methods_encapsulate_test.rb +25 -25
  25. data/test/class_methods_test.rb +7 -12
  26. data/test/classes_test.rb +36 -40
  27. data/test/compiling_test.rb +23 -19
  28. data/test/constructors_test.rb +5 -5
  29. data/test/custom_code_test.rb +25 -32
  30. data/test/default_arguments_test.rb +38 -42
  31. data/test/director_test.rb +51 -53
  32. data/test/enumerations_test.rb +37 -41
  33. data/test/extension_test.rb +10 -10
  34. data/test/file_writers_test.rb +17 -21
  35. data/test/function_pointer_test.rb +9 -13
  36. data/test/function_pointers_classes_test.rb +7 -11
  37. data/test/functions_test.rb +4 -10
  38. data/test/generated/extconf.rb +2 -2
  39. data/test/headers/alloc_strats.h +3 -1
  40. data/test/headers/implicit_cast.h +107 -0
  41. data/test/headers/to_from_ruby.h +13 -6
  42. data/test/headers/to_from_ruby_source.cpp +2 -2
  43. data/test/implicit_cast_test.rb +67 -0
  44. data/test/modules_test.rb +39 -40
  45. data/test/nested_test.rb +14 -16
  46. data/test/overloading_test.rb +17 -20
  47. data/test/struct_test.rb +4 -6
  48. data/test/subclass_test.rb +10 -12
  49. data/test/test_helper.rb +21 -12
  50. data/test/to_from_ruby_test.rb +7 -1
  51. data/test/wrap_as_test.rb +32 -29
  52. metadata +170 -108
  53. data/lib/rbplusplus/transformers/node_cache.rb +0 -15
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require 'rake/rdoctask'
3
3
  require 'rake/contrib/sshpublisher'
4
4
 
5
5
  PROJECT_NAME = "rb++"
6
- RBPLUSPLUS_VERSION = "0.9.1"
6
+ RBPLUSPLUS_VERSION = "1.0"
7
7
 
8
8
  task :default => :test
9
9
 
@@ -70,14 +70,11 @@ spec = Gem::Specification.new do |s|
70
70
 
71
71
  s.description = <<-END
72
72
  Rb++ combines the powerful query interface of rbgccxml and the Rice library to
73
- make Ruby wrapping extensions easier to write than ever.
73
+ make Ruby wrapping extensions of C++ libraries easier to write than ever.
74
74
  END
75
75
 
76
- s.add_dependency "rbgccxml", "~> 0.9"
77
- s.add_dependency "rice", "~> 1.3.0"
78
-
79
- s.add_development_dependency "test-unit", "1.2.3"
80
- s.add_development_dependency "mocha", "~> 0.9"
76
+ s.add_dependency "rbgccxml", "~> 1.0"
77
+ s.add_dependency "rice", "~> 1.4.0"
81
78
 
82
79
  patterns = [
83
80
  'TODO',
@@ -93,6 +90,4 @@ make Ruby wrapping extensions easier to write than ever.
93
90
  end
94
91
 
95
92
  Rake::GemPackageTask.new(spec) do |pkg|
96
- pkg.need_zip = true
97
- pkg.need_tar = true
98
93
  end
@@ -27,7 +27,6 @@ module RbPlusPlus
27
27
  namespace Rice {
28
28
  template<>
29
29
  struct Default_Allocation_Strategy< #{node_name} > {
30
- static #{node_name} * allocate();
31
30
  static void free(#{node_name} * obj);
32
31
  };
33
32
  }
@@ -37,12 +36,6 @@ namespace Rice {
37
36
 
38
37
  pre = "Rice::Default_Allocation_Strategy< #{node_name} >::"
39
38
 
40
- tmp = "#{node_name} * #{pre}allocate() { return "
41
- tmp += @public_constructor ? "new #{node_name};" : "NULL;"
42
- tmp += " }"
43
-
44
- registrations << tmp
45
-
46
39
  tmp = "void #{pre}free(#{node_name} * obj) { "
47
40
  tmp += @public_destructor ? "delete obj;" : ""
48
41
  tmp += " }"
@@ -64,8 +64,7 @@ module RbPlusPlus
64
64
  raise "Nodes must implement #build"
65
65
  end
66
66
 
67
- # After #build has run, this then triggers the actual generation of the C++
68
- # code and returns the final string.
67
+ # After #build has run, this then triggers the actual generation of the C++ code
69
68
  # All nodes must implement this.
70
69
  def write
71
70
  raise "Nodes must implement #write"
@@ -84,7 +83,13 @@ module RbPlusPlus
84
83
  # up sorted farther down the list
85
84
  @nodes =
86
85
  @nodes.sort_by do |a|
87
- a.is_a?(ClassNode) ? superclass_count(a.code) : 0
86
+ if a.is_a?(ClassNode)
87
+ superclass_count(a.code)
88
+ elsif a.is_a?(ImplicitCasterNode) # Hmm, hack
89
+ 1_000_000
90
+ else
91
+ 0
92
+ end
88
93
  end
89
94
  end
90
95
 
@@ -111,7 +116,8 @@ module RbPlusPlus
111
116
  node.ignored? ||
112
117
  (node.moved_to && node.moved_to != self.code) ||
113
118
  !node.public? ||
114
- (node.is_a?(RbGCCXML::Struct) && node.incomplete?)
119
+ (node.is_a?(RbGCCXML::Struct) && node.incomplete?) ||
120
+ node.is_a?(RbGCCXML::FundamentalType)
115
121
  end
116
122
 
117
123
  # Given a new node, build it and add it to our nodes list
@@ -142,7 +148,7 @@ module RbPlusPlus
142
148
  if !node._disable_typedef_lookup?
143
149
  while found
144
150
  last_found = found
145
- typedef = RbGCCXML::XMLParsing.find(:node_type => "Typedef", :type => found.attributes["id"])
151
+ typedef = RbGCCXML::NodeCache.all("Typedef").select {|t| t.attributes["type"] == found.attributes["id"]}.first
146
152
 
147
153
  # Some typedefs have the access attribute, some don't. We want those without the attribute
148
154
  # and those with the access="public". For this reason, we can't put :access => "public" in the
@@ -54,10 +54,6 @@ module RbPlusPlus
54
54
  unless @director
55
55
  check_allocation_strategies
56
56
  end
57
-
58
- # For now, build a const& type converter for all class types until Rice has
59
- # better management of to_ruby of class types, if it ever happens
60
- add_global_child ConstConverterNode.new(self.code, self)
61
57
  end
62
58
 
63
59
  def write
@@ -70,10 +66,10 @@ module RbPlusPlus
70
66
  class_names = class_names.join(",")
71
67
 
72
68
  if parent.rice_variable
73
- registrations << "#{prefix} Rice::define_class_under< #{class_names} >" +
69
+ registrations << "\t#{prefix} Rice::define_class_under< #{class_names} >" +
74
70
  "(#{parent.rice_variable}, \"#{ruby_name}\");"
75
71
  else
76
- registrations << "#{prefix} Rice::define_class< #{class_names} >(\"#{ruby_name}\");"
72
+ registrations << "\t#{prefix} Rice::define_class< #{class_names} >(\"#{ruby_name}\");"
77
73
  end
78
74
 
79
75
  handle_custom_code
@@ -83,7 +79,6 @@ module RbPlusPlus
83
79
 
84
80
  # Here we take the code manually added to the extension via #add_custom_code
85
81
  def handle_custom_code
86
-
87
82
  # Any declaration code, usually wrapper function definitions
88
83
  self.code._get_custom_declarations.flatten.each do |decl|
89
84
  declarations << decl
@@ -91,7 +86,7 @@ module RbPlusPlus
91
86
 
92
87
  # And the registration code to hook into Rice
93
88
  self.code._get_custom_wrappings.flatten.each do |wrap|
94
- registrations << "#{wrap.gsub(/<class>/, self.rice_variable)}"
89
+ registrations << "\t#{wrap.gsub(/<class>/, self.rice_variable)}"
95
90
  end
96
91
  end
97
92
 
@@ -105,16 +100,12 @@ module RbPlusPlus
105
100
  # We check here if we're one of those classes and completely skip this step
106
101
  return if [self.code.constructors].flatten.empty?
107
102
 
108
- # Find a public default constructor
109
- found = [self.code.constructors.find(:arguments => [], :access => "public")].flatten
110
- has_public_constructor = !found.empty?
111
-
112
103
  # See if the destructor is public
113
104
  has_public_destructor = self.code.destructor && self.code.destructor.public?
114
105
 
115
- if !has_public_constructor || !has_public_destructor
106
+ if !has_public_destructor
116
107
  add_global_child AllocationStrategyNode.new(self,
117
- self.code, has_public_constructor, has_public_destructor)
108
+ self.code, true, has_public_destructor)
118
109
  end
119
110
  end
120
111
 
@@ -20,7 +20,7 @@ module RbPlusPlus
20
20
  end
21
21
 
22
22
  prefix = parent.rice_variable ? "#{parent.rice_variable}." : "Rice::Module(rb_mKernel)."
23
- registrations << "#{prefix}const_set(\"#{code.name}\", to_ruby(#{set_to}));"
23
+ registrations << "\t#{prefix}const_set(\"#{code.name}\", to_ruby(#{set_to}));"
24
24
  end
25
25
 
26
26
  end
@@ -10,7 +10,7 @@ module RbPlusPlus
10
10
 
11
11
  def write
12
12
  args = [code.parent.qualified_name, code.arguments.map {|a| a.cpp_type.to_cpp }].flatten.compact
13
- registrations << "#{parent.rice_variable}.define_constructor(Rice::Constructor< #{args.join(",")} >());"
13
+ registrations << "\t#{parent.rice_variable}.define_constructor(Rice::Constructor< #{args.join(",")} >());"
14
14
  end
15
15
 
16
16
  end
@@ -27,7 +27,7 @@ module RbPlusPlus
27
27
  def build
28
28
  add_child IncludeNode.new(self, "rice/Director.hpp", :global)
29
29
  add_child IncludeNode.new(self, "rice/Constructor.hpp", :global)
30
-
30
+
31
31
  # To ensure proper compilation, this director class needs
32
32
  # to implement all pure virtual methods found up the
33
33
  # inheritance heirarchy of this class. So here, we traverse
@@ -68,15 +68,15 @@ module RbPlusPlus
68
68
  end
69
69
  end
70
70
 
71
- declarations << "#{@name}(#{args.join(", ")}) : #{@class_qualified_name}(#{supercall_args.join(", ")}), Rice::Director(self) { }"
71
+ declarations << "\t\t#{@name}(#{args.join(", ")}) : #{@class_qualified_name}(#{supercall_args.join(", ")}), Rice::Director(self) { }"
72
72
 
73
- registrations << "#{self.parent.rice_variable}.define_director< #{@name} >();"
74
- registrations << "#{self.parent.rice_variable}.define_constructor(Rice::Constructor< #{types.join(", ")} >());"
73
+ registrations << "\t#{self.parent.rice_variable}.define_director< #{@name} >();"
74
+ registrations << "\t#{self.parent.rice_variable}.define_constructor(Rice::Constructor< #{types.join(", ")} >());"
75
75
  end
76
76
 
77
77
  def write
78
78
  declarations << "class #{@name} : public #{@class_qualified_name}, public Rice::Director {"
79
- declarations << "public:"
79
+ declarations << "\tpublic:"
80
80
 
81
81
  # Handle constructors
82
82
  if @constructors.empty?
@@ -104,7 +104,7 @@ module RbPlusPlus
104
104
  def_arguments = def_arguments.length == 0 ? "" : def_arguments.join(", ")
105
105
 
106
106
  reverse = ""
107
- up_or_raise =
107
+ up_or_raise =
108
108
  if method.default_return_value
109
109
  reverse = "!"
110
110
  "return #{method.default_return_value}"
@@ -123,17 +123,17 @@ module RbPlusPlus
123
123
 
124
124
  # Write out the virtual method that forwards calls into Ruby
125
125
  declarations << ""
126
- declarations << "virtual #{return_type} #{cpp_name}(#{def_arguments}) #{const} {"
127
- declarations << "#{call_down};"
128
- declarations << "}"
126
+ declarations << "\t\tvirtual #{return_type} #{cpp_name}(#{def_arguments}) #{const} {"
127
+ declarations << "\t\t\t#{call_down};"
128
+ declarations << "\t\t}"
129
129
 
130
130
  # Write out the wrapper method that gets exposed to Ruby that handles
131
131
  # going up the inheritance chain
132
132
  declarations << ""
133
- declarations << "#{return_type} default_#{cpp_name}(#{def_arguments}) #{const} {"
134
- declarations << "#{up_or_raise};"
135
- declarations << "}"
136
-
133
+ declarations << "\t\t#{return_type} default_#{cpp_name}(#{def_arguments}) #{const} {"
134
+ declarations << "\t\t\t#{up_or_raise};"
135
+ declarations << "\t\t}"
136
+
137
137
  end
138
138
 
139
139
  declarations << "};"
@@ -20,11 +20,11 @@ module RbPlusPlus
20
20
  def write
21
21
  second = parent.rice_variable ? ", #{parent.rice_variable}" : ""
22
22
 
23
- registrations << "#{rice_variable_type} #{rice_variable} = " \
23
+ registrations << "\t#{rice_variable_type} #{rice_variable} = " \
24
24
  "Rice::define_enum<#{code.qualified_name}>(\"#{code.name}\"#{second});"
25
25
 
26
26
  code.values.each do |v|
27
- registrations << "#{rice_variable}.define_value(\"#{v.name}\", #{v.qualified_name});"
27
+ registrations << "\t#{rice_variable}.define_value(\"#{v.name}\", #{v.qualified_name});"
28
28
  end
29
29
  end
30
30
 
@@ -35,8 +35,6 @@ module RbPlusPlus
35
35
  "please use #use_contructor to select which one to use."
36
36
  end
37
37
 
38
- # First, lets see if we have any non-generated constructors
39
-
40
38
  [to_use || real_constructors].flatten.each do |constructor|
41
39
  next if do_not_wrap?(constructor)
42
40
 
@@ -44,6 +42,15 @@ module RbPlusPlus
44
42
  next if ignore_artificial || constructor.arguments.length == 1
45
43
  end
46
44
 
45
+ if implicit_converter?(constructor)
46
+ if constructor.implicit_casting?
47
+ parent.add_child ImplicitCasterNode.new(constructor, self)
48
+ end
49
+
50
+ # We don't want to expose these constructors to Rice
51
+ next
52
+ end
53
+
47
54
  if @director
48
55
  @director.wrap_constructor constructor
49
56
  else
@@ -52,6 +59,14 @@ module RbPlusPlus
52
59
  end
53
60
  end
54
61
 
62
+ # Is this constructor a converter constructor?
63
+ def implicit_converter?(constructor)
64
+ # Single argument
65
+ constructor.arguments.length == 1 &&
66
+ # We are wrapping the type converting from
67
+ !do_not_wrap?(constructor.arguments[0].cpp_type.base_type)
68
+ end
69
+
55
70
  # Wrap up any class constants
56
71
  def with_constants
57
72
  [self.code.constants].flatten.each do |const|
@@ -0,0 +1,24 @@
1
+ module RbPlusPlus
2
+ module Builders
3
+
4
+ class ImplicitCasterNode < Base
5
+
6
+ def initialize(constructor, parent)
7
+ super(constructor, parent)
8
+
9
+ @to = parent.code.qualified_name
10
+ @from = constructor.arguments[0].cpp_type.base_type.qualified_name
11
+ end
12
+
13
+ def build
14
+ end
15
+
16
+ def write
17
+ if @from != @to
18
+ registrations << "\tRice::define_implicit_cast< #{@from}, #{@to} >();"
19
+ end
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -15,19 +15,19 @@ module RbPlusPlus
15
15
  if !code.cpp_type.const?
16
16
  method_name = "wrap_#{parent_name}_#{code.name}_set"
17
17
  declarations << "void #{method_name}(#{parent.code.qualified_name}* self, #{code.cpp_type.to_cpp} val) {"
18
- declarations << "self->#{code.name} = val;"
18
+ declarations << "\tself->#{code.name} = val;"
19
19
  declarations << "}"
20
20
 
21
- registrations << "#{parent.rice_variable}.define_method(\"#{ruby_name}=\", &#{method_name});"
21
+ registrations << "\t#{parent.rice_variable}.define_method(\"#{ruby_name}=\", &#{method_name});"
22
22
  end
23
23
 
24
24
  # Getter
25
25
  method_name = "wrap_#{parent_name}_#{code.name}_get"
26
26
  declarations << "#{code.cpp_type.to_cpp} #{method_name}(#{parent.code.qualified_name}* self) {"
27
- declarations << "return self->#{code.name};"
27
+ declarations << "\treturn self->#{code.name};"
28
28
  declarations << "}"
29
29
 
30
- registrations << "#{parent.rice_variable}.define_method(\"#{ruby_name}\", &#{method_name});"
30
+ registrations << "\t#{parent.rice_variable}.define_method(\"#{ruby_name}\", &#{method_name});"
31
31
  end
32
32
 
33
33
  end
@@ -72,9 +72,9 @@ module RbPlusPlus
72
72
 
73
73
  funcall = "rb_funcall(#{block_var_name}, rb_intern(\"call\"), #{callback_values.join(", ")})"
74
74
  if return_type == "void"
75
- declarations << "#{funcall};"
75
+ declarations << "\t#{funcall};"
76
76
  else
77
- declarations << "return from_ruby<#{return_type} >(#{funcall});"
77
+ declarations << "\treturn from_ruby<#{return_type} >(#{funcall});"
78
78
  end
79
79
 
80
80
  declarations << "}"
@@ -96,7 +96,7 @@ module RbPlusPlus
96
96
  declarations << "\treturn Qnil;"
97
97
  declarations << "}"
98
98
 
99
- registrations << "#{self.prefix}#{self.rice_method}(\"#{@ruby_name + self.suffix}\", &#{wrapper_func});"
99
+ registrations << "\t#{self.prefix}#{self.rice_method}(\"#{@ruby_name + self.suffix}\", &#{wrapper_func});"
100
100
  end
101
101
 
102
102
  def wrap_normal_method
@@ -137,13 +137,14 @@ module RbPlusPlus
137
137
 
138
138
  const = self.code.const? ? " const" : ""
139
139
 
140
- registrations << "{"
140
+ registrations << ""
141
+ registrations << "\t{"
141
142
 
142
- registrations << "typedef #{return_type} ( #{method_ref} )( #{arguments.join(", ")} )#{const};"
143
- registrations << "#{self.prefix}#{self.rice_method}(\"#{@ruby_name + self.suffix}\", " +
143
+ registrations << "\t\ttypedef #{return_type} ( #{method_ref} )( #{arguments.join(", ")} )#{const};"
144
+ registrations << "\t\t#{self.prefix}#{self.rice_method}(\"#{@ruby_name + self.suffix}\", " +
144
145
  "#{usage_ref}( &#{code_path} )#{def_args});"
145
146
 
146
- registrations << "}"
147
+ registrations << "\t}"
147
148
  end
148
149
 
149
150
  # See http://www.gccxml.org/Bug/view.php?id=9234
@@ -45,7 +45,7 @@ module RbPlusPlus
45
45
  end
46
46
 
47
47
  def write
48
- prefix = "#{rice_variable_type} #{rice_variable} = "
48
+ prefix = "\t#{rice_variable_type} #{rice_variable} = "
49
49
 
50
50
  if parent.rice_variable
51
51
  registrations << "#{prefix} Rice::define_module_under(#{parent.rice_variable}, \"#{@name}\");"
@@ -15,6 +15,10 @@ module RbPlusPlus
15
15
  @@quiet = val
16
16
  end
17
17
 
18
+ def silent!
19
+ @@silent = true
20
+ end
21
+
18
22
  def verbose?
19
23
  @@verbose = false unless defined?(@@verbose)
20
24
  @@verbose
@@ -25,20 +29,25 @@ module RbPlusPlus
25
29
  @@quiet
26
30
  end
27
31
 
32
+ def silent?
33
+ @@silent = false unless defined?(@@silent)
34
+ @@silent
35
+ end
36
+
28
37
  def info(msg)
29
- $stdout.puts "(INFO) #{msg}" unless quiet?
38
+ $stdout.puts "(INFO) #{msg}" if !quiet? && !silent?
30
39
  end
31
40
 
32
41
  def warn(type, msg)
33
- $stdout.puts "(WARNING) #{msg}"
42
+ $stdout.puts "(WARNING) #{msg}" if !silent?
34
43
  end
35
44
 
36
45
  def debug(msg)
37
- $stdout.puts "(DEBUG) #{msg}" if verbose?
46
+ $stdout.puts "(DEBUG) #{msg}" if verbose? && !silent?
38
47
  end
39
48
 
40
49
  def error(msg)
41
- $stderr.puts "(ERROR) #{msg}"
50
+ $stderr.puts "(ERROR) #{msg}" if !silent?
42
51
  end
43
52
  end
44
53
  end
@@ -1,11 +1,22 @@
1
1
  module RbGCCXML
2
2
  class Class < Node
3
+
4
+ def initialize(*args)
5
+ super
6
+
7
+ @included_classes = []
8
+ @included_methods = []
9
+
10
+ @declarations = []
11
+ @wrappings = []
12
+ end
13
+
3
14
  # Class can include nested classes and nested structs.
4
15
  #
5
16
  # Class can also include external methods/functions as class level methods
6
17
  # also supports instance level methods
7
18
  #
8
- # ex.
19
+ # ex.
9
20
  #
10
21
  # math_class.includes node.namespaces("Math").functions("mod")
11
22
  #
@@ -19,23 +30,21 @@ module RbGCCXML
19
30
  #
20
31
  def includes(val)
21
32
  if (val.is_a?(RbGCCXML::Struct) || val.is_a?(RbGCCXML::Class))
22
- cache[:classes] ||= []
23
- cache[:classes] << val
33
+ @included_classes << val
24
34
  else
25
- cache[:methods] ||= []
26
- cache[:methods] << val
35
+ @included_methods << val
27
36
  end
28
37
  val.moved_to = self
29
38
  end
30
-
39
+
31
40
  alias_method :node_classes, :classes
32
41
  def classes(*args) #:nodoc:
33
- find_with_cache(:classes, node_classes(*args))
42
+ find_with(node_classes(*args), @included_classes)
34
43
  end
35
44
 
36
45
  alias_method :node_methods, :methods
37
46
  def methods(*args) #:nodoc:
38
- find_with_cache(:methods, node_methods(*args))
47
+ find_with(node_methods(*args), @included_methods)
39
48
  end
40
49
 
41
50
  # Specify which superclass to use.
@@ -45,42 +54,42 @@ module RbGCCXML
45
54
  # where this method hasn't been used yet.
46
55
  #
47
56
  # klass should be the node for the class you want to wrap
48
- def use_superclass(node)
49
- cache[:use_superclass] = node
57
+ def use_superclass(klass)
58
+ @use_superclass = klass
50
59
  end
51
60
 
52
61
  def _get_superclass #:nodoc:
53
- cache[:use_superclass]
62
+ @use_superclass
54
63
  end
55
64
 
56
- # Like #use_superclass, this method allows the user to specify
57
- # which constructor Rice should expose to Ruby.
58
- # Rice currently, because of the lack of method overloading,
65
+ # Like #use_superclass, this method allows the user to specify
66
+ # which constructor Rice should expose to Ruby.
67
+ # Rice currently, because of the lack of method overloading,
59
68
  # only supports one constructor definition. Having multiple
60
69
  # in the code will work, but only the last defined will actually
61
- # work.
70
+ # work.
62
71
  def use_constructor(node)
63
- cache[:use_constructor] = node
72
+ @use_constructor = node
64
73
  end
65
74
 
66
75
  def _get_constructor #:nodoc:
67
- cache[:use_constructor]
76
+ @use_constructor
68
77
  end
69
78
 
70
79
  # Sometimes, type manipulation, moving nodes around, or flat
71
80
  # ignoring nodes just doesn't do the trick and you need to write
72
81
  # your own custom wrapper code. This method is for that. There are
73
- # two parts to custom code: the declaration and the wrapping.
82
+ # two parts to custom code: the declaration and the wrapping.
74
83
  #
75
84
  # The Declaration:
76
85
  # This is the actual custom code you write. It may need to take
77
86
  # a pointer to the class type as the first parameter
78
- # and follow with that any parameters you want.
87
+ # and follow with that any parameters you want.
79
88
  #
80
89
  # The Wrapping
81
90
  # The wrapping is the custom (usually one-line) bit of Rice code that
82
91
  # hooks up your declaration with the class in question. To ensure that
83
- # you doesn't need to know the variable of the ruby class object,
92
+ # you doesn't need to know the variable of the ruby class object,
84
93
  # use <class> and rb++ will replace it as needed.
85
94
  #
86
95
  # Example (taken from Ogre.rb's wrapping of Ogre)
@@ -100,45 +109,45 @@ module RbGCCXML
100
109
  # of times for a class, it won't clobber any previous uses.
101
110
  #
102
111
  def add_custom_code(declaration, wrapping)
103
- cache[:declarations] ||= []
104
- cache[:declarations] << declaration
105
-
106
- cache[:wrappings] ||= []
107
- cache[:wrappings] << wrapping
112
+ @declarations << declaration
113
+ @wrappings << wrapping
108
114
  end
109
115
 
110
116
  def _get_custom_declarations #:nodoc:
111
- cache[:declarations] || []
117
+ @declarations
112
118
  end
113
119
 
114
120
  def _get_custom_wrappings #:nodoc:
115
- cache[:wrappings] || []
121
+ @wrappings
116
122
  end
117
123
 
118
124
  # Does this class have virtual methods (especially pure virtual?)
119
- # If so, then rb++ will generate a proxy class to handle
125
+ # If so, then rb++ will generate a proxy class to handle
120
126
  # the message routing as needed.
121
127
  def needs_director? #:nodoc:
122
- !!cache[:build_director] #[methods].flatten.select {|m| m.virtual? }.length > 0
128
+ !!@build_director
123
129
  end
124
130
 
125
131
  # Until all the kinks of the director code generation can be
126
132
  # worked out, rb++ must be told which classes to build
127
133
  # directors for. Simply call this method on the class to do so
128
134
  def director
129
- cache[:build_director] = true
135
+ @build_director = true
136
+ end
137
+
138
+ # See RbGCCXML::Constructor::implicit_casting
139
+ def implicit_casting(state)
140
+ self.constructors.each {|c| c.implicit_casting(state) }
130
141
  end
131
142
 
132
143
  private
133
144
 
134
145
  # Take the cache key, and the normal results, adds to the results
135
146
  # those that are in the cache and returns them properly.
136
- def find_with_cache(type, results)
137
- in_cache = cache[type]
138
-
147
+ def find_with(results, with = nil)
139
148
  ret = QueryResult.new
140
149
  ret << results if results
141
- ret << in_cache if in_cache
150
+ ret << with if with
142
151
  ret.flatten!
143
152
 
144
153
  ret.size == 1 ? ret[0] : ret
@@ -0,0 +1,30 @@
1
+ module RbGCCXML
2
+ class Constructor < Function
3
+
4
+ # See:
5
+ # http://msdn.microsoft.com/en-us/library/h1y7x448.aspx
6
+ # http://msdn.microsoft.com/en-us/library/s2ff0fz8(VS.100).aspx
7
+ #
8
+ # Single argument constructors of a class are called Conversion constructors.
9
+ # They manage the conversion of one type to another. Rice handles this functionality
10
+ # through a special method, define_implicit_cast<From, To>().
11
+ #
12
+ # Rb++ attempts to find all classes and constructors that fit this pattern
13
+ # and write out the casting declarations as needed. In the cases where this is
14
+ # functionality not wanted, use this method to turn off this casting check.
15
+ #
16
+ # This method can be called per Constructor or per Class.
17
+ def implicit_casting(state)
18
+ @implicit_casting = state
19
+ end
20
+
21
+ def implicit_casting? #:nodoc:
22
+ if @implicit_casting.nil?
23
+ @implicit_casting = true
24
+ end
25
+
26
+ @implicit_casting
27
+ end
28
+
29
+ end
30
+ end
@@ -2,19 +2,19 @@ module RbGCCXML
2
2
  class Function < Node
3
3
  # Always true for functions, false for methods
4
4
  def static?
5
- !cache[:as_method]
5
+ !@as_method
6
6
  end
7
7
 
8
8
  # Sets this function to be an instance method.
9
9
  # Useful for custom function declaration.
10
10
  def as_instance_method
11
- cache[:as_method] = true
11
+ @as_method = true
12
12
  self
13
13
  end
14
14
 
15
15
  # Are we wrapping this function as an instance method?
16
16
  def as_instance_method?
17
- !!cache[:as_method]
17
+ !!@as_method
18
18
  end
19
19
 
20
20
  # For Class#needs_director?