use serde::{Deserialize, Serialize}; pub mod read; pub mod write; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] pub enum Kind { // TODO: `read::Read` and `write::Write` hold real values atm -- they should actually // point to `Const` instructions instead (which are... yet to be done...) Read(read::Read), Write(write::Write), Math(Math), Blend(Blend), Noise(Noise), Filter(Filter), } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] pub enum Math { Add, Subtract, Multiply, Divide, } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] pub enum Blend { Normal, Multiply, Additive, Overlay, Screen, Subtractive, Difference, Darken, Lighten, } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] pub enum Noise { Perlin, Simplex, Voronoi, } #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] pub enum Filter { Invert, } // TODO: given that this basically matches on all instructions, we may need to use // the visitor pattern in future here, or at least get them behind traits // which should allow far more nuanced description impl Kind { /// Returns how many sockets this kind of instruction has. #[must_use] pub fn socket_count(&self) -> SocketCount { match self { Self::Read(_) => (0, 1), Self::Write(_) => (1, 0), Self::Math(_) | Self::Blend(_) => (2, 1), Self::Noise(_) => { todo!("how many arguments does noise take? how many outputs does it have?") } Self::Filter(Filter::Invert) => (1, 1), } .into() } } /// How many sockets are on an instruction? pub struct SocketCount { pub inputs: u16, pub outputs: u16, } impl From<(u16, u16)> for SocketCount { fn from((inputs, outputs): (u16, u16)) -> Self { Self { inputs, outputs } } }