rice 4.9.0 → 4.9.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -1
- data/CMakePresets.json +77 -50
- data/FindRuby.cmake +1 -1
- data/include/rice/rice.hpp +114 -81
- data/include/rice/stl.hpp +157 -95
- data/lib/rice/doc/config.rb +57 -57
- data/lib/rice/doc/cpp_reference.rb +158 -158
- data/lib/rice/doc/doxygen.rb +289 -289
- data/lib/rice/doc/mkdocs.rb +332 -332
- data/lib/rice/doc/rice.rb +48 -48
- data/lib/rice/doc/ruby.rb +26 -26
- data/lib/rice/native.rb +15 -15
- data/lib/rice/native_registry.rb +12 -12
- data/lib/rice/parameter.rb +5 -5
- data/lib/rice/rbs.rb +71 -71
- data/lib/rice/version.rb +1 -1
- data/lib/rubygems/builder.rb +9 -9
- data/lib/rubygems_plugin.rb +8 -8
- data/rice/Data_Type.ipp +1 -1
- data/rice/detail/Native.ipp +2 -4
- data/rice/detail/NativeAttributeGet.ipp +1 -1
- data/rice/detail/NativeAttributeSet.hpp +5 -3
- data/rice/detail/NativeAttributeSet.ipp +41 -33
- data/rice/detail/NativeMethod.ipp +25 -22
- data/rice/detail/NativeRegistry.hpp +3 -2
- data/rice/detail/NativeRegistry.ipp +13 -9
- data/rice/detail/Parameter.ipp +3 -4
- data/rice/detail/Wrapper.hpp +5 -1
- data/rice/detail/Wrapper.ipp +15 -1
- data/rice/stl/exception.ipp +1 -1
- data/rice/stl/filesystem.ipp +1 -1
- data/rice/stl/map.ipp +13 -11
- data/rice/stl/multimap.ipp +13 -11
- data/rice/stl/pair.ipp +14 -8
- data/rice/stl/set.ipp +16 -16
- data/rice/stl/shared_ptr.ipp +15 -1
- data/rice/stl/type_index.ipp +1 -1
- data/rice/stl/unique_ptr.ipp +2 -2
- data/rice/stl/unordered_map.ipp +14 -12
- data/rice/stl/vector.ipp +67 -31
- data/test/test_Attribute.cpp +72 -0
- data/test/test_Callback.cpp +3 -0
- data/test/test_Stl_Map.cpp +46 -0
- data/test/test_Stl_Multimap.cpp +46 -0
- data/test/test_Stl_Set.cpp +34 -0
- data/test/test_Stl_Unordered_Map.cpp +46 -0
- data/test/test_Stl_Variant.cpp +10 -14
- data/test/test_Stl_Vector.cpp +140 -13
- data/test/test_Tracking.cpp +3 -0
- metadata +1 -1
data/lib/rice/doc/rice.rb
CHANGED
|
@@ -1,50 +1,50 @@
|
|
|
1
1
|
module Rice
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
2
|
+
module Doc
|
|
3
|
+
class Rice
|
|
4
|
+
ROOT = "https://ruby-rice.github.io/4.x"
|
|
5
|
+
|
|
6
|
+
CLASS_DOCS = {
|
|
7
|
+
/^Rice::Buffer/ => "ruby_api/buffer",
|
|
8
|
+
/^Rice::Pointer/ => "ruby_api/pointer",
|
|
9
|
+
/^Rice::Reference/ => "ruby_api/reference"
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
def class_url(klass)
|
|
13
|
+
CLASS_DOCS.each do |pattern, path|
|
|
14
|
+
if klass.name.match?(pattern)
|
|
15
|
+
return "#{ROOT}/#{path}"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def module_url(klass)
|
|
22
|
+
nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def union_url(klass)
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def enum_url(klass)
|
|
30
|
+
nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def enum_value_url(klass, enum_value)
|
|
34
|
+
nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def singleton_method_url(klass, native)
|
|
38
|
+
nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def method_url(klass, native)
|
|
42
|
+
class_url(klass)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def attribute_url(klass, native)
|
|
46
|
+
nil
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
50
|
end
|
data/lib/rice/doc/ruby.rb
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
module Rice
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
module Doc
|
|
3
|
+
class Ruby
|
|
4
|
+
ROOT = "https://docs.ruby-lang.org/en/master"
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
def initialize
|
|
7
|
+
end
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
def class_url(klass)
|
|
10
|
+
name = klass.name.split('::').last
|
|
11
|
+
name[0].upcase! # Can't use capitalize because it lowercases other letters which breaks links like NilClass
|
|
12
|
+
"#{ROOT}/#{name}.html"
|
|
13
|
+
end
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
def module_url(klass)
|
|
16
|
+
end
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
def union_url(klass)
|
|
19
|
+
end
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
def enum_url(klass)
|
|
22
|
+
end
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
def enum_value_url(klass, enum_value)
|
|
25
|
+
end
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
def singleton_method_url(klass, native)
|
|
28
|
+
end
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
def method_url(klass, native)
|
|
31
|
+
end
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
def attribute_url(klass, native)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
37
|
end
|
data/lib/rice/native.rb
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
module Rice
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
class Native
|
|
3
|
+
include Comparable
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
5
|
+
def <=>(other)
|
|
6
|
+
case
|
|
7
|
+
when self.name == other.name
|
|
8
|
+
self.parameters.size <=> other.parameters.size
|
|
9
|
+
when self.name == "initialize"
|
|
10
|
+
-1
|
|
11
|
+
when self.name == "initialize"
|
|
12
|
+
1
|
|
13
|
+
else
|
|
14
|
+
self.name <=> other.name
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
18
|
end
|
data/lib/rice/native_registry.rb
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
module Rice
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
class NativeRegistry
|
|
3
|
+
def native_attributes(klass)
|
|
4
|
+
self.lookup_by_kind(klass, Rice::NativeKind::AttributeReader) +
|
|
5
|
+
self.lookup_by_kind(klass, Rice::NativeKind::AttributeWriter)
|
|
6
|
+
end
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
def native_methods(klass)
|
|
9
|
+
self.lookup_by_kind(klass, Rice::NativeKind::Method)
|
|
10
|
+
end
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
def native_functions(klass)
|
|
13
|
+
self.lookup_by_kind(klass, Rice::NativeKind::Function)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
16
|
end
|
data/lib/rice/parameter.rb
CHANGED
data/lib/rice/rbs.rb
CHANGED
|
@@ -2,87 +2,87 @@ require 'erb'
|
|
|
2
2
|
require 'fileutils'
|
|
3
3
|
|
|
4
4
|
module Rice
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
class Rbs
|
|
6
|
+
attr_reader :extension, :output
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
def initialize(extension, output)
|
|
9
|
+
@extension = extension
|
|
10
|
+
@output = output
|
|
11
|
+
end
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
def generate
|
|
14
|
+
STDOUT << "Writing rbs files to #{@output}" << "\n"
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
# Add the extension directory the path in case it ships with extra libraries
|
|
17
|
+
ENV["PATH"] = "#{File.dirname(self.extension)}#{File::PATH_SEPARATOR}#{ENV["PATH"]}"
|
|
18
|
+
require self.extension
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
types = Registries.instance.types
|
|
21
|
+
types.klasses.each do |klass|
|
|
22
|
+
process_class(klass)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
def process_class(klass)
|
|
27
|
+
STDOUT << " " << klass << "\n"
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
native_attributes = Registries.instance.natives.native_attributes(klass).sort.group_by(&:name)
|
|
30
|
+
native_functions = Registries.instance.natives.native_functions(klass).sort.group_by(&:name)
|
|
31
|
+
native_methods = Registries.instance.natives.native_methods(klass).sort.group_by(&:name)
|
|
32
|
+
content = render_template("class", :klass => klass,
|
|
33
|
+
:native_attributes => native_attributes,
|
|
34
|
+
:native_functions => native_functions,
|
|
35
|
+
:native_methods => native_methods)
|
|
36
|
+
write_file(klass, content)
|
|
37
|
+
end
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
def write_file(klass, content)
|
|
40
|
+
parts = klass.name.split("::")
|
|
41
|
+
file_name = "#{parts.pop}.rbs"
|
|
42
|
+
dir = File.join(self.output, *parts)
|
|
43
|
+
FileUtils.mkdir_p(dir)
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
path = File.join(dir, file_name)
|
|
46
|
+
File.write(path, content, mode: "wb")
|
|
47
|
+
end
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
49
|
+
def attribute_sig(native_attributes)
|
|
50
|
+
attr_type = if native_attributes.size == 2
|
|
51
|
+
"attr_accessor"
|
|
52
|
+
elsif native_attributes.first.kind == Rice::NativeKind::AttributeReader
|
|
53
|
+
"attr_reader"
|
|
54
|
+
else
|
|
55
|
+
"attr_writer"
|
|
56
|
+
end
|
|
57
|
+
"#{attr_type} #{native_attributes.first.name}: #{native_attributes.first.return_klass}"
|
|
58
|
+
end
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
60
|
+
def method_sigs(native_methods, indent = 0)
|
|
61
|
+
join_string = "\n" + (" " * indent) + "| "
|
|
62
|
+
a = native_methods.map do |native_method|
|
|
63
|
+
method_sig(native_method)
|
|
64
|
+
end
|
|
65
|
+
a.join(join_string)
|
|
66
|
+
end
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
def method_sig(native)
|
|
69
|
+
params = native.parameters.map do |parameter|
|
|
70
|
+
"#{parameter.arg.name}: #{parameter.klass}"
|
|
71
|
+
end.join(", ")
|
|
72
|
+
"(#{params}) -> #{native.return_klass}"
|
|
73
|
+
end
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
75
|
+
def render_template(template, local_variables = {})
|
|
76
|
+
template = ERB.new(self.template, :trim_mode => '-')
|
|
77
|
+
b = self.binding
|
|
78
|
+
local_variables.each do |key, value|
|
|
79
|
+
b.local_variable_set(key, value)
|
|
80
|
+
end
|
|
81
|
+
template.result(b)
|
|
82
|
+
end
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
def template
|
|
85
|
+
<<~EOS
|
|
86
86
|
module <%= klass.name.split("::")[0..-2].join("::") %>
|
|
87
87
|
class <%= klass.name.split("::").last %>
|
|
88
88
|
<%- native_functions.each do |name, functions| -%>
|
|
@@ -98,7 +98,7 @@ module Rice
|
|
|
98
98
|
<%- end -%>
|
|
99
99
|
end
|
|
100
100
|
end
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
EOS
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
104
|
end
|
data/lib/rice/version.rb
CHANGED
data/lib/rubygems/builder.rb
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
class Gem::Ext::Builder
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
alias :builder_for_original :builder_for
|
|
3
|
+
def builder_for(extension)
|
|
4
|
+
case extension
|
|
5
|
+
when /CMakeLists.txt/ then
|
|
6
|
+
Gem::Ext::CmakeBuilder.new
|
|
7
|
+
else
|
|
8
|
+
builder_for_original(extension)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
11
|
end
|
data/lib/rubygems_plugin.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# For older versions of RubyGems replace the default CMakeBuilder with a
|
|
2
2
|
# more modern one
|
|
3
3
|
if Gem.rubygems_version < Gem::Version.new('4.0')
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
Gem.pre_install do |installer|
|
|
5
|
+
extensions = installer.package&.spec&.extensions
|
|
6
|
+
if extensions && extensions.grep(/CMakeLists/)
|
|
7
|
+
require_relative 'rubygems/builder'
|
|
8
|
+
require_relative 'rubygems/cmake_builder'
|
|
9
|
+
end
|
|
10
|
+
true
|
|
11
|
+
end
|
|
12
12
|
end
|
data/rice/Data_Type.ipp
CHANGED
|
@@ -385,7 +385,7 @@ namespace Rice
|
|
|
385
385
|
}
|
|
386
386
|
else
|
|
387
387
|
{
|
|
388
|
-
detail::NativeAttributeSet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute));
|
|
388
|
+
detail::NativeAttributeSet<Attribute_T>::define(klass, name, std::forward<Attribute_T>(attribute), args...);
|
|
389
389
|
}
|
|
390
390
|
}
|
|
391
391
|
|
data/rice/detail/Native.ipp
CHANGED
|
@@ -176,16 +176,14 @@ namespace Rice::detail
|
|
|
176
176
|
Arg* arg = parameters_[i]->arg();
|
|
177
177
|
if (arg->isKeepAlive())
|
|
178
178
|
{
|
|
179
|
-
|
|
180
|
-
selfWrapper->addKeepAlive(rubyValues[i].value());
|
|
179
|
+
WrapperBase::addKeepAlive(self, rubyValues[i].value());
|
|
181
180
|
}
|
|
182
181
|
}
|
|
183
182
|
|
|
184
183
|
// Check return value
|
|
185
184
|
if (this->returnInfo_->isKeepAlive())
|
|
186
185
|
{
|
|
187
|
-
WrapperBase
|
|
188
|
-
returnWrapper->addKeepAlive(self);
|
|
186
|
+
WrapperBase::addKeepAlive(returnValue, self);
|
|
189
187
|
}
|
|
190
188
|
}
|
|
191
189
|
|
|
@@ -23,7 +23,7 @@ namespace Rice::detail
|
|
|
23
23
|
// matches or calls function pointer. Instead Ruby can call the static call method defined on
|
|
24
24
|
// this class (&NativeAttribute_T::get).
|
|
25
25
|
Identifier identifier(name);
|
|
26
|
-
detail::Registries::instance.natives.
|
|
26
|
+
detail::Registries::instance.natives.replace(klass, identifier.id(), native);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
template<typename Attribute_T>
|
|
@@ -15,8 +15,9 @@ namespace Rice
|
|
|
15
15
|
using Receiver_T = typename attribute_traits<Attribute_T>::class_type;
|
|
16
16
|
|
|
17
17
|
public:
|
|
18
|
-
// Register attribute
|
|
19
|
-
|
|
18
|
+
// Register attribute setter with Ruby
|
|
19
|
+
template<typename...Arg_Ts>
|
|
20
|
+
static void define(VALUE klass, std::string name, Attribute_T attribute, Arg_Ts&...args);
|
|
20
21
|
|
|
21
22
|
public:
|
|
22
23
|
// Disallow creating/copying/moving
|
|
@@ -34,11 +35,12 @@ namespace Rice
|
|
|
34
35
|
VALUE returnKlass() override;
|
|
35
36
|
|
|
36
37
|
protected:
|
|
37
|
-
NativeAttributeSet(VALUE klass, std::string name, Attribute_T attr);
|
|
38
|
+
NativeAttributeSet(VALUE klass, std::string name, Attribute_T attr, std::unique_ptr<Parameter<T_Unqualified>> parameter);
|
|
38
39
|
|
|
39
40
|
private:
|
|
40
41
|
VALUE klass_;
|
|
41
42
|
Attribute_T attribute_;
|
|
43
|
+
std::unique_ptr<Parameter<T_Unqualified>> parameter_;
|
|
42
44
|
};
|
|
43
45
|
} // detail
|
|
44
46
|
} // Rice
|
|
@@ -5,28 +5,46 @@
|
|
|
5
5
|
namespace Rice::detail
|
|
6
6
|
{
|
|
7
7
|
template<typename Attribute_T>
|
|
8
|
-
|
|
8
|
+
template<typename...Arg_Ts>
|
|
9
|
+
void NativeAttributeSet<Attribute_T>::define(VALUE klass, std::string name, Attribute_T attribute, Arg_Ts&...args)
|
|
9
10
|
{
|
|
10
|
-
//
|
|
11
|
-
|
|
11
|
+
// Extract Arg from Arg_Ts if present, otherwise create default
|
|
12
|
+
using Arg_Tuple = std::tuple<Arg_Ts...>;
|
|
13
|
+
constexpr std::size_t index = tuple_element_index_v<Arg_Tuple, Arg, ArgBuffer>;
|
|
14
|
+
|
|
15
|
+
std::unique_ptr<Arg> arg;
|
|
16
|
+
if constexpr (index < std::tuple_size_v<Arg_Tuple>)
|
|
17
|
+
{
|
|
18
|
+
using Arg_T_Local = std::decay_t<std::tuple_element_t<index, Arg_Tuple>>;
|
|
19
|
+
const Arg_T_Local& argInfo = std::get<index>(std::forward_as_tuple(std::forward<Arg_Ts>(args)...));
|
|
20
|
+
arg = std::make_unique<Arg_T_Local>(argInfo);
|
|
21
|
+
}
|
|
22
|
+
else
|
|
23
|
+
{
|
|
24
|
+
arg = std::make_unique<Arg>("value");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Create the parameter
|
|
28
|
+
auto parameter = std::make_unique<Parameter<T_Unqualified>>(std::move(arg));
|
|
29
|
+
|
|
30
|
+
// Create a NativeAttributeSet that Ruby will call to write C++ variables
|
|
31
|
+
NativeAttribute_T* nativeAttribute = new NativeAttribute_T(klass, name, std::forward<Attribute_T>(attribute), std::move(parameter));
|
|
12
32
|
std::unique_ptr<Native> native(nativeAttribute);
|
|
13
33
|
|
|
14
34
|
// Define the write method name
|
|
15
35
|
std::string setter = name + "=";
|
|
16
36
|
|
|
17
|
-
// Tell Ruby to invoke the static method
|
|
37
|
+
// Tell Ruby to invoke the static method resolve to set the attribute value
|
|
18
38
|
detail::protect(rb_define_method, klass, setter.c_str(), (RUBY_METHOD_FUNC)&Native::resolve, -1);
|
|
19
39
|
|
|
20
|
-
// Add to native registry
|
|
21
|
-
// matches or calls function pointer. Instead Ruby can call the static call method defined on
|
|
22
|
-
// this class (&NativeAttribute_T::set).
|
|
40
|
+
// Add to native registry
|
|
23
41
|
Identifier identifier(setter);
|
|
24
|
-
detail::Registries::instance.natives.
|
|
42
|
+
detail::Registries::instance.natives.replace(klass, identifier.id(), native);
|
|
25
43
|
}
|
|
26
44
|
|
|
27
45
|
template<typename Attribute_T>
|
|
28
|
-
NativeAttributeSet<Attribute_T>::NativeAttributeSet(VALUE klass, std::string name, Attribute_T attribute)
|
|
29
|
-
: Native(name), klass_(klass), attribute_(attribute)
|
|
46
|
+
NativeAttributeSet<Attribute_T>::NativeAttributeSet(VALUE klass, std::string name, Attribute_T attribute, std::unique_ptr<Parameter<T_Unqualified>> parameter)
|
|
47
|
+
: Native(name), klass_(klass), attribute_(attribute), parameter_(std::move(parameter))
|
|
30
48
|
{
|
|
31
49
|
}
|
|
32
50
|
|
|
@@ -47,25 +65,25 @@ namespace Rice::detail
|
|
|
47
65
|
throw std::runtime_error("Incorrect number of parameters for setting attribute. Attribute: " + this->name_);
|
|
48
66
|
}
|
|
49
67
|
|
|
68
|
+
// Get the Ruby value and convert to native
|
|
50
69
|
VALUE value = values.begin()->second;
|
|
70
|
+
std::optional<VALUE> valueOpt(value);
|
|
71
|
+
T_Unqualified nativeValue = this->parameter_->convertToNative(valueOpt);
|
|
51
72
|
|
|
52
73
|
if constexpr (!std::is_null_pointer_v<Receiver_T>)
|
|
53
74
|
{
|
|
54
75
|
Receiver_T* nativeSelf = From_Ruby<Receiver_T*>().convert(self);
|
|
55
|
-
|
|
56
|
-
// Deal with pointers to pointes, see Parameter::convertToNative commment
|
|
57
|
-
if constexpr (is_pointer_pointer_v<Attr_T> && !std::is_convertible_v<remove_cv_recursive_t<Attr_T>, Attr_T>)
|
|
58
|
-
{
|
|
59
|
-
nativeSelf->*attribute_ = (Attr_T)From_Ruby<T_Unqualified>().convert(value);
|
|
60
|
-
}
|
|
61
|
-
else
|
|
62
|
-
{
|
|
63
|
-
nativeSelf->*attribute_ = From_Ruby<T_Unqualified>().convert(value);
|
|
64
|
-
}
|
|
76
|
+
nativeSelf->*attribute_ = (Attr_T)nativeValue;
|
|
65
77
|
}
|
|
66
78
|
else
|
|
67
79
|
{
|
|
68
|
-
*attribute_ =
|
|
80
|
+
*attribute_ = nativeValue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Check if we need to prevent the value from being garbage collected
|
|
84
|
+
if (this->parameter_->arg()->isKeepAlive())
|
|
85
|
+
{
|
|
86
|
+
WrapperBase::addKeepAlive(self, value);
|
|
69
87
|
}
|
|
70
88
|
|
|
71
89
|
return value;
|
|
@@ -86,17 +104,7 @@ namespace Rice::detail
|
|
|
86
104
|
template<typename Attribute_T>
|
|
87
105
|
inline VALUE NativeAttributeSet<Attribute_T>::returnKlass()
|
|
88
106
|
{
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (isBuffer)
|
|
92
|
-
{
|
|
93
|
-
TypeMapper<Pointer<detail::remove_cv_recursive_t<std::remove_pointer_t<Attr_T>>>> typeMapper;
|
|
94
|
-
return typeMapper.rubyKlass();
|
|
95
|
-
}
|
|
96
|
-
else
|
|
97
|
-
{
|
|
98
|
-
TypeMapper<Attr_T> typeMapper;
|
|
99
|
-
return typeMapper.rubyKlass();
|
|
100
|
-
}
|
|
107
|
+
TypeMapper<Attr_T> typeMapper;
|
|
108
|
+
return typeMapper.rubyKlass();
|
|
101
109
|
}
|
|
102
110
|
}
|