Theme Catppuccin
Make yourself at homeCatppuccin

A softer light for long learning sessions.

Appearance

Loading your preference…

Dark palette

Choose a dark palette to try it.

Light uses Latte. Your choices stay in this browser.

Back to your source shelf

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.

49 lines gallery_main.cpp
#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