use crate::ui::{NodeUI, SocketUI};
pub trait Id: Clone + Eq + core::hash::Hash + Send + Sync + 'static {}
impl<T> Id for T where T: Clone + Eq + core::hash::Hash + Send + Sync + 'static {}
pub trait GraphAdapter {
type NodeId: Id;
type SocketId: Id;
fn nodes(&mut self) -> impl NodeIterator<NodeId = Self::NodeId, SocketId = Self::SocketId>;
fn connection_hint(&self, a: Self::SocketId, b: Self::SocketId) -> ConnectionHint;
fn connect(&mut self, a: Self::SocketId, b: Self::SocketId);
fn connections(&self) -> impl Iterator<Item = (Self::SocketId, Self::SocketId)>;
}
pub trait NodeAdapter {
type NodeId: Id;
type SocketId: Id;
fn sockets(&self) -> impl Iterator<Item: SocketAdapter<SocketId = Self::SocketId>>;
fn id(&self) -> Self::NodeId;
fn pos(&self) -> Pos;
fn set_pos(&mut self, pos: Pos);
#[inline]
fn ui(&self) -> NodeUI {
NodeUI::default()
}
}
pub trait SocketAdapter {
type SocketId: Id;
fn id(&self) -> Self::SocketId;
fn ui(&self) -> SocketUI;
}
pub trait NodeIterator {
type NodeId: Id;
type SocketId: Id;
type Item<'this>: NodeAdapter<NodeId = Self::NodeId, SocketId = Self::SocketId>
where
Self: 'this;
fn next(&mut self) -> Option<Self::Item<'_>>;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
impl<I> NodeIterator for I
where
I: Iterator,
I::Item: NodeAdapter,
{
type NodeId = <I::Item as NodeAdapter>::NodeId;
type SocketId = <I::Item as NodeAdapter>::SocketId;
type Item<'this> = I::Item
where
Self: 'this;
#[inline]
fn next(&mut self) -> Option<Self::Item<'_>> {
Iterator::next(self)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
Iterator::size_hint(self)
}
}
#[warn(clippy::missing_trait_methods)]
impl<'a, T: GraphAdapter + ?Sized> GraphAdapter for &'a mut T {
type NodeId = T::NodeId;
type SocketId = T::SocketId;
#[inline]
fn nodes(&mut self) -> impl NodeIterator<NodeId = Self::NodeId, SocketId = Self::SocketId> {
GraphAdapter::nodes(*self)
}
#[inline]
fn connection_hint(&self, a: Self::SocketId, b: Self::SocketId) -> ConnectionHint {
GraphAdapter::connection_hint(*self, a, b)
}
#[inline]
fn connect(&mut self, a: Self::SocketId, b: Self::SocketId) {
GraphAdapter::connect(*self, a, b);
}
#[inline]
fn connections(&self) -> impl Iterator<Item = (Self::SocketId, Self::SocketId)> {
GraphAdapter::connections(*self)
}
}
#[warn(clippy::missing_trait_methods)]
impl<'a, T: NodeAdapter + ?Sized> NodeAdapter for &'a mut T {
type NodeId = T::NodeId;
type SocketId = T::SocketId;
#[inline]
fn sockets(&self) -> impl Iterator<Item: SocketAdapter<SocketId = Self::SocketId>> {
NodeAdapter::sockets(*self)
}
#[inline]
fn id(&self) -> Self::NodeId {
NodeAdapter::id(*self)
}
#[inline]
fn pos(&self) -> Pos {
NodeAdapter::pos(*self)
}
#[inline]
fn set_pos(&mut self, pos: Pos) {
NodeAdapter::set_pos(*self, pos);
}
#[inline]
fn ui(&self) -> NodeUI {
NodeAdapter::ui(*self)
}
}
#[warn(clippy::missing_trait_methods)]
impl<'a, T: SocketAdapter + ?Sized> SocketAdapter for &'a T {
type SocketId = T::SocketId;
#[inline]
fn id(&self) -> Self::SocketId {
SocketAdapter::id(*self)
}
#[inline]
fn ui(&self) -> SocketUI {
SocketAdapter::ui(*self)
}
}
#[warn(clippy::missing_trait_methods)]
impl<'a, T: SocketAdapter + ?Sized> SocketAdapter for &'a mut T {
type SocketId = T::SocketId;
#[inline]
fn id(&self) -> Self::SocketId {
SocketAdapter::id(*self)
}
#[inline]
fn ui(&self) -> SocketUI {
SocketAdapter::ui(*self)
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Pos {
#[allow(missing_docs)]
pub x: i32,
#[allow(missing_docs)]
pub y: i32,
}
impl Pos {
#[inline]
#[must_use]
pub fn new(x: i32, y: i32) -> Self {
Pos { x, y }
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum ConnectionHint {
Reject,
Accept,
}