26 lines
3.0 KiB
C++
26 lines
3.0 KiB
C++
#include "logic_assembly.hpp"
|
|
#include <algorithm>
|
|
|
|
namespace fluidsim::port {
|
|
void extract_machine_logic(const MachineDocument& source,const std::set<std::uint32_t>& selected,MachineDocument& assembly){
|
|
std::set<std::uint32_t> chosen;std::unordered_map<std::uint32_t,std::vector<std::uint32_t>> 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<std::uint32_t> pending(chosen.begin(),chosen.end());for(std::size_t i=0;i<pending.size();++i)for(const auto id:neighbours[pending[i]])if(chosen.insert(id).second)pending.push_back(id);
|
|
for(auto node:source.logic.nodes)if(chosen.contains(node.id)){
|
|
if((node.kind==LogicNodeKind::Command||node.kind==LogicNodeKind::Ecu)&&!selected.contains(node.part)){if(const auto host=source.find(node.part))node.binding_label=host->name;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<std::uint32_t,std::uint32_t>& parts,const std::unordered_map<std::uint32_t,std::uint32_t>& sensors){
|
|
std::unordered_map<std::uint32_t,std::uint32_t> 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));}
|
|
}
|
|
}
|