cocoa 0.1.1 → 0.1.2

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/README.md CHANGED
@@ -2,3 +2,23 @@ cocoa
2
2
  =====
3
3
 
4
4
  Ruby FFI bindings for the OSX Cocoa API
5
+
6
+ ### Installation
7
+
8
+ ```
9
+ gem install cocoa
10
+ ```
11
+
12
+ ### Usage
13
+
14
+ ```ruby
15
+ require 'cocoa'
16
+ array = Cocoa::NSMutableArray.array
17
+ array.addObject "head"
18
+ array.addObject "tail"
19
+ array.description
20
+ => (
21
+ head,
22
+ tail
23
+ )
24
+ ```
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- PROJECT_SPECS = FileList['spec/**/*.rb']
3
+ PROJECT_SPECS = FileList['spec/**/*_spec.rb']
4
4
 
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "cocoa"
8
- s.version = "0.1.1"
8
+ s.version = "0.1.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Patrick Hanevold"]
12
- s.date = "2014-03-25"
12
+ s.date = "2014-03-26"
13
13
  s.description = "Ruby FFI bindings for the OSX Cocoa API"
14
14
  s.email = "patrick.hanevold@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -411,9 +411,14 @@ Gem::Specification.new do |s|
411
411
  "lib/cocoa/bindings/NSXPCConnection.rb",
412
412
  "lib/cocoa/bindings/NSXPCInterface.rb",
413
413
  "lib/cocoa/bindings/NSXPCListener.rb",
414
+ "lib/cocoa/extensions.rb",
414
415
  "lib/cocoa/helpers.rb",
416
+ "lib/cocoa/objc.rb",
417
+ "lib/cocoa/structs/NSPoint.rb",
418
+ "lib/cocoa/structs/NSRect.rb",
419
+ "lib/cocoa/structs/NSSize.rb",
415
420
  "spec/cocoa/cocoa_spec.rb",
416
- "spec/cocoa/spec_helper.rb",
421
+ "spec/spec_helper.rb",
417
422
  "tasks/bacon.rake",
418
423
  "tasks/generate.rake",
419
424
  "tasks/setup.rake"
@@ -2,21 +2,7 @@
2
2
  require 'active_support'
3
3
 
4
4
  require 'cocoa/helpers'
5
- Dir[File.dirname(__FILE__) + '/cocoa/bindings/*'].each do |name|
6
- require "cocoa/bindings/#{name.split('/').last}"
7
- end
8
-
9
- class String
10
- def method_missing meth,*args
11
- if Cocoa::NSString.method_defined?(meth)
12
- str = Cocoa::NSString.new(true)
13
- str.object = Cocoa::String_to_NSString(self)
14
- str.send(meth,*args)
15
- else
16
- super
17
- end
18
- end
19
- end
5
+ require "cocoa/bindings/NSString"
20
6
 
21
7
  module Cocoa
22
8
  extend FFI::Library
@@ -28,6 +14,15 @@ module Cocoa
28
14
  attach_function :NSApplicationLoad, [], :bool
29
15
  NSApplicationLoad()
30
16
 
17
+ def const_missing name
18
+ if File.exists?(File.dirname(__FILE__) + "/cocoa/bindings/#{name}.rb")
19
+ require "cocoa/bindings/#{name}"
20
+ "Cocoa::#{name}".constantize
21
+ else
22
+ super
23
+ end
24
+ end
25
+
31
26
  CA_WARN_DEPRECATED = 1
32
27
  CFByteOrderBigEndian = 2
33
28
  CFByteOrderLittleEndian = 1
@@ -6720,3 +6715,4 @@ module Cocoa
6720
6715
  attach_method :NSZoneRealloc, :args=>3, :names=>[], :types=>["^{_NSZone=}", "^v", "Q"], :retval=>"^v"
6721
6716
  attach_method :NXReadNSObjectFromCoder, :args=>1, :names=>[], :types=>["@"], :retval=>"@"
6722
6717
  end
