cocoa 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 04969b65f9381a64dff26285eadea02ee22a5707
4
- data.tar.gz: 328544cf27ee82e63349e8e1978a972867243a51
3
+ metadata.gz: 5f71aa43ea295a1886c05be665d147e1312fb09a
4
+ data.tar.gz: c33bb6813e008b446256ceec2592d4b1dd897bcc
5
5
  SHA512:
6
- metadata.gz: 9eb8aa0801e1737d082428259cef0108ece9d5d95263ba0ffe1646b6c5324910074ad208b70e90a8ce60b28c0217772e0b5c719ce7c75f2ac04bc27d83135769
7
- data.tar.gz: 2d904420d15c59dfbe60962a7eb17e46dd029382ab00540817adb6b66fc961aa456c1a3c8254fcb8892380857cacd0735d369a379c29fd9da20873ca8bad54ac
6
+ metadata.gz: e655407c657e9e8b7a7bfbdf65fa7cd1f27cdbbaa050183e283c03a6308041abb71f678914e974d7f2a5caf6b8454cf808ce8269bf99b16612b657c3f401fb32
7
+ data.tar.gz: 4eddefb01fbb2b0bef984084a2adcb0ff50c144614887cf3591a29211cad5ca3fbe4d53471661446b5da273e3edf48c6dded60b20b89f2a50468eb4f089d787b
data/Rakefile CHANGED
@@ -1,6 +1,10 @@
1
1
  # encoding: utf-8
2
2
 
3
- PROJECT_SPECS = FileList['spec/**/*_spec.rb']
3
+ PROJECT_SPECS = if RUBY_VERSION.split.first.to_i >= 2
4
+ FileList['spec/**/*_spec.rb'] + FileList['spec/**/*_spec_r2.rb']
5
+ else
6
+ FileList['spec/**/*_spec.rb']
7
+ end
4
8
 
5
9
  require 'jeweler'
6
10
  Jeweler::Tasks.new do |gem|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.5
1
+ 0.1.6
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: cocoa 0.1.5 ruby lib
5
+ # stub: cocoa 0.1.6 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "cocoa"
9
- s.version = "0.1.5"
9
+ s.version = "0.1.6"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Patrick Hanevold"]
14
- s.date = "2014-04-11"
14
+ s.date = "2014-04-13"
15
15
  s.description = "Ruby FFI bindings for the OSX Cocoa API"
16
16
  s.email = "patrick.hanevold@gmail.com"
