diff options
Diffstat (limited to 'core/src/mod.rs')
-rw-r--r-- | core/src/mod.rs | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/core/src/mod.rs b/core/src/mod.rs new file mode 100644 index 0000000..40fe74f --- /dev/null +++ b/core/src/mod.rs | |||
@@ -0,0 +1,90 @@ | |||
1 | pub mod constraints; | ||
2 | pub mod drawable; | ||
3 | pub mod shapes; | ||
4 | pub mod text; | ||
5 | pub mod types; | ||
6 | |||
7 | pub use self::drawable::Drawable; | ||
8 | pub use self::shapes::Shape as CoreShape; | ||
9 | pub use self::types::{Bounded, Bounds, DefinitelyBounded}; | ||
10 | |||
11 | use self::constraints::Constrainable; | ||
12 | |||
13 | const RECURSION_LIMIT: u64 = 10_000; | ||
14 | |||
15 | pub struct Context<'z3> { | ||
16 | drawables: Vec<Bounded<'z3, Box<dyn Drawable>>>, | ||
17 | } | ||
18 | |||
19 | impl<'z3> Context<'z3> { | ||
20 | pub fn new() -> Self { | ||
21 | Self { drawables: vec![] } | ||
22 | } | ||
23 | |||
24 | pub fn add_shape(&mut self, shape: Bounded<'z3, Box<dyn Drawable>>) { | ||
25 | self.drawables.push(shape); | ||
26 | } | ||
27 | |||
28 | pub fn set_constraints(&self, z3_ctx: &z3::Context, solver: &z3::Solver) { | ||
29 | for drawable in &self.drawables { | ||
30 | for constraint in drawable.shape.constraints(&drawable.bounds, &z3_ctx) { | ||
31 | solver.assert(&constraint); | ||
32 | } | ||
33 | } | ||
34 | } | ||
35 | |||
36 | // TODO: simplify until not possible? | ||
37 | |||
38 | pub fn draw(&self, model: &z3::Model) -> Vec<DefinitelyBounded<CoreShape>> { | ||
39 | let mut acc_core_drawables = Vec::new(); | ||
40 | let mut acc_complex_drawables = Vec::new(); | ||
41 | |||
42 | for drawable in &self.drawables { | ||
43 | let bounds = &drawable.bounds; | ||
44 | let shape = &drawable.shape; | ||
45 | |||
46 | let (core_drawables, mut complex_drawables) = shape.draw(bounds); | ||
47 | |||
48 | acc_core_drawables.extend(core_drawables.iter().map(|Bounded { bounds, shape }| { | ||
49 | DefinitelyBounded { | ||
50 | bounds: bounds.fixate(model), | ||
51 | shape: shape.clone(), | ||
52 | } | ||
53 | })); | ||
54 | |||
55 | acc_complex_drawables.append(&mut complex_drawables); | ||
56 | } | ||
57 | |||
58 | let mut recursion_count = 0; | ||
59 | |||
60 | while !acc_complex_drawables.is_empty() { | ||
61 | recursion_count += 1; | ||
62 | |||
63 | let mut tmp_complex_drawables = Vec::new(); | ||
64 | |||
65 | for drawable in acc_complex_drawables.drain(..) { | ||
66 | let bounds = drawable.bounds; | ||
67 | let shape = drawable.shape; | ||
68 | |||
69 | let (core_drawables, mut complex_drawables) = shape.draw(&bounds); | ||
70 | |||
71 | acc_core_drawables.extend(core_drawables.into_iter().map( | ||
72 | |Bounded { bounds, shape }| DefinitelyBounded { | ||
73 | bounds: bounds.fixate(model), | ||
74 | shape, | ||
75 | }, | ||
76 | )); | ||
77 | |||
78 | tmp_complex_drawables.append(&mut complex_drawables); | ||
79 | } | ||
80 | |||
81 | acc_complex_drawables = tmp_complex_drawables; | ||
82 | |||
83 | if recursion_count > RECURSION_LIMIT { | ||
84 | panic!("Recursion limit reached"); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | acc_core_drawables | ||
89 | } | ||
90 | } | ||