Skip to content

🎯 IMPLEMENTATION PLAN: Composition Tools (08_01)

📍 UBICACIÓN

Carpeta de trabajo: 4 - INTEGRATION/08_PLUGINS/08_01_composition_tools/

🤖 INSTRUCCIONES PARA LA IA

Prompt Inicial

Cuando comiences a trabajar en esta carpeta, di:

"Estoy trabajando en la carpeta 08_01_composition_tools. Voy a implementar el sistema de herramientas de composición de plugins. Déjame leer el IMPLEMENTATION_PLAN.md y organizarme en fases."

Workflow Automático

  1. Lee este archivo completo antes de empezar
  2. Organízate en las 5 FASES definidas abajo
  3. Cada fase = 1 prompt (aprox. 3-4 horas de trabajo)
  4. Al finalizar cada fase: Actualiza el checklist y haz commit
  5. Entre fases: Espera confirmación del usuario antes de continuar

📊 DIVISIÓN EN FASES (5 prompts totales)

FASE 1: Component Library (Prompt 1)

Duración estimada: 3-4 horas Objetivo: Crear biblioteca de componentes DSP reutilizables

Micro-pipeline: 1. Crear subdirectorio 08_01_00_component_library/ 2. Implementar ComponentRegistry.hpp/.cpp 3. Implementar ComponentFactory.hpp/.cpp 4. Implementar ComponentMetadata.hpp 5. Crear component_catalog.json con 10-15 componentes 6. Crear CMakeLists.txt 7. Escribir README.md 8. Verificar compilación

Checklist: - [ ] ComponentRegistry implementado - [ ] ComponentFactory implementado - [ ] ComponentMetadata definido - [ ] component_catalog.json creado (10+ componentes) - [ ] CMakeLists.txt funcional - [ ] README.md completo - [ ] Compila sin errores


FASE 2: Visual Composer + Manifest Compiler (Prompt 2)

Duración estimada: 4-5 horas Objetivo: Parser de manifiestos y compilador a C++

Micro-pipeline: 1. Crear subdirectorio 08_01_01_visual_composer/ 2. Implementar ManifestParser.hpp/.cpp (nlohmann/json) 3. Implementar NodeGraph.hpp/.cpp 4. Implementar RoutingValidator.hpp/.cpp 5. Crear manifest_schema.json 6. Crear example_compressor.json 7. Crear subdirectorio 08_01_02_manifest_compiler/ 8. Implementar ManifestCompiler.hpp/.cpp 9. Implementar CodeGenerator.hpp/.cpp 10. Implementar TemplateEngine.hpp/.cpp 11. Verificar que genera código C++ válido

Checklist: - [ ] ManifestParser lee JSON correctamente - [ ] NodeGraph valida conectividad - [ ] RoutingValidator detecta ciclos - [ ] manifest_schema.json completo - [ ] Ejemplo funcional creado - [ ] ManifestCompiler genera código - [ ] Código generado compila - [ ] CMakeLists.txt funcional


FASE 3: Template System (Prompt 3)

Duración estimada: 4-5 horas Objetivo: Sistema de templates reutilizables

Micro-pipeline: 1. Crear subdirectorio 08_01_03_template_system/ 2. Implementar TemplateRegistry.hpp/.cpp 3. Implementar TemplateInstantiator.hpp/.cpp 4. Crear templates/l4_simple/ con archivos template 5. Crear templates/l4_modulation/ con archivos template 6. Crear templates/l5_suite/ con archivos template 7. Crear templates/l5_channelstrip/ con archivos template 8. Crear ejemplos de uso 9. Verificar instantiation funciona

Checklist: - [ ] TemplateRegistry implementado - [ ] TemplateInstantiator implementado - [ ] Template l4_simple creado - [ ] Template l4_modulation creado - [ ] Template l5_suite creado - [ ] Template l5_channelstrip creado - [ ] Ejemplos funcionan - [ ] Templates se instancian correctamente


FASE 4: Validation Engine (Prompt 4)

Duración estimada: 3-4 horas Objetivo: Motor de validación exhaustiva

Micro-pipeline: 1. Crear subdirectorio 08_01_04_validation_engine/ 2. Implementar ManifestValidator.hpp/.cpp 3. Implementar SyntaxValidator.hpp/.cpp 4. Implementar SemanticValidator.hpp/.cpp 5. Implementar DependencyValidator.hpp/.cpp 6. Implementar PerformanceValidator.hpp/.cpp 7. Implementar ValidationRules.hpp 8. Crear tests de validación 9. Verificar detecta errores correctamente

