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>
This commit is contained in:
+29
-7
@@ -194,13 +194,12 @@ int main() {
|
||||
const auto pinnedAgain = renderBlur(sources, 300, 200, 6, {{"first_source", true}});
|
||||
check(sameBytes(pinned, pinnedAgain), "first_source is reproducible");
|
||||
|
||||
bool threw = false;
|
||||
try {
|
||||
renderBlur({}, 100, 100, 1, {});
|
||||
} catch (const EffectError&) {
|
||||
threw = true;
|
||||
}
|
||||
check(threw, "no sources throws");
|
||||
// Blur declares that it needs no sources, so with none it softens the
|
||||
// empty canvas it starts from instead of refusing to run.
|
||||
const auto blank = renderBlur({}, 100, 100, 1, {});
|
||||
bool allBlack = blank.width() == 100 && blank.height() == 100;
|
||||
for (std::size_t i = 0; i < blank.byteSize(); ++i) allBlack = allBlack && blank.data()[i] == 0;
|
||||
check(allBlack, "without sources blur renders an empty canvas");
|
||||
}
|
||||
|
||||
std::cout << "chain\n";
|
||||
@@ -241,6 +240,29 @@ int main() {
|
||||
threw = true;
|
||||
}
|
||||
check(threw, "an empty chain throws");
|
||||
|
||||
// Sources are an effect's own business: scanlines cuts strips out of
|
||||
// them, blur only softens what it is handed and runs without any.
|
||||
check(effectByName("scanlines")->needsSources(), "scanlines needs source images");
|
||||
check(!effectByName("blur")->needsSources(), "blur needs no source images");
|
||||
check(chainNeedsSources({scanlines, blur}), "a chain led by scanlines needs sources");
|
||||
check(!chainNeedsSources({blur, scanlines}),
|
||||
"a chain led by blur needs none, later stages see the stage before them");
|
||||
check(!chainNeedsSources({}), "an empty chain needs no sources");
|
||||
|
||||
Rng bare(5);
|
||||
const auto sourceless = renderChain({blur}, {}, 200, 150, bare);
|
||||
check(sourceless.width() == 200 && sourceless.height() == 150,
|
||||
"blur renders a canvas without sources");
|
||||
|
||||
bool scanlinesThrew = false;
|
||||
try {
|
||||
Rng rng(1);
|
||||
renderChain({scanlines}, {}, 100, 100, rng);
|
||||
} catch (const EffectError&) {
|
||||
scanlinesThrew = true;
|
||||
}
|
||||
check(scanlinesThrew, "scanlines still refuses to run without sources");
|
||||
}
|
||||
|
||||
std::cout << "project\n";
|
||||
|
||||
Reference in New Issue
Block a user