2. The RubyCocoa Jukebox
2.1 Now the embarrassingly easy part
To access this library from RubyCocoa, all that we need to do is define an Objective-C class to wrap the jukebox structure and provide messages to access the API.
2.2 Jukebox.h
Here’s the header file for our Objective-C wrapper. Since our class methods get looked up at runtime, we can leave them out of the header file (which may or may not be advisable, I’ll leave that decision to you).
#import <Cocoa/Cocoa.h>
#import "cdjukebox.h"
@interface Jukebox : NSObject {
CDJukebox *jukebox;
}
@end2.3 Jukebox.m
Here’s the implementation of the Objective-C wrapper class. This is the hardest part of the whole process, and it’s not much of a challenge.
#import "Jukebox.h"
@implementation Jukebox
- (Jukebox *) initWithUnit:(int) unit {
jukebox = new_jukebox();
assign_jukebox(jukebox, unit);
return self;
}
- (void) seekDisc:(int)disc track:(int)track {
jukebox_seek(jukebox, disc, track, 0);
}
- (double) seekTime {
return get_avg_seek_time(jukebox);
}
- (void) dealloc {
free_jukebox(jukebox);
[super dealloc];
}
@end
// This initialization function gets called when we import the Ruby module.
// It doesn't need to do anything because the RubyCocoa bridge will do
// all the initialization work.
void Init_jukebox() { }2.4 Let's build and test it
You can compile the example with the following command:
% gcc -o jukebox.bundle -bundle -framework Foundation cdjukebox.c Jukebox.m
The extension is compiled into a file named jukebox.bundle. You can import it into ruby sessions that you start in the same working directory. To make it available from anywhere on your system, copy it to the appropriate site_ruby directory. If you’re running with the Apple-installed version of Ruby, this is probably /usr/lib/ruby/site_ruby/1.8. If you’ve built your own version from the Ruby sources, this is probably /usr/local/lib/ruby/site_ruby/1.8.
To test the extension, jump into irb and type the commands in the session log shown below:
% irb irb(main):001:0> require 'osx/cocoa' => true irb(main):002:0> require 'jukebox' => true irb(main):003:0> OSX::ns_import :Jukebox => OSX::Jukebox irb(main):004:0> j = OSX::Jukebox.alloc.initWithUnit(13) allocating jukebox assigning jukebox to unit 13 => #<OSX::Jukebox:0x3ad11c class='Jukebox' id=0x1159620> irb(main):005:0> j.seekDisc(3, :track, 16) seeking disc 3 and track 16 for player 13 => nil irb(main):006:0> k = j => #<OSX::Jukebox:0x3ad11c class='Jukebox' id=0x1159620> irb(main):007:0> k.seekDisc(3, :track, 16) seeking disc 3 and track 16 for player 13 => nil irb(main):008:0> k.seekTime getting seek time for unit 13 => 54.321 irb(main):009:0> k = 0 => 0 irb(main):010:0> j = 0 => 0 irb(main):011:0> puts "the jukebox hasn't been freed yet" the jukebox hasn't been freed yet => nil irb(main):012:0> GC.start # explicitly call the ruby garbage collector disposing of jukebox with unit id 13 => nil irb(main):013:0> quit
Did you find an error? Is something missing? Post your comment or suggestion below!
Comments (0) post