Checklist: - [ ] ManifestValidator implementado - [ ] SyntaxValidator implementado - [ ] SemanticValidator implementado - [ ] DependencyValidator implementado - [ ] PerformanceValidator implementado - [ ] ValidationRules configurables - [ ] Tests de validación pasan - [ ] Mensajes de error claros


FASE 5: Integration, Tests & Docs (Prompt 5)

Duración estimada: 3-4 horas Objetivo: Tests completos y documentación

Micro-pipeline: 1. Crear tests en 03_INFRA/03_04_testing_framework/ 2. Implementar test_component_library.cpp 3. Implementar test_manifest_parser.cpp 4. Implementar test_code_generator.cpp 5. Implementar test_validator.cpp 6. Crear example_workflow.cpp 7. Ejecutar todos los tests 8. Escribir documentación completa (6 docs) 9. Crear carpeta examples/ con 3-5 ejemplos completos 10. Commit final

Checklist: - [ ] test_component_library.cpp pasa - [ ] test_manifest_parser.cpp pasa - [ ] test_code_generator.cpp pasa - [ ] test_validator.cpp pasa - [ ] example_workflow.cpp funciona - [ ] Cobertura > 80% - [ ] 6 documentos escritos - [ ] 3-5 ejemplos completos - [ ] Commit realizado


📝 TAREAS DETALLADAS

TAREA 1.1: ComponentRegistry

Archivo: 08_01_00_component_library/ComponentRegistry.hpp

#pragma once

#include <string>
#include <vector>
#include <unordered_map>

namespace audiolab {
namespace plugins {
namespace composition {

struct ComponentInfo {
    std::string id;           // "compressor_rms"
    std::string name;         // "RMS Compressor"
    std::string category;     // "dynamics"
    uint32_t cpuCost;         // Estimated CPU cost (0-100)
    uint32_t latencySamples;  // Latency in samples
    uint32_t numInputs;       // Audio inputs
    uint32_t numOutputs;      // Audio outputs
    std::string manifestPath; // Path to JSON manifest
};

class ComponentRegistry {
public:
    static ComponentRegistry& getInstance();

    void registerComponent(const ComponentInfo& info);
    const ComponentInfo* findComponent(const std::string& id) const;
    std::vector<const ComponentInfo*> getComponentsByCategory(
        const std::string& category) const;
    std::vector<const ComponentInfo*> getAllComponents() const;

    bool loadFromJson(const std::string& jsonPath);

private:
    ComponentRegistry() = default;
    std::unordered_map<std::string, ComponentInfo> m_components;
};

} // namespace composition
} // namespace plugins
} // namespace audiolab

Implementación: ComponentRegistry.cpp con métodos

Tiempo: 1 hora


TAREA 1.2: ComponentFactory

Archivo: 08_01_00_component_library/ComponentFactory.hpp

#pragma once

#include "ComponentRegistry.hpp"
#include "../../08_00_plugin_infrastructure/08_00_00_contracts/IAudioEngine.hpp"
#include <memory>
#include <functional>

namespace audiolab {
namespace plugins {
namespace composition {

using ComponentCreator = std::function<std::unique_ptr<IAudioEngine>()>;

class ComponentFactory {
public:
    static ComponentFactory& getInstance();

    void registerCreator(const std::string& componentId, ComponentCreator creator);
    std::unique_ptr<IAudioEngine> createComponent(const std::string& id);
    bool supportsComponent(const std::string& id) const;

private:
    ComponentFactory() = default;
    std::unordered_map<std::string, ComponentCreator> m_creators;
};

// Helper macro for registration
#define REGISTER_COMPONENT(ID, CLASS) \
    namespace { \
        struct CLASS##_Registrar { \
            CLASS##_Registrar() { \
                ComponentFactory::getInstance().registerCreator(ID, \
                    []() { return std::make_unique<CLASS>(); }); \
            } \
        }; \
        static CLASS##_Registrar g_##CLASS##_registrar; \
    }

} // namespace composition
} // namespace plugins
} // namespace audiolab

Tiempo: 1 hora


TAREA 1.3: component_catalog.json

Archivo: 08_01_00_component_library/component_catalog.json

