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

53 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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<_>>`でラップするとかしないといけない。
```rust
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にするのが難しい