|
From: Tim B. <tim...@gm...> - 2006-01-31 06:46:15
|
Hi David,
Thanks for your comments on the documentation.
I too have wanted to mix RubyCocoa into an existing application, but I
hadn't tried it until this evening, when I successfully converted one
of my pure Objective-C Cocoa projects to RubyCocoa. Here's my story:
First I added the RubyCocoa framework to the project in Xcode. In my
case, I right-clicked on the project name in the Groups & Files panel
in Xcode, then selected Add->Existing Frameworks... and navigated to
/Library/Frameworks/RubyCocoa.framework.
Next I replaced the contents of main.m with the following, taken from
the RubyCocoa Xcode templates:
---
#import <RubyCocoa/RBRuntime.h>
int main(int argc, const char *argv[])
{
return RBApplicationMain("rb_main.rb", argc, argv);
}
---
This is necessary to make sure that Ruby is properly initialized and
it also gives you a way to run some Ruby code when your program
starts. As far as I know, you *must* replace your main() to use
RubyCocoa, but you probably didn't have anything special there anyway
-- just a call to NSApplicationMain, which your converted app will
make with Ruby.
Then I added rb_main.rb to my project using Add->Existing Files... and
then finding and selecting one from a template-based RubyCocoa
application. For reference, this short file contains the following
Ruby code:
---
require 'osx/cocoa'
def rb_main_init
path =3D OSX::NSBundle.mainBundle.resourcePath.to_s
rbfiles =3D Dir.entries(path).select {|x| /\.rb\z/ =3D~ x}
rbfiles -=3D [ File.basename(__FILE__) ]
rbfiles.each do |path|
require( File.basename(path) )
OSX::NSLog "require #{File.basename(path)}"
end
end
if $0 =3D=3D __FILE__ then
rb_main_init
OSX.NSApplicationMain(0, nil)
end
---
It loads any ruby files in your application's resource directory and
then calls NSApplicationMain.
Then I built and tested my application. Everything seemed to work
just as before, but now my formerly mild-mannered Objective-C program
can speak Ruby.
From here forward, you can add Ruby files to your application and know
that all inline code in them will get executed when rb_main_init loads
the files during startup.
In my case, I added a console object that I've been writing/debugging
that let's me run irb inside a Cocoa app. Accessing my Objective-C
objects was a puzzle at first, but I managed to get to my top-level
document object (a game) from the NSDocumentController:
> game_controller =3D OSX::NSDocumentController.sharedDocumentController
> game =3D game_controller.documents.objectAtIndex(0)
From there, I could directly call the methods of my object from Ruby:
> game.start
> game.sendEvent_forPlayer(10, 0)
> game.stop
I'll test it more in the next few days, but as far as I can tell, the
transplant went smoothly.
Hope that helps,
Tim
|