Phase 9.75-C: Complete SimpleIntentBox, RandomBox, JSONBox RwLock conversions

Co-authored-by: moe-charm <217100418+moe-charm@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-08-15 01:07:48 +00:00
parent 95e093c767
commit cc9c529a74
3 changed files with 60 additions and 28 deletions

View File

@ -6,33 +6,44 @@ use crate::box_trait::{NyashBox, BoxCore, BoxBase, StringBox, BoolBox, IntegerBo
use crate::boxes::array::ArrayBox; use crate::boxes::array::ArrayBox;
use crate::boxes::map_box::MapBox; use crate::boxes::map_box::MapBox;
use std::any::Any; use std::any::Any;
use std::sync::{Arc, Mutex}; use std::sync::RwLock;
use serde_json::{Value, Error}; use serde_json::{Value, Error};
#[derive(Debug, Clone)] #[derive(Debug)]
pub struct JSONBox { pub struct JSONBox {
value: Arc<Mutex<Value>>, value: RwLock<Value>,
base: BoxBase, 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 { impl JSONBox {
pub fn from_str(s: &str) -> Result<Self, Error> { pub fn from_str(s: &str) -> Result<Self, Error> {
let value = serde_json::from_str(s)?; let value = serde_json::from_str(s)?;
Ok(JSONBox { Ok(JSONBox {
value: Arc::new(Mutex::new(value)), value: RwLock::new(value),
base: BoxBase::new() base: BoxBase::new()
}) })
} }
pub fn new(value: Value) -> Self { pub fn new(value: Value) -> Self {
JSONBox { JSONBox {
value: Arc::new(Mutex::new(value)), value: RwLock::new(value),
base: BoxBase::new() base: BoxBase::new()
} }
} }
pub fn to_string(&self) -> String { pub fn to_string(&self) -> String {
let value = self.value.lock().unwrap(); let value = self.value.read().unwrap();
value.to_string() value.to_string()
} }
@ -53,7 +64,7 @@ impl JSONBox {
/// 値取得 /// 値取得
pub fn get(&self, key: Box<dyn NyashBox>) -> Box<dyn NyashBox> { pub fn get(&self, key: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
let key_str = key.to_string_box().value; 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(obj) = value.as_object() {
if let Some(val) = obj.get(&key_str) { if let Some(val) = obj.get(&key_str) {
@ -79,7 +90,7 @@ impl JSONBox {
/// 値設定 /// 値設定
pub fn set(&self, key: Box<dyn NyashBox>, new_value: Box<dyn NyashBox>) -> Box<dyn NyashBox> { pub fn set(&self, key: Box<dyn NyashBox>, new_value: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
let key_str = key.to_string_box().value; 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); let json_value = nyash_box_to_json_value(new_value);
@ -94,7 +105,7 @@ impl JSONBox {
/// キー存在チェック /// キー存在チェック
pub fn has(&self, key: Box<dyn NyashBox>) -> Box<dyn NyashBox> { pub fn has(&self, key: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
let key_str = key.to_string_box().value; 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(obj) = value.as_object() {
Box::new(BoolBox::new(obj.contains_key(&key_str))) Box::new(BoolBox::new(obj.contains_key(&key_str)))
@ -105,7 +116,7 @@ impl JSONBox {
/// すべてのキーを取得 /// すべてのキーを取得
pub fn keys(&self) -> Box<dyn NyashBox> { pub fn keys(&self) -> Box<dyn NyashBox> {
let value = self.value.lock().unwrap(); let value = self.value.read().unwrap();
let array = ArrayBox::new(); let array = ArrayBox::new();
if let Some(obj) = value.as_object() { 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 { 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 { let json_type = match *value {
Value::Null => "null", Value::Null => "null",
Value::Bool(_) => "boolean", Value::Bool(_) => "boolean",
@ -166,7 +177,7 @@ impl NyashBox for JSONBox {
} }
fn to_string_box(&self) -> StringBox { fn to_string_box(&self) -> StringBox {
let value = self.value.lock().unwrap(); let value = self.value.read().unwrap();
StringBox::new(value.to_string()) StringBox::new(value.to_string())
} }
@ -178,8 +189,8 @@ impl NyashBox for JSONBox {
fn equals(&self, other: &dyn NyashBox) -> BoolBox { fn equals(&self, other: &dyn NyashBox) -> BoolBox {
if let Some(other_json) = other.as_any().downcast_ref::<JSONBox>() { if let Some(other_json) = other.as_any().downcast_ref::<JSONBox>() {
let self_value = self.value.lock().unwrap(); let self_value = self.value.read().unwrap();
let other_value = other_json.value.lock().unwrap(); let other_value = other_json.value.read().unwrap();
BoolBox::new(*self_value == *other_value) BoolBox::new(*self_value == *other_value)
} else { } else {
BoolBox::new(false) BoolBox::new(false)

View File

@ -71,16 +71,27 @@ use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, BoxCore, BoxBas
use crate::boxes::{ArrayBox, FloatBox}; use crate::boxes::{ArrayBox, FloatBox};
use std::fmt::{Debug, Display}; use std::fmt::{Debug, Display};
use std::any::Any; use std::any::Any;
use std::sync::{Arc, Mutex}; use std::sync::RwLock;
/// 乱数生成を提供するBox /// 乱数生成を提供するBox
#[derive(Debug, Clone)] #[derive(Debug)]
pub struct RandomBox { pub struct RandomBox {
// 簡易線形合同法による疑似乱数生成器 // 簡易線形合同法による疑似乱数生成器
seed: Arc<Mutex<u64>>, seed: RwLock<u64>,
base: BoxBase, 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 { impl RandomBox {
pub fn new() -> Self { pub fn new() -> Self {
// 現在時刻を種として使用 // 現在時刻を種として使用
@ -90,7 +101,7 @@ impl RandomBox {
.as_nanos() as u64; .as_nanos() as u64;
Self { Self {
seed: Arc::new(Mutex::new(seed)), seed: RwLock::new(seed),
base: BoxBase::new(), base: BoxBase::new(),
} }
} }
@ -98,7 +109,7 @@ impl RandomBox {
/// 種を設定 /// 種を設定
pub fn seed(&self, new_seed: Box<dyn NyashBox>) -> Box<dyn NyashBox> { pub fn seed(&self, new_seed: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
if let Some(int_box) = new_seed.as_any().downcast_ref::<IntegerBox>() { if let Some(int_box) = new_seed.as_any().downcast_ref::<IntegerBox>() {
*self.seed.lock().unwrap() = int_box.value as u64; *self.seed.write().unwrap() = int_box.value as u64;
Box::new(StringBox::new("Seed set")) Box::new(StringBox::new("Seed set"))
} else { } else {
Box::new(StringBox::new("Error: seed() requires integer input")) Box::new(StringBox::new("Error: seed() requires integer input"))
@ -107,7 +118,7 @@ impl RandomBox {
/// 次の乱数を生成(線形合同法) /// 次の乱数を生成(線形合同法)
fn next_random(&self) -> u64 { fn next_random(&self) -> u64 {
let mut seed = self.seed.lock().unwrap(); let mut seed = self.seed.write().unwrap();
// 線形合同法の定数Numerical Recipes より) // 線形合同法の定数Numerical Recipes より)
*seed = seed.wrapping_mul(1664525).wrapping_add(1013904223); *seed = seed.wrapping_mul(1664525).wrapping_add(1013904223);
*seed *seed

View File

@ -161,21 +161,32 @@
use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase}; use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase};
use std::any::Any; use std::any::Any;
use std::sync::{Arc, Mutex}; use std::sync::RwLock;
use std::collections::HashMap; use std::collections::HashMap;
#[derive(Debug)] #[derive(Debug)]
pub struct SimpleIntentBox { pub struct SimpleIntentBox {
base: BoxBase, base: BoxBase,
// ードID -> コールバック関数のマップ // ードID -> コールバック関数のマップ
listeners: Arc<Mutex<HashMap<String, Vec<String>>>>, // 仮実装 listeners: RwLock<HashMap<String, Vec<String>>>, // 仮実装
}
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 { impl SimpleIntentBox {
pub fn new() -> Self { pub fn new() -> Self {
SimpleIntentBox { SimpleIntentBox {
base: BoxBase::new(), 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) write!(f, "SimpleIntentBox(id: {}))", self.base.id)
} }
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any { fn as_any_mut(&mut self) -> &mut dyn Any {
self self
@ -217,11 +231,7 @@ impl NyashBox for SimpleIntentBox {
} }
fn clone_box(&self) -> Box<dyn NyashBox> { fn clone_box(&self) -> Box<dyn NyashBox> {
// IntentBoxは共有されるので、新しいインスタンスを作らない Box::new(self.clone())
Box::new(SimpleIntentBox {
base: BoxBase::new(), // Create new base with unique ID for clone
listeners: self.listeners.clone(),
})
} }
} }