1use bevy_ecs::prelude::Entity;
19
20use crate::{
21 AddBranchToForkClone, AddOperation, Builder, Chain, ForkClone, ForkTargetStorage,
22 SingleInputStorage, StreamPack, UnusedTarget,
23};
24
25pub mod dyn_node;
26
27#[derive(Debug)]
29#[must_use]
30pub struct Node<Request, Response, Streams: StreamPack = ()> {
31 pub input: InputSlot<Request>,
34 pub output: Output<Response>,
37 pub streams: Streams::StreamOutputPack,
42}
43
44#[must_use]
49pub struct InputSlot<Request> {
50 scope: Entity,
51 source: Entity,
52 _ignore: std::marker::PhantomData<fn(Request)>,
53}
54
55impl<T> Clone for InputSlot<T> {
56 fn clone(&self) -> Self {
57 *self
58 }
59}
60
61impl<T> Copy for InputSlot<T> {}
62
63impl<Request> std::fmt::Debug for InputSlot<Request> {
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 f.debug_struct(format!("Input<{}>", std::any::type_name::<Request>()).as_str())
66 .field("scope", &self.scope)
67 .field("source", &self.source)
68 .finish()
69 }
70}
71
72impl<Request> InputSlot<Request> {
73 pub fn id(&self) -> Entity {
74 self.source
75 }
76 pub fn scope(&self) -> Entity {
77 self.scope
78 }
79 pub(crate) fn new(scope: Entity, source: Entity) -> Self {
80 Self {
81 scope,
82 source,
83 _ignore: Default::default(),
84 }
85 }
86}
87
88#[must_use]
96pub struct Output<Response> {
97 scope: Entity,
98 target: Entity,
99 _ignore: std::marker::PhantomData<fn(Response)>,
100}
101
102impl<Response> std::fmt::Debug for Output<Response> {
103 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104 f.debug_struct(format!("Output<{}>", std::any::type_name::<Response>()).as_str())
105 .field("scope", &self.scope)
106 .field("target", &self.target)
107 .finish()
108 }
109}
110
111impl<Response: 'static + Send + Sync> Output<Response> {
112 pub fn chain<'w, 's, 'a, 'b>(
114 self,
115 builder: &'b mut Builder<'w, 's, 'a>,
116 ) -> Chain<'w, 's, 'a, 'b, Response>
117 where
118 Response: 'static + Send + Sync,
119 {
120 assert_eq!(self.scope, builder.scope());
121 Chain::new(self.target, builder)
122 }
123
124 pub fn fork_clone(self, builder: &mut Builder) -> ForkCloneOutput<Response>
127 where
128 Response: Clone,
129 {
130 assert_eq!(self.scope, builder.scope());
131 builder.commands.queue(AddOperation::new(
132 Some(self.scope),
133 self.target,
134 ForkClone::<Response>::new(ForkTargetStorage::new()),
135 ));
136 ForkCloneOutput::new(self.scope, self.target)
137 }
138
139 pub fn id(&self) -> Entity {
141 self.target
142 }
143
144 pub fn scope(&self) -> Entity {
146 self.scope
147 }
148
149 pub(crate) fn new(scope: Entity, target: Entity) -> Self {
150 Self {
151 scope,
152 target,
153 _ignore: Default::default(),
154 }
155 }
156}
157
158#[must_use]
161pub struct ForkCloneOutput<Response> {
162 scope: Entity,
163 source: Entity,
164 _ignore: std::marker::PhantomData<fn(Response)>,
165}
166
167impl<Response: 'static + Send + Sync> ForkCloneOutput<Response> {
168 pub fn clone_output(&self, builder: &mut Builder) -> Output<Response> {
169 assert_eq!(self.scope, builder.scope());
170 let target = builder
171 .commands
172 .spawn((SingleInputStorage::new(self.id()), UnusedTarget))
173 .id();
174 builder.commands.queue(AddBranchToForkClone {
175 source: self.source,
176 target,
177 });
178
179 Output::new(self.scope, target)
180 }
181
182 pub fn clone_chain<'w, 's, 'a, 'b>(
183 &self,
184 builder: &'b mut Builder<'w, 's, 'a>,
185 ) -> Chain<'w, 's, 'a, 'b, Response> {
186 let output = self.clone_output(builder);
187 output.chain(builder)
188 }
189
190 pub fn id(&self) -> Entity {
191 self.source
192 }
193
194 pub fn scope(&self) -> Entity {
195 self.scope
196 }
197
198 pub(crate) fn new(scope: Entity, source: Entity) -> Self {
199 Self {
200 scope,
201 source,
202 _ignore: Default::default(),
203 }
204 }
205}
206
207pub struct ForkResultOutput<T, E> {
210 pub ok: Output<T>,
212 pub err: Output<E>,
214}
215
216pub struct ForkOptionOutput<T> {
219 pub some: Output<T>,
221 pub none: Output<()>,
223}