Files
hakorune/docs/説明書/reference/box-design/plugin-system.md

158 lines
4.1 KiB
Markdown
Raw Normal View History

# Nyash Box プラグインシステム設計
## 概要
Nyashの「Everything is Box」哲学を維持しながら、Boxの実装をプラグイン化できるシステム。ビルトインBoxとプラグインBoxを透過的に切り替え可能。
## 🎯 設計原則
1. **シンプル** - 設定ファイル1つで切り替え
2. **透過的** - Nyashコードの変更不要
3. **統一的** - ビルトインもプラグインも同じBox
## 📋 プラグイン定義YAML署名DSL
```yaml
# filebox.plugin.yaml
schema: 1
plugin:
name: filebox
version: 1
apis:
# 静的メソッド(::
- sig: "FileBox::open(path: string, mode?: string) -> FileBox"
doc: "Open a file with optional mode"
- sig: "FileBox::exists(path: string) -> bool"
doc: "Check if file exists"
# インスタンスメソッド(#
- sig: "FileBox#read(size?: int) -> string"
doc: "Read file content"
- sig: "FileBox#write(content: string) -> int"
doc: "Write to file"
- sig: "FileBox#close() -> void"
doc: "Close file handle"
```
### 署名DSL仕様
- **静的メソッド**: `Type::method()` - C++風の`::`記法
- **インスタンスメソッド**: `Type#method()` - Ruby風の`#`記法
- **オプショナル引数**: `arg?: type` - `?`サフィックス
- **戻り値**: `-> type` - 矢印記法
## 🔧 設定ファイルnyash.toml
```toml
# プロジェクトルートのnyash.toml
[plugins]
FileBox = "filebox" # FileBoxはプラグイン版を使用
# StringBox = "mystring" # コメントアウト = ビルトイン使用
```
## 🏗️ アーキテクチャ
### 1. Boxレジストリ
```rust
// 起動時の動作
let mut registry = HashMap::new();
// 1. ビルトインBoxを登録
registry.insert("FileBox", BoxProvider::Builtin(native_filebox));
registry.insert("StringBox", BoxProvider::Builtin(native_stringbox));
// 2. nyash.toml読み込み
let config = parse_nyash_toml()?;
// 3. プラグイン設定で上書き
for (box_name, plugin_name) in config.plugins {
registry.insert(box_name, BoxProvider::Plugin(plugin_name));
}
```
### 2. 透過的なディスパッチ
```nyash
# Nyashコード変更不要
local file = new FileBox("test.txt")
file.write("Hello, plugin!")
local content = file.read()
```
内部動作:
1. `new FileBox` → レジストリ検索
2. `BoxProvider::Plugin("filebox")` → プラグインロード
3. BID-FFI経由で実行
### 3. PluginBoxプロキシ
```rust
// すべてのプラグインBoxの統一インターフェース
pub struct PluginBox {
plugin_name: String,
handle: BidHandle, // プラグイン内のインスタンス
}
impl NyashBox for PluginBox {
// NyashBoxトレイトの全メソッドを
// FFI経由でプラグインに転送
}
```
## 📦 プラグイン実装例
```rust
// plugins/filebox/src/lib.rs
#[no_mangle]
pub extern "C" fn filebox_open(
path: *const c_char,
mode: *const c_char
) -> BidHandle {
// ファイルを開いてハンドルを返す
}
#[no_mangle]
pub extern "C" fn filebox_read(
handle: BidHandle,
size: i32
) -> *const u8 {
// ファイルを読む
}
```
## 🚀 段階的導入計画
### Phase 1: 基本実装(現在)
- [x] BID-FFI基盤
- [x] FileBoxプラグイン実装
- [ ] nyash.tomlパーサー
- [ ] PluginBoxプロキシ
- [ ] 手動プラグインロード
### Phase 2: 開発体験向上
- [ ] YAMLからFFIコード自動生成
- [ ] エラーメッセージ改善
- [ ] プラグインテンプレート
### Phase 3: エコシステム
- [ ] プラグインレジストリ
- [ ] バージョン管理
- [ ] 依存関係解決
## 🎉 利点
1. **ビルド時間短縮** - 使わないBoxはコンパイル不要
2. **動的拡張** - 再コンパイルなしで新Box追加
3. **Everything is Box維持** - 哲学は変わらない
4. **段階的移行** - 1つずつBoxをプラグイン化
## 📚 関連ドキュメント
- [BID-FFI仕様](./ffi-abi-specification.md)
- [Everything is Box哲学](./everything-is-box.md)
- [実装タスク](../../../予定/native-plan/issues/phase_9_75g_0_chatgpt_enhanced_final.md)