cocoa 0.1.2 → 0.1.3
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 +12 -8
- data/VERSION +1 -1
- data/cocoa.gemspec +5 -2
- data/examples/hello_world.rb +10 -0
- data/lib/cocoa/bindings/Cocoa.rb +6693 -0
- data/lib/cocoa/extensions.rb +58 -8
- data/lib/cocoa/helpers.rb +23 -429
- data/lib/cocoa/objc.rb +262 -0
- data/lib/cocoa/structs/NSPoint.rb +6 -0
- data/lib/cocoa/structs/NSRange.rb +23 -0
- data/lib/cocoa/structs/NSRect.rb +6 -0
- data/lib/cocoa/structs/NSSize.rb +4 -0
- data/lib/cocoa.rb +2 -6694
- data/spec/cocoa/cocoa_spec.rb +1 -1
- data/tasks/generate.rake +2 -28
- metadata +5 -2
data/lib/cocoa/objc.rb
CHANGED
@@ -22,4 +22,266 @@ module ObjC
|
|
22
22
|
end
|
23
23
|
send(method, id, selector, *args )
|
24
24
|
end
|
25
|
+
|
26
|
+
def self.String_to_NSString( string )
|
27
|
+
nsstring_class = objc_getClass("NSString")
|
28
|
+
msgSend(nsstring_class, "stringWithUTF8String:", :string, string )
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.NSString_to_String( nsstring_pointer )
|
32
|
+
c_string = msgSend( nsstring_pointer, "UTF8String")
|
33
|
+
if c_string.null?
|
34
|
+
return "(NULL)"
|
35
|
+
else
|
36
|
+
return c_string.read_string()
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.object_to_instance ret
|
41
|
+
klass_name = NSString_to_String(Cocoa::NSStringFromClass(ObjC.msgSend(ret,"class")))
|
42
|
+
return self if klass_name == '(NULL)'
|
43
|
+
instance = begin
|
44
|
+
("Cocoa::"+klass_name).constantize.new(true)
|
45
|
+
rescue
|
46
|
+
klass_name = if klass_name =~ /^__NSCF/
|
47
|
+
"NS#{klass_name[6..-1]}"
|
48
|
+
elsif klass_name[0]=='_'
|
49
|
+
"FIX_#{klass_name}"
|
50
|
+
else
|
51
|
+
klass_name
|
52
|
+
end
|
53
|
+
klass = begin
|
54
|
+
Cocoa.const_get(klass_name)
|
55
|
+
rescue => e
|
56
|
+
superclass_name = NSString_to_String(Cocoa::NSStringFromClass(ObjC.msgSend(ret,'superclass')))
|
57
|
+
superclass = "Cocoa::#{superclass_name}".constantize
|
58
|
+
proxy = Class.new(superclass)
|
59
|
+
Cocoa.const_set(klass_name, proxy)
|
60
|
+
klass = ("Cocoa::"+klass_name).constantize
|
61
|
+
superclass.inherited(klass)
|
62
|
+
klass
|
63
|
+
end
|
64
|
+
klass.new(true)
|
65
|
+
end
|
66
|
+
instance.object = ret
|
67
|
+
instance
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.translate_retval method,ret,type
|
71
|
+
case type
|
72
|
+
when '@'
|
73
|
+
return nil if ret.address == 0
|
74
|
+
return ret if method == :NSStringFromClass
|
75
|
+
object_to_instance ret
|
76
|
+
when '#'
|
77
|
+
ret
|
78
|
+
when /^{([^=]*)=.*}$/
|
79
|
+
ret
|
80
|
+
when /^\^{[^=]*=.*}$/
|
81
|
+
return nil if ret.address == 0
|
82
|
+
object_to_instance ret
|
83
|
+
else
|
84
|
+
raise type
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.fixed_args args,params={},types=[],options={}
|
89
|
+
if options[:variadic]
|
90
|
+
_types = (types.dup*args.size)
|
91
|
+
args
|
92
|
+
else
|
93
|
+
_types = types.dup
|
94
|
+
([args.first]+params.values)
|
95
|
+
end.map do |arg|
|
96
|
+
type = _types.shift
|
97
|
+
case arg
|
98
|
+
when TrueClass, FalseClass
|
99
|
+
[:bool,arg]
|
100
|
+
when Fixnum, Bignum
|
101
|
+
case type
|
102
|
+
when 'q'
|
103
|
+
[:long_long,arg]
|
104
|
+
when 'Q'
|
105
|
+
[:ulong_long,arg]
|
106
|
+
when 'd'
|
107
|
+
[:double,arg]
|
108
|
+
else
|
109
|
+
raise type.inspect
|
110
|
+
end
|
111
|
+
when Float
|
112
|
+
[:double,arg]
|
113
|
+
when String
|
114
|
+
[:pointer,ObjC.String_to_NSString(arg)]
|
115
|
+
when NilClass
|
116
|
+
[:pointer,nil]
|
117
|
+
when Symbol
|
118
|
+
[:pointer,ObjC.sel_registerName("#{arg}:")]
|
119
|
+
when Cocoa::NSObject
|
120
|
+
[:pointer,arg.object]
|
121
|
+
when FFI::Struct
|
122
|
+
[arg.class.by_value,arg]
|
123
|
+
when FFI::Pointer
|
124
|
+
[:pointer,arg]
|
125
|
+
else
|
126
|
+
raise ArgumentError.new("#{arg.class.name}: #{arg.inspect}")
|
127
|
+
end
|
128
|
+
end.flatten
|
129
|
+
end
|
130
|
+
|
131
|
+
def self.apple_type_to_ffi type
|
132
|
+
# TODO: These are just stubbed on guess - check'em'all
|
133
|
+
case type
|
134
|
+
when 'C'
|
135
|
+
:uchar
|
136
|
+
when '@'
|
137
|
+
:pointer
|
138
|
+
when '#'
|
139
|
+
:pointer
|
140
|
+
when 'Q'
|
141
|
+
:int
|
142
|
+
when ':'
|
143
|
+
:pointer
|
144
|
+
when 'I'
|
145
|
+
:int
|
146
|
+
when 'L'
|
147
|
+
:int
|
148
|
+
when 'd'
|
149
|
+
:double
|
150
|
+
when 'f'
|
151
|
+
:float
|
152
|
+
when 'i'
|
153
|
+
:int
|
154
|
+
when 's'
|
155
|
+
:int
|
156
|
+
when 'q'
|
157
|
+
:long_long
|
158
|
+
when 'S'
|
159
|
+
:int
|
160
|
+
when /^\^/
|
161
|
+
:pointer
|
162
|
+
when 'B'
|
163
|
+
:bool
|
164
|
+
when 'v'
|
165
|
+
:void
|
166
|
+
when '[5*]'
|
167
|
+
:void
|
168
|
+
when /^{[^=]*=.*}$/
|
169
|
+
begin
|
170
|
+
/^{_*([^=]*)=.*}$/.match(type)[1].constantize.by_value
|
171
|
+
rescue => e
|
172
|
+
begin
|
173
|
+
"Cocoa::#{/^{_*([^=]*)=.*}$/.match(type)[1]}".constantize.by_value
|
174
|
+
rescue => e
|
175
|
+
match = /^{_*([^=]*)=(.*)}$/.match(type)
|
176
|
+
klass = begin
|
177
|
+
Cocoa.const_get(match[1])
|
178
|
+
rescue
|
179
|
+
# puts "defining struct Cocoa::#{match[1]} as #{match[2]}"
|
180
|
+
# this stuff doesnt work with jruby
|
181
|
+
klass = Class.new(FFI::Struct)
|
182
|
+
Cocoa.const_set(match[1], klass)
|
183
|
+
name = 'a'
|
184
|
+
layout = []
|
185
|
+
match[2].each_char do |c|
|
186
|
+
case c
|
187
|
+
when 'd'
|
188
|
+
layout << name.to_sym
|
189
|
+
name = name.next
|
190
|
+
layout << :double
|
191
|
+
end
|
192
|
+
end
|
193
|
+
klass = "Cocoa::#{match[1]}".constantize
|
194
|
+
klass.layout *layout
|
195
|
+
klass
|
196
|
+
end
|
197
|
+
klass.by_ref
|
198
|
+
end
|
199
|
+
end
|
200
|
+
when nil
|
201
|
+
:void
|
202
|
+
when '*' # character string
|
203
|
+
:pointer
|
204
|
+
when '@?'
|
205
|
+
:pointer
|
206
|
+
else
|
207
|
+
raise type.inspect
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def self.objc_type type,default='i'
|
212
|
+
case type
|
213
|
+
when nil
|
214
|
+
default
|
215
|
+
when '@'
|
216
|
+
type
|
217
|
+
when 'v'
|
218
|
+
type
|
219
|
+
when /^{([^=]*)=.*}$/
|
220
|
+
type
|
221
|
+
else
|
222
|
+
raise type.inspect
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.call_arguments params,args
|
227
|
+
fixed_args = []
|
228
|
+
args.each_with_index do |arg,i|
|
229
|
+
case params[:types][i]
|
230
|
+
when '@'
|
231
|
+
fixed_args << arg
|
232
|
+
when 'd'
|
233
|
+
if arg.is_a?(Fixnum)
|
234
|
+
fixed_args << arg.to_f
|
235
|
+
else
|
236
|
+
raise ArgumentError.new("float expected, got #{arg.class.name}") unless arg.is_a?(Float)
|
237
|
+
fixed_args << arg
|
238
|
+
end
|
239
|
+
when 'I'
|
240
|
+
raise ArgumentError unless arg.is_a?(Fixnum)
|
241
|
+
fixed_args << arg
|
242
|
+
when 'Q'
|
243
|
+
raise ArgumentError.new(arg.inspect) unless arg.is_a?(Fixnum)
|
244
|
+
fixed_args << arg
|
245
|
+
when 'q'
|
246
|
+
raise ArgumentError unless arg.is_a?(Fixnum)
|
247
|
+
fixed_args << arg
|
248
|
+
when '#'
|
249
|
+
raise ArgumentError unless arg.is_a?(FFI::Pointer)
|
250
|
+
fixed_args << arg
|
251
|
+
when /^{[^=]*=.*}$/
|
252
|
+
raise ArgumentError.new(arg.inspect) unless arg.kind_of?(FFI::Struct)
|
253
|
+
fixed_args << arg
|
254
|
+
when /^\^{([^=]*)=.*}$/
|
255
|
+
case arg
|
256
|
+
when FFI::Pointer
|
257
|
+
fixed_args << arg
|
258
|
+
when Array
|
259
|
+
raise ArgumentError unless $1 == '__CFArray'
|
260
|
+
fixed_args << NSArray.arrayWithObjects(arg).object
|
261
|
+
else
|
262
|
+
match = $1
|
263
|
+
if arg.class.name =~ /^Cocoa::/ # "Cocoa::#{$1}".constantize
|
264
|
+
fixed_args << arg.object
|
265
|
+
elsif arg.is_a?(NilClass)
|
266
|
+
fixed_args << FFI::MemoryPointer::NULL
|
267
|
+
elsif arg.is_a?(String) && match == '__CFString'
|
268
|
+
fixed_args << Cocoa::String_to_NSString(arg)
|
269
|
+
else
|
270
|
+
raise ArgumentError.new("expected #{params[:types][i]} got #{arg.class.name} (#{match})")
|
271
|
+
end
|
272
|
+
end
|
273
|
+
when '^d'
|
274
|
+
raise ArgumentError unless arg.is_a?(Array)
|
275
|
+
arr = FFI::MemoryPointer.new(:double,arg.size)
|
276
|
+
arr.write_array_of_double(arg)
|
277
|
+
fixed_args << arr
|
278
|
+
when '^v'
|
279
|
+
raise ArgumentError unless arg.is_a?(NilClass)
|
280
|
+
fixed_args << FFI::MemoryPointer::NULL
|
281
|
+
else
|
282
|
+
raise params[:types][i]
|
283
|
+
end
|
284
|
+
end
|
285
|
+
fixed_args
|
286
|
+
end
|
25
287
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Cocoa
|
2
|
+
class CFRange < FFI::Struct
|
3
|
+
def initialize *args
|
4
|
+
options = args.first
|
5
|
+
if options.is_a? Hash
|
6
|
+
self[:location] = options[:location]
|
7
|
+
self[:length] = options[:length]
|
8
|
+
else
|
9
|
+
super *args
|
10
|
+
end
|
11
|
+
end
|
12
|
+
def to_s
|
13
|
+
"<CFRange: #{self[:location]} #{self[:length]}>"
|
14
|
+
end
|
15
|
+
layout :location, :long_long, :length, :long_long
|
16
|
+
end
|
17
|
+
|
18
|
+
NSRange = CFRange
|
19
|
+
|
20
|
+
def CFRangeMake loc,len
|
21
|
+
CFRange.new(location: loc, length: len)
|
22
|
+
end
|
23
|
+
end
|
data/lib/cocoa/structs/NSRect.rb
CHANGED