#ifndef _PIN_MODEL_HPP_ #define _PIN_MODEL_HPP_ #include "pin_spec.hpp" #include #include #include class Part; // A source of *expected* pin attributes for a part — a connector layout, a BSDL // device, (later) a SPICE/Modelica model. Both of today's sources implement this // interface and feed the single `apply_model()`, so `verify` stays agnostic of // where a pin's spec came from. struct PinModel { virtual ~PinModel() = default; // Expected spec for the pin identified by `pin_name` — its logical name, and // for models that index physical pads, its package ball too. Returns a // default PinSpec (source == None) when the model has nothing to say. virtual PinSpec spec_for(const std::string &pin_name) const = 0; // Canonical full pin-name list, used to materialise pins absent from the // imported netlist. Empty means the model does not drive materialisation. virtual std::vector layout() const = 0; // Which source this model represents (recorded in each spec it sets). virtual SpecSource source() const = 0; }; struct ApplyReport { int pins_total = 0; ///< pins on the part after materialisation int set = 0; ///< pins whose spec the model set int materialised = 0; ///< pins created from layout() }; // Materialise the layout pins missing from the part, then set each pin's `spec` // from the model — only where the model actually speaks for that pin // (`spec.source != None`), so a model never wipes another source's spec. ApplyReport apply_model(Part *part, const PinModel &model); // Connector-layout model: wraps `pin_role(kind, name)` / `pin_layout(kind)`. class ConnectorModel : public PinModel { public: explicit ConnectorModel(std::string kind) : kind_(std::move(kind)) {} PinSpec spec_for(const std::string &pin_name) const override; std::vector layout() const override; SpecSource source() const override { return SpecSource::ConnectorModel; } private: std::string kind_; }; #endif // _PIN_MODEL_HPP_