a render argument namespace class (subclass of ArgsNamespace)
associated [3] with the render class, or
None, if the render class has no render arguments.
If this is a class, an instance of it (or a subclass thereof) is contained within
any RenderArgs instance associated [1] with the render class or
any of its subclasses. Also, an instance of this class (or a subclass of it) is
returned by render_args[render_cls]; where render_args is
an instance of RenderArgs as previously
described and render_cls is the render class with which this namespace class
is associated [3].
A set of render arguments (an instance of this class) is basically a container of
render argument namespaces (instances of
ArgsNamespace); one for
each render class, which has render arguments, in the Method Resolution
Order of its associated [1] render class.
The namespace for each render class is derived from the following sources, in
[descending] order of precedence:
namespaces
init_render_args
default render argument namespaces
Note
Instances are immutable but updated copies can be created via update().
The return type hint is Any only for compatibility
with static type checking, as this aspect of the interface seems too
dynamic to be correctly expressed with the exisiting type system.
Regardless, the return value is guaranteed to always be an instance
of a render argument namespace class associated with render_cls.
For instance, the following would always be valid for
Renderable:
The number and order of namespaces is guaranteed to be the same across all
instances associated [1] with the same render class but
beyond this, should not be relied upon as the details (such as the
specific number or order) may change without notice.
The order is an implementation detail of the Renderable API and the number
should be considered alike with respect to the associated render class.
A set of render arguments associated [1] with render_cls and
initialized with all constituent namespaces (of this set of render
arguments, self) that are compatible [4] with render_cls.
The number and order of fields are guaranteed to be the same for a
namespace class that defines fields, its subclasses, and all their
instances; but beyond this, should not be relied upon as the details
(such as the specific number or order) may change without notice.
The order is an implementation detail of the Render Arguments/Data API
and the number should be considered an implementation detail of the
specific namespace subclass.
The number and order of fields are guaranteed to be the same for a
namespace class that defines fields, its subclasses, and all their
instances; but beyond this, should not be relied upon as the details
(such as the specific number or order) may change without notice.
The order is an implementation detail of the Render Arguments/Data API
and the number should be considered an implementation detail of the
specific namespace subclass.
A set of render arguments associated with render_cls (or the
associated [3] render class of the namespace, if None) and
initialized with the namespace.
The number of the rendered frame (a non-negative integer), if the frame was
rendered by a renderable with definite frame count. Otherwise, the value range
and meaning of this field is unspecified.
The duration of the rendered frame (a non-negative integer), if the frame was
rendered by an animated renderable. Otherwise, the value range and meaning
of this field is unspecified.
Hint
For animated renderables, a zero value indicates that the next frame should
be displayed immediately after (without any delay), except stated otherwise.
The following interfaces are provided and required only to extend the Renderable API
i.e to create custom renderables or extend any of those provided by this library.
Everything required for normal usage should typically be exposed in the public API.
For performance reasons, all implementations of these interfaces within this library
perform no form of argument validation, except stated otherwise. The same should apply
to any extension or override of these interfaces. All arguments are and should be
expected to be valid. Hence, arguments should be validated beforehand if necessary.
In the same vein, return values of any of these interfaces will not be validated by
the callers before use.
If this is a class, an instance of it (or a subclass thereof) is contained within
any RenderData instance associated [5] with the render class or
any of its subclasses. Also, an instance of this class (or a subclass of it) is
returned by render_data[render_cls]; where render_data is
an instance of RenderData as previously
described and render_cls is the render class with which this namespace class
is associated [6].
Example
>>> classFoo(Renderable):... pass...... class_Data_(DataNamespace,render_cls=Foo):... foo:str|None...>>> Foo._Data_isFooDataTrue>>>>>> foo_data=Foo._Data_()>>> foo_data<FooData: foo=<uninitialized>>>>> foo_data.fooTraceback (most recent call last):...UninitializedDataFieldError: The render data field 'foo' of 'Foo' has not been initialized>>>>>> foo_data.foo="FOO">>> foo_data<FooData: foo='FOO'>>>> foo_data.foo'FOO'>>>>>> render_data=RenderData(Foo)>>> render_data[Foo]<FooData: foo=<uninitialized>>>>>>>> render_data[Foo].foo="bar">>> render_data[Foo]<FooData: foo='bar'>
On the other hand, if this is None, it implies the render class has no
render data.
Example
>>> classBar(Renderable):... pass...>>> Bar._Data_isNoneTrue>>>>>> render_data=RenderData(Bar)>>> render_data[Bar]Traceback (most recent call last):...NoDataNamespaceError: 'Bar' has no render data
This specifies class attributes defined by the class (not a parent) on itself
but not its subclasses which should be exported to definitions of the class
in subprocesses.
These attributes are typically assigned using __class__.* within methods.
Note
Defining this is optional.
The attributes are exported for a class if and only if they are defined
on that class when starting a subprocess.
This specifies class attributes defined by the class (not a parent) on itself
and its subclasses (i.e descendant attributes) which should be exported
to definitions of the class and its subclasses in subprocesses.
These attributes are typically assigned using cls.* within class methods.
This extends the exported descendant attributes of parent classes i.e all
exported descendant attributes of a class are also exported for its subclasses.
Note
Defining this is optional.
The attributes are exported for a class if and only if they are defined
on that class when starting a subprocess.
Column/horizontal position of the cursor at the point of calling
this method.
Note
The position is 1-based i.e the leftmost column on the
screen is at position 1 (one).
output (TextIO) – The text I/O stream to which frames of the animation are being
written.
Called by the base implementation of _animate_() just before drawing
the next frame of an animation.
Upon calling this method, the cursor should be positioned at the top-left-most
cell of the region occupied by the frame render output on the terminal screen.
Upon return, ensure the cursor is at the same position it was at the point of
calling this method (at least logically, since output shouldn’t be flushed
yet).
The base implementation does nothing.
Note
This is required only if drawing the next frame doesn’t inherently
overwrite the previous frame.
This is only meant (and should only be used) as a last resort since
clearing the previous frame before drawing the next may result in
visible flicker.
Ensure whatever this method does doesn’t result in the screen being
scrolled.
Tip
To reduce flicker, it’s advisable to not flush output. It will be
flushed after writing the next frame.
The frame count of the renderable. See frame_count.
Note
Returning POSTPONED or
1 (one) is invalid and may result in unexpected/undefined behaviour
across various interfaces defined by this library (and those derived
from them), since re-postponing evaluation is unsupported and the
renderable would have been taken to be animated.
Generates data required for rendering that’s based on internal or
external state.
Parameters:
iteration (bool) – Whether the render operation requiring the data involves a
sequence of renders (most likely of different frames), or it’s
a one-off render.
The render data should include copies of any variable/mutable
internal/external state required for rendering and other data generated from
constant state but which should persist throughout a render operation
(which may involve consecutive/repeated renders of one or more frames).
May also be used to “allocate” and initialize storage for mutable/variable
data specific to a render operation.
Typically, an overriding method should
call the overridden method,
update the namespace for its defining class (i.e
render_data[__class__]) within the
RenderData instance returned by the
overridden method,
The RenderData instance returned must be
associated [5] with the type of the renderable on which this method
is called i.e type(self). This is always the case for the base
implementation of this method.
Note
This method being called doesn’t mean the data generated will be used
immediately.
renderer (Callable[[RenderData, RenderArgs], T]) – Performs a render operation or extracts render data and arguments
for a render operation to be performed later on.
After preparing render data and processing arguments, renderer is called with
the following positional arguments:
Render data associated with the renderable’s class
Render arguments associated with the renderable’s class and initialized
with render_args
Any exception raised by renderer is propagated.
Important
Beyond this method (i.e any context from renderer onwards), use of any
variable state (internal or external) should be avoided if possible.
Any variable state (internal or external) required for rendering should
be provided via _get_render_data_().
If at all any variable state has to be used and is not
reasonable/practicable to be provided via _get_render_data_(),
it should be read only once during a single render and passed to any
nested/subsequent calls that require the value of that state during the
same render.
This is to prevent inconsistency in data used for the same render which may
result in unexpected output.
contain as many lines as render_size.height i.e exactly
render_size.height-1 occurrences of \n (the newline
sequence).
occupy exactly render_size.height lines and render_size.width
columns on each line when drawn onto a terminal screen, at least
when the render size it not greater than the terminal size on
either axis.
Tip
If for any reason, the output behaves differently when the render
height is greater than the terminal height, the behaviour, along
with any possible alternatives or workarounds, should be duely noted.
This doesn’t apply to the width.
Fields are defined as annotated class attributes. All annotated attributes of a
subclass are taken to be fields. Every such attribute must be assigned a value which
is taken to be the default value of the field.
The attribute annotations are only used to identify the fields, they’re never
evaluated or used otherwise by any part of the Renderable API.
The field names will be unbound from their assigned values (the default field
values) during the creation of the class.
Note
A subclass that inherits fields must not define fields.
To associate a namespace class with a render class, the render class should be
specified via the render_cls keyword argument in the class definition header.
A subclass that has fields must be associated [3] with a render class.
A subclass that has NO fields cannot be associated with a render class.
A subclass that inherits fields cannot be
reassociated with another render class.
Attention
Due to the design of the Renderable API, if a render class is intended to have
a namespace class asssociated, the namespace class should be associated with it
before it is subclassed or any RenderArgs
instance associated with it is created.
Fields are inherited from any associated [3] render argument namespace class
(i.e anyone that has fields) by subclassing it. The new subclass inherits both
the fields and associated render class of its parent.
The constructor of any subclass that has fields must not have required
parameters.
Tip
A subclass may neither define nor inherit fields. Such can be used as a base
class for other namespace classes.
Important
Due to the design and implementation of the API, field values (including defaults)
should:
(and are expected to) be immutable.
Otherwise, such may yield unexpected behaviour during render operations or
unexpected render outputs, if an object used as a field value is modified,
as:
a namespace containing a mutable field value (or a set of render arguments
containing such a namespace) may be in use in an asynchronous render
operation,
different sets of render arguments may contain the same namespace, and
different namespaces may contain the same object as field values.
be hashable.
Otherwise, the namespace and any containing set of render arguments will also
not be hashable.
An instance of this class is basically a container of render data namespaces
(instances of DataNamespace); one for each
render class, which has render data, in the Method Resolution Order
of its associated [5] render class.
Note
Instances are immutable but the constituent namespaces are mutable.
Instances and their contents shouldn’t be copied by any means because
finalizing an instance may invalidate all other copies.
Instances should always be explicitly finalized as soon as they’re no longer
needed.
The return type hint is Any only for compatibility
with static type checking, as this aspect of the interface seems too
dynamic to be correctly expressed with the exisiting type system.
Regardless, the return value is guaranteed to always be an instance
of a render data namespace class associated with render_cls.
For instance, the following would always be valid for
Renderable:
The number and order of namespaces is guaranteed to be the same across all
instances associated [5] with the same render class but
beyond this, should not be relied upon as the details (such as the
specific number or order) may change without notice.
The order is an implementation detail of the Renderable API and the number
should be considered alike with respect to the associated render class.
Subclassing, defining (and inheriting) fields and associating with a render
class are just as they are for ArgsNamespace, except that values
assigned to class attributes are neither required nor used.
Every field of a namespace is uninitialized immediately after instantiation.
The fields are expected to be initialized within the
_get_render_data_() method of the
render class with which the namespace is associated [6] or at some other
point during a render operation, if necessary.
Note
Fields are exposed as instance attributes.
Instances are mutable and fields can be updated in-place, either
individually by assignment to an attribute reference or in batch via
update().
An instance shouldn’t be copied by any means because finalizing its
containing RenderData instance may invalidate all copies of
the namespace.
The number and order of fields are guaranteed to be the same for a
namespace class that defines fields, its subclasses, and all their
instances; but beyond this, should not be relied upon as the details
(such as the specific number or order) may change without notice.
The order is an implementation detail of the Render Arguments/Data API
and the number should be considered an implementation detail of the
specific namespace subclass.
The number and order of fields are guaranteed to be the same for a
namespace class that defines fields, its subclasses, and all their
instances; but beyond this, should not be relied upon as the details
(such as the specific number or order) may change without notice.
The order is an implementation detail of the Render Arguments/Data API
and the number should be considered an implementation detail of the
specific namespace subclass.
If iteration is False, the value is always zero and
anything (such as a placeholder frame) may be rendered, as renderables with
INDEFINITE frame count are
typically meant for iteration/animation.
zero, denoting that the stream should be seeked to its end
and then the last frame should be rendered.
negative, denoting that the stream should be seeked to the
(-frame_offset)th frame before the last and then the new
next frame should be rendered.
If the end of the stream cannot be determined (yet), such as with a live
source, the furthest available frame in the forward direction should
be taken to be the end.
Note
If any seek operation is not supported by the underlying source, it
should be ignored and the next frame on the stream should be rendered.
If forward seek is supported but the offset is out of the range of
available frames, the stream should be seeked to the furthest available
frame in the forward direction if its end cannot be determined (yet),
such as with a live source.
Otherwise i.e if the offset is determined to be beyond the end of the
stream, StopIteration should be raised
(see _render_()).
If backward seek is supported but the offset is out of the range of
available frames, the stream should be seeked to its beginning or the
furthest available frame in the backward direction.
Tip
A render class that implements
INDEFINITE frame count should
specify which seek operations it supports and any necessary details.
True if the render is part of a render operation involving a sequence of
renders (most likely of different frames). Otherwise i.e if it’s a one-off
render, False.