Skip to content

Commit

Permalink
python: make it possible to skip gl.Context.current() blowing up.
Browse files Browse the repository at this point in the history
This was originally added in d6fec89 as
a doc-generation-only hack, but other tools such as stub generation may
need similar special cases, so it's now a env var check in the binding
generation directly.

It's not a check in every invocation because that *feels* slow (although
pybind11 itself likely does a lot more nasty string comparisons, hashmap
lookups and linked link traversal than that), so if such an env var was
defined while importing the module, the current() is then forever
broken, until interpreter restart.
  • Loading branch information
mosra committed Jun 11, 2024
1 parent b0df197 commit 3218db2
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 23 deletions.
8 changes: 0 additions & 8 deletions doc/python/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,6 @@ class DoNotPrintValue: pass
magnum.TARGET_EGL = DoNotPrintValue()
magnum.TARGET_VK = DoNotPrintValue()

# Otherwise it blows during doc generation up because there's no content
# TODO is there a way to make Python not execute the property when inspecting
# it?!
# TODO also, it's a static property together with has_current, and as such it
# has no docstring -- fix
delattr(magnum.gl.Context, 'current')
setattr(magnum.gl.Context, 'current', DoNotPrintValue())

# TODO ugh... can this be expressed directly in pybind? and the docs parsed
# from it so i don't need to repeat them in docs/*.rst files?
for i in [magnum.text.AbstractFont,
Expand Down
36 changes: 21 additions & 15 deletions src/python/magnum/gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,21 +373,27 @@ void gl(py::module_& m) {
.def_property_readonly_static("has_current", [](const py::object&) {
return GL::Context::hasCurrent();
}, "Whether there is any current context")
.def_property_readonly_static("current", [](const py::object&) {
if(!GL::Context::hasCurrent()) {
PyErr_SetString(PyExc_RuntimeError, "no current context");
throw py::error_already_set{};
}

py::object owner = py::none{};
auto* glContextOwner = reinterpret_cast<std::pair<const void*, const std::type_info*>*>(py::get_shared_data("magnumGLContextOwner"));
if(glContextOwner && glContextOwner->first) {
CORRADE_INTERNAL_ASSERT(glContextOwner->second);
owner = Corrade::pyObjectFromInstance(glContextOwner->first, *glContextOwner->second);
}

return ContextHolder<GL::Context>{&GL::Context::current(), std::move(owner)};
}, "Current context")
.def_property_readonly_static("current",
std::getenv("MCSS_GENERATING_OUTPUT") ?
[](const py::object&) {
return ContextHolder<GL::Context>{nullptr};
} :
[](const py::object&) {
if(!GL::Context::hasCurrent()) {
PyErr_SetString(PyExc_RuntimeError, "no current context");
throw py::error_already_set{};
}

py::object owner = py::none{};
auto* glContextOwner = reinterpret_cast<std::pair<const void*, const std::type_info*>*>(py::get_shared_data("magnumGLContextOwner"));
if(glContextOwner && glContextOwner->first) {
CORRADE_INTERNAL_ASSERT(glContextOwner->second);
owner = Corrade::pyObjectFromInstance(glContextOwner->first, *glContextOwner->second);
}

return ContextHolder<GL::Context>{&GL::Context::current(), std::move(owner)};
}
, "Current context")
/** @todo context switching (needs additions to the "who owns
current context instance" variable -- a map?) */
.def_property_readonly("version", &GL::Context::version, "OpenGL version")
Expand Down

0 comments on commit 3218db2

Please sign in to comment.