6718
+ require "cocoa/extensions"
@@ -0,0 +1,23 @@
1
+ class Cocoa::NSObject
2
+ def self.const_missing name
3
+ Cocoa.const_get name
4
+ end
5
+ end
6
+
7
+ class Cocoa::NSString < Cocoa::NSObject
8
+ def to_s
9
+ Cocoa::NSString_to_String(object)
10
+ end
11
+ end
12
+
13
+ class String
14
+ def method_missing meth,*args
15
+ if Cocoa::NSString.method_defined?(meth)
16
+ str = Cocoa::NSString.new(true)
17
+ str.object = Cocoa::String_to_NSString(self)
18
+ str.send(meth,*args)
19
+ else
20
+ super
21
+ end
22
+ end
23
+ end
@@ -1,94 +1,13 @@
1
1
  require 'active_support/inflector'
2
2
  require 'ffi'
3
-
4
- module ObjC
5
- extend FFI::Library
6
-
7
- # Load the 'libobjc' library.
8
- ffi_lib 'objc'
9
-
10
- # Bind the 'sel_registerName' function, which accepts a String and
11
- # returns an equivalent Objective-C selector (i.e. message name).
12
- attach_function :sel_registerName, [:string], :pointer
13
-
14
- # Bind the 'objc_msgSend' function, which sends a message to an
15
- # Objective-C object. It accepts a pointer to the object being sent
16
- # the message, a pointer to a selector, and a varargs array of
17
- # arguments to be sent with the message. It returns a pointer to the
18
- # result of sending the message.
19
- attach_function :objc_msgSend, [:pointer, :pointer, :varargs], :pointer
20
- #attach_function :objc_msgSend_stret, [:pointer, :pointer, :varargs], CGRect.by_value
21
-
22
- # A convenience method using objc_msgSend and sel_registerName to easily
23
- # send Objective-C messages from Ruby.
24
- def self.msgSend( id, selector, *args )
25
- selector = sel_registerName(selector) if selector.is_a? String
26
- objc_msgSend( id, selector, *args )
27
- end
28
-
29
- def self.msgSend_stret( return_type, id, selector, *args )
30
- selector = sel_registerName(selector) if selector.is_a? String
31
- method = "objc_msgSend_stret_for_#{return_type.name.underscore}".to_sym
32
- unless respond_to? method
33
- attach_function method, :objc_msgSend_stret, [:pointer, :pointer, :varargs], return_type.by_value
34
- end
35
- send(method, id, selector, *args )
36
- end
37
-
38
- # Bind the 'objc_getClass' function, which accepts the name of an
39
- # Objective-C class, and returns a pointer to that class.
40
- attach_function :objc_getClass, [:string], :pointer
41
-
42
- attach_function :objc_allocateClassPair, [:pointer, :string, :int], :pointer
43
- attach_function :objc_registerClassPair, [:pointer], :void
44
- end
45
-
46
- class CGPoint < FFI::Struct
47
- def initialize *args
48
- options = args.first
49
- if options.is_a? Hash
50
- self[:x] = options[:x]
51
- self[:y] = options[:y]
52
- else
53
- super *args
54
- end
55
- end
56
- layout :x, :double,
57
- :y, :double
58
- end
59
-
60
- class CGSize < FFI::Struct
61
- def initialize *args
62
- options = args.first
63
- if options.is_a? Hash
64
- self[:width] = options[:width]
65
- self[:height] = options[:height]
66
- else
67
- super *args
68
- end
69
- end
70
- layout :width, :double,
71
- :height, :double
72
- end
73
-
74
- class CGRect < FFI::Struct
75
- def initialize *args
76
- options = args.first
77
- if options.is_a? Hash
78
- self[:origin][:x] = options[:x]
79
- self[:origin][:y] = options[:y]
80
- self[:size][:width] = options[:width]
81
- self[:size][:height] = options[:height]
82
- else
83
- super *args
84
- end
85
- end
86
- layout :origin, CGPoint,
87
- :size, CGSize
88
- end
3
+ require 'cocoa/objc'
89
4
 
90
5
  module Cocoa; end
91
6
 
7
+ require 'cocoa/structs/NSPoint'
8
+ require 'cocoa/structs/NSSize'
9
+ require 'cocoa/structs/NSRect'
10
+
92
11
  class Cocoa::CFRange < FFI::Struct
93
12
  def initialize *args
94
13
  options = args.first
@@ -105,10 +24,6 @@ class Cocoa::CFRange < FFI::Struct
105
24
  layout :location, :long_long, :length, :long_long
106
25
  end
107
26
 
108
- NSRect = CGRect
109
- NSSize = CGSize
110
- NSPoint = CGPoint
111
-
112
27
  module Cocoa