{
  "version": "1.0.0",
  "components": [
    {
      "id": "filter_biquad",
      "name": "Biquad Filter",
      "category": "filters",
      "cpuCost": 10,
      "latency": 0,
      "inputs": 1,
      "outputs": 1,
      "parameters": [
        {"id": "cutoff", "name": "Cutoff", "min": 20, "max": 20000, "default": 1000},
        {"id": "q", "name": "Q", "min": 0.1, "max": 10, "default": 0.707},
        {"id": "type", "name": "Type", "options": ["lowpass", "highpass", "bandpass"]}
      ]
    },
    {
      "id": "compressor_rms",
      "name": "RMS Compressor",
      "category": "dynamics",
      "cpuCost": 25,
      "latency": 0,
      "inputs": 1,
      "outputs": 1,
      "parameters": [
        {"id": "threshold", "name": "Threshold", "min": -60, "max": 0, "default": -20},
        {"id": "ratio", "name": "Ratio", "min": 1, "max": 20, "default": 4},
        {"id": "attack", "name": "Attack", "min": 0.1, "max": 100, "default": 10},
        {"id": "release", "name": "Release", "min": 10, "max": 1000, "default": 100}
      ]
    },
    {
      "id": "delay_simple",
      "name": "Simple Delay",
      "category": "time",
      "cpuCost": 15,
      "latency": 0,
      "inputs": 1,
      "outputs": 1,
      "parameters": [
        {"id": "time", "name": "Time", "min": 0, "max": 2000, "default": 500},
        {"id": "feedback", "name": "Feedback", "min": 0, "max": 100, "default": 30},
        {"id": "mix", "name": "Mix", "min": 0, "max": 100, "default": 50}
      ]
    }
  ]
}

Agregar 7-12 componentes más (reverb, EQ, saturation, gate, limiter, etc.)

Tiempo: 1 hora


TAREA 2.1: ManifestParser

Archivo: 08_01_01_visual_composer/ManifestParser.hpp

#pragma once

#include <nlohmann/json.hpp>
#include <string>
#include <vector>

namespace audiolab {
namespace plugins {
namespace composition {

struct PluginManifest {
    std::string name;
    std::string version;
    std::string description;

    struct Component {
        std::string id;
        std::string type;
        std::map<std::string, float> parameters;
    };

    struct Connection {
        std::string sourceNode;
        uint32_t sourcePort;
        std::string destNode;
        uint32_t destPort;
    };

    std::vector<Component> components;
    std::vector<Connection> connections;
};

class ManifestParser {
public:
    bool parse(const std::string& jsonPath);
    bool parseFromString(const std::string& jsonStr);

    const PluginManifest& getManifest() const { return m_manifest; }
    std::vector<std::string> getErrors() const { return m_errors; }
    bool hasErrors() const { return !m_errors.empty(); }

private:
    PluginManifest m_manifest;
    std::vector<std::string> m_errors;

    void parseComponents(const nlohmann::json& j);
    void parseConnections(const nlohmann::json& j);
};

} // namespace composition
} // namespace plugins
} // namespace audiolab

Implementación en .cpp

Tiempo: 1.5 horas


TAREA 2.2: NodeGraph

Archivo: 08_01_01_visual_composer/NodeGraph.hpp

#pragma once

#include "ManifestParser.hpp"
#include <set>

namespace audiolab {
namespace plugins {
namespace composition {

class NodeGraph {
public:
    void buildFromManifest(const PluginManifest& manifest);

    bool validate() const;
    bool hasCycles() const;
    std::vector<std::string> topologicalSort() const;

    std::vector<std::string> getConnectedNodes(const std::string& nodeId) const;
    bool isConnected(const std::string& from, const std::string& to) const;

private:
    struct Node {
        std::string id;
        std::string type;
        std::set<std::string> dependencies; // nodes this depends on
    };

    std::unordered_map<std::string, Node> m_nodes;

    bool dfsHasCycle(const std::string& nodeId,
                    std::set<std::string>& visited,
                    std::set<std::string>& recStack) const;
};

} // namespace composition
} // namespace plugins
} // namespace audiolab

Tiempo: 1.5 horas


TAREA 3.1: TemplateRegistry & Instantiator

Similar a ComponentRegistry pero para templates.

Tiempo: 1 hora


TAREA 3.2: Crear Templates L4/L5

Archivos: - templates/l4_simple/manifest.json - templates/l4_simple/plugin.hpp.template - templates/l4_simple/plugin.cpp.template - templates/l4_simple/CMakeLists.txt.template

Contenido de plugin.hpp.template:

#pragma once

#include "PluginL4Base.hpp"

