Inside the companion
Renderer Engineering
Explore bounded image work, allocator lifetimes, cancellation, and Asio coroutines.
Project files 15
Keep the newest complete image
Drive the image pipeline, publish a result, and save its pixels.
#include "prism_engineering/asset_pipeline.hpp"
#include <fstream>
#include <iostream>
#include <locale>
#include <stdexcept>
using namespace prism_engineering;
int main(int argc, char** argv) {
try {
if (argc > 2) throw std::runtime_error{"usage: prism-gallery [image.ppm]"};
auto created = AssetPipeline::create();
if (!created) throw std::runtime_error{"could not create bounded workers"};
auto pipeline = std::move(*created);
Gallery gallery;
auto gate = std::make_shared<WorkGate>();
if (!gallery.request(*pipeline,{1,32,32,40,gate}) || !gate->wait_for_arrivals(1))
throw std::runtime_error{"could not begin A"};
if (pipeline->try_take()) throw std::runtime_error{"closed gate unexpectedly completed"};
std::cout << "A is still preparing; the application thread can handle another request.\n";
if (!gallery.request(*pipeline,{2,32,32,180,{},false})) throw std::runtime_error{"could not begin B"};
// Blocking terminal driver. A real UI calls try_take on each ordinary tick.
auto b = pipeline->wait_take();
if (!b || !gallery.apply(std::move(*b))) throw std::runtime_error{"B did not publish"};
gate->open();
auto a = pipeline->wait_take();
if (!a || gallery.apply(std::move(*a))) throw std::runtime_error{"stale A replaced B"};
if (!gallery.request(*pipeline,{3,32,32,0,{},true})) throw std::runtime_error{"failure request rejected"};
auto failed = pipeline->wait_take();
if (!failed || gallery.apply(std::move(*failed)) || gallery.latest_status()!=Status::failed)
throw std::runtime_error{"failure publication contract"};
pipeline->shutdown();
if (pipeline->runtime_failed()) throw std::runtime_error{"unexpected worker runtime failure"};
std::cout << "Published generation 2; stale generation 1 and failed generation 3 preserved it.\n";
if (argc == 2) {
std::ofstream output{argv[1],std::ios::binary};
output.imbue(std::locale::classic());
const auto& image=gallery.image();
output << "P6\n" << image.width << ' ' << image.height << "\n255\n";
for (const auto pixel : image.pixels) {
const char bytes[]{static_cast<char>(pixel.r),static_cast<char>(pixel.g),static_cast<char>(pixel.b)};
output.write(bytes,3);
}
output.flush();
output.close();
if (!output) throw std::runtime_error{"image write failed"};
}
return 0;
} catch(const std::exception& error) { std::cerr << error.what() << '\n'; return 1; }
}
This is the file included with the course. Copy and download give you its complete source.
Taking your work offline? Download all course companions
