krpc 0.2.0 → 0.2.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/.travis.yml +28 -0
- data/README.md +5 -23
- data/bin/TestServer/Google.ProtocolBuffers.Serialization.dll +0 -0
- data/bin/TestServer/Google.ProtocolBuffers.dll +0 -0
- data/bin/TestServer/TestServer.exe +0 -0
- data/bin/TestServer/TestServer.xml +32 -0
- data/bin/TestServer/kRPC.dll +0 -0
- data/bin/TestServer/kRPC.xml +2208 -0
- data/krpc.gemspec +4 -2
- data/lib/krpc.rb +1 -0
- data/lib/krpc/client.rb +58 -44
- data/lib/krpc/core_extensions.rb +9 -0
- data/lib/krpc/doc.rb +5 -4
- data/lib/krpc/encoder.rb +5 -5
- data/lib/krpc/error.rb +4 -0
- data/lib/krpc/gen.rb +47 -40
- data/lib/krpc/service.rb +0 -7
- data/lib/krpc/types.rb +9 -4
- data/lib/krpc/version.rb +3 -0
- metadata +32 -4
data/krpc.gemspec
CHANGED
@@ -2,10 +2,11 @@
|
|
2
2
|
|
3
3
|
lib = File.expand_path('../lib', __FILE__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'krpc/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
8
|
s.name = "krpc"
|
8
|
-
s.version =
|
9
|
+
s.version = KRPC::VERSION
|
9
10
|
s.authors = ["Tomasz Więch"]
|
10
11
|
s.email = ["tewu.dev@gmail.com"]
|
11
12
|
|
@@ -27,7 +28,8 @@ Gem::Specification.new do |s|
|
|
27
28
|
s.add_runtime_dependency "ruby_protobuf", "~> 0.4"
|
28
29
|
s.add_runtime_dependency "colorize", "~> 0.7"
|
29
30
|
s.add_runtime_dependency "nokogiri", "~> 1.6"
|
30
|
-
s.add_development_dependency
|
31
|
+
s.add_development_dependency 'bundler', '~> 1.7', '>= 1.7.0'
|
31
32
|
s.add_development_dependency "pry", "~> 0.10"
|
33
|
+
s.add_development_dependency "rspec", "~> 3.0"
|
32
34
|
s.add_development_dependency "hanna-nouveau", "~> 0.4"
|
33
35
|
end
|
data/lib/krpc.rb
CHANGED
data/lib/krpc/client.rb
CHANGED
@@ -14,7 +14,7 @@ module KRPC
|
|
14
14
|
# A kRPC client, through which all Remote Procedure Calls are made. To make RPC calls client
|
15
15
|
# must first connect to server. This can be achieved by calling Client#connect or Client#connect!
|
16
16
|
# methods. Client object can connect and disconnect from the server many times during it's
|
17
|
-
# lifetime. RPCs can be made by calling Client#
|
17
|
+
# lifetime. RPCs can be made by calling Client#execute_rpc method. After generating services API (with
|
18
18
|
# Client#generate_services_api! call), RPCs can be also made using
|
19
19
|
# `client.service_name.procedure_name(parameter, ...)`
|
20
20
|
#
|
@@ -126,72 +126,86 @@ module KRPC
|
|
126
126
|
|
127
127
|
# Returns `true` if services API has been already generated, `false` otherwise.
|
128
128
|
def services_api_generated?
|
129
|
-
respond_to? :space_center
|
129
|
+
respond_to? :space_center or respond_to? :test_service
|
130
130
|
end
|
131
131
|
|
132
132
|
# Execute an RPC.
|
133
|
-
def
|
134
|
-
|
135
|
-
|
136
|
-
rpc_connection.send Encoder.encode_request(req)
|
137
|
-
# Receive response
|
138
|
-
resp_length = rpc_connection.recv_varint
|
139
|
-
resp_data = rpc_connection.recv resp_length
|
140
|
-
resp = PB::Response.new
|
141
|
-
resp.parse_from_string resp_data
|
142
|
-
# Check for an error response
|
133
|
+
def execute_rpc(service, procedure, args=[], kwargs={}, param_names=[], param_types=[], param_default=[], return_type: nil)
|
134
|
+
send_request(service, procedure, args, kwargs, param_names, param_types, param_default)
|
135
|
+
resp = receive_response
|
143
136
|
raise(RPCError, resp.error) if resp.has_field? "error"
|
144
|
-
|
145
|
-
if return_type == nil
|
146
|
-
nil
|
147
|
-
else
|
137
|
+
unless return_type.nil?
|
148
138
|
Decoder.decode(resp.return_value, return_type, self)
|
139
|
+
else
|
140
|
+
nil
|
149
141
|
end
|
150
142
|
rescue IOError => e
|
151
143
|
raise(Exception, "RPC call attempt while not connected to server -- call Client#connect first") if not connected?
|
152
144
|
raise e
|
153
145
|
end
|
154
|
-
|
146
|
+
|
155
147
|
# Build a PB::Request object.
|
156
148
|
def build_request(service, procedure, args=[], kwargs={}, param_names=[], param_types=[], param_default=[])
|
157
149
|
begin
|
158
150
|
raise(ArgumentError, "param_names and param_types should be equal length\n\tparam_names = #{param_names}\n\tparam_types = #{param_types}") unless param_names.length == param_types.length
|
159
151
|
raise(ArgumentError, "param_names and param_default should be equal length\n\tparam_names = #{param_names}\n\tparam_default = #{param_default}") unless param_names.length == param_default.length
|
160
|
-
required_params_count = param_default.take_while
|
152
|
+
required_params_count = param_default.take_while{|pd| pd == :no_default_value}.count
|
161
153
|
raise ArgumentsNumberErrorSig.new(args.count, required_params_count..param_names.count) unless args.count <= param_names.count
|
162
|
-
|
163
|
-
|
164
|
-
param_names_symbols = param_names.map(&:to_sym)
|
165
|
-
req_args = param_names_symbols.map.with_index do |name,i|
|
166
|
-
is_kwarg = kwargs.has_key? name
|
167
|
-
raise ArgumentErrorSig.new("there are both positional and keyword arguments for parameter \"#{name}\"") if is_kwarg && i < args.count
|
168
|
-
kwargs_remaining -= 1 if is_kwarg
|
169
|
-
unless i >= required_params_count &&
|
170
|
-
(!is_kwarg && i >= args.count ||
|
171
|
-
!is_kwarg && args[i] == param_default[i] ||
|
172
|
-
is_kwarg && kwargs[name] == param_default[i])
|
173
|
-
arg = if is_kwarg then kwargs[name]
|
174
|
-
elsif i < args.count then args[i]
|
175
|
-
else raise ArgumentErrorSig.new("missing argument for parameter \"#{name}\"")
|
176
|
-
end
|
177
|
-
begin
|
178
|
-
arg = TypeStore.coerce_to(arg, param_types[i])
|
179
|
-
rescue ValueError
|
180
|
-
raise ArgumentErrorSig.new("argument for parameter \"#{name}\" must be a #{param_types[i].ruby_type} -- got #{args[i]} of type #{args[i].class}")
|
181
|
-
end
|
182
|
-
v = Encoder.encode(arg, param_types[i])
|
183
|
-
PB::Argument.new(position: i, value: v)
|
184
|
-
end
|
185
|
-
end.compact
|
186
|
-
raise ArgumentErrorSig.new("keyword arguments for non existing parameters: #{(kwargs.keys - param_names_symbols).join(", ")}") unless kwargs_remaining == 0
|
154
|
+
req_args = construct_arguments(args, kwargs, param_names, param_types, param_default, required_params_count)
|
187
155
|
rescue ArgumentErrorSig => err
|
188
156
|
raise err.with_signature(Doc.docstring_for_procedure(service, procedure, false))
|
189
157
|
end
|
190
158
|
PB::Request.new(service: service, procedure: procedure, arguments: req_args)
|
191
159
|
end
|
192
|
-
|
160
|
+
|
193
161
|
protected #----------------------------------
|
194
162
|
|
163
|
+
def construct_arguments(args, kwargs, param_names, param_types, param_default, required_params_count)
|
164
|
+
param_names_symbols = param_names.map(&:to_sym)
|
165
|
+
kwargs_remaining = kwargs.count
|
166
|
+
|
167
|
+
req_args = param_names_symbols.map.with_index do |name, i|
|
168
|
+
is_kwarg = kwargs.has_key? name
|
169
|
+
kwargs_remaining -= 1 if is_kwarg
|
170
|
+
raise ArgumentErrorSig.new("there are both positional and keyword arguments for parameter \"#{name}\"") if is_kwarg && i < args.count
|
171
|
+
is_parameter_optional = i >= required_params_count
|
172
|
+
is_parameter_has_default_value = !is_kwarg && i >= args.count ||
|
173
|
+
!is_kwarg && args[i] == param_default[i] ||
|
174
|
+
is_kwarg && kwargs[name] == param_default[i]
|
175
|
+
unless is_parameter_optional and is_parameter_has_default_value
|
176
|
+
arg = if is_kwarg then
|
177
|
+
kwargs[name]
|
178
|
+
elsif i < args.count then
|
179
|
+
args[i]
|
180
|
+
else
|
181
|
+
raise ArgumentErrorSig.new("missing argument for parameter \"#{name}\"")
|
182
|
+
end
|
183
|
+
begin
|
184
|
+
arg = TypeStore.coerce_to(arg, param_types[i])
|
185
|
+
rescue ValueError
|
186
|
+
raise ArgumentErrorSig.new("argument for parameter \"#{name}\" must be a #{param_types[i].ruby_type} -- got #{args[i].inspect} of type #{args[i].class}")
|
187
|
+
end
|
188
|
+
v = Encoder.encode(arg, param_types[i])
|
189
|
+
PB::Argument.new(position: i, value: v)
|
190
|
+
end
|
191
|
+
end.compact
|
192
|
+
|
193
|
+
raise ArgumentErrorSig.new("keyword arguments for non existing parameters: #{(kwargs.keys - param_names_symbols).join(", ")}") unless kwargs_remaining == 0
|
194
|
+
req_args
|
195
|
+
end
|
196
|
+
|
197
|
+
def send_request(service, procedure, args, kwargs, param_names, param_types, param_default)
|
198
|
+
req = build_request(service, procedure, args, kwargs, param_names, param_types, param_default)
|
199
|
+
rpc_connection.send Encoder.encode_request(req)
|
200
|
+
end
|
201
|
+
|
202
|
+
def receive_response
|
203
|
+
resp_length = rpc_connection.recv_varint
|
204
|
+
resp_data = rpc_connection.recv resp_length
|
205
|
+
resp = PB::Response.new
|
206
|
+
resp.parse_from_string resp_data
|
207
|
+
end
|
208
|
+
|
195
209
|
def call_block_and_close(block)
|
196
210
|
begin block.call(self) ensure close end
|
197
211
|
end
|
data/lib/krpc/core_extensions.rb
CHANGED
@@ -24,8 +24,17 @@ class String
|
|
24
24
|
tr("-", "_").
|
25
25
|
downcase
|
26
26
|
end
|
27
|
+
|
28
|
+
def integer?
|
29
|
+
Integer(self) != nil rescue false
|
30
|
+
end
|
31
|
+
|
32
|
+
def numeric?
|
33
|
+
Float(self) != nil rescue false
|
34
|
+
end
|
27
35
|
end
|
28
36
|
|
37
|
+
|
29
38
|
class Array
|
30
39
|
def extract_kwargs!
|
31
40
|
last.is_a?(::Hash) ? pop : {}
|
data/lib/krpc/doc.rb
CHANGED
@@ -13,7 +13,7 @@ module KRPC
|
|
13
13
|
service_module_name, class_name = ruby_class_to_pb_module_class_pair(class_cls)
|
14
14
|
key = [service_module_name, is_static, class_name, method_name.to_s].hash
|
15
15
|
if @docstr_infos.has_key? key
|
16
|
-
construct_docstring(*@docstr_infos[key], true, is_print_xmldoc_summary)
|
16
|
+
construct_docstring(*@docstr_infos[key], true, is_static, is_print_xmldoc_summary)
|
17
17
|
else
|
18
18
|
"No docstring for #{class_cls.name}#{calc_separator(is_static)}#{method_name.to_s} method" +
|
19
19
|
(method_owner.respond_to?(method_name) ? "" : "\nThere is no such method -- maybe a typo")
|
@@ -23,7 +23,7 @@ module KRPC
|
|
23
23
|
def docstring_for_procedure(service_name, procedure_name, is_print_xmldoc_summary = true)
|
24
24
|
key = [service_name, procedure_name].hash
|
25
25
|
if @procedure_docstr_infos.has_key? key
|
26
|
-
construct_docstring(service_name, '.', procedure_name, *@procedure_docstr_infos[key][3..-1], false, is_print_xmldoc_summary)
|
26
|
+
construct_docstring(service_name, '.', procedure_name, *@procedure_docstr_infos[key][3..-1], false, false, is_print_xmldoc_summary)
|
27
27
|
else
|
28
28
|
"No docstring for #{service_name}.#{procedure_name} procedure"
|
29
29
|
end
|
@@ -58,7 +58,7 @@ module KRPC
|
|
58
58
|
is_static ? '.' : '#'
|
59
59
|
end
|
60
60
|
|
61
|
-
def construct_docstring(namespace, separator, name, param_names, param_types, param_default, return_type, xmldoc, is_hide_this_param, is_print_xmldoc_summary)
|
61
|
+
def construct_docstring(namespace, separator, name, param_names, param_types, param_default, return_type, xmldoc, is_hide_this_param, is_prepend_client_param, is_print_xmldoc_summary)
|
62
62
|
xmldoc = Nokogiri::XML(xmldoc)
|
63
63
|
xmldoc_summary = xmlElements2str(xmldoc.xpath("doc/summary").children, :light_blue, :light_green, :light_red)
|
64
64
|
|
@@ -79,11 +79,12 @@ module KRPC
|
|
79
79
|
|
80
80
|
param_infos = param_names.zip(param_types.map{|x| type2str(x)}, param_default)
|
81
81
|
param_infos.shift if is_hide_this_param && param_names[0] == "this"
|
82
|
+
param_infos.unshift ["client", "Client", :no_default_value] if is_prepend_client_param
|
82
83
|
if param_infos.empty?
|
83
84
|
params = ""
|
84
85
|
else
|
85
86
|
params = "\n" + param_infos.map.with_index do |pi, i|
|
86
|
-
"\t#{pi[0].light_green} :#{pi[1]}" + (pi[2]
|
87
|
+
"\t#{pi[0].light_green} :#{pi[1]}" + (pi[2] == :no_default_value ? "" : " = #{pi[2].inspect}".magenta) \
|
87
88
|
+ (param_infos.size == i+1 ? "" : ",") \
|
88
89
|
+ xmldoc_params[pi[0]].to_s
|
89
90
|
end.join("\n") + "\n"
|
data/lib/krpc/encoder.rb
CHANGED
@@ -20,25 +20,25 @@ module KRPC
|
|
20
20
|
encode_value(remote_oid, TypeStore["uint64"])
|
21
21
|
elsif type.is_a?(Types::ListType)
|
22
22
|
msg = TypeStore["KRPC.List"].ruby_type.new
|
23
|
-
msg.items = obj.map{|x| encode(x, type.value_type)}.to_a
|
23
|
+
msg.items = obj.map{|x| encode( TypeStore.coerce_to(x, type.value_type), type.value_type )}.to_a
|
24
24
|
msg.serialize_to_string
|
25
25
|
elsif type.is_a?(Types::DictionaryType)
|
26
26
|
entry_type = TypeStore["KRPC.DictionaryEntry"].ruby_type
|
27
27
|
msg = TypeStore["KRPC.Dictionary"].ruby_type.new
|
28
28
|
msg.entries = obj.map do |k,v|
|
29
29
|
entry = entry_type.new
|
30
|
-
entry.key = encode(k, type.key_type)
|
31
|
-
entry.value = encode(v, type.value_type)
|
30
|
+
entry.key = encode( TypeStore.coerce_to(k, type.key_type), type.key_type )
|
31
|
+
entry.value = encode( TypeStore.coerce_to(v, type.value_type), type.value_type )
|
32
32
|
entry
|
33
33
|
end
|
34
34
|
msg.serialize_to_string
|
35
35
|
elsif type.is_a?(Types::SetType)
|
36
36
|
msg = TypeStore["KRPC.Set"].ruby_type.new
|
37
|
-
msg.items = obj.map{|x| encode(x, type.value_type)}.to_a
|
37
|
+
msg.items = obj.map{|x| encode( TypeStore.coerce_to(x, type.value_type), type.value_type )}.to_a
|
38
38
|
msg.serialize_to_string
|
39
39
|
elsif type.is_a?(Types::TupleType)
|
40
40
|
msg = TypeStore["KRPC.Tuple"].ruby_type.new
|
41
|
-
msg.items = obj.zip(type.value_types).map{|x,t| encode(x, t)}.to_a
|
41
|
+
msg.items = obj.zip(type.value_types).map{|x,t| encode( TypeStore.coerce_to(x, t), t )}.to_a
|
42
42
|
msg.serialize_to_string
|
43
43
|
else raise(RuntimeError, "Cannot encode object #{obj} of type #{type}")
|
44
44
|
end
|
data/lib/krpc/error.rb
CHANGED
@@ -28,6 +28,10 @@ module KRPC
|
|
28
28
|
super("wrong number of arguments (#{args_count} for #{valid_params_str})", sig)
|
29
29
|
end
|
30
30
|
|
31
|
+
def with_arguments_count_incremented_by(args_count_increment)
|
32
|
+
self.class.new(args_count + args_count_increment, (valid_params_count_range.min + args_count_increment)..(valid_params_count_range.max + args_count_increment), signature)
|
33
|
+
end
|
34
|
+
|
31
35
|
def with_signature(sig)
|
32
36
|
self.class.new(args_count, valid_params_count_range, sig)
|
33
37
|
end
|
data/lib/krpc/gen.rb
CHANGED
@@ -5,8 +5,6 @@ require 'colorize'
|
|
5
5
|
|
6
6
|
module KRPC
|
7
7
|
module Gen
|
8
|
-
AvailableToClassAndInstanceModuleName = "AvailableToClassAndInstance"
|
9
|
-
|
10
8
|
class << self
|
11
9
|
def service_gen_module(service_name)
|
12
10
|
const_get_or_create(service_name, Module.new)
|
@@ -28,52 +26,71 @@ module KRPC
|
|
28
26
|
values.map{|ev| [ev.name.underscore.to_sym, ev.value]}.to_h
|
29
27
|
end
|
30
28
|
end
|
31
|
-
|
29
|
+
|
32
30
|
def add_rpc_method(cls, method_name, service_name, proc, *options)
|
33
31
|
is_static = options.include? :static
|
34
32
|
prepend_self_to_args = options.include? :prepend_self_to_args
|
35
|
-
target_module = is_static ? cls.const_get_or_create(AvailableToClassAndInstanceModuleName, Module.new) : cls
|
36
33
|
param_names, param_types, param_default, return_type = parse_procedure(proc)
|
37
34
|
method_name = method_name.underscore
|
35
|
+
args = [cls, method_name, param_default, param_names, param_types, prepend_self_to_args, proc, return_type, service_name]
|
36
|
+
|
37
|
+
define_rpc_method(*args)
|
38
|
+
define_static_rpc_method(*args) if is_static
|
39
|
+
add_stream_constructing_proc(*args) unless options.include? :no_stream
|
40
|
+
Doc.add_docstring_info(is_static, cls, method_name, service_name, proc.name, param_names, param_types, param_default, return_type: return_type, xmldoc: proc.documentation)
|
41
|
+
end
|
38
42
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
def transform_exceptions(method_owner, method_name, prepend_self_to_args, &block)
|
44
|
+
begin
|
45
|
+
block.call
|
46
|
+
rescue ArgumentsNumberErrorSig => err
|
47
|
+
err = err.with_signature(Doc.docstring_for_method(method_owner, method_name, false))
|
48
|
+
if prepend_self_to_args then raise err.with_arguments_count_incremented_by(-1)
|
49
|
+
elsif method_owner.is_a?(Class) then raise err.with_arguments_count_incremented_by(1)
|
50
|
+
else raise err end
|
51
|
+
rescue ArgumentErrorSig => err
|
52
|
+
raise err.with_signature(Doc.docstring_for_method(method_owner, method_name, false))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private #----------------------------------
|
57
|
+
|
58
|
+
def define_static_rpc_method(cls, method_name, param_default, param_names, param_types, prepend_self_to_args, proc, return_type, service_name)
|
59
|
+
cls.instance_eval do
|
60
|
+
define_singleton_method method_name do |*args|
|
61
|
+
Gen.transform_exceptions(cls, method_name, prepend_self_to_args) do
|
62
|
+
raise ArgumentErrorSig.new("missing argument for parameter \"client\"") if args.count < 1
|
63
|
+
raise ArgumentErrorSig.new("argument for parameter \"client\" must be a #{KRPC::Client.name} -- got #{args.first.inspect} of type #{args.first.class}") unless args.first.is_a?(KRPC::Client)
|
64
|
+
client = args.shift
|
65
|
+
kwargs = args.extract_kwargs!
|
66
|
+
client.execute_rpc(service_name, proc.name, args, kwargs, param_names, param_types, param_default, return_type: return_type)
|
67
|
+
end
|
48
68
|
end
|
49
69
|
end
|
70
|
+
end
|
50
71
|
|
51
|
-
|
52
|
-
|
72
|
+
def define_rpc_method(cls, method_name, param_default, param_names, param_types, prepend_self_to_args, proc, return_type, service_name)
|
73
|
+
cls.instance_eval do
|
53
74
|
define_method method_name do |*args|
|
54
|
-
transform_exceptions
|
75
|
+
Gen.transform_exceptions(self, method_name, prepend_self_to_args) do
|
55
76
|
kwargs = args.extract_kwargs!
|
56
77
|
args = [self] + args if prepend_self_to_args
|
57
|
-
self.client.
|
78
|
+
self.client.execute_rpc(service_name, proc.name, args, kwargs, param_names, param_types, param_default, return_type: return_type)
|
58
79
|
end
|
59
80
|
end
|
60
81
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
82
|
+
end
|
83
|
+
|
84
|
+
def add_stream_constructing_proc(cls, method_name, param_default, param_names, param_types, prepend_self_to_args, proc, return_type, service_name)
|
85
|
+
cls.stream_constructors[method_name] = Proc.new do |this, *args, **kwargs|
|
86
|
+
Gen.transform_exceptions(this, method_name, prepend_self_to_args) do
|
87
|
+
req_args = prepend_self_to_args ? [this] + args : args
|
88
|
+
request = this.client.build_request(service_name, proc.name, req_args, kwargs, param_names, param_types, param_default)
|
89
|
+
this.client.streams_manager.create_stream(request, return_type, this.method(method_name), *args, **kwargs)
|
69
90
|
end
|
70
91
|
end
|
71
|
-
# Add docstring info
|
72
|
-
Doc.add_docstring_info(is_static, cls, method_name, service_name, proc.name, param_names, param_types, param_default, return_type: return_type, xmldoc: proc.documentation)
|
73
92
|
end
|
74
93
|
|
75
|
-
private #----------------------------------
|
76
|
-
|
77
94
|
def parse_procedure(proc)
|
78
95
|
param_names = proc.parameters.map{|p| p.name.underscore}
|
79
96
|
param_types = proc.parameters.map.with_index do |p,i|
|
@@ -82,7 +99,7 @@ module KRPC
|
|
82
99
|
param_default = proc.parameters.zip(param_types).map do |param, type|
|
83
100
|
if param.has_field?("default_argument")
|
84
101
|
Decoder.decode(param.default_argument, type, :clientless)
|
85
|
-
else
|
102
|
+
else :no_default_value
|
86
103
|
end
|
87
104
|
end
|
88
105
|
return_type = if proc.has_field?("return_type")
|
@@ -98,19 +115,9 @@ module KRPC
|
|
98
115
|
end
|
99
116
|
end
|
100
117
|
|
101
|
-
module AvailableToClassAndInstanceMethodsHandler
|
102
|
-
def add_methods_available_to_class_and_instance
|
103
|
-
if const_defined? AvailableToClassAndInstanceModuleName
|
104
|
-
extend const_get(AvailableToClassAndInstanceModuleName)
|
105
|
-
include const_get(AvailableToClassAndInstanceModuleName)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
118
|
##
|
111
119
|
# Base class for service-defined class types.
|
112
120
|
class ClassBase
|
113
|
-
extend AvailableToClassAndInstanceMethodsHandler
|
114
121
|
include Doc::SuffixMethods
|
115
122
|
include Streaming::StreamConstructors
|
116
123
|
|
data/lib/krpc/service.rb
CHANGED
@@ -55,12 +55,6 @@ module KRPC
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
# Add methods available to class and instance in service class & service' classes
|
59
|
-
service_class.add_methods_available_to_class_and_instance
|
60
|
-
mod = Gen.service_gen_module(service_name)
|
61
|
-
service_classes = mod.constants.map{|c| mod.const_get(c)}.select {|c| c.is_a? Class}
|
62
|
-
service_classes.each(&:add_methods_available_to_class_and_instance)
|
63
|
-
|
64
58
|
# Return service class
|
65
59
|
service_class
|
66
60
|
end
|
@@ -70,7 +64,6 @@ module KRPC
|
|
70
64
|
##
|
71
65
|
# Base class for service objects, created at runtime using information received from the server.
|
72
66
|
class ServiceBase
|
73
|
-
extend Gen::AvailableToClassAndInstanceMethodsHandler
|
74
67
|
include Doc::SuffixMethods
|
75
68
|
include Streaming::StreamConstructors
|
76
69
|
|
data/lib/krpc/types.rb
CHANGED
@@ -8,7 +8,7 @@ require 'set'
|
|
8
8
|
module KRPC
|
9
9
|
module Types
|
10
10
|
PROTOBUF_VALUE_TYPES = ["double", "float", "int32", "int64", "uint32", "uint64", "bool", "string", "bytes"]
|
11
|
-
RUBY_VALUE_TYPES = [Float, Integer, Boolean, String]
|
11
|
+
RUBY_VALUE_TYPES = [Float, Integer, Boolean, String, Array]
|
12
12
|
PROTOBUF_TO_RUBY_VALUE_TYPE = {
|
13
13
|
"double" => Float,
|
14
14
|
"float" => Float,
|
@@ -18,7 +18,7 @@ module KRPC
|
|
18
18
|
"uint64" => Integer,
|
19
19
|
"bool" => Boolean,
|
20
20
|
"string" => String,
|
21
|
-
"bytes" =>
|
21
|
+
"bytes" => Array
|
22
22
|
}
|
23
23
|
PROTOBUF_TO_MESSAGE_TYPE = ProtobufUtils.create_PB_to_PB_message_class_hash("KRPC")
|
24
24
|
|
@@ -37,6 +37,7 @@ module KRPC
|
|
37
37
|
elsif type_string.start_with? "Dictionary(" || type_string == "Dictionary" then DictionaryType.new(type_string)
|
38
38
|
elsif type_string.start_with? "Set(" || type_string == "Set" then SetType.new(type_string)
|
39
39
|
elsif type_string.start_with? "Tuple(" || type_string == "Tuple" then TupleType.new(type_string)
|
40
|
+
elsif type_string == "Test.TestEnum" then ValueType.new("int32")
|
40
41
|
else # A message type (eg. type_string = "KRPC.List" or "KRPC.Services")
|
41
42
|
raise(ValueError, "\"#{type_string}\" is not a valid type string") unless /^[A-Za-z0-9_\.]+$/ =~ type_string
|
42
43
|
if PROTOBUF_TO_MESSAGE_TYPE.has_key? type_string
|
@@ -97,11 +98,15 @@ module KRPC
|
|
97
98
|
raise(ValueError, "Failed to coerce value #{value.to_s} of type #{value.class} to type #{type}")
|
98
99
|
end
|
99
100
|
# Numeric types
|
100
|
-
if type.ruby_type == Float && value.
|
101
|
+
if type.ruby_type == Float && ( value.kind_of?(Float) || value.to_s.numeric? )
|
101
102
|
return value.to_f
|
102
|
-
elsif type.ruby_type == Integer && value.
|
103
|
+
elsif type.ruby_type == Integer && ( value.kind_of?(Integer) || value.to_s.integer? )
|
103
104
|
return value.to_i
|
104
105
|
end
|
106
|
+
# Convert value type to string
|
107
|
+
if type.is_a?(ValueType) && type.ruby_type == String
|
108
|
+
return value.to_s
|
109
|
+
end
|
105
110
|
raise(ValueError, "Failed to coerce value #{value.to_s} of type #{value.class} to type #{type}")
|
106
111
|
end
|
107
112
|
|