diff --git a/src/boxes/json/mod.rs b/src/boxes/json/mod.rs index c7d86180..1c789f50 100644 --- a/src/boxes/json/mod.rs +++ b/src/boxes/json/mod.rs @@ -6,33 +6,44 @@ use crate::box_trait::{NyashBox, BoxCore, BoxBase, StringBox, BoolBox, IntegerBo use crate::boxes::array::ArrayBox; use crate::boxes::map_box::MapBox; use std::any::Any; -use std::sync::{Arc, Mutex}; +use std::sync::RwLock; use serde_json::{Value, Error}; -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct JSONBox { - value: Arc>, + value: RwLock, base: BoxBase, } +impl Clone for JSONBox { + fn clone(&self) -> Self { + let value_clone = self.value.read().unwrap().clone(); + + Self { + value: RwLock::new(value_clone), + base: BoxBase::new(), // New unique ID for clone + } + } +} + impl JSONBox { pub fn from_str(s: &str) -> Result { let value = serde_json::from_str(s)?; Ok(JSONBox { - value: Arc::new(Mutex::new(value)), + value: RwLock::new(value), base: BoxBase::new() }) } pub fn new(value: Value) -> Self { JSONBox { - value: Arc::new(Mutex::new(value)), + value: RwLock::new(value), base: BoxBase::new() } } pub fn to_string(&self) -> String { - let value = self.value.lock().unwrap(); + let value = self.value.read().unwrap(); value.to_string() } @@ -53,7 +64,7 @@ impl JSONBox { /// 値取得 pub fn get(&self, key: Box) -> Box { let key_str = key.to_string_box().value; - let value = self.value.lock().unwrap(); + let value = self.value.read().unwrap(); if let Some(obj) = value.as_object() { if let Some(val) = obj.get(&key_str) { @@ -79,7 +90,7 @@ impl JSONBox { /// 値設定 pub fn set(&self, key: Box, new_value: Box) -> Box { let key_str = key.to_string_box().value; - let mut value = self.value.lock().unwrap(); + let mut value = self.value.write().unwrap(); let json_value = nyash_box_to_json_value(new_value); @@ -94,7 +105,7 @@ impl JSONBox { /// キー存在チェック pub fn has(&self, key: Box) -> Box { let key_str = key.to_string_box().value; - let value = self.value.lock().unwrap(); + let value = self.value.read().unwrap(); if let Some(obj) = value.as_object() { Box::new(BoolBox::new(obj.contains_key(&key_str))) @@ -105,7 +116,7 @@ impl JSONBox { /// すべてのキーを取得 pub fn keys(&self) -> Box { - let value = self.value.lock().unwrap(); + let value = self.value.read().unwrap(); let array = ArrayBox::new(); if let Some(obj) = value.as_object() { @@ -129,7 +140,7 @@ impl BoxCore for JSONBox { } fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - let value = self.value.lock().unwrap(); + let value = self.value.read().unwrap(); let json_type = match *value { Value::Null => "null", Value::Bool(_) => "boolean", @@ -166,7 +177,7 @@ impl NyashBox for JSONBox { } fn to_string_box(&self) -> StringBox { - let value = self.value.lock().unwrap(); + let value = self.value.read().unwrap(); StringBox::new(value.to_string()) } @@ -178,8 +189,8 @@ impl NyashBox for JSONBox { fn equals(&self, other: &dyn NyashBox) -> BoolBox { if let Some(other_json) = other.as_any().downcast_ref::() { - let self_value = self.value.lock().unwrap(); - let other_value = other_json.value.lock().unwrap(); + let self_value = self.value.read().unwrap(); + let other_value = other_json.value.read().unwrap(); BoolBox::new(*self_value == *other_value) } else { BoolBox::new(false) diff --git a/src/boxes/random_box.rs b/src/boxes/random_box.rs index e321517d..61bb1f2a 100644 --- a/src/boxes/random_box.rs +++ b/src/boxes/random_box.rs @@ -71,16 +71,27 @@ use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, BoxCore, BoxBas use crate::boxes::{ArrayBox, FloatBox}; use std::fmt::{Debug, Display}; use std::any::Any; -use std::sync::{Arc, Mutex}; +use std::sync::RwLock; /// 乱数生成を提供するBox -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct RandomBox { // 簡易線形合同法による疑似乱数生成器 - seed: Arc>, + seed: RwLock, base: BoxBase, } +impl Clone for RandomBox { + fn clone(&self) -> Self { + let seed_val = *self.seed.read().unwrap(); + + Self { + seed: RwLock::new(seed_val), + base: BoxBase::new(), // New unique ID for clone + } + } +} + impl RandomBox { pub fn new() -> Self { // 現在時刻を種として使用 @@ -90,7 +101,7 @@ impl RandomBox { .as_nanos() as u64; Self { - seed: Arc::new(Mutex::new(seed)), + seed: RwLock::new(seed), base: BoxBase::new(), } } @@ -98,7 +109,7 @@ impl RandomBox { /// 種を設定 pub fn seed(&self, new_seed: Box) -> Box { if let Some(int_box) = new_seed.as_any().downcast_ref::() { - *self.seed.lock().unwrap() = int_box.value as u64; + *self.seed.write().unwrap() = int_box.value as u64; Box::new(StringBox::new("Seed set")) } else { Box::new(StringBox::new("Error: seed() requires integer input")) @@ -107,7 +118,7 @@ impl RandomBox { /// 次の乱数を生成(線形合同法) fn next_random(&self) -> u64 { - let mut seed = self.seed.lock().unwrap(); + let mut seed = self.seed.write().unwrap(); // 線形合同法の定数(Numerical Recipes より) *seed = seed.wrapping_mul(1664525).wrapping_add(1013904223); *seed diff --git a/src/boxes/simple_intent_box.rs b/src/boxes/simple_intent_box.rs index 25df769b..4452b8c8 100644 --- a/src/boxes/simple_intent_box.rs +++ b/src/boxes/simple_intent_box.rs @@ -161,21 +161,32 @@ use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase}; use std::any::Any; -use std::sync::{Arc, Mutex}; +use std::sync::RwLock; use std::collections::HashMap; #[derive(Debug)] pub struct SimpleIntentBox { base: BoxBase, // ノードID -> コールバック関数のマップ - listeners: Arc>>>, // 仮実装 + listeners: RwLock>>, // 仮実装 +} + +impl Clone for SimpleIntentBox { + fn clone(&self) -> Self { + let listeners_val = self.listeners.read().unwrap().clone(); + + Self { + base: BoxBase::new(), // New unique ID for clone + listeners: RwLock::new(listeners_val), + } + } } impl SimpleIntentBox { pub fn new() -> Self { SimpleIntentBox { base: BoxBase::new(), - listeners: Arc::new(Mutex::new(HashMap::new())), + listeners: RwLock::new(HashMap::new()), } } } @@ -193,6 +204,9 @@ impl BoxCore for SimpleIntentBox { write!(f, "SimpleIntentBox(id: {}))", self.base.id) } + fn as_any(&self) -> &dyn Any { + self + } fn as_any_mut(&mut self) -> &mut dyn Any { self @@ -217,11 +231,7 @@ impl NyashBox for SimpleIntentBox { } fn clone_box(&self) -> Box { - // IntentBoxは共有されるので、新しいインスタンスを作らない - Box::new(SimpleIntentBox { - base: BoxBase::new(), // Create new base with unique ID for clone - listeners: self.listeners.clone(), - }) + Box::new(self.clone()) } }