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:
@ -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)
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user