simvx.editor.convert_to_class¶
Turn a node in the editor into a class of its own, and bind the scene to it.
A scene is Python, and a node’s behaviour is its class, so giving a node behaviour means giving it a class the scene file names. That is what this does, end to end: write the class file, point the scene’s own source at it, save, and reload so the node in front of the user IS an instance of the new class – with whatever the template declared already built, the way it will be every time the game runs.
Two shapes, according to which node was picked:
A child. The class is written, the live node’s class is rebound, and the save carries the swap into the construction the file already has (:mod:
~simvx.editor.scene_diffrepoints it where it stands rather than deleting and re-emitting it, so the author’s arguments, comments and any attribute the statement binds all survive). The import goes in beside it.The scene root. There is no construction to repoint – the root is the class the file defines – so that class is rebased instead:
class Arena(Node3D)becomesclass Arena(ArenaLogic)where the new class extends the base the file already had. What the file gives the root goes on reaching the old base, because the new class stands between them and the templates written here declare no__init__of their own. The rebase itself moves one name and nothing else; the save that carries it is an ordinary save of that scene, so a value the file already sets can end up set twice – once where the author set it, and again as a kwarg the save writes.
Anything the file cannot express is refused, and the refusal says what stopped
it (:class:ConversionRefused). Most of them are answered before a byte is
written: the file says something about its root class that this cannot rewrite
without guessing – two bases, a base that is not a plain name, a base the
running scene does not agree with – or the scene has never been saved, so there
is no source to bind to, or the node is deeper in the tree than a save writes,
which is the root and its own children, or the class file would be imported
under a name that already means something else in Python. The two that can only
be answered by trying – a class file that will not import, and a save that
cannot point the scene at the class – put the class file back as it was found
before they raise, along with the live node’s class and the path entry the
import needed, so a refusal always leaves the process as the user left it.
Module Contents¶
Classes¶
What one conversion did, once the scene has been saved and reloaded. |
Functions¶
The project’s |
|
Where a class of this name would go, following the project’s own layout. |
|
The template names worth offering for |
|
Give |
Data¶
API¶
- simvx.editor.convert_to_class.log¶
‘getLogger(…)’
- simvx.editor.convert_to_class.__all__¶
[‘Conversion’, ‘ConversionRefused’, ‘EMPTY_TEMPLATE’, ‘class_files_dir’, ‘convert_node_to_class’, ‘d…
- simvx.editor.convert_to_class.EMPTY_TEMPLATE¶
‘Empty’
- exception simvx.editor.convert_to_class.ConversionRefused(message: str)[source]¶
Bases:
ExceptionThe conversion did not happen, and this says what stopped it.
Nothing of it is on disk when this is raised: the questions the file’s own text can answer are asked before anything is written, and the two that can only be answered by trying – a class file that will not import, a save that cannot point the scene at the class – put that file back as they found it, the scene never having been written at all. :attr:
entryis the same- Class:
~simvx.editor.scene_diff.ReportEntrya save would have used to say so, categorised :data:~simvx.editor.scene_diff.DESTRUCTIVE, because the only way past it is for the user to change something themselves.
Initialization
Initialize self. See help(type(self)) for accurate signature.
- class __cause__¶
- class __context__¶
- __delattr__()¶
- __dir__()¶
- __eq__()¶
- __format__()¶
- __ge__()¶
- __getattribute__()¶
- __getstate__()¶
- __gt__()¶
- __hash__()¶
- __le__()¶
- __lt__()¶
- __ne__()¶
- __new__()¶
- __reduce__()¶
- __reduce_ex__()¶
- __repr__()¶
- __setattr__()¶
- __setstate__()¶
- __sizeof__()¶
- __str__()¶
- __subclasshook__()¶
- class __suppress_context__¶
- class __traceback__¶
- add_note()¶
- class args¶
- with_traceback()¶
- class simvx.editor.convert_to_class.Conversion[source]¶
What one conversion did, once the scene has been saved and reloaded.
- class_name: str¶
None
- source_path: pathlib.Path¶
None
- module_path: str | None¶
None
- node: simvx.core.Node | None¶
None
- rebased: bool¶
None
- report: tuple[simvx.editor.scene_diff.ReportEntry, ...]¶
()
- simvx.editor.convert_to_class.class_files_dir(state: simvx.editor.state.State) str[source]¶
The project’s
[editor] class_files_dir, orsrcwhen it has none.
- simvx.editor.convert_to_class.default_class_file(state: simvx.editor.state.State, class_name: str) pathlib.Path | None[source]¶
Where a class of this name would go, following the project’s own layout.
<project>/<class_files_dir>/<snake_case>.py, which is where the rest of the editor puts user classes and where its class index looks for them.Nonefor a session with no project open, which is a session with nowhere to put one.
- simvx.editor.convert_to_class.templates_for(node: simvx.core.Node) list[str][source]¶
The template names worth offering for
node, most specific first.A template is written against a base class, and only one whose base the node already descends from produces code that runs: the 2D character template reads
is_on_floorand moves aVec2, which aNode3Dhas no answer for. :data:EMPTY_TEMPLATEleads the list, so the default stays a class with nothing in it.
- simvx.editor.convert_to_class.convert_node_to_class(state: simvx.editor.state.State, node: simvx.core.Node, class_name: str, *, destination: pathlib.Path | None = None, template: str | None = None) simvx.editor.convert_to_class.Conversion[source]¶
Give
nodea class of its own and bind the scene’s source to it.destinationis the file the class is written to, defaulting to- Func:
default_class_file. A destination that already exists gains the class at module scope with its imports merged, which is how a class lands inside the scene file itself; anything else is written as a new module.
templatenames an entry of :data:~simvx.editor.templates.TEMPLATESwhose body the class is written with, rendered against the node’s own class rather than the template’s declared base, so aCharacterBody3Dconverted with the plain 3D template still extendsCharacterBody3D. The default (:data:EMPTY_TEMPLATE) writes a class with nothing in it.The scene is saved through the plan/commit path and then reloaded, so what comes back is what the file says – a node built by running the new class’s
__init__, declared children and all. The reload is also why this returns a node rather than mutating the one it was given: the tree in front of the user afterwards is a different one.That the binding reached the file is checked rather than assumed, and twice: the save is read before it is committed (:func:
_would_build_it) and refused, with the class file put back as it was found, when the scene would go on constructing the node as it always did; and the node the reload produced is compared against the class that was written (:func:_is_bound_to), which is the end-to-end answer. A conversion that did not bind never returns quietly.Raises :class:
ConversionRefusedfor anything the file could not express, with the message naming what stopped it and the project as the user left it: everything written between the class file and the scene’s own save is put back by whatever refuses, and the scene is not written until every question has been answered.