113
28
 
114
29
  def instances
@@ -138,16 +53,12 @@ module Cocoa
138
53
  CFRange.new(location: loc, length: len)
139
54
  end
140
55
 
141
- # Accepts a Ruby String and creates an equivalent NSString instance
142
- # and returns a pointer to it.
143
56
  def self.String_to_NSString( string )
144
57
  nsstring_class = ObjC.objc_getClass("NSString")
145
58
  ObjC.msgSend( nsstring_class, "stringWithUTF8String:",
146
59
  :string, string )
147
60
  end
148
61
 
149
- # Accepts a pointer to an NSString object, and returns the string
150
- # contents as a Ruby String.
151
62
  def self.NSString_to_String( nsstring_pointer )
152
63
  c_string_pointer = ObjC.msgSend( nsstring_pointer, "UTF8String" )
153
64
  if c_string_pointer.null?
@@ -196,7 +107,7 @@ module Cocoa
196
107
 
197
108
  def self.attach_singular_method method,*params
198
109
  params = params.extract_options!
199
- params.freeze
110
+ params.freeze
200
111
  if params[:args] == 0
201
112
  define_singleton_method method do
202
113
  instance = new(true)
@@ -300,7 +211,13 @@ params.freeze
300
211
  instance = begin
301
212
  ("Cocoa::"+klass_name).constantize.new(true)
302
213
  rescue
303
- klass_name = "FIX_#{klass_name}" if klass_name[0]=='_'
214
+ klass_name = if klass_name =~ /^__NSCF/
215
+ "NS#{klass_name[6..-1]}"
216
+ elsif klass_name[0]=='_'
217
+ "FIX_#{klass_name}"
218
+ else
219
+ klass_name
220
+ end
304
221
  klass = begin
305
222
  Cocoa.const_get(klass_name)
306
223
  rescue => e
@@ -354,7 +271,7 @@ params.freeze
354
271
  end
355
272
 
356
273
  params = params.extract_options!
357
- params.freeze
274
+ params.freeze
358
275
  if params[:args] == 0
359
276
  begin
360
277
  attach_function "call_#{method}".to_sym, method, [], apple_type_to_ffi(params[:retval])
@@ -451,7 +368,6 @@ params.freeze
451
368
 
452
369
  def self.inherited(parent)
453
370
  if parent.name
454
- puts "INHERITED #{parent.name}" if parent.name =~ /Timer/
455
371
  klass = ObjC.objc_allocateClassPair(ObjC.objc_getClass(name.split('::').last),parent.name,0)
456
372
  ObjC.objc_registerClassPair(klass)
457
373
  end
@@ -553,7 +469,7 @@ puts "INHERITED #{parent.name}" if parent.name =~ /Timer/
553
469
  end
554
470
 
555
471
  def self.attach_singular_method method,*__params
556
- __params.freeze
472
+ __params.freeze
557
473
  return if method==:class
558
474
  return if method==:new
559
475
  if __params.first.is_a?(Hash) && __params.first[:args] == 0
@@ -564,11 +480,8 @@ __params.freeze
564
480
  end
565
481
  else
566
482
  _params = [__params.dup].flatten
567
- _params.freeze
483
+ _params.freeze
568
484
  define_singleton_method method do |*args|
569
- # puts method
570
- # puts args.inspect
571
- # puts _params.inspect
572
485
  par = if _params.size == 1 && _params.first[:variadic]
573
486
  _params
574
487
  else
@@ -613,7 +526,7 @@ _params.freeze
613
526
  @@method_specs ||= {}
614
527
  if _params.first.is_a? Array
615
528
  _params = [_params].flatten
616
- _params.freeze
529
+ _params.freeze
617
530
  define_method method do |*args|
618
531
  if args.last.is_a? Hash
619
532
  params = _params.select{ |par| par[:args] == args.last.size+1 && par[:names].map(&:to_sym).sort == args.last.keys.sort }
@@ -641,7 +554,7 @@ _params.freeze
641
554
  params = _params.extract_options!
642
555
  @@method_specs[method] = params
643
556
  if params[:args] == 0
644
- params.freeze
557
+ params.freeze
645
558
  define_method method do
646
559
  case params[:retval]
647
560
  when '@'