17
17
  s.extra_rdoc_files = [
@@ -425,6 +425,7 @@ Gem::Specification.new do |s|
425
425
  "lib/cocoa/structs/NSRect.rb",
426
426
  "lib/cocoa/structs/NSSize.rb",
427
427
  "spec/cocoa/cocoa_spec.rb",
428
+ "spec/cocoa/cocoa_spec_r2.rb",
428
429
  "spec/spec_helper.rb",
429
430
  "tasks/bacon.rake",
430
431
  "tasks/generate.rake",
@@ -26,7 +26,13 @@ class Cocoa::NSObject
26
26
  end
27
27
 
28
28
  def self.native_name
29
- name.split('::').last
29
+ arr = name.split('::')
30
+ native = if arr.first == 'Cocoa'
31
+ arr.last
32
+ else
33
+ name.gsub(/::/,'__')
34
+ end
35
+ native
30
36
  end
31
37
 
32
38
  def self.alloc
@@ -123,24 +123,27 @@ module Cocoa
123
123
 
124
124
  def self.attach_method method,*_params
125
125
  return if method==:class
126
- @@method_specs ||= {}
127
- @@method_specs[method] = []
126
+ @method_specs ||= {}
127
+ @method_specs[method] = []
128
128
  [_params].flatten.each do |spec|
129
- @@method_specs[method] << ObjC::MethodDef.new(method,spec)
129
+ @method_specs[method] << ObjC::MethodDef.new(method,spec)
130
130
  end
131
131
  define_method method do |*args|
132
+ klass = self.class; klass = klass.superclass while !klass.instance_methods(false).include?(method)
133
+ spec = klass.instance_variable_get(:@method_specs)[method]
134
+
132
135
  matching = if args.size <= 1
133
- matching = @@method_specs[method].select do |m|
136
+ matching = spec.select do |m|
134
137
  m.types.size == args.size
135
138
  end
136
139
  else
137
140
  matching = if args.last.is_a? Hash
138
- @@method_specs[method].select do |m|
141
+ spec.select do |m|
139
142
  args.last.keys == m.names
140
143
  end
141
144
  else
142
145
  raise "hell" unless args.size == 1
143
- @@method_specs[method].select do |m|
146
+ spec.select do |m|
144
147
  m.types.size == 1
145
148
  end
146
149
  end
@@ -157,18 +160,26 @@ module Cocoa
157
160
  end
158
161
 
159
162
  def self.method_defs method
160
- return nil unless @@method_specs[method]
163
+ klass = self
164
+ method_specs = klass.instance_variable_get(:@method_specs)
165
+ while klass && (!method_specs || !method_specs[method])
166
+ klass = klass.superclass
167
+ method_specs = klass.instance_variable_get(:@method_specs)
168
+ end
169
+ return nil unless method_specs
170
+
171
+ spec = method_specs[method]
161
172
  params = instance_method(method).parameters
162
173
  keys = params.select{ |param| param.first == :key }.map{ |param| param.last }
163
174
  if params.size > 0 && params.last.first == :rest
164
- filtered = @@method_specs[method].select do |m|
175
+ filtered = spec.select do |m|
165
176
  ((m.types.size == 0 && keys.size == 0) || (m.types.size > keys.size)) &&
166
177
  (m.names[0,keys.size-1] || []) == keys
167
178
  end
168
179
  return nil if filtered.size == 0
169
180
  filtered
170
181
  else
171
- filtered = @@method_specs[method].select do |m|
182
+ filtered = spec.select do |m|
172
183
  ((m.types.size == 0 && keys.size == 0) || (m.types.size == keys.size+1)) &&
173
184
  m.names == keys
174
185
  end
@@ -181,18 +192,42 @@ module Cocoa
181
192
  def self.method_added(name)
182
193
  return if name == :== # TODO: define as equals or something?
183
194
  return if name.to_s[-1] == '='
195
+ return if caller[1].split('`').last[0..-2] == 'method_added' # self
184
196
  return if caller.first.split('`').last[0..-2] == 'define_method' # MRI
185
197
  return if caller.first.split('`').last[0..-2] == 'attach_method' # Rubinius
186
198
 
199
+ # define an alias for keyword argument methods such that:
200
+ # class Foo
201
+ # def bar whatever, alpha: nil
202
+ # puts "alpha is: #{alpha}"
203
+ # end
204
+ # def bar whatever, omega: nil
205
+ # puts "omega is: #{omega}"
206
+ # end
207
+ # end
208
+ # Foo.new.bar "hello", omega: "is omega"
209
+ # Foo.new.bar "hello", alpha: "is alpha"
210
+ #=>
211
+ # omega is: is omega
212
+ # alpha is: is alpha
213
+ keys = instance_method(name).parameters.select{ |param| param.first == :key }.map{ |param| param.last }
214
+ ruby_name = name
215
+ if keys.size > 0
216
+ ruby_name = "_#{name}_with_#{keys.join('_and_')}".to_sym
217
+ alias_method ruby_name, name
218
+ end
219
+
220
+
187
221
  defs = method_defs name
188
222
  defs ||= ObjC::MethodDef.new(name, :names => [], :types => ['@'], :retval => 'v') # TODO: generate from method arguments!
189
223
 
190
224
  [defs].flatten.each do |m|
191
225
  @callbacks ||= []
192
226
  @callbacks << Proc.new do |this,cmd,*args|
227
+ m.ruby_name = ruby_name
193
228
  begin
194
229
  instance = Cocoa.instances[this.address]
195
- params = instance_method(name).parameters
230
+ params = instance_method(ruby_name).parameters
196
231
  m.callback(instance,params,args)
197
232
  rescue => e
198
233
  puts e.message
@@ -203,10 +238,20 @@ module Cocoa
203
238
  callback_name = "#{self.name.gsub('::','__')}_#{m.selector.gsub(/:/,'_')}".to_sym
204
239
  add_method = "add_#{callback_name}".to_sym
205
240
 
241
+ native_name = begin
242
+ arr = self.name.split('::')
243
+ native = if arr.first == 'Cocoa'
244
+ arr.last
245
+ else
246
+ self.name.gsub(/::/,'__')
247
+ end
248
+ native
249
+ end
250
+
206
251
  ObjC.callback callback_name, [:pointer, :pointer]+m.ffi_types, m.ffi_return_type
207
252
  ObjC.attach_function add_method, :class_addMethod, [:pointer,:pointer,callback_name,:string], :void
208
253
 
209
- ObjC.send(add_method,ObjC.objc_getClass(self.name.split('::').last),ObjC.sel_registerName(m.selector),@callbacks.last,m.objc_types)
254
+ ObjC.send(add_method,ObjC.objc_getClass(native_name),ObjC.sel_registerName(m.selector),@callbacks.last,m.objc_types)
210
255
  end
211
256
  end
212
257
  end
@@ -75,19 +75,23 @@ module ObjC
75
75
  instance = begin
76
76
  Cocoa::const_get(klass_name).new(true)
77
77
  rescue
78
- klass_name = if klass_name =~ /^__NSCF/
79
- "NS#{klass_name[6..-1]}"
80
- elsif klass_name[0]=='_'
81
- if superklass = Cocoa::const_get(NSString_to_String(Cocoa::NSStringFromClass(ObjC.msgSend_pointer(ret,"superclass"))))
82
- superklass.name.split('::').last
78
+ begin
79
+ Object.const_get(klass_name.gsub(/__/,'::')).new(true)
80
+ rescue
81
+ klass_name = if klass_name =~ /^__NSCF/
82
+ "NS#{klass_name[6..-1]}"
83
+ elsif klass_name[0]=='_'
84
+ if superklass = Cocoa::const_get(NSString_to_String(Cocoa::NSStringFromClass(ObjC.msgSend_pointer(ret,"superclass"))))
85
+ superklass.name.split('::').last
86
+ else
87
+ "FIX_#{klass_name}"
88
+ end
83
89
  else
84
- "FIX_#{klass_name}"
90
+ klass_name
85
91
  end
86
- else
87
- klass_name
92
+ klass = smart_constantize(ret,klass_name)
93
+ klass.new(true)
88
94
  end
89
- klass = smart_constantize(ret,klass_name)
90
- klass.new(true)
91
95
  end
92
96
  instance.object = ret
93
97
  instance
@@ -119,7 +123,7 @@ module ObjC
119
123
  case type
120
124
  when nil
121
125
  default
122
- when '@', 'v', 'q', 'Q', '^v'
126
+ when '@', 'v', 'q', 'Q', '^v', 'B'
123
127
  type
124
128
  when /^{([^=]*)=.*}$/
125
129
  type
@@ -1,6 +1,6 @@
1
1
  module ObjC
2
2
  class MethodDef
3
- attr_accessor :name,:names,:types,:return_type
3
+ attr_accessor :name,:names,:types,:return_type,:ruby_name
4
4
 
5
5
  TYPES = {
6
6
  'c' => :char,
@@ -31,6 +31,7 @@ module ObjC
31
31
 
32
32
  def initialize name,options
33
33
  @name = name.to_sym
34
+ @ruby_name = name.to_sym
34
35
  @names = options[:names].map(&:to_sym)
35
36
  @types = options[:types]
36
37
  @return_type = options[:retval]
@@ -280,12 +281,12 @@ module ObjC
280
281
 
281
282
  ret = if params.size > 0 && params.last.first == :rest
282
283
  args = args.map{ |arg| Cocoa::instance_for(arg) }
283
- instance.send(name, args.first, Hash[*names.zip(args[1..-1]).flatten])
284
+ instance.send(ruby_name, args.first, Hash[*names.zip(args[1..-1]).flatten])
284
285
  elsif keys.size > 0
285
286
  args = args.map{ |arg| Cocoa::instance_for(arg) }
286
- instance.send(name, args.first, Hash[*keys.zip(args[1..-1]).flatten])
287
+ instance.send(ruby_name, args.first, Hash[*keys.zip(args[1..-1]).flatten])
287
288
  else
288
- instance.send(name, *args.map{ |arg| Cocoa::instance_for(arg) })
289
+ instance.send(ruby_name, *args.map{ |arg| Cocoa::instance_for(arg) })
289
290
  end
290
291
  ffi_return_value(ret)
291
292
  end
@@ -17,6 +17,17 @@ describe 'Cocoa' do
17
17
  Derived.superclass.name.should == 'Cocoa::NSObject'
18
18
  end
19
19
 
20
+ it 'should provide native names' do
21
+ class Derived < Cocoa::NSObject
22
+ end
23
+ module Scoped; end
24
+ class Scoped::Derived < Cocoa::NSObject
25
+ end
26
+ Cocoa::NSObject.native_name.should == 'NSObject'
27
+ Derived.native_name.should == 'Derived'
28
+ Scoped::Derived.native_name.should == 'Scoped__Derived'
29
+ end
30
+
20
31
  it 'should provide correct return types for class methods' do
21
32
  Cocoa::NSMutableArray.array.class.name.should == 'Cocoa::NSMutableArray'
22
33
  end
@@ -115,6 +126,7 @@ describe 'Cocoa' do
115
126
  # fake ruby 2
116
127
  unbound_method = mock('UnboundMethod')
117
128
  Cocoa::NSObject.expects(:instance_method).with(:tableView).at_least_once.returns(unbound_method)
129
+ Cocoa::NSObject.expects(:instance_method).with(:_tableView_with_objectValueForTableColumn_and_row).at_least_once.returns(unbound_method)
118
130
  unbound_method.expects(:parameters).at_least_once.returns([[:req, :table_view], [:key, :objectValueForTableColumn], [:key, :row]])
119
131
  class Derived < Cocoa::NSObject
120
132
  #def tableView(table_view, objectValueForTableColumn: column, row: i); end
@@ -122,7 +134,7 @@ describe 'Cocoa' do
122
134
  end
123
135
 
124
136
  derived = Derived.new
125
- derived.expects(:tableView).with(
137
+ derived.expects(:_tableView_with_objectValueForTableColumn_and_row).with(
126
138
  Cocoa::NSString.stringWithString("arg1"),
127
139
  objectValueForTableColumn: Cocoa::NSString.stringWithString("arg2"),
128
140
  row: 123
@@ -137,6 +149,7 @@ describe 'Cocoa' do
137
149
  # fake ruby 2
138
150
  unbound_method = mock('UnboundMethod')
139
151
  Cocoa::NSObject.expects(:instance_method).with(:tableView).at_least_once.returns(unbound_method)
152
+ Cocoa::NSObject.expects(:instance_method).with(:_tableView_with_objectValueForTableColumn_and_row).at_least_once.returns(unbound_method)
140
153
  unbound_method.expects(:parameters).at_least_once.returns([[:req, :table_view], [:key, :objectValueForTableColumn], [:key, :row]])
141
154
  class Derived < Cocoa::NSObject
142
155
  #def tableView(table_view, objectValueForTableColumn: column, row: i); end
@@ -157,7 +170,7 @@ describe 'Cocoa' do
157
170
  end
158
171
 
159
172
  derived = Derived.new
160
- derived.expects(:tableView).with(
173
+ derived.expects(:_tableView_with_objectValueForTableColumn_and_row).with(
161
174
  Cocoa::NSString.stringWithString("arg1"),
162
175
  objectValueForTableColumn: Cocoa::NSString.stringWithString("arg2"),
163
176
  row: 123
@@ -0,0 +1,18 @@
1
+ require_relative '../spec_helper'
2
+ require 'cocoa'
3
+
4
+ describe 'Cocoa' do
5
+ # context 'callbacks' do
6
+ it 'should be able to call overridden methods with keword arguments and return a value' do
7
+ class Derived < Cocoa::NSObject
8
+ def tableView(table_view, objectValueForTableColumn: column, row: i)
9
+ "returned value"
10
+ end
11
+ end
12
+
13
+ derived = Derived.new
14
+ ret = derived.tableView("arg1", objectValueForTableColumn: "arg2", row: 123)
15
+ ret.to_s.should == "returned value"
16
+ end
17
+ # end
18
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocoa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick Hanevold
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-11 00:00:00.000000000 Z
11
+ date: 2014-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -550,6 +550,7 @@ files:
550
550
  - lib/cocoa/structs/NSRect.rb
551
551
  - lib/cocoa/structs/NSSize.rb
552
552
  - spec/cocoa/cocoa_spec.rb
553
+ - spec/cocoa/cocoa_spec_r2.rb
553
554
  - spec/spec_helper.rb
554
555
  - tasks/bacon.rake
555
556
  - tasks/generate.rake