Skip to main content

geop_cad_base/
registry.rs

1//! What the editor offers ([`registry`]): every crate's operations,
2//! drawers, exporters, inspectors, panels, tools, settler and examples,
3//! one `register` line per crate — and the one way a program
4//! is built outside the editor ([`build`]), in a workspace beside the
5//! standard parts ([`workspace`]).
6
7use std::{collections::BTreeMap, rc::Rc};
8
9use geop_core_editor::{editor::Editor, output::Outputs, registry::Registry};
10use geop_core_math::geop_error::GeopResult;
11use geop_core_program::{
12    cache::Cache,
13    part::Part,
14    program::Program,
15    runner::Runner,
16    workspace::{self, FileStore, Files, Location},
17};
18use geop_lib_stdlib::WithStandardParts;
19
20/// Everything the editor offers. Operations are offered group by group,
21/// and within a group and tier in the order they are registered here; the
22/// exporters and inspectors in the order they are registered — the first
23/// exporter's first format is what a part is written in unless told
24/// otherwise — and a part is drawn and listed by the drawers in turn.
25pub fn registry() -> GeopResult<Registry> {
26    let r = Registry::default();
27    let r = geop_ops_model::register(r)?;
28    let r = geop_ops_sketch::register(r)?;
29    let r = geop_ops_reference_geometry::register(r)?;
30    let r = geop_ops_sketch3d::register(r)?;
31    let r = geop_ops_extrude_revolve::register(r)?;
32    let r = geop_ops_hole::register(r)?;
33    let r = geop_ops_fillet::register(r)?;
34    let r = geop_ops_shell::register(r)?;
35    let r = geop_ops_plastic::register(r)?;
36    let r = geop_ops_boolean::register(r)?;
37    let r = geop_ops_pattern::register(r)?;
38    let r = geop_ops_subd::register(r)?;
39    let r = geop_ops_surface::register(r)?;
40    let r = geop_ops_edit::register(r)?;
41    let r = geop_ops_assembly::register(r)?;
42    let r = geop_ops_harness::register(r)?;
43    let r = geop_ops_step::register(r)?;
44    let r = geop_ops_drawing::register(r)?;
45    let r = geop_ops_sheetmetal::register(r)?;
46    let r = geop_ops_inspect::register(r)?;
47    geop_ops_bom::register(r)
48}
49
50/// An editor of everything [`registry`] offers, the standard parts beside
51/// the files it is sent.
52pub fn editor() -> Editor {
53    editor_with(Cache::new())
54}
55
56/// [`editor`], what its files are made into kept in `cache`.
57pub fn editor_with(cache: Cache) -> Editor {
58    let registry = registry().expect("the editor's extensions each have a name of their own");
59    Editor::with_cache(registry, WithStandardParts(BTreeMap::new()), cache)
60}
61
62/// The exporters and inspectors the editor offers (see
63/// [`geop_core_editor::output`]), in the order it offers them.
64pub fn outputs() -> GeopResult<Outputs> {
65    Ok(registry()?.into_outputs())
66}
67
68/// The workspace the editor builds programs in: a set of program files, and
69/// the standard parts beside them.
70pub type Workspace<F = BTreeMap<String, String>> = Files<WithStandardParts<F>>;
71
72/// The workspace of `files`, beside the standard parts, whose programs are
73/// written in the editor's operations.
74pub fn workspace<F: FileStore + 'static>(files: F) -> Rc<Workspace<F>> {
75    workspace_with(files, Cache::new())
76}
77
78/// [`workspace()`], what its files are made into kept in `cache`.
79pub fn workspace_with<F: FileStore + 'static>(files: F, cache: Cache) -> Rc<Workspace<F>> {
80    let registry = registry().expect("the editor's extensions each have a name of their own");
81    Workspace::with_cache(
82        WithStandardParts(files),
83        Rc::new(registry.operations()),
84        cache,
85    )
86}
87
88/// A runner of the editor's operations, that has run nothing yet.
89pub fn runner() -> Runner {
90    let registry = registry().expect("the editor's extensions each have a name of their own");
91    Runner::new(registry.operations())
92}
93
94/// A part a program built, and the runner that built it, to run it again.
95pub struct BuiltPart {
96    pub runner: Runner,
97    pub part: Part,
98}
99
100/// Builds `program`, the file `file` of `workspace` — for a program on its
101/// own, an empty [`workspace()`] — with its parameters as it defines them.
102pub fn build(
103    program: &Program,
104    file: &str,
105    workspace: Rc<dyn workspace::Workspace>,
106) -> GeopResult<BuiltPart> {
107    let mut runner = runner();
108    runner.workspace = Some(workspace);
109    runner.location = Location {
110        file: workspace::resolve("", file),
111        within: Vec::new(),
112    };
113    let mut part = Part::default();
114    program.run(&runner, &mut part)?;
115    Ok(BuiltPart { runner, part })
116}