diff --git a/src/boxes/buffer/mod.rs b/src/boxes/buffer/mod.rs index f4421564..59f1dcf8 100644 --- a/src/boxes/buffer/mod.rs +++ b/src/boxes/buffer/mod.rs @@ -28,7 +28,7 @@ * ``` */ -use crate::box_trait::{NyashBox, StringBox, BoolBox, IntegerBox}; +use crate::box_trait::{NyashBox, StringBox, BoolBox, IntegerBox, BoxCore, BoxBase}; use crate::boxes::array::ArrayBox; use std::any::Any; use std::sync::{Arc, Mutex}; @@ -37,31 +37,21 @@ use std::fmt::{Debug, Display}; #[derive(Debug, Clone)] pub struct BufferBox { data: Arc>>, - id: u64, + base: BoxBase, } impl BufferBox { pub fn new() -> Self { - static mut COUNTER: u64 = 0; - let id = unsafe { - COUNTER += 1; - COUNTER - }; BufferBox { data: Arc::new(Mutex::new(Vec::new())), - id, + base: BoxBase::new(), } } pub fn from_vec(data: Vec) -> Self { - static mut COUNTER: u64 = 0; - let id = unsafe { - COUNTER += 1; - COUNTER - }; BufferBox { data: Arc::new(Mutex::new(data)), - id, + base: BoxBase::new(), } } @@ -158,6 +148,23 @@ impl BufferBox { } } +impl BoxCore for BufferBox { + fn box_id(&self) -> u64 { + self.base.id + } + + fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let data = self.data.lock().unwrap(); + write!(f, "BufferBox({} bytes)", data.len()) + } +} + +impl Display for BufferBox { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.fmt_box(f) + } +} + impl NyashBox for BufferBox { fn clone_box(&self) -> Box { Box::new(self.clone()) @@ -176,9 +183,6 @@ impl NyashBox for BufferBox { "BufferBox" } - fn box_id(&self) -> u64 { - self.id - } fn equals(&self, other: &dyn NyashBox) -> BoolBox { if let Some(other_buffer) = other.as_any().downcast_ref::() { diff --git a/src/boxes/egui_box.rs b/src/boxes/egui_box.rs index 5ed07444..27e689da 100644 --- a/src/boxes/egui_box.rs +++ b/src/boxes/egui_box.rs @@ -31,7 +31,7 @@ * - `run()`はブロッキング動作(アプリ終了まで制御を返さない) */ -use crate::box_trait::{NyashBox, StringBox, BoolBox}; +use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase}; use crate::interpreter::RuntimeError; use std::any::Any; use std::sync::{Arc, Mutex}; @@ -47,6 +47,7 @@ use eframe::{self, epaint::Vec2}; /// app.run() /// ``` pub struct EguiBox { + base: BoxBase, title: String, size: Vec2, app_state: Arc>>, @@ -65,6 +66,7 @@ impl std::fmt::Debug for EguiBox { impl EguiBox { pub fn new() -> Self { Self { + base: BoxBase::new(), title: "Nyash GUI Application".to_string(), size: Vec2::new(800.0, 600.0), app_state: Arc::new(Mutex::new(Box::new(()) as Box)), @@ -100,6 +102,22 @@ impl eframe::App for NyashApp { } } +impl BoxCore for EguiBox { + fn box_id(&self) -> u64 { + self.base.id + } + + fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "EguiBox('{}', {}x{})", self.title, self.size.x, self.size.y) + } +} + +impl std::fmt::Display for EguiBox { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.fmt_box(f) + } +} + impl NyashBox for EguiBox { fn to_string_box(&self) -> StringBox { StringBox::new( @@ -110,6 +128,7 @@ impl NyashBox for EguiBox { fn clone_box(&self) -> Box { // GUI Boxはクローン不可(単一インスタンス) Box::new(Self { + base: BoxBase::new(), title: self.title.clone(), size: self.size, app_state: Arc::new(Mutex::new(Box::new(()) as Box)), @@ -133,10 +152,6 @@ impl NyashBox for EguiBox { "EguiBox" } - fn box_id(&self) -> u64 { - // 簡易的なIDとしてポインタアドレスを使用 - self as *const _ as u64 - } } // EguiBoxのメソッド実装(実際にはインタープリターから呼ばれない) diff --git a/src/boxes/file/mod.rs b/src/boxes/file/mod.rs index a71aef2f..e933bd9a 100644 --- a/src/boxes/file/mod.rs +++ b/src/boxes/file/mod.rs @@ -2,7 +2,7 @@ // Nyashの箱システムによるファイル入出力を提供します。 // 参考: 既存Boxの設計思想 -use crate::box_trait::{NyashBox, StringBox, BoolBox}; +use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase}; use std::any::Any; use std::fs::{File, OpenOptions}; use std::io::{Read, Write, Result}; @@ -12,21 +12,16 @@ use std::sync::{Arc, Mutex}; pub struct FileBox { file: Arc>, path: Arc, - id: u64, + base: BoxBase, } impl FileBox { pub fn open(path: &str) -> Result { - static mut COUNTER: u64 = 0; - let id = unsafe { - COUNTER += 1; - COUNTER - }; let file = OpenOptions::new().read(true).write(true).create(true).open(path)?; Ok(FileBox { file: Arc::new(Mutex::new(file)), path: Arc::new(path.to_string()), - id, + base: BoxBase::new(), }) } @@ -82,6 +77,16 @@ impl FileBox { } } +impl BoxCore for FileBox { + fn box_id(&self) -> u64 { + self.base.id + } + + fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "FileBox({})", self.path) + } +} + impl NyashBox for FileBox { fn clone_box(&self) -> Box { // Note: Cannot truly clone a File handle, so create a new one to the same path @@ -103,9 +108,6 @@ impl NyashBox for FileBox { "FileBox" } - fn box_id(&self) -> u64 { - self.id - } fn equals(&self, other: &dyn NyashBox) -> BoolBox { if let Some(other_file) = other.as_any().downcast_ref::() { @@ -115,3 +117,9 @@ impl NyashBox for FileBox { } } } + +impl std::fmt::Display for FileBox { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.fmt_box(f) + } +} diff --git a/src/boxes/json/mod.rs b/src/boxes/json/mod.rs index cd2ee1a8..10803868 100644 --- a/src/boxes/json/mod.rs +++ b/src/boxes/json/mod.rs @@ -2,7 +2,7 @@ // Nyashの箱システムによるJSON解析・生成を提供します。 // 参考: 既存Boxの設計思想 -use crate::box_trait::{NyashBox, StringBox, BoolBox, IntegerBox}; +use crate::box_trait::{NyashBox, BoxCore, BoxBase, StringBox, BoolBox, IntegerBox}; use crate::boxes::array::ArrayBox; use crate::boxes::map_box::MapBox; use std::any::Any; @@ -12,32 +12,22 @@ use serde_json::{Value, Error}; #[derive(Debug, Clone)] pub struct JSONBox { value: Arc>, - id: u64, + base: BoxBase, } impl JSONBox { pub fn from_str(s: &str) -> Result { - static mut COUNTER: u64 = 0; - let id = unsafe { - COUNTER += 1; - COUNTER - }; let value = serde_json::from_str(s)?; Ok(JSONBox { value: Arc::new(Mutex::new(value)), - id + base: BoxBase::new() }) } pub fn new(value: Value) -> Self { - static mut COUNTER: u64 = 0; - let id = unsafe { - COUNTER += 1; - COUNTER - }; JSONBox { value: Arc::new(Mutex::new(value)), - id + base: BoxBase::new() } } @@ -129,6 +119,35 @@ impl JSONBox { } } +impl BoxCore for JSONBox { + fn box_id(&self) -> u64 { + self.base.id + } + + fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let value = self.value.lock().unwrap(); + let json_type = match *value { + Value::Null => "null", + Value::Bool(_) => "boolean", + Value::Number(_) => "number", + Value::String(_) => "string", + Value::Array(ref arr) => { + return write!(f, "JSONBox[array:{}]", arr.len()); + }, + Value::Object(ref obj) => { + return write!(f, "JSONBox[object:{}]", obj.len()); + }, + }; + write!(f, "JSONBox[{}]", json_type) + } +} + +impl std::fmt::Display for JSONBox { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + self.fmt_box(f) + } +} + impl NyashBox for JSONBox { fn clone_box(&self) -> Box { Box::new(self.clone()) @@ -147,9 +166,6 @@ impl NyashBox for JSONBox { "JSONBox" } - fn box_id(&self) -> u64 { - self.id - } fn equals(&self, other: &dyn NyashBox) -> BoolBox { if let Some(other_json) = other.as_any().downcast_ref::() { diff --git a/src/boxes/map_box.rs b/src/boxes/map_box.rs index 87b7f7c6..6dfd80fe 100644 --- a/src/boxes/map_box.rs +++ b/src/boxes/map_box.rs @@ -103,7 +103,7 @@ * - 存在しないキーの取得は "Key not found" メッセージ返却 */ -use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox}; +use crate::box_trait::{BoxCore, BoxBase, NyashBox, StringBox, IntegerBox, BoolBox}; use crate::boxes::array::ArrayBox; use std::fmt::{Debug, Display}; use std::any::Any; @@ -114,20 +114,14 @@ use std::sync::{Arc, Mutex}; #[derive(Clone)] pub struct MapBox { data: Arc>>>, - id: u64, + base: BoxBase, } impl MapBox { pub fn new() -> Self { - static mut COUNTER: u64 = 0; - let id = unsafe { - COUNTER += 1; - COUNTER - }; - Self { data: Arc::new(Mutex::new(HashMap::new())), - id, + base: BoxBase::new(), } } @@ -229,6 +223,17 @@ impl MapBox { } } +impl BoxCore for MapBox { + fn box_id(&self) -> u64 { + self.base.id + } + + fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let size = self.data.lock().unwrap().len(); + write!(f, "MapBox(size={})", size) + } +} + impl NyashBox for MapBox { fn type_name(&self) -> &'static str { "MapBox" @@ -246,7 +251,7 @@ impl NyashBox for MapBox { fn equals(&self, other: &dyn NyashBox) -> BoolBox { if let Some(other_map) = other.as_any().downcast_ref::() { // 同じインスタンスかチェック(データの共有を考慮) - BoolBox::new(self.id == other_map.id) + BoolBox::new(self.box_id() == other_map.box_id()) } else { BoolBox::new(false) } @@ -255,15 +260,11 @@ impl NyashBox for MapBox { fn as_any(&self) -> &dyn Any { self } - - fn box_id(&self) -> u64 { - self.id - } } impl Display for MapBox { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.to_string_box().value) + self.fmt_box(f) } } @@ -271,7 +272,7 @@ impl Debug for MapBox { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let data = self.data.lock().unwrap(); f.debug_struct("MapBox") - .field("id", &self.id) + .field("id", &self.base.id) .field("size", &data.len()) .field("keys", &data.keys().collect::>()) .finish() diff --git a/src/boxes/sound_box.rs b/src/boxes/sound_box.rs index 8f999dc5..ceaa85da 100644 --- a/src/boxes/sound_box.rs +++ b/src/boxes/sound_box.rs @@ -138,7 +138,7 @@ * - Web環境では制限が多い(ユーザー操作後のみ音声再生可能) */ -use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox}; +use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, BoxCore, BoxBase}; use std::fmt::{Debug, Display}; use std::any::Any; use std::process::Command; @@ -147,18 +147,14 @@ use std::time::Duration; /// 音響効果を提供するBox #[derive(Debug, Clone)] pub struct SoundBox { - id: u64, + base: BoxBase, } impl SoundBox { pub fn new() -> Self { - static mut COUNTER: u64 = 0; - let id = unsafe { - COUNTER += 1; - COUNTER - }; - - Self { id } + Self { + base: BoxBase::new() + } } /// ビープ音を鳴らす(基本) @@ -332,7 +328,7 @@ impl NyashBox for SoundBox { fn equals(&self, other: &dyn NyashBox) -> BoolBox { if let Some(other_sound) = other.as_any().downcast_ref::() { - BoolBox::new(self.id == other_sound.id) + BoolBox::new(self.base.id == other_sound.base.id) } else { BoolBox::new(false) } @@ -342,13 +338,20 @@ impl NyashBox for SoundBox { self } +} + +impl BoxCore for SoundBox { fn box_id(&self) -> u64 { - self.id + self.base.id + } + + fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "SoundBox()") } } impl Display for SoundBox { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "SoundBox()") + self.fmt_box(f) } } \ No newline at end of file