もっとRubyCocoaでQuicksilverプラグインを書く
RubyCocoaを使ってQuicksilverプラグインを書く の続編です。 前回書いたあと、hisaさんからアドバイスをもらい、RubyCocoaでプラグインを書くことができるようになりました。
ポイントは以下の2つ。
- NSPrincipalClass
- RubyActionClass < OSX::QSActionProvider
コードは、CodeReposのものをupdateしておきました。 hisaさんコードがたくさん入っていますが、煮るなり焼くなり好きにせよとのことなので、前回と同じ修正BSDライセンスとします。
NSPrincipalClass
Quicksilver プラグインに限らず、Cocoaで何らかのBundleを書く際には、Info.plistの NSPrincipalClass にクラス名を指定しておくと、そのクラスの +load() メソッドが呼ばれてプラグインが組み込まれるようです。 なので、ここでRBBundleInit()を呼んでRubyCocoaを初期化すると。とてもスマート。 前回はこのことを知らずに、無理矢理なハックをしていたのでした。
RCLoader.m:
ここでは、NSPrincipalClassにRCLoaderというクラスを指定しています。
@implementation RCLoader + (void)load { static bool installed = 0; if (! installed) { if (! RBBundleInit("load_ruby.rb", [self class], self)) { installed = true; } } }
load_ruby.rb:
そんで、RubyCocoaの初期化の中で、必要な.rbを読み込んでおく、と。
def load_ruby_programs(bundle, logger) path = bundle.resourcePath.fileSystemRepresentation rbfiles = Dir.entries(path).select {|x| /\.rb\z/ =~ x} rbfiles -= [ File.basename(__FILE__) ] rbfiles.each do |path| require( File.basename(path) ) end end OSX.init_for_bundle do |bundle, param, logger| load_ruby_programs(bundle, logger) end
RubyActionClass < OSX::QSActionProvider
前回説明したように、QuicksilverのActionを記述するには、QSActionProviderを継承したクラスでメソッドを用意します。 今回は、RubyのクラスでQSActionProviderを実装します。RubyCocoaのパワーがすごすぎる。
class RubyAction < OSX::QSActionProvider def act(arg) val = arg.stringValue OSX::QSObject.objectWithString('Hello world, ' + val) end end
あとは、このRubyActionクラスを、Info.plistのactionClassに、actionSelectorをact:に指定しておけば、ちゃんとactが呼ばれます。
疑問
- OSX.require_framework とか使わないで、QSActionProviderとかのQS frameworkが使えてるのはなぜ?
- hisaさんは、この方法だとCPU usageが高くなると懸念されているのですが、僕のところではいまひとつ高くなってるように見えません。why?
まとめ
RubyCocoaで、Quicsilverプラグインを書く方法をまとめました。 これで、あとはRubyのクラスとInfo.plistを書くだけでどんどんプラグインが書けますね。みんながんばれ!
あと、自分でもイマイチだなーと思うことでも、何かしら書いて晒すことが大事なんだなと。そんで改善していければOKなんだ。 hisaさん、ありがとうございました。
- Newer: デブサミ 2008 (1)
- Older: Write a Quicksilver plugin with RubyCocoa
Comments:10
- hisa 08-02-06 (Wed) 17:35
-
おお、新しくなりましたね。
require_frameworkを明示的に書かなくていいのはすでにQSフレームワークがリンクされているからです。RubyCocoa内部で、QSフレームワークのクラス名が最初に書かれたときにconst_missingでフックされてクラスオブジェクトを探しにいってるはずです。
CPU usageはRubyCocoaのバージョンによったりするのかな?僕は10.5.2に入ってるのをそのまま使ってます。
Objective-Cでbool型を使えるんですね。知らんかった(忘れてた)。どうせなら初期値は0よりfalseの方がいいかも。
- mootoh 08-02-06 (Wed) 23:25
-
hisaさん:
フレームワーク
なるほどー。リンクしておけば、探しにいって見つかるのですね。
CPU usage
僕のとこでは、10.5.1 に付属のRubyCocoaです。 Activity Monitor で見ると、たしかにプラグインを有効にしてQuicksilverを起動した場合は、CPU usage が 2-4% になり、無効にしていれば0.5-1% が定常状態となり、CPU時間を食ってますね。プロファイラで調べたら分かるかな。
bool
確かにfalseで初期化すべきですね。やり忘れてました。
- kimuraw 08-02-07 (Thu) 1:08
-
こまかいですけどObjective-C的には大文字のBOOLでYES/NOです>hisa
ドキュメントされていませんがQuicksilverの機能としては、 Info.plistでQSLoadImmediatelyをtrueにすると NSPrincipalClassで指定したクラスの+(void)loadPlugInが呼ばれる、 というようになっているようです。 Crucible/Code/QSPlugIn.[hm]の_registerPluginのあたり。
- mootoh 08-02-08 (Fri) 1:16
-
kimurawさん:
たしかに、[currPrincipalClass loadPlugin] してますね。
Quicksilver/Pluginsにあるプラグインで使ってるものは見あたらないみたいですが…どういう意図なんでしょうね。
- kimuraw 08-02-09 (Sat) 11:00
-
~/Library/Application Support/Quicksilverにある、自分で入れたものでは
- Clipboard Module
- Services Menu Module
- Shelf Module
- Smoke Actions
が使っているようです。
- hisa 08-02-10 (Sun) 8:47
-
まだmootohさんのプラグインでは試してなくて、この前メールで送ったプラグインでのことなのですが、プラグインが無効になっている状態のQuicksilverを立ち上げてから有効にすると2-4%くらい(無効だと1%以下)なのですが、プラグインが有効になっている状態のQuicksilverを立ち上げると30-40%くらいから徐々にCPU usageが上がりファンが回り出します。
- mootoh 08-02-12 (Tue) 0:00
-
hisaさん:
hisaさんに送って頂いたプラグインでためしてみました。 たしかに、こちらを有効にするとCPU usageが50%程度に跳ね上がりますね… Shark.appで簡単にプロファイルとってみました。
http://gyazo.com/60b43424ea23b607f7614c4ca5e004a6.png http://gyazo.com/70e573f2b6c6ef4b7b78a1c56be2a583.png
objc_msgSendがdominantなのかなーと。ものすごい回数のobjc_msgSendが行われているのかと想像しています。
- konn 08-08-25 (Mon) 11:20
-
初めまして。konnと申します。
これを見て見様見真似で作ってみたのですが、RubyCocoa製のプラグインが複数ある場合、RubyCocoaの初期化を行なう load_ruby.rb の名前をそれぞれ変えないと正しく動作しないようです。
- mootoh 08-08-25 (Mon) 13:10
-
konn さん:
参照してくださってありがとうございます。 そうなんですよね、同じ名前で初期化してしまうとハングしてしまいます。
- konn 08-08-25 (Mon) 21:45
-
こちらを参考にして作ったプラグインを公開してみました。
http://d.hatena.ne.jp/mr_konn/20080825/1219666577
ありがとうございました。興味がおありでしたらどうぞ。
Trackbacks:1
- Trackback URL for this entry
- http://blog.deadbeaf.org/2008/02/06/quicksilver-plugin-with-rubycocoa-more/trackback/
- Listed below are links to weblogs that reference
- もっとRubyCocoaでQuicksilverプラグインを書く from mootoh.log
- trackback from はてな使ったら負けだと思っている 08-08-27 (Wed) 22:06
-
[RubyCocoa][QSRubyModule][Ruby][プログラミング]Ruby on Quicksilver…
紫ログ:Gauche on Quicksilver - livedoor Blog(ブログ)を見て良いなぁと思ったのでRuby版を作ってみた。 mootoh.log - もっとRubyCocoaでQuicksilverプラグインを書くを見ていつかなにか作りたいなぁと思…