namespace audiolab {
namespace plugins {

class {{plugin_name}} : public PluginL4Base {
public:
    {{plugin_name}}();

    // IPluginProcessor
    const char* getName() const override { return "{{plugin_name}}"; }
    const char* getVersion() const override { return "{{version}}"; }

    // IAudioProcessor
    void processBlock(core::AudioBuffer<float>& buffer) override;

private:
    {% for component in components %}
    std::unique_ptr<{{component.type}}> m_{{component.id}};
    {% endfor %}
};

} // namespace plugins
} // namespace audiolab

Repetir para cada template (4 templates totales)

Tiempo: 3 horas


TAREA 4.1-4.5: Validators

5 archivos de validación, cada uno con: - Header con clase Validator - Implementación con reglas específicas - Método validate() que retorna vector<ValidationMessage>

Estructura similar para todos:

class SyntaxValidator {
public:
    std::vector<ValidationMessage> validate(const PluginManifest& manifest);
private:
    void checkRequiredFields(const nlohmann::json& j);
    void checkTypes(const nlohmann::json& j);
};

Tiempo: 3 horas (30-40 min cada uno)


TAREA 5.1-5.4: Tests

4 archivos de test, estructura:

#include <catch2/catch_all.hpp>
#include "ComponentRegistry.hpp"

TEST_CASE("ComponentRegistry: Register and find component") {
    ComponentRegistry& registry = ComponentRegistry::getInstance();

    ComponentInfo info;
    info.id = "test_comp";
    info.name = "Test Component";
    info.category = "test";

    registry.registerComponent(info);

    const ComponentInfo* found = registry.findComponent("test_comp");
    REQUIRE(found != nullptr);
    REQUIRE(found->name == "Test Component");
}

TEST_CASE("ComponentRegistry: Load from JSON") {
    ComponentRegistry& registry = ComponentRegistry::getInstance();
    REQUIRE(registry.loadFromJson("component_catalog.json"));
    REQUIRE(registry.getAllComponents().size() > 0);
}

Tiempo: 2 horas


TAREA 5.5: Documentación

6 documentos a crear:

  1. 08_01_composition_tools/README.md - Overview completo
  2. docs/component_library_guide.md - Cómo usar biblioteca
  3. docs/manifest_format.md - Formato de manifiestos con ejemplos
  4. docs/template_guide.md - Cómo crear templates
  5. docs/validation_rules.md - Reglas de validación
  6. docs/workflow_example.md - Workflow completo end-to-end

Tiempo: 1.5 horas


🎯 Criterios de Aceptación Final

Funcionalidad

  • Component library registra y encuentra componentes
  • Manifest parser lee JSON correctamente
  • Node graph detecta ciclos
  • Code generator produce código válido
  • Templates se instancian correctamente
  • Validadores detectan errores

Tests

  • Cobertura > 80%
  • Todos los tests pasan
  • Ejemplos funcionan end-to-end

Documentación

  • README completo
  • 5 guías detalladas
  • 3-5 ejemplos completos

📦 Dependencias

Depende de: - ✅ 08_00 (Plugin Infrastructure) - Necesita interfaces base - ✅ nlohmann/json (vcpkg) - JSON parsing

Bloqueante para: - 08_06 (Development Paths) - 08_07 (Manifest Validation) - 08_10 (L4 Architecture) - Usa templates


💾 Commits Recomendados

# Fase 1
git commit -m "feat(08_01): add component library

- Implement ComponentRegistry and ComponentFactory
- Add component_catalog.json with 10+ components
- Add README and tests"

# Fase 2
git commit -m "feat(08_01): add manifest parser and compiler

- Implement ManifestParser with JSON schema
- Implement NodeGraph with cycle detection
- Implement CodeGenerator for C++ output"

# Fase 3
git commit -m "feat(08_01): add template system

- Implement TemplateRegistry and Instantiator
- Add 4 templates (l4_simple, l4_modulation, l5_suite, l5_channelstrip)"

# Fase 4
git commit -m "feat(08_01): add validation engine

- Implement 5 validators (syntax, semantic, dependency, performance)
- Add configurable validation rules"

# Fase 5
git commit -m "feat(08_01): add tests and documentation

- Add comprehensive tests (80%+ coverage)
- Add 6 documentation files
- Add 3-5 complete examples"

Estado: 📝 LISTO PARA IMPLEMENTACIÓN Última actualización: 2025-10-08 Estimación total: 17-22 horas (5 fases de 3-4.5h cada una)