Conversation
| frame = frame.f_back | ||
| return None | ||
| finally: | ||
| del frame |
|
|
||
|
|
||
| def get_module(file_name: Path) -> types.ModuleType: | ||
| def get_module(file_name: Path, *, source: bytes | None = None) -> types.ModuleType: |
16c9836 to
631c3a8
Compare
nikolajmunk
left a comment
There was a problem hiding this comment.
Some quick documentation suggestions. This overall reads very well and I'm excited about this experimental feature!
| Standalone reader | ||
| ----------------- | ||
|
|
||
| The repository also includes a reader that uses only Python's standard library: |
There was a problem hiding this comment.
I suspect the user doesn't need to know that the reader uses only stdlib. Maybe remove?
| * ``policy`` is ``no-raster-full``, identifying the evaluation mode used for | ||
| capture. ``complete`` is true for a completed capture. ``termination`` is | ||
| ``completed`` for ordinary completion, or ``scene-end-request`` when | ||
| ``construct()`` ends with a handled ``EndSceneEarlyException``. | ||
| * Each event represents one play or wait call. It includes an ID, play index | ||
| (``ordinal``), kind, requested duration (``nominal_duration``), observed | ||
| ``start`` and ``end`` times in seconds, and top-level animation types/run times. | ||
| * ``samples`` counts animation steps; ``hold_intervals`` counts the frame | ||
| intervals occupied by a frozen wait. In the Python example these are | ||
| ``(2, 0)`` and ``(0, 1)``. When a stop condition ends a wait early, ``end`` | ||
| records the time reached by that wait. | ||
| * ``declarations`` contains section, caption, and sound calls. Their ``at`` time | ||
| records when the call happened; placement can differ because of an offset. | ||
| Captions have resolved ``start`` and ``end`` times. Sounds have a ``start``; | ||
| ``duration`` is null to indicate an unknown duration. Relative sound paths | ||
| retain the requested string. Sound options must be JSON-serializable. | ||
| * Events and declarations share an ``order`` counter. A declaration's | ||
| ``event_id`` refers to a play being prepared or executed, or is null outside | ||
| one. ``event_boundary`` is the number of completed plays when it was declared. |
There was a problem hiding this comment.
I would turn this into a more formal list with descriptions of every key-value in the report, largely for the sake of future maintainability.
There was a problem hiding this comment.
While this is technically a correct example, I question the utility of including it in the example gallery when none of its visual output is actually relevant to the concept that the example is explaining.
I would either remove this entirely or find a way to turn it into a visual example. Maybe there's a way to fetch the timeline info of one scene and actually display it as a visual timeline in another scene?
| """Return the completed timeline requested during :meth:`evaluate`. | ||
|
|
||
| Read this property after ``evaluate(capture_timeline=True)`` returns | ||
| successfully. The returned snapshot is immutable. |
There was a problem hiding this comment.
| """Return the completed timeline requested during :meth:`evaluate`. | |
| Read this property after ``evaluate(capture_timeline=True)`` returns | |
| successfully. The returned snapshot is immutable. | |
| """The completed timeline produced by a successful execution of | |
| :meth:`evaluate` with argument ``capture_timeline=True``. This timeline | |
| is immutable. |
Perhaps something like this?
5e94c10 to
296331a
Compare
296331a to
6af115a
Compare
Overview: What does this pull request change?
Stacked on #5005. Last one for the file writer refactor cycle!
Adds execution timeline capture to scene evaluation, with an immutable Python report and JSON export:
The CLI can evaluate a selected scene and save its timeline directly:
manim --fps 4 --timeline-output timeline.json example_scenes/timeline_scene.py TimelineExampleThe format and Python API are experimental and may change without a deprecation period.
Motivation and Explanation: Why and how do your changes improve the library?
A scene's timing depends on Python control flow, updaters, stop conditions, and frame-rate sampling. Capturing observations from the existing evaluation loop gives external tools a structured account of the execution for inspection and visualization.
The report includes:
Capturing, saving, and reading
manager.timelinebecomes available after successful capture.to_dict()returns an independent dictionary,to_json()returns canonical JSON, andwrite()saves the captured report.Timeline.from_json()checks the schema name, version, completion flag, and content revision.Version 1 uses the schema name
manim.execution-timelineand a SHA-256 revision identifying the report's content.The CLI resolves the output path before scene code runs. It compiles captured primary-file bytes and checks that file again during loading, evaluation, and cleanup. After those steps succeed, it writes a temporary JSON file and replaces the destination. If evaluation fails before publication, an existing report remains available as its original result.
Source hashes and freshness checks cover the primary file. Python capture reads the scene class's source file from disk before evaluation; CLI capture compiles the bytes it records. The standalone reader compares the current primary file with its recorded hash and marks changes as stale.
Capture also validates event completion, declaration serialization, and finite, nondecreasing animation time. Errors leave the capture incomplete so callers can fix the cause and evaluate a fresh scene.
Links to added or changed documentation pages
docs/source/guides/timeline.rst.Manager/TimelineAPI documentation.example_scenes/timeline_scene.pyandexamples/timeline_reader.py. The reader uses Python's standard library to print events and optionally create an HTML view with source links and declarations.