[macruby-changes] [312] MacRuby/branches/testing
source_changes at macosforge.org
source_changes at macosforge.org
Sun Jul 6 15:18:19 PDT 2008
Revision: 312
http://trac.macosforge.org/projects/ruby/changeset/312
Author: lsansonetti at apple.com
Date: 2008-07-06 15:18:19 -0700 (Sun, 06 Jul 2008)
Log Message:
-----------
merge from trunk
Modified Paths:
--------------
MacRuby/branches/testing/Rakefile
MacRuby/branches/testing/class.c
MacRuby/branches/testing/instruby.rb
MacRuby/branches/testing/objc.m
MacRuby/branches/testing/test/ruby/test_objc.rb
MacRuby/branches/testing/vm.c
MacRuby/branches/testing/vm_eval.c
MacRuby/branches/testing/vm_insnhelper.c
Added Paths:
-----------
MacRuby/branches/testing/lib/osx/
MacRuby/branches/testing/lib/osx/cocoa.rb
MacRuby/branches/testing/lib/osx/rubycocoa.rb
MacRuby/branches/testing/sample-macruby/RubyCocoa/
MacRuby/branches/testing/sample-macruby/RubyCocoa/HelloWorld.rb
MacRuby/branches/testing/sample-macruby/RubyCocoa/README
MacRuby/branches/testing/sample-macruby/RubyCocoa/TransparentHello.rb
MacRuby/branches/testing/sample-macruby/RubyCocoa/darkroom.rb
MacRuby/branches/testing/sample-macruby/RubyCocoa/fontnames.rb
MacRuby/branches/testing/sample-macruby/RubyCocoa/sndplay.rb
MacRuby/branches/testing/test-macruby/rubycocoa_test.rb
Removed Paths:
-------------
MacRuby/branches/testing/lib/osx/cocoa.rb
MacRuby/branches/testing/lib/osx/rubycocoa.rb
MacRuby/branches/testing/sample-macruby/RubyCocoa/HelloWorld.rb
MacRuby/branches/testing/sample-macruby/RubyCocoa/README
MacRuby/branches/testing/sample-macruby/RubyCocoa/TransparentHello.rb
MacRuby/branches/testing/sample-macruby/RubyCocoa/darkroom.rb
MacRuby/branches/testing/sample-macruby/RubyCocoa/fontnames.rb
MacRuby/branches/testing/sample-macruby/RubyCocoa/sndplay.rb
Modified: MacRuby/branches/testing/Rakefile
===================================================================
--- MacRuby/branches/testing/Rakefile 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/Rakefile 2008-07-06 22:18:19 UTC (rev 312)
@@ -1,12 +1,29 @@
# User customizable variables.
-RUBY_INSTALL_NAME = 'macruby'
-RUBY_SO_NAME = RUBY_INSTALL_NAME
-ARCHS = %w{ppc i386}
-FRAMEWORK_NAME = 'MacRuby'
-FRAMEWORK_INSTDIR = '/Library/Frameworks'
-NO_WARN_BUILD = true
+def do_option(name, default)
+ val = ENV[name]
+ if val
+ if block_given?
+ yield val
+ else
+ val
+ end
+ else
+ default
+ end
+end
+RUBY_INSTALL_NAME = do_option('ruby_install_name', 'macruby')
+RUBY_SO_NAME = do_option('ruby_so_name', RUBY_INSTALL_NAME)
+ARCHS = do_option('archs', %w{ppc i386}) { |x| x.split(',') }
+FRAMEWORK_NAME = do_option('framework_name', 'MacRuby')
+FRAMEWORK_INSTDIR = do_option('framework_instdir', '/Library/Frameworks')
+NO_WARN_BUILD = !do_option('allow_build_warnings', false)
+BUILD_AS_EMBEDDABLE = do_option('build_as_embeddable', false)
+ENABLE_STATIC_LIBRARY = do_option('enable_static_library', 'no') { 'yes' }
+
+# TODO: we should find a way to document these options in rake's --help
+
# Everything below this comment should *not* be customized.
version_h = File.read('version.h')
@@ -30,12 +47,21 @@
RUBY_VENDOR_LIB2 = File.join(RUBY_VENDOR_LIB, NEW_RUBY_VERSION)
RUBY_VENDOR_ARCHLIB = File.join(RUBY_VENDOR_LIB2, NEW_RUBY_PLATFORM)
+INSTALL_NAME =
+ if BUILD_AS_EMBEDDABLE
+ File.join("@executable_path/../Frameworks", FRAMEWORK_NAME + '.framework',
+ 'Versions', MACRUBY_VERSION, 'usr/lib',
+ 'lib' + RUBY_SO_NAME + '.dylib')
+ else
+ File.join(FRAMEWORK_USR_LIB, 'lib' + RUBY_SO_NAME + '.dylib')
+ end
+
ARCHFLAGS = ARCHS.map { |a| '-arch ' + a }.join(' ')
CFLAGS = "-I. -I./include -I/usr/include/libxml2 #{ARCHFLAGS} -fno-common -pipe -O2 -g -Wall"
CFLAGS << " -Wno-parentheses -Wno-deprecated-declarations -Werror" if NO_WARN_BUILD
OBJC_CFLAGS = CFLAGS + " -fobjc-gc-only"
LDFLAGS = "-lpthread -ldl -lxml2 -lobjc -lffi -lauto -framework Foundation"
-DLDFLAGS = "-dynamiclib -undefined suppress -flat_namespace -install_name #{File.join(FRAMEWORK_USR_LIB, 'lib' + RUBY_SO_NAME + '.dylib')} -current_version #{MACRUBY_VERSION} -compatibility_version #{MACRUBY_VERSION}"
+DLDFLAGS = "-dynamiclib -undefined suppress -flat_namespace -install_name #{INSTALL_NAME} -current_version #{MACRUBY_VERSION} -compatibility_version #{MACRUBY_VERSION}"
OBJS = %w{
array bignum class compar complex dir enum enumerator error eval load proc
@@ -388,6 +414,7 @@
CONFIG["SOLIBS"] = ""
CONFIG["DLDLIBS"] = ""
CONFIG["ENABLE_SHARED"] = "yes"
+ CONFIG["ENABLE_STATIC"] = "#{ENABLE_STATIC_LIBRARY}"
CONFIG["MAINLIBS"] = ""
CONFIG["COMMON_LIBS"] = ""
CONFIG["COMMON_MACROS"] = ""
@@ -550,6 +577,34 @@
end
end
+namespace :rubycocoa do
+ def get(url)
+ file = File.basename(url)
+ sh "curl #{url} -o /tmp/#{file}"
+ # for some reason mocha extracts with some junk...
+ puts `cd /tmp && tar -zxvf #{file}`
+ end
+
+ def install(path)
+ cp_r path, '/Library/Frameworks/MacRuby.framework/Versions/Current/usr/lib/ruby/site_ruby/'
+ end
+
+ desc 'For lack of working RubyGems this is a task that installs the dependencies for the RubyCocoa layer tests'
+ task :install_test_spec_and_mocha do
+ get 'http://files.rubyforge.vm.bytemark.co.uk/test-spec/test-spec-0.4.0.tar.gz'
+ install '/tmp/test-spec-0.4.0/lib/test'
+
+ get 'http://files.rubyforge.mmmultiworks.com/mocha/mocha-0.5.6.tgz'
+ mocha = '/tmp/mocha-0.5.6'
+ FileList["#{mocha}/lib/*.rb", "#{mocha}/lib/mocha"].each { |f| install f }
+ end
+
+ desc 'Run the RubyCocoa layer tests'
+ task :test do
+ sh 'macruby test-macruby/rubycocoa_test.rb'
+ end
+end
+
desc "Same as framework:install"
task :install => 'framework:install'
Modified: MacRuby/branches/testing/class.c
===================================================================
--- MacRuby/branches/testing/class.c 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/class.c 2008-07-06 22:18:19 UTC (rev 312)
@@ -130,17 +130,24 @@
}
static VALUE
-rb_objc_alloc_class(const char *name, VALUE super, VALUE flags, VALUE klass)
+rb_objc_alloc_class(const char *name, VALUE *psuper, VALUE flags, VALUE klass)
{
- VALUE obj;
+ VALUE super, obj;
Class ocklass, ocsuper;
char ocname[128];
+ super = psuper == NULL ? 0 : *psuper;
+
if (name == NULL) {
static long anon_count = 1;
snprintf(ocname, sizeof ocname, "RBAnonymous%ld", ++anon_count);
}
else {
+ if (super == rb_cBasicObject && strcmp(name, "Object") != 0) {
+ rb_warn("Do not subclass NSObject directly, please subclass " \
+ "Object instead.");
+ super = *psuper = rb_cObject;
+ }
if (objc_getClass(name) != NULL) {
long count = 1;
snprintf(ocname, sizeof ocname, "RB%s", name);
@@ -183,7 +190,7 @@
{
VALUE klass;
- klass = rb_objc_alloc_class(name, super, T_CLASS, rb_cClass);
+ klass = rb_objc_alloc_class(name, &super, T_CLASS, rb_cClass);
class_init(klass);
@@ -247,7 +254,7 @@
class_alloc(VALUE flags, VALUE klass)
{
#if WITH_OBJC
- VALUE obj = rb_objc_alloc_class(NULL, 0, flags, klass);
+ VALUE obj = rb_objc_alloc_class(NULL, NULL, flags, klass);
#else
NEWOBJ(obj, struct RClass);
OBJSETUP(obj, klass, flags);
Modified: MacRuby/branches/testing/instruby.rb
===================================================================
--- MacRuby/branches/testing/instruby.rb 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/instruby.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -221,6 +221,7 @@
mandir = File.join(CONFIG["mandir"], "man")
configure_args = Shellwords.shellwords(CONFIG["configure_args"])
enable_shared = CONFIG["ENABLE_SHARED"] == 'yes'
+enable_static = CONFIG["ENABLE_STATIC"] == 'yes'
dll = CONFIG["LIBRUBY_SO"]
lib = CONFIG["LIBRUBY"]
arc = CONFIG["LIBRUBY_A"]
@@ -241,7 +242,7 @@
install dll, bindir, :mode => $prog_mode
end
install lib, libdir, :mode => $prog_mode unless lib == arc
- install arc, libdir, :mode => $data_mode
+ install arc, libdir, :mode => $data_mode if enable_static
install "rbconfig.rb", archlibdir, :mode => $data_mode
if CONFIG["ARCHFILE"]
for file in CONFIG["ARCHFILE"].split
@@ -435,6 +436,8 @@
install_stuff('Xcode templates', 'misc/xcode-templates',
'/Library/Application Support/Developer/3.0/Xcode', 0755)
+install_stuff('Xcode 3.1 templates', 'misc/xcode-templates',
+ '/Library/Application Support/Developer/Shared/Xcode', 0755)
install_stuff('samples', 'sample-macruby',
'/Developer/Examples/Ruby/MacRuby', 0775)
Copied: MacRuby/branches/testing/lib/osx (from rev 311, MacRuby/trunk/lib/osx)
Deleted: MacRuby/branches/testing/lib/osx/cocoa.rb
===================================================================
--- MacRuby/trunk/lib/osx/cocoa.rb 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/lib/osx/cocoa.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -1,2 +0,0 @@
-Kernel.framework 'AppKit'
-require File.expand_path('../rubycocoa', __FILE__)
\ No newline at end of file
Copied: MacRuby/branches/testing/lib/osx/cocoa.rb (from rev 311, MacRuby/trunk/lib/osx/cocoa.rb)
===================================================================
--- MacRuby/branches/testing/lib/osx/cocoa.rb (rev 0)
+++ MacRuby/branches/testing/lib/osx/cocoa.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -0,0 +1,2 @@
+Kernel.framework 'AppKit'
+require File.expand_path('../rubycocoa', __FILE__)
\ No newline at end of file
Deleted: MacRuby/branches/testing/lib/osx/rubycocoa.rb
===================================================================
--- MacRuby/trunk/lib/osx/rubycocoa.rb 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/lib/osx/rubycocoa.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -1,93 +0,0 @@
-#!/usr/bin/env macruby
-
-module Kernel
- class << self
- alias_method :__framework_before_rubycocoa_layer, :framework
- def framework(f)
- $LOADING_FRAMEWORK = true
- __framework_before_rubycocoa_layer(f)
- $LOADING_FRAMEWORK = false
- end
- end
-end
-
-class NSObject
- class << self
- alias_method :ib_outlets, :ib_outlet
-
- alias_method :__method_added_before_rubycocoa_layer, :method_added
- def method_added(mname)
- unless $LOADING_FRAMEWORK
- mname_str = mname.to_s
- unless mname_str =~ /^__|\s/
- parts = mname_str.split('_')
- if parts.length > 1 and parts.length == instance_method(mname).arity
- class_eval { alias_method (parts.join(':') << ':').to_sym, mname }
- return
- end
- end
- end
- __method_added_before_rubycocoa_layer(mname)
- end
- end
-
- def objc_send(*args)
- if args.length > 1
- selector, new_args = '', []
- (args.length / 2).times do
- selector << "#{args.shift}:"
- new_args << args.shift
- end
- send(selector, *new_args)
- else
- send(args.first)
- end
- end
-
- alias_method :__method_missing_before_rubycocoa_layer, :method_missing
- def method_missing(mname, *args, &block)
- if (parts = mname.to_s.split('_')).length > 1
- if parts.first == 'super'
- selector = args.empty? ? parts.last : parts[1..-1].join(':') << ':'
- if self.class.superclass.instance_methods.include?(selector.to_sym)
- return __super_objc_send__(selector, *args)
- end
- end
-
- selector = parts.join(':') << ':'
- if respond_to?(selector) || respondsToSelector(selector) == 1
- eval "def #{mname}(*args); send('#{selector}', *args); end"
- return send(selector, *args)
- end
- end
- # FIXME: For some reason calling super or the original implementation
- # causes a stack level too deep execption. Is this a problem?
- #__method_missing_before_rubycocoa_layer(mname, *args, &block)
-
- raise NoMethodError, "undefined method `#{mname}' for #{inspect}:#{self.class}"
- end
-end
-
-module OSX
- class << self
- def require_framework(framework)
- Kernel.framework(framework)
- end
-
- def method_missing(mname, *args)
- if Kernel.respond_to? mname
- module_eval "def #{mname}(*args); Kernel.send(:#{mname}, *args); end"
- Kernel.send(mname, *args)
- else
- super
- end
- end
-
- def const_missing(constant)
- Object.const_get(constant)
- rescue NameError
- super
- end
- end
-end
-include OSX
Copied: MacRuby/branches/testing/lib/osx/rubycocoa.rb (from rev 311, MacRuby/trunk/lib/osx/rubycocoa.rb)
===================================================================
--- MacRuby/branches/testing/lib/osx/rubycocoa.rb (rev 0)
+++ MacRuby/branches/testing/lib/osx/rubycocoa.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -0,0 +1,93 @@
+#!/usr/bin/env macruby
+
+module Kernel
+ class << self
+ alias_method :__framework_before_rubycocoa_layer, :framework
+ def framework(f)
+ $LOADING_FRAMEWORK = true
+ __framework_before_rubycocoa_layer(f)
+ $LOADING_FRAMEWORK = false
+ end
+ end
+end
+
+class NSObject
+ class << self
+ alias_method :ib_outlets, :ib_outlet
+
+ alias_method :__method_added_before_rubycocoa_layer, :method_added
+ def method_added(mname)
+ unless $LOADING_FRAMEWORK
+ mname_str = mname.to_s
+ unless mname_str =~ /^__|\s/
+ parts = mname_str.split('_')
+ if parts.length > 1 and parts.length == instance_method(mname).arity
+ class_eval { alias_method (parts.join(':') << ':').to_sym, mname }
+ return
+ end
+ end
+ end
+ __method_added_before_rubycocoa_layer(mname)
+ end
+ end
+
+ def objc_send(*args)
+ if args.length > 1
+ selector, new_args = '', []
+ (args.length / 2).times do
+ selector << "#{args.shift}:"
+ new_args << args.shift
+ end
+ send(selector, *new_args)
+ else
+ send(args.first)
+ end
+ end
+
+ alias_method :__method_missing_before_rubycocoa_layer, :method_missing
+ def method_missing(mname, *args, &block)
+ if (parts = mname.to_s.split('_')).length > 1
+ if parts.first == 'super'
+ selector = args.empty? ? parts.last : parts[1..-1].join(':') << ':'
+ if self.class.superclass.instance_methods.include?(selector.to_sym)
+ return __super_objc_send__(selector, *args)
+ end
+ end
+
+ selector = parts.join(':') << ':'
+ if respond_to?(selector) || respondsToSelector(selector) == 1
+ eval "def #{mname}(*args); send('#{selector}', *args); end"
+ return send(selector, *args)
+ end
+ end
+ # FIXME: For some reason calling super or the original implementation
+ # causes a stack level too deep execption. Is this a problem?
+ #__method_missing_before_rubycocoa_layer(mname, *args, &block)
+
+ raise NoMethodError, "undefined method `#{mname}' for #{inspect}:#{self.class}"
+ end
+end
+
+module OSX
+ class << self
+ def require_framework(framework)
+ Kernel.framework(framework)
+ end
+
+ def method_missing(mname, *args)
+ if Kernel.respond_to? mname
+ module_eval "def #{mname}(*args); Kernel.send(:#{mname}, *args); end"
+ Kernel.send(mname, *args)
+ else
+ super
+ end
+ end
+
+ def const_missing(constant)
+ Object.const_get(constant)
+ rescue NameError
+ super
+ end
+ end
+end
+include OSX
Modified: MacRuby/branches/testing/objc.m
===================================================================
--- MacRuby/branches/testing/objc.m 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/objc.m 2008-07-06 22:18:19 UTC (rev 312)
@@ -163,7 +163,7 @@
type++;
buf[0] = _C_PTR;
buf_len -= 1;
- return rb_objc_get_first_type(type, buf, buf_len);
+ return rb_objc_get_first_type(type, &buf[1], buf_len);
}
type++;
@@ -402,7 +402,7 @@
}
static bool
-rb_objc_rval_to_ocid(VALUE rval, void **ocval)
+rb_objc_rval_to_ocid(VALUE rval, void **ocval, bool force_nsnil)
{
if (!rb_special_const_p(rval) && rb_objc_is_non_native(rval)) {
*(id *)ocval = (id)rval;
@@ -423,7 +423,15 @@
return true;
case T_NIL:
- *(id *)ocval = NULL;
+ if (force_nsnil) {
+ static id snull = nil;
+ if (snull == nil)
+ snull = [NSNull null];
+ *(id *)ocval = snull;
+ }
+ else {
+ *(id *)ocval = NULL;
+ }
return true;
case T_TRUE:
@@ -710,7 +718,7 @@
switch (*octype) {
case _C_ID:
case _C_CLASS:
- ok = rb_objc_rval_to_ocid(rval, ocval);
+ ok = rb_objc_rval_to_ocid(rval, ocval, false);
break;
case _C_SEL:
@@ -1063,47 +1071,21 @@
Method method;
ffi_cif *cif;
IMP imp;
+ Class klass;
};
static VALUE
-rb_objc_to_ruby_closure(int argc, VALUE *argv, VALUE rcv)
+rb_objc_call_objc(int argc, VALUE *argv, id ocrcv, Class klass,
+ bool super_call, struct objc_ruby_closure_context *ctx)
{
unsigned i, real_count, count;
ffi_type *ffi_rettype, **ffi_argtypes;
void *ffi_ret, **ffi_args;
ffi_cif *cif;
- Class klass;
const char *type;
char buf[128];
- id ocrcv;
void *imp;
- struct objc_ruby_closure_context *ctx;
- bool super_call;
- super_call = (ruby_current_thread->cfp->flag >> FRAME_MAGIC_MASK_BITS)
- & VM_CALL_SUPER_BIT;
-
- rb_objc_rval_to_ocid(rcv, (void **)&ocrcv);
- klass = *(Class *)ocrcv;
-
- assert(rb_current_cfunc_node != NULL);
-
- if (rb_current_cfunc_node->u3.value == 0) {
- ctx = (struct objc_ruby_closure_context *)xmalloc(sizeof(
- struct objc_ruby_closure_context));
- ctx->selector = sel_registerName(rb_id2name(rb_frame_this_func()));
- ctx->bs_method = rb_bs_find_method(klass, ctx->selector);
- ctx->method = class_getInstanceMethod(klass, ctx->selector);
- ctx->cif = NULL;
- ctx->imp = NULL;
- assert(ctx->method != NULL);
- GC_WB(&rb_current_cfunc_node->u3.value, ctx);
- }
- else {
- ctx = (struct objc_ruby_closure_context *)
- rb_current_cfunc_node->u3.value;
- }
-
count = method_getNumberOfArguments(ctx->method);
assert(count >= 2);
@@ -1127,7 +1109,7 @@
if (super_call) {
struct objc_super s;
s.receiver = ocrcv;
- s.class = class_getSuperclass(*(Class *)ocrcv);
+ s.class = klass;
ffi_ret = objc_msgSendSuper(&s, ctx->selector);
}
else {
@@ -1154,16 +1136,14 @@
ffi_args[1] = &ctx->selector;
if (super_call) {
- Class sklass;
Method smethod;
- sklass = class_getSuperclass(klass);
- assert(sklass != NULL);
- smethod = class_getInstanceMethod(sklass, ctx->selector);
+ smethod = class_getInstanceMethod(klass, ctx->selector);
assert(smethod != ctx->method);
- imp = method_getImplementation(smethod);
+ imp = method_getImplementation(smethod);
+ assert(imp != NULL);
}
else {
- if (ctx->imp != NULL) {
+ if (ctx->imp != NULL && ctx->klass == klass) {
imp = ctx->imp;
}
else {
@@ -1238,6 +1218,82 @@
}
}
+static VALUE
+rb_objc_to_ruby_closure(int argc, VALUE *argv, VALUE rcv)
+{
+ id ocrcv;
+ bool super_call;
+ Class klass;
+ struct objc_ruby_closure_context *ctx;
+
+ rb_objc_rval_to_ocid(rcv, (void **)&ocrcv, true);
+ super_call = (ruby_current_thread->cfp->flag >> FRAME_MAGIC_MASK_BITS)
+ & VM_CALL_SUPER_BIT;
+ klass = super_call ? class_getSuperclass(*(Class *)ocrcv) : *(Class *)ocrcv;
+
+ assert(rb_current_cfunc_node != NULL);
+
+ if (rb_current_cfunc_node->u3.value == 0) {
+ const char *selname;
+ size_t selnamelen;
+
+ ctx = (struct objc_ruby_closure_context *)xmalloc(sizeof(
+ struct objc_ruby_closure_context));
+
+ selname = rb_id2name(rb_frame_this_func());
+ selnamelen = strlen(selname);
+ if (argc == 1 && selname[selnamelen - 1] != ':') {
+ char *tmp = alloca(selnamelen + 2);
+ snprintf(tmp, selnamelen + 2, "%s:", selname);
+ selname = (const char *)tmp;
+ }
+ ctx->selector = sel_registerName(selname);
+
+ ctx->bs_method = rb_bs_find_method(*(Class *)rcv, ctx->selector);
+ ctx->method = class_getInstanceMethod(*(Class *)rcv, ctx->selector);
+ assert(ctx->method != NULL);
+ ctx->cif = NULL;
+ ctx->imp = NULL;
+ ctx->klass = NULL;
+ GC_WB(&rb_current_cfunc_node->u3.value, ctx);
+ }
+ else {
+ ctx = (struct objc_ruby_closure_context *)
+ rb_current_cfunc_node->u3.value;
+ }
+
+ return rb_objc_call_objc(argc, argv, ocrcv, klass, super_call, ctx);
+}
+
+static VALUE
+rb_super_objc_send(int argc, VALUE *argv, VALUE rcv)
+{
+ struct objc_ruby_closure_context fake_ctx;
+ id ocrcv;
+ ID mid;
+ Class klass;
+
+ if (argc < 1)
+ rb_raise(rb_eArgError, "expected at least one argument");
+
+ mid = rb_to_id(argv[0]);
+ argv++;
+ argc--;
+
+ rb_objc_rval_to_ocid(rcv, (void **)&ocrcv, true);
+ klass = class_getSuperclass(*(Class *)ocrcv);
+
+ fake_ctx.selector = sel_registerName(rb_id2name(mid));
+ fake_ctx.method = class_getInstanceMethod(klass, fake_ctx.selector);
+ assert(fake_ctx.method != NULL);
+ fake_ctx.bs_method = NULL;
+ fake_ctx.cif = NULL;
+ fake_ctx.imp = NULL;
+ fake_ctx.klass = NULL;
+
+ return rb_objc_call_objc(argc, argv, ocrcv, klass, true, &fake_ctx);
+}
+
#define IGNORE_PRIVATE_OBJC_METHODS 1
static void
@@ -2521,6 +2577,13 @@
return rb_objc_allocate(rcv);
}
+static void *
+imp_rb_obj_init(void *rcv, SEL sel)
+{
+ rb_funcall((VALUE)rcv, idInitialize, 0);
+ return rcv;
+}
+
static void
rb_install_alloc_methods(void)
{
@@ -2529,6 +2592,8 @@
rb_objc_install_method(klass, @selector(alloc), (IMP)imp_rb_obj_alloc);
rb_objc_install_method(klass, @selector(allocWithZone:),
(IMP)imp_rb_obj_allocWithZone);
+ rb_objc_install_method(RCLASS_OCID(rb_cObject), @selector(init),
+ (IMP)imp_rb_obj_init);
}
ID
@@ -2987,6 +3052,8 @@
CFAbsoluteTimeGetCurrent(), 0.1, 0, 0, timer_cb, NULL);
CFRunLoopAddTimer(CFRunLoopGetMain(), timer, kCFRunLoopDefaultMode);
}
+
+ rb_define_method(rb_cBasicObject, "__super_objc_send__", rb_super_objc_send, -1);
}
@interface Protocol
Copied: MacRuby/branches/testing/sample-macruby/RubyCocoa (from rev 311, MacRuby/trunk/sample-macruby/RubyCocoa)
Deleted: MacRuby/branches/testing/sample-macruby/RubyCocoa/HelloWorld.rb
===================================================================
--- MacRuby/trunk/sample-macruby/RubyCocoa/HelloWorld.rb 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/sample-macruby/RubyCocoa/HelloWorld.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -1,70 +0,0 @@
-# HelloWorld.rb
-#
-# Translate HelloWorld.py of PyObjc (Python Objective-C Bridge) to
-# Ruby with RubyCocoa.
-#
-# A quick guide to runtime name mangling:
-#
-# ObjC becomes Ruby
-# [obj method] obj.method
-# [obj method: arg] obj.method(arg)
-# [obj method: arg1 withOtherArgs: arg2]
-# obj.method_withOtherArgs(arg1, arg2)
-
-require 'osx/cocoa'
-include OSX
-
-class AppDelegate < NSObject
- def applicationDidFinishLaunching(aNotification)
- puts "Hello, World!"
- end
-
- def sayHello(sender)
- puts "Hello again, World!"
- speak "Hello again, World!"
- end
-
- def speak(str)
- script = NSAppleScript.alloc.initWithSource("say \"#{str}\"")
- script.performSelector_withObject('executeAndReturnError:', nil)
- end
-end
-
-if $0 == __FILE__ then
- $stderr.print "just wait..." ; $stderr.flush
- app = NSApplication.sharedApplication
-
- app.setDelegate AppDelegate.alloc.init
-
- frame = NSRect.new(NSSize.new(200.0, 300.0), NSSize.new(250.0, 100.0))
- win = NSWindow.alloc.initWithContentRect_styleMask_backing_defer(frame, 15, 2, 0)
- win.setTitle 'HelloWorld'
- # floating window
- win.setLevel 3
-
- hel = NSButton.alloc.initWithFrame(NSRect.new(NSSize.new(10.0, 10.0), NSSize.new(80.0, 80.0)))
- win.contentView.addSubview(hel)
- hel.setBezelStyle(4)
- hel.setTitle( 'Hello!' )
- hel.setTarget( app.delegate )
- hel.setAction( "sayHello:" )
-
- beep = NSSound.alloc.initWithContentsOfFile_byReference( '/System/Library/Sounds/Tink.Aiff', 1 )
- hel.setSound( beep )
-
- bye = NSButton.alloc.initWithFrame(NSRect.new(NSSize.new(100.0, 10.0), NSSize.new(80.0, 80.0)))
- win.contentView.addSubview bye
- bye.setBezelStyle 4
- bye.setTarget app
- bye.setAction 'stop:'
- bye.setEnabled true
- bye.setTitle 'Goodbye!'
-
- adios = NSSound.alloc.initWithContentsOfFile_byReference('/System/Library/Sounds/Basso.aiff', true)
- bye.setSound( adios )
-
- win.display
- win.orderFrontRegardless
-
- app.run
-end
Copied: MacRuby/branches/testing/sample-macruby/RubyCocoa/HelloWorld.rb (from rev 311, MacRuby/trunk/sample-macruby/RubyCocoa/HelloWorld.rb)
===================================================================
--- MacRuby/branches/testing/sample-macruby/RubyCocoa/HelloWorld.rb (rev 0)
+++ MacRuby/branches/testing/sample-macruby/RubyCocoa/HelloWorld.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -0,0 +1,70 @@
+# HelloWorld.rb
+#
+# Translate HelloWorld.py of PyObjc (Python Objective-C Bridge) to
+# Ruby with RubyCocoa.
+#
+# A quick guide to runtime name mangling:
+#
+# ObjC becomes Ruby
+# [obj method] obj.method
+# [obj method: arg] obj.method(arg)
+# [obj method: arg1 withOtherArgs: arg2]
+# obj.method_withOtherArgs(arg1, arg2)
+
+require 'osx/cocoa'
+include OSX
+
+class AppDelegate < NSObject
+ def applicationDidFinishLaunching(aNotification)
+ puts "Hello, World!"
+ end
+
+ def sayHello(sender)
+ puts "Hello again, World!"
+ speak "Hello again, World!"
+ end
+
+ def speak(str)
+ script = NSAppleScript.alloc.initWithSource("say \"#{str}\"")
+ script.performSelector_withObject('executeAndReturnError:', nil)
+ end
+end
+
+if $0 == __FILE__ then
+ $stderr.print "just wait..." ; $stderr.flush
+ app = NSApplication.sharedApplication
+
+ app.setDelegate AppDelegate.alloc.init
+
+ frame = NSRect.new(NSSize.new(200.0, 300.0), NSSize.new(250.0, 100.0))
+ win = NSWindow.alloc.initWithContentRect_styleMask_backing_defer(frame, 15, 2, 0)
+ win.setTitle 'HelloWorld'
+ # floating window
+ win.setLevel 3
+
+ hel = NSButton.alloc.initWithFrame(NSRect.new(NSSize.new(10.0, 10.0), NSSize.new(80.0, 80.0)))
+ win.contentView.addSubview(hel)
+ hel.setBezelStyle(4)
+ hel.setTitle( 'Hello!' )
+ hel.setTarget( app.delegate )
+ hel.setAction( "sayHello:" )
+
+ beep = NSSound.alloc.initWithContentsOfFile_byReference( '/System/Library/Sounds/Tink.Aiff', 1 )
+ hel.setSound( beep )
+
+ bye = NSButton.alloc.initWithFrame(NSRect.new(NSSize.new(100.0, 10.0), NSSize.new(80.0, 80.0)))
+ win.contentView.addSubview bye
+ bye.setBezelStyle 4
+ bye.setTarget app
+ bye.setAction 'stop:'
+ bye.setEnabled true
+ bye.setTitle 'Goodbye!'
+
+ adios = NSSound.alloc.initWithContentsOfFile_byReference('/System/Library/Sounds/Basso.aiff', true)
+ bye.setSound( adios )
+
+ win.display
+ win.orderFrontRegardless
+
+ app.run
+end
Deleted: MacRuby/branches/testing/sample-macruby/RubyCocoa/README
===================================================================
--- MacRuby/trunk/sample-macruby/RubyCocoa/README 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/sample-macruby/RubyCocoa/README 2008-07-06 22:18:19 UTC (rev 312)
@@ -1,5 +0,0 @@
-sndplay.rb - Works.
-HelloWorld.rb - Sometimes hangs when pushing the hello button.
-fontnames.rb - Works.
-darkroom.rb - Works (when used with these options: --output=google.png --height=600 http://google.com, there's a bug in darkroom which triggers when a height isn't specified). But needed to move #initialize code into #init because #initialize isn't called when used with alloc.init. However #init can't be used either in a real RubyCocoa way, because that would mean calling super_init which also isn't implemented yet.
-TransparentHello.rb - Works, but trying to interrupt the runloop doesn't work.
\ No newline at end of file
Copied: MacRuby/branches/testing/sample-macruby/RubyCocoa/README (from rev 311, MacRuby/trunk/sample-macruby/RubyCocoa/README)
===================================================================
--- MacRuby/branches/testing/sample-macruby/RubyCocoa/README (rev 0)
+++ MacRuby/branches/testing/sample-macruby/RubyCocoa/README 2008-07-06 22:18:19 UTC (rev 312)
@@ -0,0 +1,5 @@
+sndplay.rb - Works.
+HelloWorld.rb - Sometimes hangs when pushing the hello button.
+fontnames.rb - Works.
+darkroom.rb - Works (when used with these options: --output=google.png --height=600 http://google.com, there's a bug in darkroom which triggers when a height isn't specified). But needed to move #initialize code into #init because #initialize isn't called when used with alloc.init. However #init can't be used either in a real RubyCocoa way, because that would mean calling super_init which also isn't implemented yet.
+TransparentHello.rb - Works, but trying to interrupt the runloop doesn't work.
\ No newline at end of file
Deleted: MacRuby/branches/testing/sample-macruby/RubyCocoa/TransparentHello.rb
===================================================================
--- MacRuby/trunk/sample-macruby/RubyCocoa/TransparentHello.rb 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/sample-macruby/RubyCocoa/TransparentHello.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -1,88 +0,0 @@
-#
-# written by Chris Thomas for the article of DDJ May 2002.
-#
-
-require 'osx/cocoa'
-
-class HelloView < OSX::NSView
- #
- # When the Cocoa view system wants to draw a view,
- # it calls the method -(void)drawRect:(NSRect)rect.
- # The rectangle argument is relative to the origin
- # of the view's frame, and it may only be a small
- # portion of the view. For this reason, very
- # simple views with only one or two graphical
- # elements tend to ignore this parameter.
- #
- def drawRect(rect)
-
- # Set the window background to transparent
- OSX::NSColor.clearColor.set
- OSX::NSRectFill(bounds)
-
- # Draw the text in a shade of red and in a large system font
- attributes = OSX::NSMutableDictionary.alloc.init
-
- attributes.setObject_forKey(OSX::NSColor.redColor, OSX::NSForegroundColorAttributeName)
- attributes.setObject_forKey(OSX::NSFont.boldSystemFontOfSize(48.0), OSX::NSFontAttributeName)
-
- string = OSX::NSString.alloc.initWithString( "Hello, Ruby Baby" )
- string.drawAtPoint_withAttributes(OSX::NSSize.new(0,0), attributes)
-
- #
- # Turn the window's shadow off and on --
- # This is a kludge to get the shadow to recalculate
- # for the new shape of the opaque window content.
- #
- viewWindow = window
- window.setHasShadow(0)
- window.setHasShadow(1)
- end
-end
-
-#
-# If this file is the main file, then perform the followjng commands.
-# (This construct is often useful for adding simple unit tests to
-# library code.)
-#
-if __FILE__ == $0
- #
- # First, to establish a connection to the window server,
- # we must initialize the application
- #
- $stderr.print "just wait ..." ; $stderr.flush
- application = OSX::NSApplication.sharedApplication
-
- # Create the window
- window = OSX::NSWindow.alloc.
- objc_send(:initWithContentRect, OSX::NSRect.new(OSX::NSSize.new(0, 0), OSX::NSSize.new(450, 200)),
- :styleMask, OSX::NSBorderlessWindowMask,
- :backing, OSX::NSBackingStoreBuffered,
- :defer, 0)
- # Allow the window to be partially transparent
- window.setOpaque(0)
-
- # Setup the window's root view
- view = HelloView.alloc.initWithFrame(OSX::NSRect.new(OSX::NSSize.new(0, 0), OSX::NSSize.new(450, 200)))
- window.setContentView(view)
-
- # Place the window near the top of the screen.
- # (Screen coordinates in Cocoa are always PostScript
- # coordinates, which start from the bottom of the screen
- # and increase as they go up, so we have to do some math
- # to place the window at 100 pixels from the top of the
- # screen.
- #
- screenFrame = OSX::NSScreen.mainScreen.frame
- windowOriginPoint = OSX::NSSize.new(40, screenFrame.origin.y + screenFrame.size.height - 100)
- window.setFrameOrigin( windowOriginPoint )
-
- # Show the window
- window.makeKeyAndOrderFront(nil)
- window.orderFrontRegardless() ## but this one does
-
- # And start the application event loop
- $stderr.print "\rtype `Ctrl-C' for quit !\n"
- trap('SIGINT') { $stderr.puts "bye." ; exit 0 }
- application.run
-end
Copied: MacRuby/branches/testing/sample-macruby/RubyCocoa/TransparentHello.rb (from rev 311, MacRuby/trunk/sample-macruby/RubyCocoa/TransparentHello.rb)
===================================================================
--- MacRuby/branches/testing/sample-macruby/RubyCocoa/TransparentHello.rb (rev 0)
+++ MacRuby/branches/testing/sample-macruby/RubyCocoa/TransparentHello.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -0,0 +1,88 @@
+#
+# written by Chris Thomas for the article of DDJ May 2002.
+#
+
+require 'osx/cocoa'
+
+class HelloView < OSX::NSView
+ #
+ # When the Cocoa view system wants to draw a view,
+ # it calls the method -(void)drawRect:(NSRect)rect.
+ # The rectangle argument is relative to the origin
+ # of the view's frame, and it may only be a small
+ # portion of the view. For this reason, very
+ # simple views with only one or two graphical
+ # elements tend to ignore this parameter.
+ #
+ def drawRect(rect)
+
+ # Set the window background to transparent
+ OSX::NSColor.clearColor.set
+ OSX::NSRectFill(bounds)
+
+ # Draw the text in a shade of red and in a large system font
+ attributes = OSX::NSMutableDictionary.alloc.init
+
+ attributes.setObject_forKey(OSX::NSColor.redColor, OSX::NSForegroundColorAttributeName)
+ attributes.setObject_forKey(OSX::NSFont.boldSystemFontOfSize(48.0), OSX::NSFontAttributeName)
+
+ string = OSX::NSString.alloc.initWithString( "Hello, Ruby Baby" )
+ string.drawAtPoint_withAttributes(OSX::NSSize.new(0,0), attributes)
+
+ #
+ # Turn the window's shadow off and on --
+ # This is a kludge to get the shadow to recalculate
+ # for the new shape of the opaque window content.
+ #
+ viewWindow = window
+ window.setHasShadow(0)
+ window.setHasShadow(1)
+ end
+end
+
+#
+# If this file is the main file, then perform the followjng commands.
+# (This construct is often useful for adding simple unit tests to
+# library code.)
+#
+if __FILE__ == $0
+ #
+ # First, to establish a connection to the window server,
+ # we must initialize the application
+ #
+ $stderr.print "just wait ..." ; $stderr.flush
+ application = OSX::NSApplication.sharedApplication
+
+ # Create the window
+ window = OSX::NSWindow.alloc.
+ objc_send(:initWithContentRect, OSX::NSRect.new(OSX::NSSize.new(0, 0), OSX::NSSize.new(450, 200)),
+ :styleMask, OSX::NSBorderlessWindowMask,
+ :backing, OSX::NSBackingStoreBuffered,
+ :defer, 0)
+ # Allow the window to be partially transparent
+ window.setOpaque(0)
+
+ # Setup the window's root view
+ view = HelloView.alloc.initWithFrame(OSX::NSRect.new(OSX::NSSize.new(0, 0), OSX::NSSize.new(450, 200)))
+ window.setContentView(view)
+
+ # Place the window near the top of the screen.
+ # (Screen coordinates in Cocoa are always PostScript
+ # coordinates, which start from the bottom of the screen
+ # and increase as they go up, so we have to do some math
+ # to place the window at 100 pixels from the top of the
+ # screen.
+ #
+ screenFrame = OSX::NSScreen.mainScreen.frame
+ windowOriginPoint = OSX::NSSize.new(40, screenFrame.origin.y + screenFrame.size.height - 100)
+ window.setFrameOrigin( windowOriginPoint )
+
+ # Show the window
+ window.makeKeyAndOrderFront(nil)
+ window.orderFrontRegardless() ## but this one does
+
+ # And start the application event loop
+ $stderr.print "\rtype `Ctrl-C' for quit !\n"
+ trap('SIGINT') { $stderr.puts "bye." ; exit 0 }
+ application.run
+end
Deleted: MacRuby/branches/testing/sample-macruby/RubyCocoa/darkroom.rb
===================================================================
--- MacRuby/trunk/sample-macruby/RubyCocoa/darkroom.rb 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/sample-macruby/RubyCocoa/darkroom.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -1,128 +0,0 @@
-#!/usr/bin/env ruby
-#
-# DarkRoom
-# Takes fullsize screenshots of a web page.
-# Copyright (c) 2007 Justin Palmer.
-#
-# Released under an MIT LICENSE
-#
-# Usage
-# ====
-# ruby ./darkroom.rb http://activereload.net
-# ruby ./darkroom.rb --output=google.png http://google.com
-# ruby ./darkroom.rb --width=400 --delay=5 http://yahoo.com
-#
-# As a fix for the current bug specify a height:
-# macruby darkroom.rb --output=google.png --height=600 http://google.com
-require 'optparse'
-require 'osx/cocoa'
-OSX.require_framework 'Webkit'
-
-module ActiveReload
- module DarkRoom
- USER_AGENT = "DarkRoom/0.1"
- class Photographer
- def initialize
- options = {}
- opts = OptionParser.new do |opts|
- opts.banner = "Usage: #$0 [options] URL"
-
- opts.on('-w', '--width=[WIDTH]', Integer, 'Force width of the screenshot') do |v|
- options[:width] = v
- end
-
- opts.on('-h', '--height=[HEIGHT]', Integer, 'Force height of screenshot') do |v|
- options[:height] = v
- end
-
- opts.on('-o', '--output=[FILENAME]', String, 'Specify filename for saving') do |v|
- options[:output] = v
- end
-
- opts.on('-d', '--delay=[DELAY]', Integer, 'Delay in seconds to give web page assets time to load') do |v|
- options[:delay] = v
- end
-
- opts.on_tail('-h', '--help', 'Display this message and exit') do
- puts opts
- exit
- end
- end.parse!
- options[:width] ||= 1024
- options[:height] ||= 0
- options[:website] = ARGV.first || 'http://google.com'
- Camera.shoot(options)
- end
- end
-
- class Camera
- def self.shoot(options)
- app = OSX::NSApplication.sharedApplication
- delegate = Processor.alloc.init!
- delegate.options = options
- app.setDelegate(delegate)
- app.run
- end
- end
-
- class Processor < OSX::NSObject
- include OSX
- attr_accessor :options, :web_view
-
- # def initialize
- # #puts 'inits'
- # rect = [-16000.0, -16000.0, 100, 100]
- # win = NSWindow.alloc.initWithContentRect_styleMask_backing_defer(rect, NSBorderlessWindowMask, 2, 0)
- #
- # @web_view = WebView.alloc.initWithFrame(rect)
- # @web_view.mainFrame.frameView.setAllowsScrolling(false)
- # @web_view.setApplicationNameForUserAgent(USER_AGENT)
- # @web_view.setFrameLoadDelegate(self)
- #
- # win.setContentView(@web_view)
- # end
-
- def init!
- if init
- rect = NSRect.new(NSSize.new(-16000.0, -16000.0), NSSize.new(100, 100))
- win = NSWindow.alloc.initWithContentRect_styleMask_backing_defer(rect, OSX::NSBorderlessWindowMask, 2, 0)
-
- @web_view = WebView.alloc.initWithFrame(rect)
- @web_view.mainFrame.frameView.setAllowsScrolling(false)
- @web_view.setApplicationNameForUserAgent(USER_AGENT)
- @web_view.setFrameLoadDelegate(self)
- win.setContentView(@web_view)
-
- self
- end
- end
-
- def applicationDidFinishLaunching(notification)
- @options[:output] ||= "#{Time.now.strftime('%m-%d-%y-%H%I%S')}.png"
- @web_view.window.setContentSize(NSSize.new(@options[:width], @options[:height]))
- @web_view.setFrameSize(NSSize.new(@options[:width], @options[:height]))
- @web_view.mainFrame.loadRequest(NSURLRequest.requestWithURL(NSURL.URLWithString(@options[:website])))
- end
-
- def webView_didFinishLoadForFrame(web_view, frame)
- viewport = web_view.mainFrame.frameView.documentView
- viewport.window.orderFront(nil)
- viewport.window.display
- viewport.window.setContentSize(NSSize.new(@options[:width], (@options[:height] > 0 ? @options[:height] : viewport.bounds.height)))
- viewport.setFrame(viewport.bounds)
- sleep(@options[:delay]) if @options[:delay]
- capture_and_save(viewport)
- end
-
- def capture_and_save(view)
- view.lockFocus
- bitmap = NSBitmapImageRep.alloc.initWithFocusedViewRect(view.bounds)
- view.unlockFocus
-
- bitmap.representationUsingType_properties(OSX::NSPNGFileType, nil).writeToFile_atomically(@options[:output], true)
- NSApplication.sharedApplication.terminate(nil)
- end
- end
- end
-end
-ActiveReload::DarkRoom::Photographer.new
Copied: MacRuby/branches/testing/sample-macruby/RubyCocoa/darkroom.rb (from rev 311, MacRuby/trunk/sample-macruby/RubyCocoa/darkroom.rb)
===================================================================
--- MacRuby/branches/testing/sample-macruby/RubyCocoa/darkroom.rb (rev 0)
+++ MacRuby/branches/testing/sample-macruby/RubyCocoa/darkroom.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -0,0 +1,128 @@
+#!/usr/bin/env ruby
+#
+# DarkRoom
+# Takes fullsize screenshots of a web page.
+# Copyright (c) 2007 Justin Palmer.
+#
+# Released under an MIT LICENSE
+#
+# Usage
+# ====
+# ruby ./darkroom.rb http://activereload.net
+# ruby ./darkroom.rb --output=google.png http://google.com
+# ruby ./darkroom.rb --width=400 --delay=5 http://yahoo.com
+#
+# As a fix for the current bug specify a height:
+# macruby darkroom.rb --output=google.png --height=600 http://google.com
+require 'optparse'
+require 'osx/cocoa'
+OSX.require_framework 'Webkit'
+
+module ActiveReload
+ module DarkRoom
+ USER_AGENT = "DarkRoom/0.1"
+ class Photographer
+ def initialize
+ options = {}
+ opts = OptionParser.new do |opts|
+ opts.banner = "Usage: #$0 [options] URL"
+
+ opts.on('-w', '--width=[WIDTH]', Integer, 'Force width of the screenshot') do |v|
+ options[:width] = v
+ end
+
+ opts.on('-h', '--height=[HEIGHT]', Integer, 'Force height of screenshot') do |v|
+ options[:height] = v
+ end
+
+ opts.on('-o', '--output=[FILENAME]', String, 'Specify filename for saving') do |v|
+ options[:output] = v
+ end
+
+ opts.on('-d', '--delay=[DELAY]', Integer, 'Delay in seconds to give web page assets time to load') do |v|
+ options[:delay] = v
+ end
+
+ opts.on_tail('-h', '--help', 'Display this message and exit') do
+ puts opts
+ exit
+ end
+ end.parse!
+ options[:width] ||= 1024
+ options[:height] ||= 0
+ options[:website] = ARGV.first || 'http://google.com'
+ Camera.shoot(options)
+ end
+ end
+
+ class Camera
+ def self.shoot(options)
+ app = OSX::NSApplication.sharedApplication
+ delegate = Processor.alloc.init!
+ delegate.options = options
+ app.setDelegate(delegate)
+ app.run
+ end
+ end
+
+ class Processor < OSX::NSObject
+ include OSX
+ attr_accessor :options, :web_view
+
+ # def initialize
+ # #puts 'inits'
+ # rect = [-16000.0, -16000.0, 100, 100]
+ # win = NSWindow.alloc.initWithContentRect_styleMask_backing_defer(rect, NSBorderlessWindowMask, 2, 0)
+ #
+ # @web_view = WebView.alloc.initWithFrame(rect)
+ # @web_view.mainFrame.frameView.setAllowsScrolling(false)
+ # @web_view.setApplicationNameForUserAgent(USER_AGENT)
+ # @web_view.setFrameLoadDelegate(self)
+ #
+ # win.setContentView(@web_view)
+ # end
+
+ def init!
+ if init
+ rect = NSRect.new(NSSize.new(-16000.0, -16000.0), NSSize.new(100, 100))
+ win = NSWindow.alloc.initWithContentRect_styleMask_backing_defer(rect, OSX::NSBorderlessWindowMask, 2, 0)
+
+ @web_view = WebView.alloc.initWithFrame(rect)
+ @web_view.mainFrame.frameView.setAllowsScrolling(false)
+ @web_view.setApplicationNameForUserAgent(USER_AGENT)
+ @web_view.setFrameLoadDelegate(self)
+ win.setContentView(@web_view)
+
+ self
+ end
+ end
+
+ def applicationDidFinishLaunching(notification)
+ @options[:output] ||= "#{Time.now.strftime('%m-%d-%y-%H%I%S')}.png"
+ @web_view.window.setContentSize(NSSize.new(@options[:width], @options[:height]))
+ @web_view.setFrameSize(NSSize.new(@options[:width], @options[:height]))
+ @web_view.mainFrame.loadRequest(NSURLRequest.requestWithURL(NSURL.URLWithString(@options[:website])))
+ end
+
+ def webView_didFinishLoadForFrame(web_view, frame)
+ viewport = web_view.mainFrame.frameView.documentView
+ viewport.window.orderFront(nil)
+ viewport.window.display
+ viewport.window.setContentSize(NSSize.new(@options[:width], (@options[:height] > 0 ? @options[:height] : viewport.bounds.height)))
+ viewport.setFrame(viewport.bounds)
+ sleep(@options[:delay]) if @options[:delay]
+ capture_and_save(viewport)
+ end
+
+ def capture_and_save(view)
+ view.lockFocus
+ bitmap = NSBitmapImageRep.alloc.initWithFocusedViewRect(view.bounds)
+ view.unlockFocus
+
+ bitmap.representationUsingType_properties(OSX::NSPNGFileType, nil).writeToFile_atomically(@options[:output], true)
+ NSApplication.sharedApplication.terminate(nil)
+ end
+ end
+ end
+end
+ActiveReload::DarkRoom::Photographer.new
Deleted: MacRuby/branches/testing/sample-macruby/RubyCocoa/fontnames.rb
===================================================================
--- MacRuby/trunk/sample-macruby/RubyCocoa/fontnames.rb 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/sample-macruby/RubyCocoa/fontnames.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -1,11 +0,0 @@
-require 'osx/cocoa'
-
-fmgr = OSX::NSFontManager.sharedFontManager
-
-puts "## all fonts ##"
-fonts = fmgr.availableFonts.to_a.map{|i| i.to_s }
-fonts.each {|i| puts i }
-
-puts "## fixed pitch fonts ##"
-fixedfonts = fmgr.availableFontNamesWithTraits(OSX::NSFixedPitchFontMask).to_a
-fixedfonts.each {|i| puts i.to_s }
\ No newline at end of file
Copied: MacRuby/branches/testing/sample-macruby/RubyCocoa/fontnames.rb (from rev 311, MacRuby/trunk/sample-macruby/RubyCocoa/fontnames.rb)
===================================================================
--- MacRuby/branches/testing/sample-macruby/RubyCocoa/fontnames.rb (rev 0)
+++ MacRuby/branches/testing/sample-macruby/RubyCocoa/fontnames.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -0,0 +1,11 @@
+require 'osx/cocoa'
+
+fmgr = OSX::NSFontManager.sharedFontManager
+
+puts "## all fonts ##"
+fonts = fmgr.availableFonts.to_a.map{|i| i.to_s }
+fonts.each {|i| puts i }
+
+puts "## fixed pitch fonts ##"
+fixedfonts = fmgr.availableFontNamesWithTraits(OSX::NSFixedPitchFontMask).to_a
+fixedfonts.each {|i| puts i.to_s }
\ No newline at end of file
Deleted: MacRuby/branches/testing/sample-macruby/RubyCocoa/sndplay.rb
===================================================================
--- MacRuby/trunk/sample-macruby/RubyCocoa/sndplay.rb 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/sample-macruby/RubyCocoa/sndplay.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -1,14 +0,0 @@
-require 'osx/cocoa'
-
-snd_files =
- if ARGV.size == 0 then
- `ls /System/Library/Sounds/*.aiff`.split
- else
- ARGV
- end
-
-snd_files.each do |path|
- snd = OSX::NSSound.alloc.initWithContentsOfFile_byReference(path, true)
- snd.play
- sleep 0.25 while snd.playing?
-end
\ No newline at end of file
Copied: MacRuby/branches/testing/sample-macruby/RubyCocoa/sndplay.rb (from rev 311, MacRuby/trunk/sample-macruby/RubyCocoa/sndplay.rb)
===================================================================
--- MacRuby/branches/testing/sample-macruby/RubyCocoa/sndplay.rb (rev 0)
+++ MacRuby/branches/testing/sample-macruby/RubyCocoa/sndplay.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -0,0 +1,14 @@
+require 'osx/cocoa'
+
+snd_files =
+ if ARGV.size == 0 then
+ `ls /System/Library/Sounds/*.aiff`.split
+ else
+ ARGV
+ end
+
+snd_files.each do |path|
+ snd = OSX::NSSound.alloc.initWithContentsOfFile_byReference(path, true)
+ snd.play
+ sleep 0.25 while snd.playing?
+end
\ No newline at end of file
Modified: MacRuby/branches/testing/test/ruby/test_objc.rb
===================================================================
--- MacRuby/branches/testing/test/ruby/test_objc.rb 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/test/ruby/test_objc.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -71,6 +71,26 @@
assert_equal('xxxyyy', r)
end
+ class TestSuperMethod
+ def init
+ super
+ @foo = 42
+ self
+ end
+ attr_reader :foo
+ end
+ def test_super_method
+ obj = TestSuperMethod.alloc.init
+ assert_equal(42, obj.foo)
+ obj = TestSuperMethod.performSelector(:alloc).performSelector(:init)
+ assert_equal(42, obj.foo)
+ # FIXME this doesn't work yet
+ #obj = TestSuperMethod.new
+ #assert_equal(42, obj.foo)
+ obj = TestSuperMethod.performSelector(:new)
+ assert_equal(42, obj.foo)
+ end
+
def test_pure_objc_ivar
o = NSObject.alloc.init
assert_kind_of(NSObject, o)
@@ -147,5 +167,64 @@
assert_raise(ArgumentError) { NSStringFromRect([1, 2, 3, 4, 5]) }
end
+ class TestInitCallInitialize
+ attr_reader :foo
+ def initialize
+ @foo = 42
+ end
+ end
+ def test_init_call_initialize
+ o = TestInitCallInitialize.new
+ assert_equal(42, o.foo)
+ o = TestInitCallInitialize.alloc.init
+ assert_equal(42, o.foo)
+ end
+
+ def test_call_self
+ o = Object.new
+ assert_equal(o, o.self)
+ s = 'foo'
+ assert_equal(s, s.self)
+ n = 42
+ assert_kind_of(NSNumber, n.self)
+ assert_equal(42, n.self.intValue)
+ n = nil
+ assert_kind_of(NSNull, n.self)
+ assert_equal(NSNull.null, n.self)
+ # TODO this currently SEGV
+ #m = String
+ #assert_equal(m, m.self)
+ end
+
+ def test_call_superclass
+ o = Object.new
+ assert_equal(NSObject, o.superclass)
+ s = 'foo'
+ assert_equal(NSMutableString, s.superclass)
+ n = 42
+ assert_equal(NSNumber, n.superclass)
+ n = nil
+ assert_equal(NSObject, n.superclass)
+ end
+
+ def test_no_direct_nsobject_subclass
+ old_verbose = $VERBOSE
+ $VERBOSE = nil # no warn
+ klass = eval("class Foo < NSObject; end; Foo")
+ assert_equal(Object, klass.superclass)
+ $VERBOSE = old_verbose
+ end
+
+ class TestSuper1
+ def foo; 'xxx'; end
+ end
+ class TestSuper2 < TestSuper1
+ def bar; __super_objc_send__(:foo); end
+ end
+ def test_objc_super
+ o = TestSuper2.new
+ assert_equal('xxx', o.bar)
+ end
+
end
Copied: MacRuby/branches/testing/test-macruby/rubycocoa_test.rb (from rev 311, MacRuby/trunk/test-macruby/rubycocoa_test.rb)
===================================================================
--- MacRuby/branches/testing/test-macruby/rubycocoa_test.rb (rev 0)
+++ MacRuby/branches/testing/test-macruby/rubycocoa_test.rb 2008-07-06 22:18:19 UTC (rev 312)
@@ -0,0 +1,179 @@
+#!/usr/local/bin/macruby
+
+require "test/spec"
+require 'mocha'
+
+#require File.expand_path('../../lib/osx/cocoa', __FILE__)
+require 'osx/cocoa'
+
+class TestRubyCocoaStyleMethod < OSX::NSObject
+ def initialize
+ @set_from_initialize = 'represent!'
+ end
+
+ def perform_selector_with_object(sel, obj)
+ callMethod_withArgs(sel, obj)
+ end
+
+ def callMethod(method, withArgs:args)
+ send(method, *args)
+ end
+
+ def method_rubyCocoaStyle_withExtraArg(mname, rc_style, arg)
+ "#{mname}(#{rc_style}, #{arg})"
+ end
+
+ def method_notRubyCocoaStyle(first_arg, second_arg, third_arg)
+ end
+
+ def self.classMethod(mname, macRubyStyle:mr_style, withExtraArg:arg)
+ "#{mname}(#{mr_style}, #{arg})"
+ end
+end
+
+class TestRubyCocoaStyleSuperMethod < OSX::NSObject
+ def init
+ self if super_init
+ end
+end
+
+class NSObjectSubclassWithInitialize < OSX::NSObject
+ def initialize
+ @set_from_initialize = 'represent!'
+ end
+end
+
+class NSObjectSubclassWithoutInitialize < OSX::NSObject; end
+
+CONSTANT_IN_THE_TOPLEVEL_OBJECT_INSTEAD_OF_OSX = true
+
+describe "RubyCocoa layer, in general" do
+ xit "should load AppKit when the osx/cocoa file is loaded" do
+ Kernel.expects(:framework).with('AppKit')
+ load 'osx/cocoa.rb'
+ end
+
+ it "should set a global variable which indicates that a framework is being loaded" do
+ Kernel.expects(:__framework_before_rubycocoa_layer).with do |f|
+ $LOADING_FRAMEWORK.should.be true
+ f == 'Foo'
+ end
+ Kernel.framework 'Foo'
+ $LOADING_FRAMEWORK.should.be false
+ end
+end
+
+describe "NSObject additions" do
+ before do
+ @obj = TestRubyCocoaStyleMethod.alloc.init
+ end
+
+ it "should alias ib_outlet to ib_outlets" do
+ TestRubyCocoaStyleMethod.private_methods.should.include :ib_outlets
+ end
+
+ it "should call initialize from init if it exists" do
+ NSObjectSubclassWithInitialize.alloc.init.instance_variable_get(:@set_from_initialize).should == 'represent!'
+ NSObjectSubclassWithoutInitialize.alloc.init.instance_variable_get(:@set_from_initialize).should.be nil
+ end
+
+ it "should catch RubyCocoa style instance method, call the correct MacRuby style method and define a shortcut method" do
+ @obj.perform_selector_with_object('description', nil).should.match /^<TestRubyCocoaStyleMethod/
+ @obj.respond_to?(:callMethod_withArgs).should.be true
+ @obj.perform_selector_with_object('description', nil).should.match /^<TestRubyCocoaStyleMethod/
+ end
+
+ it "should catch RubyCocoa style instance methods that end with a underscore" do
+ @obj.callMethod_withArgs_('description', nil).should.match /^<TestRubyCocoaStyleMethod/
+ @obj.respond_to?(:callMethod_withArgs_).should.be true
+ end
+
+ it "should catch RubyCocoa style instance methods defined in Objective-C" do
+ color = NSColor.colorWithCalibratedRed(1.0, green:1.0, blue:1.0, alpha:1.0)
+ lambda { color.blendedColorWithFraction_ofColor(0.5, NSColor.greenColor) }.should.not.raise NoMethodError
+ end
+
+ it "should catch RubyCocoa style class methods defined in ruby" do
+ lambda { TestRubyCocoaStyleMethod.classMethod_macRubyStyle_withExtraArg(1, 2, 3) }.should.not.raise NoMethodError
+ TestRubyCocoaStyleMethod.respond_to?(:classMethod_macRubyStyle_withExtraArg).should.be true
+ end
+
+ it "should catch RubyCocoa style class methods defined in Objective-C" do
+ lambda { NSColor.colorWithCalibratedRed_green_blue_alpha(1.0, 1.0, 1.0, 1.0) }.should.not.raise NoMethodError
+ NSColor.respond_to?(:colorWithCalibratedRed_green_blue_alpha).should.be true
+ end
+
+ it "should still raise NoMethodError if a class method doesn't exist" do
+ lambda { NSColor.colorWithCalibratedRed_pink(1.0, 1.0) }.should.raise NoMethodError
+ end
+
+ it "should also work on other regular NSObject subclasses" do
+ nsstring = 'foo'
+ nsstring.insertString_atIndex('bar', 3)
+ nsstring.should == 'foobar'
+ end
+
+ it "should still raise a NoMethodError if the selector doesn't exist when a method is missing" do
+ lambda { @obj.does_not_exist }.should.raise NoMethodError
+ lambda { @obj.doesnotexist_ }.should.raise NoMethodError
+ lambda { @obj.doesnotexist }.should.raise NoMethodError
+ end
+
+ it "should be possible to call super_foo type methods" do
+ lambda { TestRubyCocoaStyleSuperMethod.alloc.init }.should.not.raise.exception
+ end
+
+ it "should handle objc_send style methods" do
+ nsstring = 'foo'
+ nsstring.objc_send(:insertString, 'bar', :atIndex, 3)
+ nsstring.should == 'foobar'
+ nsstring.objc_send(:description).should == 'foobar'
+ lambda { nsstring.objc_send(:does_not_exist) }.should.raise NoMethodError
+ end
+
+ it "should create MacRuby style method aliases for any method containing underscores" do
+ @obj.respond_to?(:"method:rubyCocoaStyle:withExtraArg:").should.be true
+ @obj.method('foo', rubyCocoaStyle:true, withExtraArg:false).should == 'foo(true, false)'
+ end
+
+ it "should not create MacRuby style method aliases for methods containing underscores if the arity doesn't match" do
+ @obj.respond_to?(:"method:notRubyCocoaStyle:").should.be false
+ end
+end
+
+describe 'OSX module' do
+ it "should exist" do
+ defined?(OSX).should.not.be nil # this is weird.. I haven't defined OSX yet?!
+ end
+
+ it "should load a framework into the runtime" do
+ OSX.require_framework 'WebKit'
+ defined?(WebView).should.not.be nil
+
+ OSX.require_framework '/System/Library/Frameworks/QTKit.framework'
+ defined?(QTMovie).should.not.be nil
+ end
+
+ it "should forward messages to Kernel if it responds to it" do
+ Kernel.expects(:NSRectFill).with(1, 2).times(2)
+ OSX::NSRectFill(1, 2)
+ OSX.respond_to?(:NSRectFill).should.be true
+ OSX::NSRectFill(1, 2)
+
+ lambda { OSX::NSRectFillllllll(1, 2) }.should.raise NoMethodError
+ end
+
+ it "should try to get missing constants from the toplevel object" do
+ OSX::CONSTANT_IN_THE_TOPLEVEL_OBJECT_INSTEAD_OF_OSX.should.be true
+ end
+
+ it "should still raise a NameError from OSX, not from the toplevel object, when a constant is missing" do
+ lambda { OSX::DOES_NOT_EXIST_IN_TOPLEVEL_OBJECT }.should.raise NameError
+
+ begin
+ OSX::DOES_NOT_EXIST_IN_TOPLEVEL_OBJECT
+ rescue NameError => e
+ e.message.should.include 'OSX::DOES_NOT_EXIST_IN_TOPLEVEL_OBJECT'
+ end
+ end
+end
\ No newline at end of file
Modified: MacRuby/branches/testing/vm.c
===================================================================
--- MacRuby/branches/testing/vm.c 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/vm.c 2008-07-06 22:18:19 UTC (rev 312)
@@ -14,6 +14,10 @@
#include "ruby/encoding.h"
#include "gc.h"
+#if WITH_OBJC
+NODE *rb_current_cfunc_node = NULL;
+#endif
+
#include "insnhelper.h"
#include "vm_insnhelper.c"
#include "vm_eval.c"
Modified: MacRuby/branches/testing/vm_eval.c
===================================================================
--- MacRuby/branches/testing/vm_eval.c 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/vm_eval.c 2008-07-06 22:18:19 UTC (rev 312)
@@ -72,7 +72,13 @@
cfp->method_id = id;
cfp->method_class = klass;
+#if WITH_OBJC
+ rb_current_cfunc_node = (NODE *)body;
+#endif
val = call_cfunc(body->nd_cfnc, recv, body->nd_argc, argc, argv);
+#if WITH_OBJC
+ rb_current_cfunc_node = NULL;
+#endif
if (reg_cfp != th->cfp + 1) {
SDR2(reg_cfp);
Modified: MacRuby/branches/testing/vm_insnhelper.c
===================================================================
--- MacRuby/branches/testing/vm_insnhelper.c 2008-07-06 22:09:00 UTC (rev 311)
+++ MacRuby/branches/testing/vm_insnhelper.c 2008-07-06 22:18:19 UTC (rev 312)
@@ -353,10 +353,6 @@
return Qnil; /* not reached */
}
-#if WITH_OBJC
-NODE *rb_current_cfunc_node = NULL;
-#endif
-
static inline VALUE
vm_call_cfunc(rb_thread_t *th, rb_control_frame_t *reg_cfp,
int num, ID id, VALUE recv, VALUE klass,
@@ -1130,6 +1126,11 @@
if (*pmn == NULL) {
const char *p, *mname;
long i;
+ mn = rb_objc_define_objc_mid_closure(recv, *pid, 0);
+ if (mn != NULL) {
+ *pmn = mn;
+ return;
+ }
mname = rb_id2name(*pid);
if (*pid > 1 && (p = strchr(mname, ':')) != NULL) {
char buf[512];
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080706/83820254/attachment-0001.html
More information about the macruby-changes
mailing list