notcurses/include/ncpp/Visual.hh
Marek Habersack 64eeb95f1e [C++] Optionally enable throwing exceptions on errors
Nick prefers error handling based on exceptions in all cases, while I
prefer to save exception handling for truly exceptional situations -
function parameter validation and class constructor. However, there's no
need to not support both approaches, to be chosen at the discretion of
the developer.

NCPP follows RAII and all classes throw exceptions from their
constructors in case they cannot initialize properly. Likewise,
functions taking pointers that are required validate them and throw
exceptions whenever the requirement isn't met.

This commit goes one step further in that it enables optional validation
of notcurses function return values and throwing an
exception (`ncpp::call_error`) should the function signal an error. This
is disabled by default but it can be enabled by defining the
`NCPP_EXCEPTIONS_PLEASE` macro (preferably on the command line or
before *each* inclusion of any NCPP headers).

Out of necessity, this breaks the ABI (plus I found a handful of minor
issues in the code), but I think it's worth having this support in
place.
2020-04-15 12:10:14 -04:00

92 lines
2.2 KiB
C++

#ifndef __NCPP_VISUAL_HH
#define __NCPP_VISUAL_HH
#include <notcurses/notcurses.h>
#include "Root.hh"
#include "NCScale.hh"
namespace ncpp
{
class Plane;
class NCPP_API_EXPORT Visual : public Root
{
public:
explicit Visual (Plane *plane, const char *file, int *averr)
: Visual (reinterpret_cast<ncplane*>(plane), file, averr)
{}
explicit Visual (Plane const* plane, const char *file, int *averr)
: Visual (const_cast<Plane*>(plane), file, averr)
{}
explicit Visual (Plane &plane, const char *file, int *averr)
: Visual (reinterpret_cast<ncplane*>(&plane), file, averr)
{}
explicit Visual (Plane const& plane, const char *file, int *averr)
: Visual (const_cast<Plane&>(plane), file, averr)
{}
explicit Visual (ncplane *plane, const char *file, int *averr)
{
if (plane == nullptr)
throw invalid_argument ("'plane' must be a valid pointer");
visual = ncplane_visual_open (reinterpret_cast<ncplane*>(plane), file, averr);
if (visual == nullptr)
throw init_error ("notcurses failed to create a new visual");
}
explicit Visual (const char *file, int *averr, int y, int x, NCScale scale)
{
visual = ncvisual_open_plane (get_notcurses (), file, averr, y, x, static_cast<ncscale_e>(scale));
if (visual == nullptr)
throw init_error ("notcurses failed to create a new visual");
}
~Visual () noexcept
{
if (!is_notcurses_stopped ())
ncvisual_destroy (visual);
}
operator ncvisual* () const noexcept
{
return visual;
}
operator ncvisual const* () const noexcept
{
return visual;
}
AVFrame* decode (int *averr) const noexcept
{
return ncvisual_decode (visual, averr);
}
bool render (int begy, int begx, int leny, int lenx) const NOEXCEPT_MAYBE
{
return error_guard (ncvisual_render (visual, begy, begx, leny, lenx), -1);
}
int stream (int *averr, float timescale, streamcb streamer, void *curry = nullptr) const NOEXCEPT_MAYBE
{
return error_guard<int> (ncvisual_stream (get_notcurses (), visual, averr, timescale, streamer, curry), -1);
}
char* subtitle () const noexcept
{
return ncvisual_subtitle (visual);
}
Plane* get_plane () const noexcept;
private:
ncvisual *visual = nullptr;
};
}
#endif