Report render progress if stdout is a TTY

This commit is contained in:
josh committed 2026-11-06 09:47:45 -05:00
1 parent d8a37c6e9a
commit 040ca57cb3
2 files changed
+86 -1

No files matched your search

+84 -1
View File
@@ -1,8 +1,81 @@
#include <fart/Engine.h> #include <fart/Engine.h>
#include <fart/Parser.h> #include <fart/Parser.h>
#include <chrono>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h>
namespace
{
/**
* Reports render progress to stdout when stdout is a TTY.
*
* An update is written only when progress has increased by at least 1%,
* or when progress has increased at all and at least 1 second has elapsed
* since the last update.
*/
class ProgressReporter
{
public:
using clock = std::chrono::steady_clock;
explicit ProgressReporter(size_t total)
: total(total)
, enabled(total > 0u && isatty(STDOUT_FILENO))
{
if (enabled)
{
last_time = clock::now();
print(0u);
}
}
void update(size_t done)
{
if (!enabled || done <= last_done)
{
return;
}
/* (done - last_done) / total >= 1 / 100 */
bool percent_step = (done - last_done) * 100u >= total;
clock::time_point now = clock::now();
if (percent_step || (now - last_time) >= std::chrono::seconds(1))
{
last_time = now;
print(done);
}
}
void finish()
{
if (enabled)
{
if (last_done < total)
{
print(total);
}
fputc('\n', stdout);
fflush(stdout);
}
}
protected:
size_t total;
bool enabled;
size_t last_done = 0u;
clock::time_point last_time;
void print(size_t done)
{
last_done = done;
printf("\rRendering: %6.2f%%", (double)done * 100.0 / (double)total);
fflush(stdout);
}
};
}
Engine::Engine(const Options & options) Engine::Engine(const Options & options)
: options(options) : options(options)
@@ -67,13 +140,18 @@ int Engine::run(string_view input_file, opt<string_view> output_file)
options.apply_defaults(); options.apply_defaults();
Image image(*options.width, *options.height); Image image(*options.width, *options.height);
ProgressReporter progress(*options.width * *options.height);
size_t pixels_done = 0u;
for (size_t y = 0u; y < *options.height; y++) for (size_t y = 0u; y < *options.height; y++)
{ {
for (size_t x = 0u; x < *options.width; x++) for (size_t x = 0u; x < *options.width; x++)
{ {
image[x, y] = *options.background; image[x, y] = render_pixel(x, y);
pixels_done++;
progress.update(pixels_done);
} }
} }
progress.finish();
if (!image_writer->write(image)) if (!image_writer->write(image))
{ {
@@ -82,3 +160,8 @@ int Engine::run(string_view input_file, opt<string_view> output_file)
return 0; return 0;
} }
Color Engine::render_pixel(size_t x, size_t y)
{
return *this->options.background;
}
+2
View File
@@ -16,4 +16,6 @@ protected:
Options options; Options options;
std::unique_ptr<ImageWriter> image_writer; std::unique_ptr<ImageWriter> image_writer;
Scene * scene = nullptr; Scene * scene = nullptr;
Color render_pixel(size_t x, size_t y);
}; };