Skip to content

Commit 38f392c

Browse files
committed
model: Implement cloning of box with concrete Model object
1 parent ee8986c commit 38f392c

File tree

2 files changed

+102
-98
lines changed

2 files changed

+102
-98
lines changed

src/models/model.rs

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
use serde::{Serialize, Serializer, Deserialize, Deserializer};
22
use serde::ser::SerializeMap;
3-
use serde_json::Value;
43
use serde::de::{self, Unexpected};
5-
use std::rc::Rc;
6-
use std::cell::RefCell;
7-
use std::collections::HashMap;
84

95
use super::ModelMessage;
106
use crate::input_modeling::UniformRNG;
@@ -13,13 +9,14 @@ use crate::utils::error::SimulationError;
139
/// `Model` wraps `model_type` and provides common ID functionality (a struct
1410
/// field and associated accessor method). The simulator requires all models
1511
/// to have an ID.
12+
#[derive(Clone)]
1613
pub struct Model {
1714
id: String,
18-
inner: Rc<RefCell<dyn AsModel>>,
15+
inner: Box<dyn AsModel>,
1916
}
2017

2118
impl Model {
22-
pub fn new(id: String, inner: Rc<RefCell<dyn AsModel>>) -> Self {
19+
pub fn new(id: String, inner: Box<dyn AsModel>) -> Self {
2320
Self { id, inner }
2421
}
2522

@@ -28,22 +25,31 @@ impl Model {
2825
}
2926
}
3027

31-
impl Clone for Model {
32-
fn clone(&self) -> Self {
33-
// Fix self.inner cloning
34-
Model {
35-
id: self.id.clone(),
36-
inner: self.inner.clone()
37-
}
28+
pub trait ModelClone {
29+
fn clone_box(&self) -> Box<dyn AsModel>;
30+
}
31+
32+
impl<T> ModelClone for T
33+
where
34+
T: 'static + AsModel + Clone,
35+
{
36+
fn clone_box(&self) -> Box<dyn AsModel> {
37+
Box::new(self.clone())
38+
}
39+
}
40+
41+
impl Clone for Box<dyn AsModel> {
42+
fn clone(&self) -> Box<dyn AsModel> {
43+
self.clone_box()
3844
}
3945
}
4046

4147
impl Serialize for Model {
4248
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
43-
let extra_fields: serde_json::Value = self.inner.borrow().serialize();
49+
let extra_fields: serde_json::Value = self.inner.serialize();
4450
let mut model = serializer.serialize_map(None)?;
4551
model.serialize_entry("id", &self.id)?;
46-
model.serialize_entry("type", self.inner.borrow().get_type())?;
52+
model.serialize_entry("type", self.inner.get_type())?;
4753
if let serde_json::Value::Object(map) = extra_fields {
4854
for (key, value) in map.iter() {
4955
model.serialize_entry(&key, &value)?;
@@ -63,10 +69,11 @@ impl<'de> Deserialize<'de> for Model {
6369
match &model_extra.model_type[..] {
6470
"Generator" => {
6571
if let Ok(generator) = serde_json::from_value::<super::Generator>(model_extra.extra) {
66-
Ok(Model::new(
72+
let model = Model::new(
6773
model_extra.id,
68-
Rc::new(RefCell::new(generator))
69-
))
74+
Box::new(generator)
75+
);
76+
Ok(model)
7077
} else {
7178
Err(de::Error::invalid_value(Unexpected::Other("Generator"), &"Generator"))
7279
}
@@ -75,7 +82,7 @@ impl<'de> Deserialize<'de> for Model {
7582
if let Ok(exclusive_gateway) = serde_json::from_value::<super::ExclusiveGateway>(model_extra.extra) {
7683
Ok(Model::new(
7784
model_extra.id,
78-
Rc::new(RefCell::new(exclusive_gateway))
85+
Box::new(exclusive_gateway)
7986
))
8087
} else {
8188
Err(de::Error::invalid_value(Unexpected::Other("ExclusiveGateway"), &"ExclusiveGateway"))
@@ -85,7 +92,7 @@ impl<'de> Deserialize<'de> for Model {
8592
if let Ok(processor) = serde_json::from_value::<super::Processor>(model_extra.extra) {
8693
Ok(Model::new(
8794
model_extra.id,
88-
Rc::new(RefCell::new(processor))
95+
Box::new(processor)
8996
))
9097
} else {
9198
Err(de::Error::invalid_value(Unexpected::Other("Processor"), &"Processor"))
@@ -95,7 +102,7 @@ impl<'de> Deserialize<'de> for Model {
95102
if let Ok(storage) = serde_json::from_value::<super::Storage>(model_extra.extra) {
96103
Ok(Model::new(
97104
model_extra.id,
98-
Rc::new(RefCell::new(storage))
105+
Box::new(storage)
99106
))
100107
} else {
101108
Err(de::Error::invalid_value(Unexpected::Other("Storage"), &"Storage"))
@@ -110,30 +117,30 @@ impl<'de> Deserialize<'de> for Model {
110117

111118
impl AsModel for Model {
112119
fn status(&self) -> String {
113-
self.inner.borrow().status()
120+
self.inner.status()
114121
}
115122

116123
fn events_ext(
117124
&mut self,
118125
uniform_rng: &mut UniformRNG,
119126
incoming_message: ModelMessage,
120127
) -> Result<Vec<ModelMessage>, SimulationError> {
121-
self.inner.borrow_mut().events_ext(uniform_rng, incoming_message)
128+
self.inner.events_ext(uniform_rng, incoming_message)
122129
}
123130

124131
fn events_int(
125132
&mut self,
126133
uniform_rng: &mut UniformRNG,
127134
) -> Result<Vec<ModelMessage>, SimulationError> {
128-
self.inner.borrow_mut().events_int(uniform_rng)
135+
self.inner.events_int(uniform_rng)
129136
}
130137

131138
fn time_advance(&mut self, time_delta: f64) {
132-
self.inner.borrow_mut().time_advance(time_delta)
139+
self.inner.time_advance(time_delta)
133140
}
134141

135142
fn until_next_event(&self) -> f64 {
136-
self.inner.borrow_mut().until_next_event()
143+
self.inner.until_next_event()
137144
}
138145
}
139146

@@ -143,7 +150,7 @@ impl AsModel for Model {
143150
/// `time_advance`, and `until_next_event`. The additional `status` is for
144151
/// facilitation of simulation reasoning, reporting, and debugging.
145152
// #[enum_dispatch]
146-
pub trait AsModel {
153+
pub trait AsModel: ModelClone {
147154
fn get_type(&self) -> &'static str {
148155
""
149156
}

0 commit comments

Comments
 (0)