#include "logic_assembly.hpp" #include namespace fluidsim::port { void extract_machine_logic(const MachineDocument& source,const std::set& selected,MachineDocument& assembly){ std::set chosen;std::unordered_map> neighbours; for(const auto& node:source.logic.nodes)if(((node.kind==LogicNodeKind::Command||node.kind==LogicNodeKind::Ecu)&&selected.contains(node.part))||(node.kind==LogicNodeKind::Sensor&&assembly.find_sensor(node.sensor)))chosen.insert(node.id); for(const auto& wire:source.logic.links){neighbours[wire.from.node].push_back(wire.to.node);neighbours[wire.to.node].push_back(wire.from.node);} std::vector pending(chosen.begin(),chosen.end());for(std::size_t i=0;iname;node.part=0;} if(node.kind==LogicNodeKind::Sensor){if(const auto sensor=source.find_sensor(node.sensor)){ if(!assembly.find_sensor(sensor->id)){auto copy=*sensor;for(auto* tap:{©.target,©.reference})if(!selected.contains(tap->part)){if(const auto host=source.find(tap->part))tap->label=host->name;tap->part=0;}assembly.next_sensor_id=std::max(assembly.next_sensor_id,copy.id+1);assembly.sensors.push_back(std::move(copy));} }else node.sensor=0; } assembly.logic.next_id=std::max(assembly.logic.next_id,node.id+1);assembly.logic.nodes.push_back(std::move(node)); } for(const auto& wire:source.logic.links)if(chosen.contains(wire.from.node)&&chosen.contains(wire.to.node))assembly.logic.links.push_back(wire); } void insert_machine_logic(MachineDocument& destination,const MachineDocument& assembly,const std::unordered_map& parts,const std::unordered_map& sensors){ std::unordered_map nodes;float shift=0;if(!destination.logic.nodes.empty()){float right=-1e6f,left=1e6f;for(const auto& n:destination.logic.nodes)right=std::max(right,n.position.x);for(const auto& n:assembly.logic.nodes)left=std::min(left,n.position.x);if(!assembly.logic.nodes.empty())shift=right-left+320;} for(auto node:assembly.logic.nodes){const auto original=node.id;node.id=destination.logic.next_id++;node.position.x+=shift;if((node.kind==LogicNodeKind::Command||node.kind==LogicNodeKind::Ecu))node.part=parts.contains(node.part)?parts.at(node.part):0;if(node.kind==LogicNodeKind::Sensor)node.sensor=sensors.contains(node.sensor)?sensors.at(node.sensor):0;nodes.emplace(original,node.id);destination.logic.nodes.push_back(std::move(node));} for(auto wire:assembly.logic.links){wire.from.node=nodes.at(wire.from.node);wire.to.node=nodes.at(wire.to.node);destination.logic.links.push_back(std::move(wire));} } }