Rename things
This commit is contained in:
parent
7dbcd4963f
commit
6de1999b8d
@ -77,13 +77,13 @@ impl Asynchronous {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Graph<Output, Synch: Synchronicity> {
|
pub struct GraphBuilder<Output, Synch: Synchronicity> {
|
||||||
node_graph: Rc<RefCell<NodeGraph<Synch>>>,
|
node_graph: Rc<RefCell<NodeGraph<Synch>>>,
|
||||||
output: Option<Input<Output>>,
|
output: Option<Input<Output>>,
|
||||||
output_type: std::marker::PhantomData<Output>,
|
output_type: std::marker::PhantomData<Output>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: 'static> Graph<O, Synchronous> {
|
impl<O: 'static> GraphBuilder<O, Synchronous> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
node_graph: Rc::new(RefCell::new(NodeGraph(StableDiGraph::new()))),
|
node_graph: Rc::new(RefCell::new(NodeGraph(StableDiGraph::new()))),
|
||||||
@ -93,7 +93,7 @@ impl<O: 'static> Graph<O, Synchronous> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: 'static> Graph<O, Asynchronous> {
|
impl<O: 'static> GraphBuilder<O, Asynchronous> {
|
||||||
pub fn new_async() -> Self {
|
pub fn new_async() -> Self {
|
||||||
Self {
|
Self {
|
||||||
node_graph: Rc::new(RefCell::new(NodeGraph(StableDiGraph::new()))),
|
node_graph: Rc::new(RefCell::new(NodeGraph(StableDiGraph::new()))),
|
||||||
@ -103,7 +103,7 @@ impl<O: 'static> Graph<O, Asynchronous> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: 'static, S: Synchronicity> Graph<O, S> {
|
impl<O: 'static, S: Synchronicity> GraphBuilder<O, S> {
|
||||||
pub fn set_output<R: Rule<Output = O>>(&mut self, rule: R) {
|
pub fn set_output<R: Rule<Output = O>>(&mut self, rule: R) {
|
||||||
let input = self.add_rule(rule);
|
let input = self.add_rule(rule);
|
||||||
self.output = Some(input);
|
self.output = Some(input);
|
||||||
@ -145,9 +145,9 @@ impl<O: 'static, S: Synchronicity> Graph<O, S> {
|
|||||||
input
|
input
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn freeze(self) -> Result<FrozenGraph<O, S>, GraphFreezeError> {
|
pub fn build(self) -> Result<Graph<O, S>, BuildGraphError> {
|
||||||
let output: &Input<O> = match &self.output {
|
let output: &Input<O> = match &self.output {
|
||||||
None => return Err(GraphFreezeError::NoOutput),
|
None => return Err(BuildGraphError::NoOutput),
|
||||||
Some(output) => output,
|
Some(output) => output,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -174,20 +174,20 @@ impl<O: 'static, S: Synchronicity> Graph<O, S> {
|
|||||||
if let Err(_cycle) = sorted {
|
if let Err(_cycle) = sorted {
|
||||||
self.node_graph.borrow_mut().clear_edges();
|
self.node_graph.borrow_mut().clear_edges();
|
||||||
// TODO: actually build a vec describing the cycle path for debugging
|
// TODO: actually build a vec describing the cycle path for debugging
|
||||||
return Err(GraphFreezeError::Cyclic(vec![]));
|
return Err(BuildGraphError::Cyclic(vec![]));
|
||||||
}
|
}
|
||||||
|
|
||||||
let frozen = FrozenGraph {
|
let graph = Graph {
|
||||||
node_graph: self.node_graph,
|
node_graph: self.node_graph,
|
||||||
output: self.output.unwrap(),
|
output: self.output.unwrap(),
|
||||||
output_type: std::marker::PhantomData,
|
output_type: std::marker::PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(frozen)
|
Ok(graph)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: 'static> Graph<O, Asynchronous> {
|
impl<O: 'static> GraphBuilder<O, Asynchronous> {
|
||||||
pub fn set_async_output<R: AsyncRule<Output = O>>(&mut self, rule: R) {
|
pub fn set_async_output<R: AsyncRule<Output = O>>(&mut self, rule: R) {
|
||||||
let input = self.add_async_rule(rule);
|
let input = self.add_async_rule(rule);
|
||||||
self.output = Some(input);
|
self.output = Some(input);
|
||||||
@ -217,18 +217,18 @@ impl<O: 'static> Graph<O, Asynchronous> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum GraphFreezeError {
|
pub enum BuildGraphError {
|
||||||
NoOutput,
|
NoOutput,
|
||||||
Cyclic(Vec<NodeIndex<u32>>),
|
Cyclic(Vec<NodeIndex<u32>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FrozenGraph<Output, Synch: Synchronicity> {
|
pub struct Graph<Output, Synch: Synchronicity> {
|
||||||
node_graph: Rc<RefCell<NodeGraph<Synch>>>,
|
node_graph: Rc<RefCell<NodeGraph<Synch>>>,
|
||||||
output: Input<Output>,
|
output: Input<Output>,
|
||||||
output_type: std::marker::PhantomData<Output>,
|
output_type: std::marker::PhantomData<Output>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: 'static, S: Synchronicity> FrozenGraph<O, S> {
|
impl<O: 'static, S: Synchronicity> Graph<O, S> {
|
||||||
pub fn is_output_valid(&self) -> bool {
|
pub fn is_output_valid(&self) -> bool {
|
||||||
let graph = self.node_graph.borrow();
|
let graph = self.node_graph.borrow();
|
||||||
let node = &graph[self.output.node_idx];
|
let node = &graph[self.output.node_idx];
|
||||||
@ -239,9 +239,9 @@ impl<O: 'static, S: Synchronicity> FrozenGraph<O, S> {
|
|||||||
self.node_graph.borrow().node_count()
|
self.node_graph.borrow().node_count()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn modify<F>(&mut self, mut f: F) -> Result<(), GraphFreezeError>
|
pub fn modify<F>(&mut self, mut f: F) -> Result<(), BuildGraphError>
|
||||||
where
|
where
|
||||||
F: FnMut(&mut Graph<O, S>) -> (),
|
F: FnMut(&mut GraphBuilder<O, S>) -> (),
|
||||||
{
|
{
|
||||||
// Copy all the current edges so we can check if any change.
|
// Copy all the current edges so we can check if any change.
|
||||||
let graph = self.node_graph.borrow();
|
let graph = self.node_graph.borrow();
|
||||||
@ -259,13 +259,13 @@ impl<O: 'static, S: Synchronicity> FrozenGraph<O, S> {
|
|||||||
graph.clear_edges();
|
graph.clear_edges();
|
||||||
drop(graph);
|
drop(graph);
|
||||||
|
|
||||||
let mut graph = Graph {
|
let mut graph = GraphBuilder {
|
||||||
node_graph: Rc::clone(&self.node_graph),
|
node_graph: Rc::clone(&self.node_graph),
|
||||||
output: Some(self.output.clone()),
|
output: Some(self.output.clone()),
|
||||||
output_type: std::marker::PhantomData,
|
output_type: std::marker::PhantomData,
|
||||||
};
|
};
|
||||||
f(&mut graph);
|
f(&mut graph);
|
||||||
*self = graph.freeze()?;
|
*self = graph.build()?;
|
||||||
|
|
||||||
// Any new inboud edges invalidate their target nodes.
|
// Any new inboud edges invalidate their target nodes.
|
||||||
let mut graph = self.node_graph.borrow_mut();
|
let mut graph = self.node_graph.borrow_mut();
|
||||||
@ -286,7 +286,7 @@ impl<O: 'static, S: Synchronicity> FrozenGraph<O, S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: 'static> FrozenGraph<O, Synchronous> {
|
impl<O: 'static> Graph<O, Synchronous> {
|
||||||
fn update_node(&mut self, idx: NodeIndex<u32>) {
|
fn update_node(&mut self, idx: NodeIndex<u32>) {
|
||||||
let graph = self.node_graph.borrow();
|
let graph = self.node_graph.borrow();
|
||||||
let node = &graph[idx];
|
let node = &graph[idx];
|
||||||
@ -317,7 +317,7 @@ impl<O: 'static> FrozenGraph<O, Synchronous> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: 'static> FrozenGraph<O, Asynchronous> {
|
impl<O: 'static> Graph<O, Asynchronous> {
|
||||||
async fn update_node_async(&mut self, idx: NodeIndex<u32>) {
|
async fn update_node_async(&mut self, idx: NodeIndex<u32>) {
|
||||||
// TODO: same note about recursing as above, and consider doing this in parallel
|
// TODO: same note about recursing as above, and consider doing this in parallel
|
||||||
let graph = self.node_graph.borrow();
|
let graph = self.node_graph.borrow();
|
||||||
@ -620,19 +620,19 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rule_output_with_no_inputs() {
|
fn rule_output_with_no_inputs() {
|
||||||
let mut graph = Graph::new();
|
let mut builder = GraphBuilder::new();
|
||||||
graph.set_output(ConstantRule(1234));
|
builder.set_output(ConstantRule(1234));
|
||||||
assert_eq!(*graph.freeze().unwrap().evaluate(), 1234);
|
assert_eq!(*builder.build().unwrap().evaluate(), 1234);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_output_is_valid() {
|
fn test_output_is_valid() {
|
||||||
let mut graph = Graph::new();
|
let mut builder = GraphBuilder::new();
|
||||||
graph.set_output(ConstantRule(1));
|
builder.set_output(ConstantRule(1));
|
||||||
let mut frozen = graph.freeze().unwrap();
|
let mut graph = builder.build().unwrap();
|
||||||
assert!(!frozen.is_output_valid());
|
assert!(!graph.is_output_valid());
|
||||||
frozen.evaluate();
|
graph.evaluate();
|
||||||
assert!(frozen.is_output_valid());
|
assert!(graph.is_output_valid());
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Double(Input<i32>);
|
struct Double(Input<i32>);
|
||||||
@ -648,19 +648,19 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rule_with_input() {
|
fn rule_with_input() {
|
||||||
let mut graph = Graph::new();
|
let mut builder = GraphBuilder::new();
|
||||||
let input = graph.add_value(42);
|
let input = builder.add_value(42);
|
||||||
graph.set_output(Double(input));
|
builder.set_output(Double(input));
|
||||||
assert_eq!(*graph.freeze().unwrap().evaluate(), 84);
|
assert_eq!(*builder.build().unwrap().evaluate(), 84);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rule_with_input_rule() {
|
fn rule_with_input_rule() {
|
||||||
let mut graph = Graph::new();
|
let mut builder = GraphBuilder::new();
|
||||||
let input = graph.add_value(42);
|
let input = builder.add_value(42);
|
||||||
let doubled = graph.add_rule(Double(input));
|
let doubled = builder.add_rule(Double(input));
|
||||||
graph.set_output(Double(doubled));
|
builder.set_output(Double(doubled));
|
||||||
assert_eq!(*graph.freeze().unwrap().evaluate(), 168);
|
assert_eq!(*builder.build().unwrap().evaluate(), 168);
|
||||||
}
|
}
|
||||||
struct Inc(i32);
|
struct Inc(i32);
|
||||||
impl Rule for Inc {
|
impl Rule for Inc {
|
||||||
@ -674,20 +674,20 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn invalidatable_rule() {
|
fn invalidatable_rule() {
|
||||||
let mut graph = Graph::new();
|
let mut builder = GraphBuilder::new();
|
||||||
let mut invalidate = None;
|
let mut invalidate = None;
|
||||||
let input = graph.add_invalidatable_rule(|inv| {
|
let input = builder.add_invalidatable_rule(|inv| {
|
||||||
invalidate = Some(inv);
|
invalidate = Some(inv);
|
||||||
Inc(0)
|
Inc(0)
|
||||||
});
|
});
|
||||||
graph.set_output(Double(input));
|
builder.set_output(Double(input));
|
||||||
let mut frozen = graph.freeze().unwrap();
|
let mut graph = builder.build().unwrap();
|
||||||
assert_eq!(*frozen.evaluate(), 2);
|
assert_eq!(*graph.evaluate(), 2);
|
||||||
invalidate.as_ref().unwrap().invalidate();
|
invalidate.as_ref().unwrap().invalidate();
|
||||||
assert_eq!(*frozen.evaluate(), 4);
|
assert_eq!(*graph.evaluate(), 4);
|
||||||
assert_eq!(*frozen.evaluate(), 4);
|
assert_eq!(*graph.evaluate(), 4);
|
||||||
invalidate.as_ref().unwrap().invalidate();
|
invalidate.as_ref().unwrap().invalidate();
|
||||||
assert_eq!(*frozen.evaluate(), 6);
|
assert_eq!(*graph.evaluate(), 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Add(Input<i32>, Input<i32>);
|
struct Add(Input<i32>, Input<i32>);
|
||||||
@ -704,35 +704,35 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rule_with_multiple_inputs() {
|
fn rule_with_multiple_inputs() {
|
||||||
let mut graph = Graph::new();
|
let mut builder = GraphBuilder::new();
|
||||||
let a = graph.add_value(2);
|
let a = builder.add_value(2);
|
||||||
let b = graph.add_value(3);
|
let b = builder.add_value(3);
|
||||||
graph.set_output(Add(a, b));
|
builder.set_output(Add(a, b));
|
||||||
assert_eq!(*graph.freeze().unwrap().evaluate(), 5);
|
assert_eq!(*builder.build().unwrap().evaluate(), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rule_with_invalidatable_inputs() {
|
fn rule_with_invalidatable_inputs() {
|
||||||
let mut graph = Graph::new();
|
let mut builder = GraphBuilder::new();
|
||||||
let mut invalidate = None;
|
let mut invalidate = None;
|
||||||
let a = graph.add_invalidatable_rule(|inv| {
|
let a = builder.add_invalidatable_rule(|inv| {
|
||||||
invalidate = Some(inv);
|
invalidate = Some(inv);
|
||||||
Inc(0)
|
Inc(0)
|
||||||
});
|
});
|
||||||
let b = graph.add_rule(Inc(0));
|
let b = builder.add_rule(Inc(0));
|
||||||
graph.set_output(Add(a, b));
|
builder.set_output(Add(a, b));
|
||||||
let mut frozen = graph.freeze().unwrap();
|
let mut graph = builder.build().unwrap();
|
||||||
assert_eq!(*frozen.evaluate(), 2);
|
assert_eq!(*graph.evaluate(), 2);
|
||||||
invalidate.as_ref().unwrap().invalidate();
|
invalidate.as_ref().unwrap().invalidate();
|
||||||
assert_eq!(*frozen.evaluate(), 3);
|
assert_eq!(*graph.evaluate(), 3);
|
||||||
assert_eq!(*frozen.evaluate(), 3);
|
assert_eq!(*graph.evaluate(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cant_freeze_no_output() {
|
fn cant_freeze_no_output() {
|
||||||
let graph = Graph::<i32, Synchronous>::new();
|
let builder = GraphBuilder::<i32, Synchronous>::new();
|
||||||
match graph.freeze() {
|
match builder.build() {
|
||||||
Err(GraphFreezeError::NoOutput) => (),
|
Err(BuildGraphError::NoOutput) => (),
|
||||||
Err(e) => assert!(false, "unexpected error {:?}", e),
|
Err(e) => assert!(false, "unexpected error {:?}", e),
|
||||||
Ok(_) => assert!(false, "shouldn't have frozen graph"),
|
Ok(_) => assert!(false, "shouldn't have frozen graph"),
|
||||||
}
|
}
|
||||||
@ -753,15 +753,15 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cant_freeze_cycle() {
|
fn cant_freeze_cycle() {
|
||||||
let mut graph = Graph::new();
|
let mut builder = GraphBuilder::new();
|
||||||
let a_input = Rc::new(RefCell::new(None));
|
let a_input = Rc::new(RefCell::new(None));
|
||||||
let a = graph.add_rule(DeferredInput(Rc::clone(&a_input)));
|
let a = builder.add_rule(DeferredInput(Rc::clone(&a_input)));
|
||||||
let b_input = Rc::new(RefCell::new(Some(a)));
|
let b_input = Rc::new(RefCell::new(Some(a)));
|
||||||
let b = graph.add_rule(DeferredInput(b_input));
|
let b = builder.add_rule(DeferredInput(b_input));
|
||||||
*a_input.borrow_mut() = Some(b.clone());
|
*a_input.borrow_mut() = Some(b.clone());
|
||||||
graph.set_output(Double(b));
|
builder.set_output(Double(b));
|
||||||
match graph.freeze() {
|
match builder.build() {
|
||||||
Err(GraphFreezeError::Cyclic(_)) => (),
|
Err(BuildGraphError::Cyclic(_)) => (),
|
||||||
Err(e) => assert!(false, "unexpected error {:?}", e),
|
Err(e) => assert!(false, "unexpected error {:?}", e),
|
||||||
Ok(_) => assert!(false, "shouldn't have frozen graph"),
|
Ok(_) => assert!(false, "shouldn't have frozen graph"),
|
||||||
}
|
}
|
||||||
@ -769,42 +769,42 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn modify_graph() {
|
fn modify_graph() {
|
||||||
let mut graph = Graph::new();
|
let mut builder = GraphBuilder::new();
|
||||||
graph.set_output(ConstantRule(1));
|
builder.set_output(ConstantRule(1));
|
||||||
let mut frozen = graph.freeze().unwrap();
|
let mut graph = builder.build().unwrap();
|
||||||
assert_eq!(*frozen.evaluate(), 1);
|
assert_eq!(*graph.evaluate(), 1);
|
||||||
frozen
|
graph
|
||||||
.modify(|g| {
|
.modify(|g| {
|
||||||
g.set_output(ConstantRule(2));
|
g.set_output(ConstantRule(2));
|
||||||
})
|
})
|
||||||
.expect("modify");
|
.expect("modify");
|
||||||
assert_eq!(*frozen.evaluate(), 2);
|
assert_eq!(*graph.evaluate(), 2);
|
||||||
assert_eq!(frozen.node_count(), 1);
|
assert_eq!(graph.node_count(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn modify_with_dependencies() {
|
fn modify_with_dependencies() {
|
||||||
let mut graph = Graph::new();
|
let mut builder = GraphBuilder::new();
|
||||||
let input = Rc::new(RefCell::new(None));
|
let input = Rc::new(RefCell::new(None));
|
||||||
graph.set_output(DeferredInput(Rc::clone(&input)));
|
builder.set_output(DeferredInput(Rc::clone(&input)));
|
||||||
*input.borrow_mut() = Some(graph.add_value(1));
|
*input.borrow_mut() = Some(builder.add_value(1));
|
||||||
let mut frozen = graph.freeze().unwrap();
|
let mut graph = builder.build().unwrap();
|
||||||
assert_eq!(*frozen.evaluate(), 1);
|
assert_eq!(*graph.evaluate(), 1);
|
||||||
frozen
|
graph
|
||||||
.modify(|g| {
|
.modify(|g| {
|
||||||
*input.borrow_mut() = Some(g.add_value(2));
|
*input.borrow_mut() = Some(g.add_value(2));
|
||||||
})
|
})
|
||||||
.expect("modify");
|
.expect("modify");
|
||||||
assert!(!frozen.is_output_valid());
|
assert!(!graph.is_output_valid());
|
||||||
assert_eq!(*frozen.evaluate(), 2);
|
assert_eq!(*graph.evaluate(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn async_graph() {
|
async fn async_graph() {
|
||||||
let mut graph = Graph::new_async();
|
let mut builder = GraphBuilder::new_async();
|
||||||
graph.set_output(ConstantRule(42));
|
builder.set_output(ConstantRule(42));
|
||||||
let mut frozen = graph.freeze().unwrap();
|
let mut graph = builder.build().unwrap();
|
||||||
assert_eq!(*frozen.evaluate_async().await, 42);
|
assert_eq!(*graph.evaluate_async().await, 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@ -817,10 +817,10 @@ mod tests {
|
|||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut graph = Graph::new_async();
|
let mut builder = GraphBuilder::new_async();
|
||||||
graph.set_async_output(AsyncConst(42));
|
builder.set_async_output(AsyncConst(42));
|
||||||
let mut frozen = graph.freeze().unwrap();
|
let mut graph = builder.build().unwrap();
|
||||||
assert_eq!(*frozen.evaluate_async().await, 42);
|
assert_eq!(*graph.evaluate_async().await, 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -835,9 +835,9 @@ mod tests {
|
|||||||
NonCloneable
|
NonCloneable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut graph = Graph::new();
|
let mut builder = GraphBuilder::new();
|
||||||
graph.set_output(Output);
|
builder.set_output(Output);
|
||||||
let mut frozen = graph.freeze().unwrap();
|
let mut graph = builder.build().unwrap();
|
||||||
assert_eq!(*frozen.evaluate(), NonCloneable);
|
assert_eq!(*graph.evaluate(), NonCloneable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user