quartz-research-note/content/mimiumのプラグインシステム.md
松浦 知也 Matsuura Tomoya a422b92b0c
All checks were successful
Build / build (push) Successful in 4m29s
[obsidian] vault backup: 2024-10-15 17:14:07[
2024-10-15 17:14:07 +09:00

2.5 KiB
Raw Permalink Blame History

date
2024-10-15 15:25

#mimium

スケジューラーをプラグインとして切り離すシステムについて考えている。

プラグインの種類は主に3つに分けられる。

  1. IOプラグイン ホストのシステムとのIOを担当する、Rustで外部関数のFFIを書く必要があるもの。printlnみたいなやつ。インスタンスの生成とか破棄については考える必要がない
  2. ネイティブUGenクラスにおけるコンストラクタに相当する関数がエクスポートされてて、実行するとクロージャとしてそのインスタンスが帰ってくるもの。
  3. システムプラグイン今回考えたいもの。原則1VMに対して1インスタンスしか存在せず、on_initとかon_sampleみたいなシステムの関数にフックして任意の処理を実行しつつ、mimium側からもいくつかの関数を通じてアクセスができる_mimium_schedule_atみたいなこと)

システムプラグインについて考えると所有権が結構めんどくさい。VMの中ではIOプラグインとネイティブUGenとシステムプラグインは同じCallExtFunもしくはCallExtClsで扱えるようにしたい。がシステムプラグインはVMホスト側というかオーディオドライバーからと、mimium側からRustのクロージャインスタンスとを通じて双方向からアクセスされることになる。システムプラグインのインスタンスはクロージャとVM本体と両方から参照されることになるので、Rc<Refcell<_>>でラップするとかしないといけない。


struct SystemPluginSignature{
	name:String,
	fun: Rc<RefCell<dyn Fn(&mut Machine)->ReturnCode>>,
	ty:TypeNodeId
}

trait SystemPlugin{
 fn on_init(&mut self, machine:&mut Machine);
 fn on_sample(&mut self, machine:&mut Machine);
 fn get_plugin_signature(self)->Vec<???>
}

impl<T:SystemPlugin> for Rc<RefCell<T>>{
 fn get_plugin_signature(&self)->Vec<SystemPluginSignature>{
	 
 }
}

struct Scheduler{
...
}
impl SystemPlugin for Scheduler{
..
	fn get_plugin_signature(self)->?{
		
	}
}

プラグインの実装側では当然いくつかメンバ関数(&mut self&mut Machineを引数にとる)を実装して、それをmimium側にエクスポートするみたいなことをしたい

が、そうするとSystemPluginSignatureの型の中にSelfが混ざってくるのを避けられず、object-safeにするのが難しい