Files
hakorune/docs/archive/design/NYASHFLOW_PROJECT_HANDOVER.md

565 lines
15 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# 🎨 NyashFlow プロジェクト引き継ぎドキュメント
## 📅 作成日: 2025-01-09
## 👤 作成者: Claude + ユーザー(にゃ〜)
---
# 🌟 プロジェクト概要
## 🎯 NyashFlowとは
**Nyashプログラミング言語のビジュアルプログラミング環境**
- 「Everything is Box」の哲学を視覚的に表現
- Boxをドラッグ&ドロップでつなげてプログラミング
- 教育的価値の高いツールを目指す
## 🚀 プロジェクトの経緯
### 1⃣ **始まりegui研究**
- NyashにGUI機能EguiBoxを実装
- Windows版メモ帳、エクスプローラー風アプリを作成
- BMPアイコン表示まで成功
### 2⃣ **ビジュアルプログラミングへの発展**
- eguiの可能性を探る中で、ードベースUIの構想が生まれる
- 「Everything is Box」を視覚化するアイデア
- 教育現場での活用を想定
### 3⃣ **CharmFlow v5からの学び**
- ユーザーが以前作成した大規模プロジェクト
- JavaScript + NyaMeshP2Pで実装
- **失敗から学んだこと**
- カプセル化の欠如 → スパゲティコード化
- 役割分担の不明確 → 保守困難
- 過剰な機能 → 複雑化
### 4⃣ **NyashFlowの方向性決定**
- Rust + WebAssemblyで実装
- Nyashとは別プロジェクトとして独立
- シンプルさを最優先
---
# 🏗️ 技術設計
## 📐 アーキテクチャ
### **基本構成**
```
nyashflow/
├── Cargo.toml # プロジェクト設定
├── src/
│ ├── lib.rs # ライブラリエントリ
│ ├── main.rs # デスクトップ版エントリ
│ ├── visual/ # 🎨 ビジュアル表示層
│ │ ├── mod.rs
│ │ ├── node_renderer.rs # ノード描画
│ │ ├── connection_renderer.rs # 接続線描画
│ │ └── canvas_manager.rs # キャンバス管理
│ ├── execution/ # ⚡ 実行エンジン層
│ │ ├── mod.rs
│ │ ├── interpreter_bridge.rs # Nyashインタープリタ連携
│ │ └── data_flow.rs # データフロー管理
│ ├── interaction/ # 🖱️ ユーザー操作層
│ │ ├── mod.rs
│ │ ├── drag_drop.rs # ドラッグ&ドロップ
│ │ ├── selection.rs # 選択処理
│ │ └── context_menu.rs # 右クリックメニュー
│ ├── model/ # 📦 データモデル層
│ │ ├── mod.rs
│ │ ├── visual_node.rs # ノード定義
│ │ ├── connection.rs # 接続定義
│ │ └── project.rs # プロジェクト管理
│ └── wasm/ # 🌐 WebAssembly層
│ ├── mod.rs
│ └── bridge.rs # JS連携
├── web/ # 🌐 Web用リソース
│ ├── index.html
│ ├── style.css
│ └── pkg/ # wasm-pack出力
└── examples/ # 📚 サンプル
└── basic_flow.rs
```
### **設計原則**
#### 1. **徹底的なカプセル化**
```rust
pub struct VisualNode {
// 🔒 すべてプライベート
id: NodeId,
node_type: BoxType,
position: Pos2,
#[serde(skip)]
internal_state: NodeState,
}
impl VisualNode {
// 🌍 公開APIは最小限
pub fn get_id(&self) -> NodeId { self.id }
pub fn get_type(&self) -> &BoxType { &self.node_type }
pub fn set_position(&mut self, pos: Pos2) {
// バリデーション付き
if self.validate_position(pos) {
self.position = pos;
}
}
}
```
#### 2. **明確な責任分離**
```rust
// ❌ 悪い例CharmFlowの失敗
impl EverythingManager {
fn handle_everything(&mut self, event: Event) {
// 描画もイベントも実行も全部...
}
}
// ✅ 良い例(単一責任)
impl NodeRenderer {
pub fn render(&self, node: &VisualNode, ui: &mut Ui) {
// 描画だけ!
}
}
impl DragDropHandler {
pub fn handle_drag(&mut self, event: DragEvent) {
// ドラッグ処理だけ!
}
}
```
#### 3. **コード品質の維持**
- 各ファイル100行以内を目標
- 関数は30行以内
- ネストは3階層まで
- 必ずテストを書く
---
# 💻 実装詳細
## 🎨 ビジュアルノードシステム
### **ノードの種類(初期実装)**
```rust
#[derive(Debug, Clone, PartialEq)]
pub enum BoxType {
// 基本Box
StringBox,
IntegerBox,
BoolBox,
// 操作Box
MathBox,
ConsoleBox,
// コンテナBox
ArrayBox,
}
impl BoxType {
pub fn color(&self) -> Color32 {
match self {
BoxType::StringBox => Color32::from_rgb(100, 149, 237),
BoxType::IntegerBox => Color32::from_rgb(144, 238, 144),
BoxType::MathBox => Color32::from_rgb(255, 182, 193),
// ...
}
}
pub fn icon(&self) -> &str {
match self {
BoxType::StringBox => "📝",
BoxType::IntegerBox => "🔢",
BoxType::MathBox => "🧮",
// ...
}
}
}
```
### **接続システム**
```rust
pub struct Connection {
id: ConnectionId,
from_node: NodeId,
from_port: PortId,
to_node: NodeId,
to_port: PortId,
}
pub struct Port {
id: PortId,
name: String,
port_type: PortType,
data_type: DataType,
}
#[derive(Debug, Clone, PartialEq)]
pub enum PortType {
Input,
Output,
}
```
## ⚡ 実行エンジン
### **Nyashインタープリタ連携**
```rust
use nyash::interpreter::{NyashInterpreter, NyashValue};
pub struct ExecutionEngine {
interpreter: NyashInterpreter,
node_mapping: HashMap<NodeId, String>, // NodeId → Nyash変数名
}
impl ExecutionEngine {
pub fn execute_flow(&mut self, nodes: &[VisualNode], connections: &[Connection]) -> Result<(), ExecutionError> {
// 1. トポロジカルソート
let sorted_nodes = self.topological_sort(nodes, connections)?;
// 2. Nyashコード生成
let nyash_code = self.generate_nyash_code(&sorted_nodes, connections);
// 3. 実行
self.interpreter.execute(&nyash_code)?;
Ok(())
}
}
```
## 🌐 WebAssembly統合
### **WASM Bridge**
```rust
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub struct NyashFlowApp {
#[wasm_bindgen(skip)]
nodes: Vec<VisualNode>,
#[wasm_bindgen(skip)]
connections: Vec<Connection>,
}
#[wasm_bindgen]
impl NyashFlowApp {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
console_error_panic_hook::set_once();
Self {
nodes: vec![],
connections: vec![],
}
}
pub fn add_node(&mut self, node_type: &str, x: f32, y: f32) -> u32 {
// ノード追加処理
}
pub fn connect_nodes(&mut self, from_id: u32, to_id: u32) -> Result<(), JsValue> {
// 接続処理
}
pub fn execute(&self) -> Result<String, JsValue> {
// 実行処理
}
}
```
---
# 🚀 開発ロードマップ
## Phase 1: MVP1-2週間
- [ ] 基本的なノード表示
- [ ] 3種類のBoxString, Integer, Console
- [ ] ドラッグでノード移動
- [ ] 接続線の表示
- [ ] 簡単な実行ConsoleBoxでprint
## Phase 2: 基本機能2-3週間
- [ ] 全基本Boxタイプ実装
- [ ] 接続の作成/削除
- [ ] 右クリックメニュー
- [ ] プロジェクト保存/読み込みJSON
- [ ] 実行結果の表示
## Phase 3: WebAssembly対応2週間
- [ ] wasm-pack設定
- [ ] Web用UI調整
- [ ] ブラウザでの動作確認
- [ ] GitHubPages公開
## Phase 4: 高度な機能1ヶ月
- [ ] カスタムBox作成
- [ ] デバッグ機能(ステップ実行)
- [ ] アニメーション(データフロー可視化)
- [ ] テンプレート機能
---
# 📝 実装上の注意点
## ⚠️ CharmFlowの失敗を避ける
### 1. **過剰な機能を避ける**
- P2P通信 → 不要
- プラグインシステム → Phase 4以降
- 複雑なIntent → 直接的なデータフロー
### 2. **コードレビューポイント**
```rust
// 毎回チェック
- [ ] ファイルが100行を超えていないか?
- [ ] 関数が30行を超えていないか?
- [ ] Private Fieldsを使っているか
- [ ] 責任が単一か?
- [ ] テストを書いたか?
```
### 3. **定期的なリファクタリング**
- 週1回はコード全体を見直す
- 重複を見つけたら即座に統合
- 複雑になったら分割
## 🧪 テスト戦略
```rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_node_creation() {
let node = VisualNode::new(BoxType::StringBox, Pos2::new(100.0, 100.0));
assert_eq!(node.get_type(), &BoxType::StringBox);
}
#[test]
fn test_connection_validation() {
// StringBox → ConsoleBoxは接続可能
assert!(Connection::can_connect(
&BoxType::StringBox,
&PortType::Output,
&BoxType::ConsoleBox,
&PortType::Input
));
}
}
```
---
# 🎯 成功の指標
## 定量的指標
- コード行数5,000行以内CharmFlowの1/10
- ファイル数50個以内
- テストカバレッジ80%以上
- 起動時間1秒以内
## 定性的指標
- 小学生でも使える直感性
- Nyashの哲学が伝わる
- メンテナンスが苦にならない
- 拡張が容易
---
# 🔗 参考資料
## 技術資料
- [egui公式ドキュメント](https://docs.rs/egui)
- [wasm-bindgen book](https://rustwasm.github.io/wasm-bindgen/)
- [Nyashプロジェクト](../../../README.md)
## 設計思想
- CharmFlow v5の経験反面教師
- 「Everything is Box」哲学
- シンプル・イズ・ベスト
## 類似プロジェクト
- Scratch教育的UI
- Node-REDフロープログラミング
- Unreal Engine Blueprintゲーム向け
---
# 💬 最後に
このプロジェクトは「プログラミングを視覚的に理解する」という夢を実現するものです。
CharmFlowの失敗から学び、Nyashの哲学を活かし、シンプルで美しいツールを作りましょう。
**「Everything is Box」が「Everything is Visible Box」になる瞬間を楽しみにしています**
にゃ〜🎨✨
---
# 🔮 P2PBox/intentbox設計の活用2025-01-09追記
## 🎯 NyaMesh設計から学ぶこと
### **核心概念の抽出**
NyaMeshの`P2PBox``intentbox`から、NyashFlowに活用できる**本質的な設計思想**
1. **intentbox = 通信世界の定義**
- プロセス内、WebSocket、メモリ共有など
- 通信の「場」を抽象化
2. **P2PBox = その世界に参加するノード**
- どのintentboxに所属するかで通信相手が決まる
- シンプルなsend/onインターフェース
### **NyashFlowへの応用シンプル版**
```rust
// ⚡ ローカル実行モードPhase 1-2
pub struct LocalExecutionContext {
// ビジュアルノード間のデータフロー管理
data_bus: DataFlowBus,
}
// 🌐 将来の拡張Phase 4以降
pub trait ExecutionContext {
fn send_data(&mut self, from: NodeId, to: NodeId, data: NyashValue);
fn on_data(&mut self, node: NodeId, callback: DataCallback);
}
// 異なる実行コンテキストの実装例
impl ExecutionContext for LocalExecutionContext { ... }
impl ExecutionContext for RemoteExecutionContext { ... } // WebSocket経由
impl ExecutionContext for SharedMemoryContext { ... } // 高速共有メモリ
```
### **段階的な導入計画**
#### Phase 1-2: シンプルなデータフロー
```rust
// 最初はシンプルに
pub struct DataFlowEngine {
nodes: HashMap<NodeId, VisualNode>,
connections: Vec<Connection>,
}
impl DataFlowEngine {
pub fn execute(&mut self) {
// 単純な同期実行
for connection in &self.connections {
let data = self.get_output_data(connection.from_node);
self.set_input_data(connection.to_node, data);
}
}
}
```
#### Phase 3-4: 抽象化された実行コンテキスト
```rust
// P2PBox的な抽象化を導入
pub struct VisualNodeBox {
id: NodeId,
context: Box<dyn ExecutionContext>, // どの「世界」で実行するか
}
impl VisualNodeBox {
pub fn send(&self, data: NyashValue, to: NodeId) {
self.context.send_data(self.id, to, data);
}
pub fn on_receive<F>(&mut self, callback: F)
where F: Fn(NyashValue) + 'static {
self.context.on_data(self.id, Box::new(callback));
}
}
```
### **実用的な応用例**
#### 1. **マルチスレッド実行(ローカル)**
```rust
// 重い処理を別スレッドで
let math_context = ThreadedExecutionContext::new();
let math_node = VisualNodeBox::new(BoxType::MathBox, math_context);
```
#### 2. **リアルタイムコラボレーション(将来)**
```rust
// WebSocketで他のユーザーと共有
let collab_context = WebSocketContext::new("wss://nyashflow.example.com");
let shared_node = VisualNodeBox::new(BoxType::SharedBox, collab_context);
```
#### 3. **デバッグモード**
```rust
// すべてのデータフローを記録
let debug_context = RecordingContext::new();
// 後でデータフローを再生・分析可能
```
### **設計上の重要な判断**
1. **最初はローカル実行のみ**
- P2P機能は作らないCharmFlowの教訓
- でも将来の拡張性は確保
2. **インターフェースの統一**
- send/onのシンプルなAPIを維持
- 実行コンテキストは隠蔽
3. **段階的な複雑性**
- Phase 1-2: 同期的なローカル実行
- Phase 3: 非同期実行対応
- Phase 4: リモート実行(必要なら)
### **実装の指針**
```rust
// ❌ 避けるべき実装CharmFlow的
struct EverythingNode {
p2p_manager: P2PManager,
intent_bus: IntentBus,
websocket: WebSocket,
// ... 100個の機能
}
// ✅ 推奨される実装NyashFlow的
struct VisualNode {
data: NodeData,
// 実行コンテキストは外部から注入
}
struct ExecutionEngine {
context: Box<dyn ExecutionContext>,
// コンテキストを差し替え可能
}
```
### **まとめ:「いいとこ取り」の精神**
- **P2PBox/intentboxの優れた抽象化**を参考に
- **最初はシンプルに**実装
- **将来の拡張性**を設計に組み込む
- **過剰な機能は避ける**
これにより、NyashFlowは
- 初期は単純なビジュアルプログラミング環境
- 必要に応じて高度な実行モデルに拡張可能
- CharmFlowの失敗を繰り返さない
---
## 📋 チェックリスト(開発開始時)
- [ ] このドキュメントを読み終えた
- [ ] Nyashプロジェクトをビルドできる
- [ ] eguiのサンプルを動かした
- [ ] プロジェクトフォルダを作成した
- [ ] 最初のコミットをした
頑張ってにゃ〜!🚀