-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Implement metaclass approach in geometry module to make mobjects compatible with cairo and opengl rendering #1272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This is smart and pythonic, I like it. The only issue I have is for autocompletion. I'm not sure that IDEs will like this. |
Customizing |
I've been playing around a bit more with this approach and got most of We could pursue a strategy like this:
The fact that some of the implementations are that different is also problematic: many improvements / features made to and for the community edition are not carried over to the OpenGL implementation. Simultaneously, the community edition has some extremely messy code (like the one for Before moving forwards, I'd like to hear opinions / feedback of the community @ManimCommunity/core -- if we commit to this metaclass approach, we'll have to pursue it together as well; I don't have the resources to implement this all on my own. |
I think I'm well-convinced that this is a good medium-term fix. One thing I'd add is that for any classes that can't be merged, the error messages for using the wrong renderer should be swift and clear. @behackl can you describe a little more what kind of support you would need? |
Definitely, I fully agree.
I'll push the latest version of my branch in a moment, the tests should look better then (at least a little). The most work then is going through the classes (for this PR I'd suggest we stick to If it is just a minor difference (like some keyword parameters renamed, or a |
for more information, see https://pre-commit.ci
Ah the docs build is failing because the MovingAngle scene in examples.rst is trying to use |
Though this brings up an issue with inheritance with this model. Will |
Indeed. I probably should have fixed
As far as I am concerned: yes. On this branch, However, this assumes that the implementation of the higher-level Mobjects is more or less independent of the lower-level ( |
I have updated the PR description and added a list of all classes (including their inheritance) in
I'll investigate If we can get it running, then I'd confident that this PR could also be merged soon. |
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
I like the idea and it would be great if we could get that to work -- however, I'm having troubles getting it running. It somehow seems that
Any ideas? |
It looks like |
Sure, it's basically 1:1 what you suggested above: class MetaVMobject(ABCMeta):
def __new__(cls, name, bases, namespace):
if len(bases) == 0:
if config.renderer == "opengl":
bases = (OpenGLVMobject,)
else:
bases = (VMobject,)
print(cls, name, bases)
return super().__new__(cls, name, bases, namespace) (Ah, even my debug print made it in the paste. 😄) |
Hm, looking at it, it seems as if the config is getting filled with its default values and then later being filled in correctly. That doesn't seem uh, intentional |
Aha, it works when I have a
It seems the config at the start of importing only takes options from files, not the command line |
…from CLI manually before importing
I have added manual parsing of I think this is ready for a new review round. :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Second pass, staying away from Angle
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty much just style suggestions, but I think even with the code as is, I'd be okay with it being merged
Co-authored-by: friedkeenan <friedkeenan@protonmail.com>
All of your suggestions looked good to me, I've applied them all. Thanks for reviewing this, I'm very happy we were able to move this forwards, and I really like the current implementation of the metaclass. (I've also checked the documentation: the current approach even renders classes for which the metaclass is set as inheriting from VMobject, which is great!) Assuming the tests and documentation build pass cleanly, I'll leave this open for a little while longer in case other devs want to take a look -- but otherwise I'll merge this tomorrow at the very latest to avoid merge conflicts. I do think that this is a substantial step towards transitioning to OpenGL. :-) |
Should the corresponding classes in |
I'd keep them around for now and if things work well with the metaclass approach remove them in 1-2 releases. |
Changelog / Overview
This PR is a proof of concept and introduces a metaclass
MetaVMobject
which allows compatible mobjects to use the same class for both OpenGL rendering and cairo rendering.Motivation
Extensive code duplication is dangerous for the hygiene of the code base. If it works in a broader setting as well, this approach offers at least a temporary solution while we are working on full support for OpenGL while maintaining support for cairo.
The solution is not ideal, as it introduces its own problems:
Polygon
inherits fromVMobject
(orOpenGLVMobject
),Polygon
inherits from eitherVMobject
orOpenGLVMobject
will have to be documented manually,Nevertheless, I think the advantages of a temporary solution following this idea (a maintainable code base for the time while we sort-of support two renderers at the same time; the fact that the implementation is relatively straightforward) outweigh these disadvantages.
Explanation for Changes
The metaclass overrides
__call__
, which means that, for example, custom code is run whenPolygon(*args, **kwargs)
is called. In particular, instead of simply creating an instance of thePolygon
class as currently implemented, this code first checks the value ofconfig.renderer
and constructs a new class inheriting from thePolygon
class ingeometry.py
, but also inheriting from eitherVMobject
(in case the renderer is cairo), orOpenGLVMobject
(in case the renderer is OpenGL). The resulting class is also calledPolygon
, and for users there shouldn't be any noticeable differences.In particular, this means that
Mobject
andOpenGLMobject
wouldn't have to be merged at all (which turned out to be rather delicate and introduced hard to trace down bugs), but we can simply inherit from the correct class dynamically instead.Testing Status
I just tested this locally: the snippet
(where the modified
Polygon
class is used directly), as well as the snippet(where a class inheriting from
Polygon
is used; no changes to the implementation ofRegularPolygon
had to be made) render sucessfully for me with--renderer=opengl
as well as--renderer=cairo
.Overall Progress in
geometry.py
(work in progress; for now this is a list of all classes in the current
geometry.py
)Checklist
Reviewer Checklist