Files
effector/src/core/effect.hpp
T
SiandClaude Opus 5 4739d39a51 Let effects declare whether they need source images
Whether an effect works from the loaded photographs is now part of the
declarative plug-in contract, next to params(): Effect::needsSources()
defaults to true, and blur — which only softens what it is handed — says
no and blurs an empty canvas when given nothing.

Only the first stage of a cascade ever sees the sources, so
chainNeedsSources() just asks the first stage. Both front-ends gate on
that instead of on "are there any images": the CLI only refuses an empty
batch when the chain wants one, and the interface renders a blur-led
chain with no images loaded, saying whichever thing is actually missing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 15:49:16 +02:00

44 lines
1.2 KiB
C++

#pragma once
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
#include "core/image.hpp"
#include "core/params.hpp"
#include "core/rng.hpp"
namespace effector {
class EffectError : public std::runtime_error {
public:
using std::runtime_error::runtime_error;
};
// Base class for every effect. Canvas size and the random source are common to
// all of them; params() covers only the effect-specific knobs.
class Effect {
public:
virtual ~Effect() = default;
virtual std::string name() const = 0;
virtual std::string title() const = 0;
virtual std::string description() const = 0;
virtual const std::vector<ParamSpec>& params() const = 0;
// Whether the effect builds its image out of the loaded source images.
// Effects that only transform what they are handed (blur) say no, and a
// chain that starts with one of them needs no sources at all.
virtual bool needsSources() const { return true; }
virtual Image render(const std::vector<Image>& sources, int width, int height, Rng& rng,
const ParamValues& values) const = 0;
ParamValues defaults() const;
};
using EffectPtr = std::shared_ptr<const Effect>;
} // namespace effector