@@ -669,7 +582,6 @@ params.freeze
669
582
  ("Cocoa::"+klass_name).constantize.new(true)
670
583
  rescue
671
584
  klass_name = "FIX_#{klass_name}" if klass_name[0]=='_'
672
- # puts "TRYING #{klass_name}"
673
585
  klass = begin
674
586
  Cocoa.const_get(klass_name)
675
587
  rescue => e
@@ -720,7 +632,7 @@ params.freeze
720
632
  when '@'
721
633
  :pointer
722
634
  when /^{([^=]*)=.*}$/
723
- $1.constantize.by_value
635
+ Cocoa::const_get($1).by_value
724
636
  else
725
637
  raise type
726
638
  end
@@ -763,8 +675,8 @@ params.freeze
763
675
  def self.method_added(name)
764
676
  return if caller.first.split('`').last[0..-2] == 'define_method' # MRI
765
677
  return if caller.first.split('`').last[0..-2] == 'attach_method' # Rubinius
766
- method_definition = "#{self.name.underscore}_#{name.to_s.underscore}".to_sym
767
- add_method = "add_#{self.name.underscore}_#{name.to_s.underscore}".to_sym
678
+ method_definition = "#{self.name.gsub('::','__')}_#{name}".to_sym
679
+ add_method = "add_#{method_definition}".to_sym
768
680
 
769
681
  @method_callers ||= {}
770
682
  raise "allready added" if @method_callers[method_definition]
@@ -0,0 +1,25 @@
1
+ module ObjC
2
+ extend FFI::Library
3
+
4
+ ffi_lib 'objc'
5
+
6
+ attach_function :sel_registerName, [:string], :pointer
7
+ attach_function :objc_msgSend, [:pointer, :pointer, :varargs], :pointer
8
+ attach_function :objc_getClass, [:string], :pointer
9
+ attach_function :objc_allocateClassPair, [:pointer, :string, :int], :pointer
10
+ attach_function :objc_registerClassPair, [:pointer], :void
11
+
12
+ def self.msgSend( id, selector, *args )
13
+ selector = sel_registerName(selector) if selector.is_a? String
14
+ objc_msgSend( id, selector, *args )
15
+ end
16
+
17
+ def self.msgSend_stret( return_type, id, selector, *args )
18
+ selector = sel_registerName(selector) if selector.is_a? String
19
+ method = "objc_msgSend_stret_for_#{return_type.name.underscore}".to_sym
20
+ unless respond_to? method
21
+ attach_function method, :objc_msgSend_stret, [:pointer, :pointer, :varargs], return_type.by_value
22
+ end
23
+ send(method, id, selector, *args )
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ module Cocoa
2
+ class CGPoint < FFI::Struct
3
+ def initialize *args
4
+ options = args.first
5
+ if options.is_a? Hash
6
+ self[:x] = options[:x]
7
+ self[:y] = options[:y]
8
+ else
9
+ super *args
10
+ end
11
+ end
12
+ layout :x, :double,
13
+ :y, :double
14
+ end
15
+
16
+ NSPoint = CGPoint
17
+ end
@@ -0,0 +1,19 @@
1
+ module Cocoa
2
+ class CGRect < FFI::Struct
3
+ def initialize *args
4
+ options = args.first
5
+ if options.is_a? Hash
6
+ self[:origin][:x] = options[:x]
7
+ self[:origin][:y] = options[:y]
8
+ self[:size][:width] = options[:width]
9
+ self[:size][:height] = options[:height]
10
+ else
11
+ super *args
12
+ end
13
+ end
14
+ layout :origin, CGPoint,
15
+ :size, CGSize
16
+ end
17
+
18
+ NSRect = Cocoa::CGRect
19
+ end
@@ -0,0 +1,17 @@
1
+ module Cocoa
2
+ class CGSize < FFI::Struct
3
+ def initialize *args
4
+ options = args.first
5
+ if options.is_a? Hash
6
+ self[:width] = options[:width]
7
+ self[:height] = options[:height]
8
+ else
9
+ super *args
10
+ end
11
+ end
12
+ layout :width, :double,
13
+ :height, :double
14
+ end
15
+
16
+ NSSize = CGSize
17
+ end
@@ -1,17 +1,32 @@
1
- require_relative 'spec_helper'
1
+ require_relative '../spec_helper'
2
2
  require 'cocoa'
3
3
 
