[macruby-changes] [118] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Sun Mar 23 19:19:41 PDT 2008
Revision: 118
http://trac.macosforge.org/projects/ruby/changeset/118
Author: lsansonetti at apple.com
Date: 2008-03-23 19:19:40 -0700 (Sun, 23 Mar 2008)
Log Message:
-----------
boxed types are now valid NSValue subclasses
Modified Paths:
--------------
MacRuby/trunk/objc.m
MacRuby/trunk/test-macruby/test_boxed.rb
MacRuby/trunk/test-macruby/test_objc.rb
Modified: MacRuby/trunk/objc.m
===================================================================
--- MacRuby/trunk/objc.m 2008-03-23 04:02:19 UTC (rev 117)
+++ MacRuby/trunk/objc.m 2008-03-24 02:19:40 UTC (rev 118)
@@ -2498,6 +2498,39 @@
rb_funcall((VALUE)rcv, rb_intern("replace"), 1, newstr);
}
+static const char *
+imp_rb_boxed_objCType(void *rcv, SEL sel)
+{
+ VALUE klass, type;
+
+ klass = CLASS_OF(rcv);
+ type = rb_boxed_objc_type(klass);
+
+ return StringValuePtr(type);
+}
+
+static void
+imp_rb_boxed_getValue(void *rcv, SEL sel, void *buffer)
+{
+ bs_element_boxed_t *bs_boxed;
+ void *data;
+ bool ok;
+
+ bs_boxed = rb_klass_get_bs_boxed(CLASS_OF(rcv));
+
+ data = bs_element_boxed_get_data(bs_boxed, (VALUE)rcv, &ok);
+ if (!ok)
+ [NSException raise:@"NSException"
+ format:@"can't get internal data for boxed type `%s'",
+ RSTRING_PTR(rb_inspect((VALUE)rcv))];
+ if (data == NULL) {
+ *(void **)buffer = NULL;
+ }
+ else {
+ memcpy(buffer, data, bs_boxed->ffi_type->size);
+ }
+}
+
static inline void
rb_objc_install_method(Class klass, SEL sel, IMP imp)
{
@@ -2545,8 +2578,16 @@
(IMP)imp_rb_string_characterAtIndex);
rb_objc_install_method(klass, @selector(getCharacters:range:),
(IMP)imp_rb_string_getCharactersRange);
- rb_objc_install_method(klass, @selector(replaceCharactersInRange:withString:),
+ rb_objc_install_method(klass,
+ @selector(replaceCharactersInRange:withString:),
(IMP)imp_rb_string_replaceCharactersInRangeWithString);
+
+ /* Boxed */
+ klass = RCLASS_OCID(rb_cBoxed);
+ rb_objc_override_method(klass, @selector(objCType),
+ (IMP)imp_rb_boxed_objCType);
+ rb_objc_override_method(klass, @selector(getValue:),
+ (IMP)imp_rb_boxed_getValue);
}
static void *
@@ -2780,7 +2821,8 @@
rb_objc_retain(
rb_objc_class_magic_cookie = rb_str_new2("rb_objc_class_magic_cookie"));
- rb_cBoxed = rb_define_class("Boxed", rb_cObject);
+ rb_cBoxed = rb_define_class("Boxed",
+ rb_objc_import_class(objc_getClass("NSValue")));
rb_define_singleton_method(rb_cBoxed, "objc_type", rb_boxed_objc_type, 0);
rb_define_singleton_method(rb_cBoxed, "opaque?", rb_boxed_is_opaque, 0);
rb_define_singleton_method(rb_cBoxed, "fields", rb_boxed_fields, 0);
Modified: MacRuby/trunk/test-macruby/test_boxed.rb
===================================================================
--- MacRuby/trunk/test-macruby/test_boxed.rb 2008-03-23 04:02:19 UTC (rev 117)
+++ MacRuby/trunk/test-macruby/test_boxed.rb 2008-03-24 02:19:40 UTC (rev 118)
@@ -4,9 +4,78 @@
def setup
framework 'Foundation'
+ bundle = '/tmp/_test_bs.bundle'
+ if !File.exist?(bundle) or File.mtime(bundle) < File.mtime(__FILE__)
+ s = <<EOS
+#import <Foundation/Foundation.h>
+ at interface NSObject (MacRubyNSPointAdditions)
+- (float)x;
+- (float)y;
+ at end
+ at interface TestBoxed : NSObject
+ at end
+ at implementation TestBoxed
+- (void)testPoint:(NSPoint)point x:(float)x y:(float)y
+{
+ if (point.x != x)
+ [NSException raise:@"NSException"
+ format:@"point.x (%f) != x (%f)", point.x, x];
+
+ if (point.y != y)
+ [NSException raise:@"NSException"
+ format:@"point.y (%f) != y (%f)", point.y, y];
+}
+- (void)testPointAsObject:(id)point x:(float)x y:(float)y
+{
+ Class boxed;
+ boxed = NSClassFromString(@"Boxed");
+
+ if (![point isKindOfClass:boxed])
+ [NSException raise:@"NSException"
+ format:@"point (%@) isn't a boxed type", point];
+
+ if (![point isKindOfClass:[NSValue class]])
+ [NSException raise:@"NSException"
+ format:@"point (%@) isn't a value type", point];
+
+#if 0 // FIXME this cannot be tested yet
+ if ([point x] != x)
+ [NSException raise:@"NSException"
+ format:@"[point x] (%f) != x (%f)", [point x], x];
+
+ if ([point y] != y)
+ [NSException raise:@"NSException"
+ format:@"[point y] (%f) != y (%f)", [point y], y];
+#endif
+
+ if (strcmp([point objCType], @encode(NSPoint)) != 0)
+ [NSException raise:@"NSException"
+ format:@"[point objCType] (%s) != @encode(NSPoint) (%s)",
+ [point objCType], @encode(NSPoint)];
+
+ NSPoint p;
+ [point getValue:&p];
+ [self testPoint:p x:x y:y];
+}
+- (NSPoint)testReturnPointWithX:(float)x y:(float)y
+{
+ NSPoint p;
+ p.x = x;
+ p.y = y;
+ return p;
+}
+ at end
+EOS
+ File.open('/tmp/_test.m', 'w') { |io| io.write(s) }
+ system("gcc /tmp/_test.m -bundle -o #{bundle} -framework Foundation -fobjc-gc-only") or exit 1
+ end
+ require 'dl'; DL.dlopen(bundle)
end
def test_boxed_classes
+ assert_kind_of(Class, Boxed)
+ assert_equal(NSValue, Boxed.superclass)
+
# struct
assert(NSRect.ancestors.include?(Boxed))
assert('{_NSRect={_NSPoint=ff}{_NSSize=ff}}', NSRect.objc_type)
@@ -80,14 +149,32 @@
end
def test_struct_nsstring_marshalling
- r = NSRange.new(1.0, 4.0)
+ r = NSRange.new(1, 4)
assert_kind_of(NSString, NSStringFromRange(r))
- # FIXME not passing yet
- #assert_equal('{1.0, 4.0}', NSStringFromRange(r))
+ assert_equal('{1, 4}', NSStringFromRange(r))
assert_equal(r, NSRangeFromString(NSStringFromRange(r)))
rect = NSRect.new(NSPoint.new(42.0, 1042.0), NSSize.new(123, 456))
assert_equal(NSPoint.new(42.0, 1042.0),
NSPointFromString(NSStringFromPoint(rect.origin)))
end
+ def test_nspoint_in_objc
+ p = NSPoint.new(42.0, 99.0)
+ o = TestBoxed.new
+ o.testPoint(p, x:42.0, y:99.0)
+ o.testPointAsObject(p, x:42.0, y:99.0)
+ assert_equal(p, o.testReturnPointWithX(42.0, y:99.0))
+ end
+
+ class MethodReturningBoxed
+ def foo
+ NSPoint.new(1, 2)
+ end
+ end
+ def test_objc_call_pure_method_returning_boxed
+ o = MethodReturningBoxed.new
+ assert_equal(NSPoint.new(1, 2), o.send(:foo))
+ assert_equal(NSPoint.new(1, 2), o.performSelector(:foo))
+ end
+
end
Modified: MacRuby/trunk/test-macruby/test_objc.rb
===================================================================
--- MacRuby/trunk/test-macruby/test_objc.rb 2008-03-23 04:02:19 UTC (rev 117)
+++ MacRuby/trunk/test-macruby/test_objc.rb 2008-03-24 02:19:40 UTC (rev 118)
@@ -109,15 +109,4 @@
assert_equal(v, o.test_getObject(dict, forKey:s))
end
- class MethodReturningBoxed
- def foo
- NSPoint.new(1, 2)
- end
- end
- def test_objc_call_pure_method_returning_boxed
- o = MethodReturningBoxed.new
- assert_equal(NSPoint.new(1, 2), o.send(:foo))
- assert_equal(NSPoint.new(1, 2), o.performSelector(:foo))
- end
-
end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080323/a6462d0e/attachment-0001.html
More information about the macruby-changes
mailing list