Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
recognition_resolver.hpp File Reference

The single merge layer for KEY-BASED control recognition in the design importer. More...

#include <pulp/view/design_ir.hpp>
#include <filesystem>
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>

Go to the source code of this file.

Classes

struct  pulp::view::RecognitionEntry
 One recognition source: a flat map of a designer's component identity to the Pulp control it materializes. More...
struct  pulp::view::RecognitionSource
 A named bundle of recognition entries from one origin (built-in library, user manifest, or — later — an installed package). More...
struct  pulp::view::ResolvedControl
 The result of resolving one node's identity against the merged table. More...
class  pulp::view::RecognitionResolver
 The single merge layer. More...
struct  pulp::view::UnmatchedComponent
 Apply the resolver to a parsed figma-plugin IR tree IN PLACE: for every node that carries a Figma component identity (attributes figmaComponentKey / figmaMainComponentName, stamped by parse_ir_node) but is NOT already a recognized audio widget, resolve it against the merged table and stamp audio_widget (built-in kinds) on a match. More...
struct  pulp::view::PackageDesignControlSources

Namespaces

namespace  pulp
namespace  pulp::view
 Hover-cursor tracking for platform window hosts.

Functions

AudioWidgetType pulp::view::audio_widget_kind_from_manifest_id (const std::string &id)
 Map an AudioWidgetType to/from the lowercase id used in manifests and the figma-plugin envelope ("knob"/"fader"/...).
const char * pulp::view::audio_widget_kind_to_manifest_id (AudioWidgetType kind)
int pulp::view::apply_recognition_resolver (IRNode &root, const RecognitionResolver &resolver, std::vector< UnmatchedComponent > *unmatched_out=nullptr)
PackageDesignControlSources pulp::view::gather_package_design_controls (const std::filesystem::path &lockfile_path, const std::filesystem::path &registry_path)
PackageDesignControlSources pulp::view::discover_package_design_controls (const std::filesystem::path &start_dir)
int pulp::view::materialize_recognized_custom_controls (IRNode &root)

Detailed Description

The single merge layer for KEY-BASED control recognition in the design importer.

── Why one module ────────────────────────────────────────────────────────── Control recognition draws from MULTIPLE sources that all answer the same question — "given a Figma `component_set_key` (or a layer-name prefix), which Pulp control kind / custom factory does it materialize?" Today there are two such sources:

  1. the built-in Pulp Figma Library (tools/figma-plugin/library-manifest.json),
  2. a USER-supplied recognition manifest (the designer's OWN component-set keys → Pulp kinds), passed via pulp import-design --recognition-manifest.

A THIRD source — installed-package design_controls fragments → registered custom-control factory_ids — is coming in issue #4677. The whole point of this module is that #4677 adds that source by calling add_source() ONCE, here, instead of threading a third lookup through the importer's parse lanes.

RecognitionResolver is that one place: it combines an ordered list of RecognitionSources into one resolved component_set_key → kind (and → factory_id) table, with later sources MERGED OVER earlier ones on key collision. The built-in library is always source 0 (lowest precedence); the user manifest is added over it; package fragments will be added over both. The built-in library's audio-control rules are a Pulp-owned pack (recognition_audio_pack.hpp); this module is the generic merge layer.

── Authoritative lane ────────────────────────────────────────────────────── The C++ figma-plugin lane (design_import.cpp::parse_figma_plugin_json) is the authoritative consumer: the plugin envelope carries each instance's figma.component_key / figma.main_component_name EVEN WHEN the in-Figma TS plugin did not recognize it (a third-party component). So re-resolving here, after parse, is where a user manifest takes effect without touching the in-Figma plugin. The TS plugin (extract.ts) and the Python REST lane (figma_rest_export.py) bake recognition for the BUILT-IN library at capture time; accepting a user manifest in those lanes too is a follow-up.

── Never-silent-knob contract ─────────────────────────────────────────────── A component instance the resolver does NOT match is left exactly as parsed — it is never guessed into a wrong kind. apply_to_figma_plugin_ir reports the unmatched-but-present component instances so they surface in the import report instead of being silently dropped.