use crate::building::builder::get_value;
use crate::building::{
BuildId, CheckBuildResult, CheckEnvironment, CheckStep, ContextualEnvironment,
DynamicBuildResult, GenesisEnvironment, StaticBuildResult,
};
use crate::building::{Builder as BuilderTrait, HostTreatment};
use crate::debug::Event;
use crate::design::Model;
use crate::error::LogicResult;
use crate::world::World;
use core::fmt::Debug;
use melodium_common::descriptor::{Model as ModelDescriptor, Parameterized};
use std::sync::{Arc, Weak};
#[derive(Debug)]
pub struct Builder {
world: Weak<World>,
design: Arc<Model>,
}
impl Builder {
pub fn new(world: Weak<World>, design: Arc<Model>) -> Self {
Self { world, design }
}
}
impl BuilderTrait for Builder {
fn static_build(
&self,
host_treatment: HostTreatment,
host_build: Option<BuildId>,
label: String,
environment: &GenesisEnvironment,
) -> LogicResult<StaticBuildResult> {
let mut environment = environment.clone();
let mut remastered_environment = GenesisEnvironment::new();
let descriptor = self.design.descriptor.upgrade().unwrap();
for (name, parameter) in descriptor
.parameters()
.iter()
.filter(|(_, p)| p.default().is_some())
{
if !environment.variables().contains_key(name) {
environment.add_variable(name, parameter.default().as_ref().unwrap().clone());
}
}
for (_, parameter) in self.design.parameters.iter() {
let data = get_value(¶meter.value, &environment, None)
.expect("Impossible data recoverage");
remastered_environment.add_variable(¶meter.name, data.clone());
}
let world = self.world.upgrade().unwrap();
world.send_debug(Event::new(crate::debug::EventKind::ModelBuilt {
model: Arc::clone(&descriptor) as Arc<dyn ModelDescriptor>,
parameters: remastered_environment.variables().clone(),
host_treatment: host_treatment.clone(),
host_build,
label: label.clone(),
}));
world
.builder(descriptor.base_model().unwrap().identifier())
.and_then(|builder| {
builder.static_build(host_treatment, host_build, label, &remastered_environment)
})
}
fn dynamic_build(
&self,
_build: BuildId,
_with_inputs: Vec<String>,
_environment: &ContextualEnvironment,
) -> Option<DynamicBuildResult> {
None
}
fn give_next(
&self,
_within_build: BuildId,
_for_label: String,
_for_outputs: Vec<String>,
_environment: &ContextualEnvironment,
) -> Option<DynamicBuildResult> {
None
}
fn check_dynamic_build(
&self,
_build: BuildId,
_environment: CheckEnvironment,
_previous_steps: Vec<CheckStep>,
) -> Option<CheckBuildResult> {
None
}
fn check_give_next(
&self,
_within_build: BuildId,
_for_label: String,
_environment: CheckEnvironment,
_previous_steps: Vec<CheckStep>,
) -> Option<CheckBuildResult> {
None
}
}