4
4
  describe 'Cocoa' do
5
+ it 'should lazy load cocoa classes in cocoa derived classes' do
6
+ class Derived < Cocoa::NSObject
7
+ def get_lazy
8
+ NSMenu.new
9
+ end
10
+ end
11
+ Derived.new.get_lazy.class.name.should == 'Cocoa::NSMenu'
12
+ end
13
+ it 'should provide correct return types for class methods' do
14
+ Cocoa::NSMutableArray.array.class.name.should == 'Cocoa::NSMutableArray'
15
+ end
16
+ it 'should provide correct return types for instance methods' do
17
+ array = Cocoa::NSMutableArray.array
18
+ Cocoa::NSMutableArray.array.description.class.name.should == 'Cocoa::NSString'
19
+ end
5
20
  it 'should convert NSString to ruby strings' do
6
21
  array = Cocoa::NSMutableArray.array
7
22
  array.addObject "head"
8
23
  array.addObject "tail"
9
24
  Cocoa::NSString_to_String(array.description.object).should == "(\n head,\n tail\n)"
10
25
  end
11
- it 'should return strings' do
26
+ it 'should return stringifyable strings' do
12
27
  array = Cocoa::NSMutableArray.array
13
28
  array.addObject "head"
14
29
  array.addObject "tail"
15
- array.description.should == "(\n head,\n tail\n)"
30
+ array.description.to_s.should == "(\n head,\n tail\n)"
16
31
  end
17
32
  end
@@ -1,4 +1,4 @@
1
- $: << File.expand_path(File.join(File.dirname(__FILE__), '/../../lib'))
1
+ $: << File.expand_path(File.join(File.dirname(__FILE__), '/../lib'))
2
2
 
3
3
  # require 'simplecov'
4
4
 
@@ -120,21 +120,7 @@ task :generate do
120
120
  require 'active_support'
121
121
 
122
122
  require 'cocoa/helpers'
123
- Dir['lib/cocoa/bindings/*'].each do |name|
124
- require "cocoa/bindings/\#{name.split('/').last}"
125
- end
126
-
127
- class String
128
- def method_missing meth,*args
129
- if Cocoa::NSString.method_defined?(meth)
130
- str = Cocoa::NSString.new(true)
131
- str.object = Cocoa::String_to_NSString(self)
132
- str.send(meth,*args)
133
- else
134
- super
135
- end
136
- end
137
- end
123
+ require "cocoa/bindings/NSString"
138
124
 
139
125
  module Cocoa
140
126
  extend FFI::Library
@@ -146,6 +132,15 @@ module Cocoa
146
132
  attach_function :NSApplicationLoad, [], :bool
147
133
  NSApplicationLoad()
148
134
 
135
+ def const_missing name
136
+ if File.exists?(File.dirname(__FILE__) + "/cocoa/bindings/\#{name}.rb")
137
+ require "cocoa/bindings/\#{name}"
138
+ "Cocoa::\#{name}".constantize
139
+ else
140
+ super
141
+ end
142
+ end
143
+
149
144
  }
150
145
  enums.each do |name,value|
151
146
  mod.puts " #{name} = #{value}"
@@ -184,5 +179,6 @@ module Cocoa
184
179
  end
185
180
  end
186
181
  mod.puts "end"
182
+ mod.puts 'require "cocoa/extensions"'
187
183
  mod.close
188
184
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocoa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-25 00:00:00.000000000 Z
12
+ date: 2014-03-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -525,9 +525,14 @@ files:
525
525
  - lib/cocoa/bindings/NSXPCConnection.rb
526
526
  - lib/cocoa/bindings/NSXPCInterface.rb
527
527
  - lib/cocoa/bindings/NSXPCListener.rb
528
+ - lib/cocoa/extensions.rb
528
529
  - lib/cocoa/helpers.rb
530
+ - lib/cocoa/objc.rb
531
+ - lib/cocoa/structs/NSPoint.rb
532
+ - lib/cocoa/structs/NSRect.rb
533
+ - lib/cocoa/structs/NSSize.rb
529
534
  - spec/cocoa/cocoa_spec.rb
530
- - spec/cocoa/spec_helper.rb
535
+ - spec/spec_helper.rb
531
536
  - tasks/bacon.rake
532
537
  - tasks/generate.rake
533
538
  - tasks/setup.rake