use std::{hash::{Hash, Hasher}, sync::{atomic::Ordering, Arc}};
use crate::{contract::Contract, object::core::ObjectCore};
pub(crate) trait ExposeContract: Send + Sync + Contract + std::fmt::Debug {
fn composition_cost(&self) -> u32;
fn assign(&self, object: &Arc<ObjectCore>) -> bool;
fn unassign(&self, object: &Arc<ObjectCore>) -> bool;
fn object(&self) -> bool;
fn expected_proportional_load(&self, delta: i32) -> Option<u32> {
let exchange = self.exchange_core();
let load = exchange.load.load(Ordering::Relaxed) as i32;
let limit = exchange.limit.load(Ordering::Relaxed) as i32;
if load + delta > limit {
None
} else {
let capacity = exchange.capacity.load(Ordering::Relaxed) as i32;
let expected_proportional_load = (load + delta) * 1000 / capacity;
if expected_proportional_load.is_positive() {
Some(expected_proportional_load as u32)
} else {
Some(0)
}
}
}
fn expected_proportional_load_with(&self) -> Option<u32> {
let cost = self.composition_cost();
self.expected_proportional_load(cost as i32)
}
fn expected_proportional_load_without(&self) -> Option<u32> {
let cost = self.composition_cost();
self.expected_proportional_load(-(cost as i32))
}
}
impl Eq for dyn ExposeContract {}
impl PartialEq for dyn ExposeContract {
fn eq(&self, other: &Self) -> bool {
self.id() == other.id()
}
}
impl Hash for dyn ExposeContract {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id().hash(state)
}
}