機能 #1063
openプラグイン着脱時にイベントが発生する機能
Description
プラグイン着脱時に何も起きないので、イベントを発生させる機能がほしい。
ので、作ります。
Updated by あひる 家鴨 over 7 years ago
ちょうど悩み始めてました。
:"plugin_load_status_#{plugin_slug}"
とかどうでしょう。
Updated by あひる 家鴨 over 7 years ago
Plugin.call() の仕様をど忘れしたのであれですが、Plugin.call(:イベントスラグ, 着脱の状態(boolean), description)
とかできるといいのかな
Updated by あひる 家鴨 over 7 years ago
最初のやつ、勘違いです。
Plugin.call(:plugin_load_status, plugin_slug, status, description)
がいいかも
Updated by toshi_a 初音 over 7 years ago
プラグインのslugはイベント名としてvalidなので可能だけど、 #1061 ではイベント名を動的に生成するか迷った結果、イベント名は固定で(key, value)を引数としたんですが、理由としては
- 動的に名前を生成すると、listenerを登録する時にエディタで補完が効きづらくなる(単一のトークンとなるため)
- どのような設定が変更されたかを知りたい場合、イベント名が動的に生成されるとトラックできない
というのがありました。一方でこの方法だと
- すべてのイベントがPlugin slugを確認するif式をもつ必要がある
という問題があります。とはいえ、このイベントを受け取る動機って、不特定のプラグインがロードされた時になにかしたいとかだと思うので、イベント名は固定が良さそうと思います
Updated by あひる 家鴨 over 7 years ago
イベント名は固定で行こうと思います。
特に mikutter 的な命名規則がなければ、このイベントは plugin_load_status というイベント名にしようと思ってますが、いかがでしょうか。
引数は前述の通り、プラグインスラグ(string)・プラグインの着脱の状態(boolean)・詳細(string)を考えています。
Updated by toshi_a 初音 over 7 years ago
細かい話だけど、pluginの着脱はイベント分けたい気がします。mikutterだと抽出タブやアカウントの追加、削除とかの単位でイベント分けてるので。
詳細とかをイベントとして送ってしまうのはいいですね。具体的にはどんな内容を想定してますか。specファイルのdescription?
Updated by あひる 家鴨 over 7 years ago
まずイベント分けることに関してですが、賛成です。
plugin_load と plugin_unload って感じに分けますかね。
ついでにロードされてるプラグイン一覧取得もほしいですね。
ロードされてるやつ、されてないやつ含めて
これはまた別のチケットになりそうですが。
description については、着脱時の状態を送ろうかと考えてました。
description というより reason っぽいですが。
失敗した時の理由とかをいれておきたかったです。
Updated by あひる 家鴨 over 7 years ago
成功時は spec ファイル丸ごと投げて、 失敗時は失敗の理由とかどうですかね
もしくは description は spec を返し、error の様なものを最後に持てば住み分けができそう。
Updated by toshi_a 初音 over 7 years ago
思いついたことをまとめて書かなくて申し訳ないんだけど、イベントが現在形だと、そのイベントをフィルタで止めてしまえばプラグインのロードを止められそうな感じになるので、既にロードが終わったことを通知しているだけなら、過去形にしたほうがいいと思います。
あと知ってるかわからないけど、面白い裏技があって
Plugin[:extract] # => #<Plugin: slug=extract>
プラグインオブジェクトが既にあれば得られるんだけど
Plugin[:extract].spec # {:slug=>:extract, :depends=>{:mikutter=>"0.2", :plugin=>["gtk", "settings", "gui", "uitranslator", "skin"]}, ...
と、specファイルの中身得ることが出来ます(specファイルがない場合は、slugなどの基本的な項目を埋めたダミーのHashオブジェクトが返される)。
PluginオブジェクトはDiva::Modelとかではないのであまりイベントで投げたくないですが、specはHashなので付けてもいいかも。その場合、そもそもslugを投げなくても、specに入っているので要らないっちゃ要らないですね。
一方で、今のところはPlugin[slug]でこれだけの情報が得られるので、slugだけでいいという考え方もあります。
Updated by あひる 家鴨 over 7 years ago
知らなかったでござるよ
load の引数に spec きてたので、それそのまま横流しすればいいんじゃねといった感じでした。
Updated by あひる 家鴨 over 7 years ago
どういった理由でロードされなかったか、ですね。
例えばそんなスラグなかったんやとかロードしようとしたけどプラグインの対応してるmikutterのバージョンちがうとか
そんなところです
Updated by toshi_a 初音 over 7 years ago
プラグインをロードするには、 Miquire::Plugin.load
を呼ぶけど、これの例外だか戻り値だか(曖昧)でエラー報告してくれるので、成否は取れますよ。ロードエラーは、結局プラグインをロードできてないので、そのことを他のプラグインが検出できることが有用なケースが思いつかないんですが、そういうのも欲しいですか
Updated by あひる 家鴨 over 7 years ago
目の前のことだけ考えると、Plugin Reloader に必要です。
プラグインが入っているか、失敗しているのかなど、細かいことを色々やりたいので
将来的に有用かどうかはわかりませんが、プラグインのロード状態が把握できていると、このプラグインが入っている場合はこんなこと動作をさせるみたいなプラグインとか作れそう
Updated by toshi_a 初音 over 7 years ago
それだったらやっぱり、Miquire::Plugin.loadがロードが正しく行えたかを返すので十分で、エラーをイベントで通知するのは有用ではないと思います。
いずれにせよ、プラグインのロード・アンロード後にそれを通知するイベントは有用だと思うので、それはmergeしたいです。
Updated by あひる 家鴨 over 7 years ago
実装で悩んでます。
ロード・アンロードの際に、対象の spec が valid か確認していて、invaild だと false を返してロードしないといった仕様ですが、
この場合、失敗の際にイベントを発生させるべきか否か迷ってます。
・イベントは発生させるが、引数の spec は nil
・イベントをそもそも発生させない
など考えられますが、どういった実装だと好ましいでしょうか。
Spec モデルのロードの状態を持たせてしまえば、イベントを発生させた方がいい気がしますが、考えがうまくまとまりません。
Updated by toshi_a 初音 over 7 years ago
plugin_loadedイベントは、新たなプラグインがロードされたことを通知するものなので、失敗したときはイベントを発生しないようにするのが良いと思います