[macruby-changes] [211] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Thu May 22 20:38:57 PDT 2008


Revision: 211
          http://trac.macosforge.org/projects/ruby/changeset/211
Author:   lsansonetti at apple.com
Date:     2008-05-22 20:38:56 -0700 (Thu, 22 May 2008)

Log Message:
-----------
fix for #58 + rewrote some samples

Modified Paths:
--------------
    MacRuby/trunk/objc.m
    MacRuby/trunk/sample-macruby/Scripts/hello_world.rb
    MacRuby/trunk/sample-macruby/Scripts/transparent_hello.rb
    MacRuby/trunk/test/ruby/test_objc.rb

Modified: MacRuby/trunk/objc.m
===================================================================
--- MacRuby/trunk/objc.m	2008-05-23 01:13:24 UTC (rev 210)
+++ MacRuby/trunk/objc.m	2008-05-23 03:38:56 UTC (rev 211)
@@ -611,34 +611,97 @@
     return Data_Wrap_Struct(bs_boxed->klass, NULL, NULL, data);     
 }
 
+static long
+rebuild_new_struct_ary(ffi_type **elements, VALUE orig, VALUE new)
+{
+    long n = 0;
+    while ((*elements) != NULL) {
+	if ((*elements)->type == FFI_TYPE_STRUCT) {
+	    long i, n2 = rebuild_new_struct_ary((*elements)->elements, orig, new);
+	    VALUE tmp = rb_ary_new();
+	    for (i = 0; i < n2; i++) {
+		if (RARRAY_LEN(orig) == 0)
+		    return 0;
+		rb_ary_push(tmp, rb_ary_shift(orig));
+	    }
+	    rb_ary_push(new, tmp);
+	}
+	elements++;
+	n++;
+    } 
+    return n;
+}
+
 static void
 rb_objc_rval_to_ocval(VALUE rval, const char *octype, void **ocval)
 {
-    bool ok;
+    bs_element_boxed_t *bs_boxed;
+    bool ok = true;
 
     octype = rb_objc_skip_octype_modifiers(octype);
 
     if (*octype == _C_VOID)
 	return;
 
-    {
-	bs_element_boxed_t *bs_boxed;
-	if (st_lookup(bs_boxeds, (st_data_t)octype, 
-		      (st_data_t *)&bs_boxed)) {
-	    void *data = bs_element_boxed_get_data(bs_boxed, rval, &ok);
-	    if (ok) {
-		if (data == NULL)
-		    *(void **)ocval = NULL;
-		else
-		    memcpy(ocval, data, bs_boxed->ffi_type->size);
+    if (st_lookup(bs_boxeds, (st_data_t)octype, (st_data_t *)&bs_boxed)) {
+	void *data;
+	if (TYPE(rval) == T_ARRAY && bs_boxed->type == BS_ELEMENT_STRUCT) {
+	    bs_element_struct_t *bs_struct;
+	    long i, n;
+	    size_t pos;
+
+	    bs_struct = (bs_element_struct_t *)bs_boxed->value;
+
+	    n = RARRAY_LEN(rval);
+	    if (n < bs_struct->fields_count)
+		rb_raise(rb_eArgError, 
+		    "not enough elements in array `%s' to create " \
+		    "structure `%s' (%d for %d)", 
+		    RSTRING_CPTR(rb_inspect(rval)), bs_struct->name, n, 
+		    bs_struct->fields_count);
+	    
+	    if (n > bs_struct->fields_count) {
+		VALUE new_rval = rb_ary_new();
+		VALUE orig = rval;
+		rval = rb_ary_dup(rval);
+		rebuild_new_struct_ary(bs_boxed->ffi_type->elements, rval, 
+				       new_rval);
+		n = RARRAY_LEN(new_rval);
+		if (RARRAY_LEN(rval) != 0 || n != bs_struct->fields_count) {
+		    rb_raise(rb_eArgError, 
+			"too much elements in array `%s' to create " \
+			"structure `%s' (%d for %d)", 
+			RSTRING_CPTR(rb_inspect(orig)), 
+			bs_struct->name, RARRAY_LEN(orig), 
+			bs_struct->fields_count);
+		}
+		rval = new_rval;
 	    }
-	    goto bails; 
+
+	    data = alloca(bs_boxed->ffi_type->size);
+
+	    for (i = 0, pos = 0; i < bs_struct->fields_count; i++) {
+		VALUE o = RARRAY_AT(rval, i);
+		char *field_type = bs_struct->fields[i].type;
+		rb_objc_rval_to_ocval(o, field_type, data + pos);
+		pos += rb_objc_octype_to_ffitype(field_type)->size;
+	    }
 	}
-	
-	if (st_lookup(bs_cftypes, (st_data_t)octype, NULL))
-	    octype = "@";
+	else {
+	    data = bs_element_boxed_get_data(bs_boxed, rval, &ok);
+	}
+	if (ok) {
+	    if (data == NULL)
+		*(void **)ocval = NULL;
+	    else
+		memcpy(ocval, data, bs_boxed->ffi_type->size);
+	}
+	goto bails; 
     }
 
+    if (st_lookup(bs_cftypes, (st_data_t)octype, NULL))
+	octype = "@";
+
     if (*octype != _C_BOOL) {
 	if (rval == Qtrue)
 	    rval = INT2FIX(1);
@@ -646,7 +709,6 @@
 	    rval = INT2FIX(0);
     }
 
-    ok = true;
     switch (*octype) {
 	case _C_ID:
 	case _C_CLASS:

Modified: MacRuby/trunk/sample-macruby/Scripts/hello_world.rb
===================================================================
--- MacRuby/trunk/sample-macruby/Scripts/hello_world.rb	2008-05-23 01:13:24 UTC (rev 210)
+++ MacRuby/trunk/sample-macruby/Scripts/hello_world.rb	2008-05-23 03:38:56 UTC (rev 211)
@@ -13,15 +13,14 @@
 app = NSApplication.sharedApplication
 app.delegate = AppDelegate.alloc.init
 
-frame = NSRect.new(NSPoint.new(200, 300), NSSize.new(250, 100))
-win = NSWindow.alloc.initWithContentRect(frame, 
+win = NSWindow.alloc.initWithContentRect([200, 300, 250, 100],
     styleMask:NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask, 
     backing:NSBackingStoreBuffered, 
     defer:false)
 win.title = 'Hello World'
 win.level = 3
 
-hel = NSButton.alloc.initWithFrame(NSRect.new(NSPoint.new(10, 10), NSSize.new(80, 80)))
+hel = NSButton.alloc.initWithFrame([10, 10, 80, 80])
 win.contentView.addSubview(hel)
 hel.bezelStyle = 4
 hel.title = 'Hello!'
@@ -31,8 +30,7 @@
 beep = NSSound.alloc.initWithContentsOfFile('/System/Library/Sounds/Tink.Aiff', byReference:true)
 hel.sound = beep
 
-bye = NSButton.alloc.initWithFrame(
-    NSRect.new(NSPoint.new(100, 10), NSSize.new(80, 80)))
+bye = NSButton.alloc.initWithFrame([100, 10, 80, 80])
 win.contentView.addSubview(bye)
 bye.bezelStyle = 4
 bye.target = app

Modified: MacRuby/trunk/sample-macruby/Scripts/transparent_hello.rb
===================================================================
--- MacRuby/trunk/sample-macruby/Scripts/transparent_hello.rb	2008-05-23 01:13:24 UTC (rev 210)
+++ MacRuby/trunk/sample-macruby/Scripts/transparent_hello.rb	2008-05-23 03:38:56 UTC (rev 211)
@@ -30,8 +30,8 @@
 application = NSApplication.sharedApplication
 
 # Create the window
-frame = NSRect.new(NSPoint.new(0, 0), NSSize.new(450, 200))
-window = NSWindow.alloc.initWithContentRect(frame, 
+frame = [0, 0, 450, 200]
+window = NSWindow.alloc.initWithContentRect(frame,
     styleMask:NSBorderlessWindowMask,
     backing:NSBackingStoreBuffered,
     defer:false)

Modified: MacRuby/trunk/test/ruby/test_objc.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_objc.rb	2008-05-23 01:13:24 UTC (rev 210)
+++ MacRuby/trunk/test/ruby/test_objc.rb	2008-05-23 03:38:56 UTC (rev 211)
@@ -91,5 +91,57 @@
     assert_equal('"foo" == "bar"', p.predicateFormat)
   end
 
+  def test_struct_create
+    p = NSPoint.new
+    assert_kind_of(NSPoint, p)
+    assert_equal(0.0, p.x)
+    assert_equal(0.0, p.y)
+
+    p = NSPoint.new(1, 2)
+    assert_equal(1.0, p.x)
+    assert_equal(2.0, p.y)
+
+    assert_raise(ArgumentError) { NSPoint.new(1) }
+    assert_raise(ArgumentError) { NSPoint.new(1, 2, 3) }
+    assert_raise(ArgumentError) { NSPoint.new('x', 'y') }
+
+    r = NSRect.new
+    assert_equal(NSPoint.new(0, 0), r.origin)
+    assert_equal(NSSize.new(0, 0), r.size)
+
+    r = NSRect.new(NSPoint.new(1, 2), NSSize.new(3, 4))
+    assert_equal(NSPoint.new(1, 2), r.origin)
+    assert_equal(NSSize.new(3, 4), r.size)
+
+    r.origin.x = 42
+    r.size.width = 42
+
+    assert_equal(NSRect.new(NSPoint.new(42, 2), NSSize.new(42, 4)), r)
+  end
+
+  def test_create_struct_with_array
+    s = NSStringFromSize([1, 2])
+    assert_equal(NSSize.new(1, 2), NSSizeFromString(s))
+    
+    assert_raise(ArgumentError) { NSStringFromSize([]) }
+    assert_raise(ArgumentError) { NSStringFromSize([1]) }
+    assert_raise(ArgumentError) { NSStringFromSize([1, 2, 3]) }
+
+    s = NSStringFromRect([[1, 2], [3, 4]])
+    assert_equal(NSRect.new(NSPoint.new(1, 2), NSSize.new(3, 4)), 
+		 NSRectFromString(s))
+
+    a = [1, 2, 3, 4]
+    s = NSStringFromRect(a)
+    assert_equal(NSRect.new(NSPoint.new(1, 2), NSSize.new(3, 4)), 
+		 NSRectFromString(s))
+    assert_equal([1, 2, 3, 4], a)
+
+    assert_raise(ArgumentError) { NSStringFromRect([]) }
+    assert_raise(ArgumentError) { NSStringFromRect([1]) }
+    assert_raise(ArgumentError) { NSStringFromRect([1, 2]) }
+    assert_raise(ArgumentError) { NSStringFromRect([1, 2, 3, 4, 5]) }
+  end
+
 end
 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080522/8206a558/attachment.htm 


More information about the macruby-changes mailing list