gdnative_python/pythonscript/_pandemonium.pyx
2023-06-02 11:42:53 +02:00

75 lines
3.1 KiB
Cython

# `_pandemonium` module contains all the callbacks needed by Pandemonium's Pluginscript
# system to expose Python as a language to Pandemonium (see pythonscript.c for
# more on this).
# Hence there is no point of importing this module from Python given it
# only expose C functions.
# Beside this module depend on the `pandemonium.hazmat` module so it would be a bad
# idea to make the `pandemonium` module depend on it...
include "_pandemonium_editor.pxi"
include "_pandemonium_profiling.pxi"
include "_pandemonium_script.pxi"
include "_pandemonium_instance.pxi"
include "_pandemonium_io.pxi"
from pandemonium._hazmat.gdnative_api_struct cimport (
pandemonium_gdnative_init_options,
pandemonium_pluginscript_language_data,
)
from pandemonium._hazmat.internal cimport set_pythonscript_verbose, get_pythonscript_verbose
from pandemonium.builtins cimport GDString
import sys
# OS and ProjectSettings are singletons exposed as global python objects,
# hence there are not available from a cimport
from pandemonium.bindings import OS, ProjectSettings
from pandemonium._version import __version__ as pythonscript_version
def _setup_config_entry(name, default_value):
gdname = GDString(name)
if not ProjectSettings.has_setting(gdname):
ProjectSettings.set_setting(gdname, default_value)
ProjectSettings.set_initial_value(gdname, default_value)
# TODO: `set_builtin_order` is not exposed by gdnative... but is it useful ?
return ProjectSettings.get_setting(gdname)
cdef api pandemonium_pluginscript_language_data *pythonscript_init() with gil:
# Pass argv arguments
sys.argv = ["pandemonium"] + [str(x) for x in OS.get_cmdline_args()]
# Update PYTHONPATH according to configuration
pythonpath = str(_setup_config_entry("python_script/path", "res://;res://lib"))
for p in pythonpath.split(";"):
p = ProjectSettings.globalize_path(GDString(p))
sys.path.insert(0, str(p))
# Redirect stdout/stderr to have it in the Pandemonium editor console
if _setup_config_entry("python_script/io_streams_capture", True):
# Note we don't have to remove the stream capture in `pythonscript_finish` given
# Pandemonium print API is available until after the Python interpreter is teardown
install_io_streams_capture()
# Enable verbose output from pythonscript framework
if _setup_config_entry("python_script/verbose", False):
set_pythonscript_verbose(True)
# Finally proudly print banner ;-)
if _setup_config_entry("python_script/print_startup_info", True):
cooked_sys_version = '.'.join(map(str, sys.version_info))
print(f"Pythonscript {pythonscript_version} (CPython {cooked_sys_version})")
if get_pythonscript_verbose():
print(f"PYTHONPATH: {sys.path}")
return NULL
cdef api void pythonscript_finish(pandemonium_pluginscript_language_data *data) with gil:
# /!\ When this function is called, the Python interpreter is fully operational
# and might be running user-created threads doing concurrent stuff.
# That will continue until `pandemonium_gdnative_terminate` is called (which is
# responsible for the actual teardown of the interpreter).
pass