/*! * Nyash P2P Channel System - Arrow構文によるBox間通信 * * alice >> bob でメッセージ送信を可能にする * Everything is Box哲学に基づくP2P通信システム */ use crate::box_trait::{BoxBase, BoxCore, NyashBox, StringBox, VoidBox}; use std::any::Any; use std::collections::HashMap; use std::fmt::{Debug, Display}; use std::sync::{Arc, Mutex, Weak}; /// チャンネル - Box間の通信路 #[derive(Clone)] pub struct ChannelBox { /// 送信者の名前 pub sender_name: String, /// 受信者の名前 pub receiver_name: String, /// リンクされたBox(弱参照) linked_boxes: Arc>>>>, /// メッセージハンドラー handlers: Arc) -> Box + Send>>>>, /// Box基底 base: BoxBase, } impl ChannelBox { /// 新しいチャンネルを作成 pub fn new(sender: &str, receiver: &str) -> Self { Self { sender_name: sender.to_string(), receiver_name: receiver.to_string(), linked_boxes: Arc::new(Mutex::new(HashMap::new())), handlers: Arc::new(Mutex::new(HashMap::new())), base: BoxBase::new(), } } /// Boxをリンク pub fn link(&self, name: &str, target: Arc>) { self.linked_boxes .lock() .unwrap() .insert(name.to_string(), Arc::downgrade(&target)); } /// メッセージハンドラーを登録 pub fn register_handler(&self, method: &str, handler: F) where F: Fn(Box) -> Box + Send + 'static, { self.handlers .lock() .unwrap() .insert(method.to_string(), Box::new(handler)); } /// メソッド呼び出しを実行 pub fn invoke(&self, method: &str, args: Vec>) -> Box { // "*" はブロードキャスト if self.receiver_name == "*" { return self.broadcast(method, args); } // 通常の送信 let handlers = self.handlers.lock().unwrap(); if let Some(handler) = handlers.get(method) { // 簡易実装:最初の引数のみ使用 let arg = args .get(0) .map(|a| a.clone_box()) .unwrap_or_else(|| Box::new(VoidBox::new())); handler(arg) } else { Box::new(StringBox::new(&format!( "No handler for method: {}", method ))) } } /// 送信者名を取得 pub fn sender(&self) -> Box { Box::new(StringBox::new(&self.sender_name)) } /// 受信者名を取得 pub fn receiver(&self) -> Box { Box::new(StringBox::new(&self.receiver_name)) } /// ブロードキャスト fn broadcast(&self, _method: &str, _args: Vec>) -> Box { let linked = self.linked_boxes.lock().unwrap(); let mut results = Vec::new(); for (name, weak_box) in linked.iter() { if let Some(_strong_box) = weak_box.upgrade() { // 各Boxにメッセージを送信 results.push(format!("Sent to {}", name)); } } Box::new(StringBox::new(&format!( "Broadcast complete: {:?}", results ))) } } impl NyashBox for ChannelBox { fn type_name(&self) -> &'static str { "ChannelBox" } fn to_string_box(&self) -> StringBox { StringBox::new(&format!( "Channel({} >> {})", self.sender_name, self.receiver_name )) } fn clone_box(&self) -> Box { Box::new(self.clone()) } /// 仮実装: clone_boxと同じ(後で修正) fn share_box(&self) -> Box { self.clone_box() } fn equals(&self, other: &dyn NyashBox) -> crate::box_trait::BoolBox { if let Some(other_channel) = other.as_any().downcast_ref::() { crate::box_trait::BoolBox::new( self.sender_name == other_channel.sender_name && self.receiver_name == other_channel.receiver_name, ) } else { crate::box_trait::BoolBox::new(false) } } } impl BoxCore for ChannelBox { fn box_id(&self) -> u64 { self.base.id } fn parent_type_id(&self) -> Option { self.base.parent_type_id } fn fmt_box(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "Channel({} >> {})", self.sender_name, self.receiver_name) } fn as_any(&self) -> &dyn Any { self } fn as_any_mut(&mut self) -> &mut dyn Any { self } } impl Display for ChannelBox { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.fmt_box(f) } } impl Debug for ChannelBox { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("ChannelBox") .field("sender_name", &self.sender_name) .field("receiver_name", &self.receiver_name) .field("id", &self.base.id) .finish() } } /// メッセージを表すBox #[derive(Debug, Clone)] pub struct MessageBox { pub sender: String, pub content: String, base: BoxBase, } impl MessageBox { pub fn new(sender: &str, content: &str) -> Self { Self { sender: sender.to_string(), content: content.to_string(), base: BoxBase::new(), } } } impl NyashBox for MessageBox { fn type_name(&self) -> &'static str { "MessageBox" } fn to_string_box(&self) -> StringBox { StringBox::new(&format!( "[{}] {}: {}", self.base.id, self.sender, self.content )) } fn clone_box(&self) -> Box { Box::new(self.clone()) } /// 仮実装: clone_boxと同じ(後で修正) fn share_box(&self) -> Box { self.clone_box() } fn equals(&self, other: &dyn NyashBox) -> crate::box_trait::BoolBox { if let Some(other_msg) = other.as_any().downcast_ref::() { crate::box_trait::BoolBox::new( self.sender == other_msg.sender && self.content == other_msg.content, ) } else { crate::box_trait::BoolBox::new(false) } } } impl BoxCore for MessageBox { fn box_id(&self) -> u64 { self.base.id } fn parent_type_id(&self) -> Option { self.base.parent_type_id } fn fmt_box(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "[{}] {}: {}", self.base.id, self.sender, self.content) } fn as_any(&self) -> &dyn Any { self } fn as_any_mut(&mut self) -> &mut dyn Any { self } } impl Display for MessageBox { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.fmt_box(f) } }