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 |