use super::prelude::*;
use std::rc::{Weak, Rc};
use std::hash::{Hash, Hasher};
#[derive(Debug)]
pub struct CircuitInstance {
pub(super) name: Option<String>,
pub(super) circuit: Weak<Circuit>,
pub(super) circuit_id: CircuitIndex,
pub(super) parent_circuit: Weak<Circuit>,
pub(super) parent_circuit_id: CircuitIndex,
pub(super) id: CircuitInstIndex,
pub(super) pin_instances: Vec<Rc<PinInstance>>,
}
impl Eq for CircuitInstance {}
impl PartialEq for CircuitInstance {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
&& self.parent_circuit_id == other.parent_circuit_id
}
}
impl Hash for CircuitInstance {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
self.parent_circuit_id.hash(state);
}
}
impl CircuitInstance {
pub fn parent_circuit(&self) -> Weak<Circuit> {
self.parent_circuit.clone()
}
pub fn circuit_ref(&self) -> Weak<Circuit> {
self.circuit.clone()
}
pub fn circuit_id(&self) -> CircuitIndex {
self.circuit_id
}
pub fn connect_pin_by_id(&self, pin_instance_id: usize, net: Option<Rc<Net>>) -> Option<Rc<Net>> {
let pin = self.pin_instances.get(pin_instance_id).unwrap();
self.connect_pin(pin, net)
}
pub fn connect_pin(&self, pin: &Rc<PinInstance>, net: Option<Rc<Net>>) -> Option<Rc<Net>> {
assert!(self.eq(&pin.circuit_instance().upgrade().unwrap()),
"Pin does not live in this circuit instance.");
if let Some(net) = &net {
assert!(net.parent_circuit.ptr_eq(&self.parent_circuit()),
"Net does not live in this circuit.");
}
if let Some(old_net) = pin.net() {
old_net.pin_instances.borrow_mut().remove(&pin.clone());
}
if let Some(net) = &net {
net.pin_instances.borrow_mut()
.insert(pin.clone());
}
pin.net.replace(net)
}
pub fn disconnect_pin_by_id(&self, pin_instance_id: usize) -> Option<Rc<Net>> {
self.connect_pin_by_id(pin_instance_id, None)
}
pub fn disconnect_pin(&self, pin_instance: &Rc<PinInstance>) -> Option<Rc<Net>> {
self.connect_pin(pin_instance, None)
}
pub fn each_pin_instance(&self) -> impl Iterator<Item=&Rc<PinInstance>> + ExactSizeIterator {
self.pin_instances.iter()
}
pub fn each_pin_instance_vec(&self) -> Vec<Rc<PinInstance>> {
self.pin_instances.to_vec()
}
pub fn id(&self) -> CircuitInstIndex {
self.id
}
pub fn name(&self) -> Option<&String> {
self.name.as_ref()
}
pub fn net_for_pin(&self, pin_index: usize) -> Option<Rc<Net>> {
self.pin_instances[pin_index]
.net.borrow().clone()
}
pub fn pin_count(&self) -> usize {
self.pin_instances.len()
}
pub fn pin_instance_by_id(&self, pin_index: usize) -> Rc<PinInstance> {
self.pin_instances[pin_index].clone()
}
}