Exposed ba module/class initing in c++ layer

This commit is contained in:
Eric Froemling 2020-11-11 15:59:46 -08:00
parent 3baa2d754f
commit 22bcd4a3d7
22 changed files with 1627 additions and 1470 deletions

View File

@ -3932,24 +3932,24 @@
"assets/build/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/b5/85/f8b6d0558ddb87267f34254b1450", "assets/build/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/b5/85/f8b6d0558ddb87267f34254b1450",
"assets/build/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/1c/e1/4a1a2eddda2f4aebd5f8b64ab08e", "assets/build/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/1c/e1/4a1a2eddda2f4aebd5f8b64ab08e",
"assets/build/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/50/8d/bc2600ac9491f1b14d659709451f", "assets/build/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/50/8d/bc2600ac9491f1b14d659709451f",
"build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c6/d0/ab980354aba10010949d93b7178e", "build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d2/35/5ff7dd7a25041c0784ba74b40137",
"build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/b6/55/ad5d921172aaa3b807c7167bb371", "build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/58/f5/97d56302b2320c328a1702b29b30",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/56/0a/38d93ee45f60277af7b54e694a51", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/bd/95/c2eee0447fd64a41a1f36e31e257",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b2/84/cff1af6f66bd5b7f4c4cb2f73c0c", "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/26/d1/3c2b8fde63213bfdfcb975d7bbaa",
"build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/be/a7/e3818a4394f9685ef9aa04a54168", "build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d7/94/c49ff5a94f47d2886c8db004c2ec",
"build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/5f/0a/368e75335223b843d33056c769c5", "build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/5f/c5/d328666183caf3acb4a315b175c3",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2f/9e/abbc94bc5a5e4dc096612f8d1d7a", "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b9/87/ac5d264cafb87348ad2e791a3393",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/83/a9/1527e7588933a87ea737b97248d2", "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d4/e3/0f65cb6c998aad83ac0f26075951",
"build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/56/d3/9c41032882c82d9c815307bc8b66", "build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/e7/bc/261d8d63a33d6a0e17fb20477ffd",
"build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/f9/f1/23276003203790454bf4270df8d8", "build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/44/23/5dd042e6845fef6e3690bd4d5734",
"build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/ba/97/15b5594cc82961beb5e17cbd5fc2", "build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/ea/c6/cdc48f95725a16297b222de3c69e",
"build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/80/49/4ee9af2a72b1becf04dcf1b9dd4d", "build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/64/c8/5ccec4eba9397107f075cf2ab401",
"build/prefab/lib/linux_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/64/4c/12a9c3e845cf29efd6a2740a9f67", "build/prefab/lib/linux_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4f/4c/8590730e5d1cdae456c1b734a2a1",
"build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2d/f9/12757cb5cb19288d2948f196d48f", "build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/44/e5/d1c3162e114e51a5b5b826c2ec7c",
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ce/b3/389a58e74c47318de2bc26269cbb", "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ee/21/8fab3da6b974cf323024d076b609",
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/91/e3/2a6988e1e5fc37365bb8bd4fb67b", "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/20/5d/881676243c5f44bdca677497b4d4",
"build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ac/1e/feb3b200f5e979e69ff98e32f797", "build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/af/fd/b522dcf75713cd293743cff84613",
"build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3a/3f/04ffa4a2626e9bfbd60e461d66bd", "build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/15/45/0c8a4e7775c699146aea682e5504",
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a9/21/0e26a17656ab1e388dd71ecf0244", "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/09/31/4cf5f0cd0c180f9ecbb973b07ed9",
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9f/5d/cd22cab6347090bd4cd9c36f4941" "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4a/1d/be1767741e32fd937917748944d6"
} }

View File

@ -1,3 +1,6 @@
### 1.5.29 (20246)
- Exposed ba method/class initing in public C++ layer.
### 1.5.28 (20239) ### 1.5.28 (20239)
- Simplified ba.enum_by_value() - Simplified ba.enum_by_value()
- Updated Google Play version to hopefully show friend high scores again on score screens (at least for levels that have an associated Google Play leaderboard). - Updated Google Play version to hopefully show friend high scores again on score screens (at least for levels that have an associated Google Play leaderboard).

View File

@ -1,5 +1,5 @@
<!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND --> <!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND -->
<h4><em>last updated on 2020-11-10 for Ballistica version 1.5.28 build 20245</em></h4> <h4><em>last updated on 2020-11-11 for Ballistica version 1.5.28 build 20246</em></h4>
<p>This page documents the Python classes and functions in the 'ba' module, <p>This page documents the Python classes and functions in the 'ba' module,
which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p> which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p>
<hr> <hr>

View File

@ -21,8 +21,8 @@
namespace ballistica { namespace ballistica {
// These are set automatically via script; don't change here. // These are set automatically via script; don't change here.
const int kAppBuildNumber = 20246; const int kAppBuildNumber = 20247;
const char* kAppVersion = "1.5.28"; const char* kAppVersion = "1.5.29";
// Our standalone globals. // Our standalone globals.
// These are separated out for easy access. // These are separated out for easy access.

View File

@ -154,8 +154,8 @@ auto IsBootstrapped() -> bool;
/// Internal bits. /// Internal bits.
auto CreateAppInternal() -> AppInternal*; auto CreateAppInternal() -> AppInternal*;
auto AppInternalPythonInit2() -> void; auto AppInternalInitPythonModule() -> void;
auto AppInternalInitModule() -> void; auto AppInternalPythonPostInit() -> void;
auto AppInternalHasBlessingHash() -> bool; auto AppInternalHasBlessingHash() -> bool;
auto AppInternalPutLog(bool fatal) -> bool; auto AppInternalPutLog(bool fatal) -> bool;
auto AppInternalAwardAdTickets() -> void; auto AppInternalAwardAdTickets() -> void;

View File

@ -20,6 +20,7 @@ typedef struct ALCcontext_struct ALCcontext;
#endif #endif
typedef struct _object PyObject; typedef struct _object PyObject;
typedef struct _ts PyThreadState; typedef struct _ts PyThreadState;
typedef struct PyMethodDef PyMethodDef;
#if BA_SDL_BUILD || BA_MINSDL_BUILD #if BA_SDL_BUILD || BA_MINSDL_BUILD
union SDL_Event; union SDL_Event;

View File

@ -3,7 +3,6 @@
#include "ballistica/python/methods/python_methods_app.h" #include "ballistica/python/methods/python_methods_app.h"
#include <string> #include <string>
#include <vector>
#include "ballistica/app/app.h" #include "ballistica/app/app.h"
#include "ballistica/app/app_globals.h" #include "ballistica/app/app_globals.h"
@ -19,6 +18,7 @@
#include "ballistica/python/class/python_class_session_data.h" #include "ballistica/python/class/python_class_session_data.h"
#include "ballistica/python/python.h" #include "ballistica/python/python.h"
#include "ballistica/python/python_context_call_runnable.h" #include "ballistica/python/python_context_call_runnable.h"
#include "ballistica/python/python_sys.h"
#include "ballistica/scene/scene.h" #include "ballistica/scene/scene.h"
namespace ballistica { namespace ballistica {
@ -885,313 +885,339 @@ auto PyTimeFormatCheck(PyObject* self, PyObject* args, PyObject* keywds)
BA_PYTHON_CATCH; BA_PYTHON_CATCH;
} }
PyMethodDef PythonMethodsApp::methods_def[] = { auto PythonMethodsApp::GetMethods() -> std::vector<PyMethodDef> {
return {
{"appname", (PyCFunction)PyAppName, METH_NOARGS, {"appname", (PyCFunction)PyAppName, METH_NOARGS,
"appname() -> str\n" "appname() -> str\n"
"\n" "\n"
"(internal)\n"}, "(internal)\n"},
{"appnameupper", (PyCFunction)PyAppNameUpper, METH_NOARGS, {"appnameupper", (PyCFunction)PyAppNameUpper, METH_NOARGS,
"appnameupper() -> str\n" "appnameupper() -> str\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Return whether this build of the game can display full unicode such as\n" "Return whether this build of the game can display full unicode such "
"Emoji, Asian languages, etc.\n"}, "as\n"
{"is_xcode_build", (PyCFunction)PyIsXCodeBuild, METH_NOARGS, "Emoji, Asian languages, etc.\n"},
"is_xcode_build() -> bool\n" {"is_xcode_build", (PyCFunction)PyIsXCodeBuild, METH_NOARGS,
"\n" "is_xcode_build() -> bool\n"
"(internal)\n"}, "\n"
{"can_display_full_unicode", (PyCFunction)PyCanDisplayFullUnicode, "(internal)\n"},
METH_NOARGS, {"can_display_full_unicode", (PyCFunction)PyCanDisplayFullUnicode,
"can_display_full_unicode() -> bool\n" METH_NOARGS,
"\n" "can_display_full_unicode() -> bool\n"
"(internal)\n"}, "\n"
{"time_format_check", (PyCFunction)PyTimeFormatCheck, "(internal)\n"},
METH_VARARGS | METH_KEYWORDS, {"time_format_check", (PyCFunction)PyTimeFormatCheck,
"time_format_check(time_format: ba.TimeFormat, length: Union[float, " METH_VARARGS | METH_KEYWORDS,
"int])\n" "time_format_check(time_format: ba.TimeFormat, length: Union[float, "
" -> None\n" "int])\n"
"\n" " -> None\n"
"(internal)\n" "\n"
"\n" "(internal)\n"
"Logs suspicious time values for timers or animate calls.\n" "\n"
"\n" "Logs suspicious time values for timers or animate calls.\n"
"(for helping with the transition from milliseconds-based time calls\n" "\n"
"to seconds-based ones)"}, "(for helping with the transition from milliseconds-based time calls\n"
"to seconds-based ones)"},
{"log", (PyCFunction)PyLog, METH_VARARGS | METH_KEYWORDS, {"log", (PyCFunction)PyLog, METH_VARARGS | METH_KEYWORDS,
"log(message: str, to_stdout: bool = True,\n" "log(message: str, to_stdout: bool = True,\n"
" to_server: bool = True) -> None\n" " to_server: bool = True) -> None\n"
"\n" "\n"
"Category: General Utility Functions\n" "Category: General Utility Functions\n"
"\n" "\n"
"Log a message. This goes to the default logging mechanism depending\n" "Log a message. This goes to the default logging mechanism depending\n"
"on the platform (stdout on mac, android log on android, etc).\n" "on the platform (stdout on mac, android log on android, etc).\n"
"\n" "\n"
"Log messages also go to the in-game console unless 'to_console'\n" "Log messages also go to the in-game console unless 'to_console'\n"
"is False. They are also sent to the master-server for use in analyzing\n" "is False. They are also sent to the master-server for use in "
"issues unless to_server is False.\n" "analyzing\n"
"\n" "issues unless to_server is False.\n"
"Python's standard print() is wired to call this (with default values)\n" "\n"
"so in most cases you can just use that."}, "Python's standard print() is wired to call this (with default "
"values)\n"
"so in most cases you can just use that."},
{"print_stdout", PyPrintStdout, METH_VARARGS, {"print_stdout", PyPrintStdout, METH_VARARGS,
"print_stdout(message: str) -> None\n" "print_stdout(message: str) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"print_stderr", PyPrintStderr, METH_VARARGS, {"print_stderr", PyPrintStderr, METH_VARARGS,
"print_stderr(message: str) -> None\n" "print_stderr(message: str) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"set_stress_testing", PySetStressTesting, METH_VARARGS, {"set_stress_testing", PySetStressTesting, METH_VARARGS,
"set_stress_testing(testing: bool, player_count: int) -> None\n" "set_stress_testing(testing: bool, player_count: int) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"env", (PyCFunction)PyEnv, METH_NOARGS, {"env", (PyCFunction)PyEnv, METH_NOARGS,
"env() -> dict\n" "env() -> dict\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Returns a dict containing general info about the operating environment\n" "Returns a dict containing general info about the operating "
"such as version, platform, etc.\n" "environment\n"
"This info is now exposed through ba.App; refer to those docs for\n" "such as version, platform, etc.\n"
"info on specific elements."}, "This info is now exposed through ba.App; refer to those docs for\n"
"info on specific elements."},
{"commit_config", (PyCFunction)PyCommitConfig, METH_VARARGS | METH_KEYWORDS, {"commit_config", (PyCFunction)PyCommitConfig,
"commit_config(config: str) -> None\n" METH_VARARGS | METH_KEYWORDS,
"\n" "commit_config(config: str) -> None\n"
"(internal)"}, "\n"
"(internal)"},
{"apply_config", PyApplyConfig, METH_VARARGS, {"apply_config", PyApplyConfig, METH_VARARGS,
"apply_config() -> None\n" "apply_config() -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
#if BA_DEBUG_BUILD #if BA_DEBUG_BUILD
{"bless", (PyCFunction)PyBless, METH_VARARGS | METH_KEYWORDS, {"bless", (PyCFunction)PyBless, METH_VARARGS | METH_KEYWORDS,
"bless() -> None\n" "bless() -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
#endif #endif
{"quit", (PyCFunction)PyQuit, METH_VARARGS | METH_KEYWORDS, {"quit", (PyCFunction)PyQuit, METH_VARARGS | METH_KEYWORDS,
"quit(soft: bool = False, back: bool = False) -> None\n" "quit(soft: bool = False, back: bool = False) -> None\n"
"\n" "\n"
"Quit the game.\n" "Quit the game.\n"
"\n" "\n"
"Category: General Utility Functions\n" "Category: General Utility Functions\n"
"\n" "\n"
"On systems like android, 'soft' will end the activity but keep the\n" "On systems like android, 'soft' will end the activity but keep the\n"
"app running."}, "app running."},
{"screenmessage", (PyCFunction)PyScreenMessage, {"screenmessage", (PyCFunction)PyScreenMessage,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"screenmessage(message: Union[str, ba.Lstr],\n" "screenmessage(message: Union[str, ba.Lstr],\n"
" color: Sequence[float] = None, top: bool = False,\n" " color: Sequence[float] = None, top: bool = False,\n"
" image: Dict[str, Any] = None, log: bool = False,\n" " image: Dict[str, Any] = None, log: bool = False,\n"
" clients: Sequence[int] = None, transient: bool = False) -> None\n" " clients: Sequence[int] = None, transient: bool = False) -> None\n"
"\n" "\n"
"Print a message to the local client's screen, in a given color.\n" "Print a message to the local client's screen, in a given color.\n"
"\n" "\n"
"Category: General Utility Functions\n" "Category: General Utility Functions\n"
"\n" "\n"
"If 'top' is True, the message will go to the top message area.\n" "If 'top' is True, the message will go to the top message area.\n"
"For 'top' messages, 'image' can be a texture to display alongside the\n" "For 'top' messages, 'image' can be a texture to display alongside "
"message.\n" "the\n"
"If 'log' is True, the message will also be printed to the output log\n" "message.\n"
"'clients' can be a list of client-ids the message should be sent to,\n" "If 'log' is True, the message will also be printed to the output "
"or None to specify that everyone should receive it.\n" "log\n"
"If 'transient' is True, the message will not be included in the\n" "'clients' can be a list of client-ids the message should be sent "
"game-stream and thus will not show up when viewing replays.\n" "to,\n"
"Currently the 'clients' option only works for transient messages."}, "or None to specify that everyone should receive it.\n"
"If 'transient' is True, the message will not be included in the\n"
"game-stream and thus will not show up when viewing replays.\n"
"Currently the 'clients' option only works for transient messages."},
{"timer", (PyCFunction)PyTimer, METH_VARARGS | METH_KEYWORDS, {"timer", (PyCFunction)PyTimer, METH_VARARGS | METH_KEYWORDS,
"timer(time: float, call: Callable[[], Any], repeat: bool = False,\n" "timer(time: float, call: Callable[[], Any], repeat: bool = False,\n"
" timetype: ba.TimeType = TimeType.SIM,\n" " timetype: ba.TimeType = TimeType.SIM,\n"
" timeformat: ba.TimeFormat = TimeFormat.SECONDS,\n" " timeformat: ba.TimeFormat = TimeFormat.SECONDS,\n"
" suppress_format_warning: bool = False)\n" " suppress_format_warning: bool = False)\n"
" -> None\n" " -> None\n"
"\n" "\n"
"Schedule a call to run at a later point in time.\n" "Schedule a call to run at a later point in time.\n"
"\n" "\n"
"Category: General Utility Functions\n" "Category: General Utility Functions\n"
"\n" "\n"
"This function adds a timer to the current ba.Context.\n" "This function adds a timer to the current ba.Context.\n"
"This timer cannot be canceled or modified once created. If you\n" "This timer cannot be canceled or modified once created. If you\n"
" require the ability to do so, use the ba.Timer class instead.\n" " require the ability to do so, use the ba.Timer class instead.\n"
"\n" "\n"
"time: length of time (in seconds by default) that the timer will wait\n" "time: length of time (in seconds by default) that the timer will "
"before firing. Note that the actual delay experienced may vary\n " "wait\n"
"depending on the timetype. (see below)\n" "before firing. Note that the actual delay experienced may vary\n "
"\n" "depending on the timetype. (see below)\n"
"call: A callable Python object. Note that the timer will retain a\n" "\n"
"strong reference to the callable for as long as it exists, so you\n" "call: A callable Python object. Note that the timer will retain a\n"
"may want to look into concepts such as ba.WeakCall if that is not\n" "strong reference to the callable for as long as it exists, so you\n"
"desired.\n" "may want to look into concepts such as ba.WeakCall if that is not\n"
"\n" "desired.\n"
"repeat: if True, the timer will fire repeatedly, with each successive\n" "\n"
"firing having the same delay as the first.\n" "repeat: if True, the timer will fire repeatedly, with each "
"\n" "successive\n"
"timetype can be either 'sim', 'base', or 'real'. It defaults to\n" "firing having the same delay as the first.\n"
"'sim'. Types are explained below:\n" "\n"
"\n" "timetype can be either 'sim', 'base', or 'real'. It defaults to\n"
"'sim' time maps to local simulation time in ba.Activity or ba.Session\n" "'sim'. Types are explained below:\n"
"Contexts. This means that it may progress slower in slow-motion play\n" "\n"
"modes, stop when the game is paused, etc. This time type is not\n" "'sim' time maps to local simulation time in ba.Activity or "
"available in UI contexts.\n" "ba.Session\n"
"\n" "Contexts. This means that it may progress slower in slow-motion "
"'base' time is also linked to gameplay in ba.Activity or ba.Session\n" "play\n"
"Contexts, but it progresses at a constant rate regardless of\n " "modes, stop when the game is paused, etc. This time type is not\n"
"slow-motion states or pausing. It can, however, slow down or stop\n" "available in UI contexts.\n"
"in certain cases such as network outages or game slowdowns due to\n" "\n"
"cpu load. Like 'sim' time, this is unavailable in UI contexts.\n" "'base' time is also linked to gameplay in ba.Activity or ba.Session\n"
"\n" "Contexts, but it progresses at a constant rate regardless of\n "
"'real' time always maps to actual clock time with a bit of filtering\n" "slow-motion states or pausing. It can, however, slow down or stop\n"
"added, regardless of Context. (the filtering prevents it from going\n" "in certain cases such as network outages or game slowdowns due to\n"
"backwards or jumping forward by large amounts due to the app being\n" "cpu load. Like 'sim' time, this is unavailable in UI contexts.\n"
"backgrounded, system time changing, etc.)\n" "\n"
"Real time timers are currently only available in the UI context.\n" "'real' time always maps to actual clock time with a bit of "
"\n" "filtering\n"
"the 'timeformat' arg defaults to seconds but can also be milliseconds.\n" "added, regardless of Context. (the filtering prevents it from "
"\n" "going\n"
"# timer example: print some stuff through time:\n" "backwards or jumping forward by large amounts due to the app being\n"
"ba.screenmessage('hello from now!')\n" "backgrounded, system time changing, etc.)\n"
"ba.timer(1.0, ba.Call(ba.screenmessage, 'hello from the future!'))\n" "Real time timers are currently only available in the UI context.\n"
"ba.timer(2.0, ba.Call(ba.screenmessage, 'hello from the future 2!'))\n"}, "\n"
"the 'timeformat' arg defaults to seconds but can also be "
"milliseconds.\n"
"\n"
"# timer example: print some stuff through time:\n"
"ba.screenmessage('hello from now!')\n"
"ba.timer(1.0, ba.Call(ba.screenmessage, 'hello from the future!'))\n"
"ba.timer(2.0, ba.Call(ba.screenmessage, 'hello from the future "
"2!'))\n"},
{"time", (PyCFunction)PyTime, METH_VARARGS | METH_KEYWORDS, {"time", (PyCFunction)PyTime, METH_VARARGS | METH_KEYWORDS,
"time(timetype: ba.TimeType = TimeType.SIM,\n" "time(timetype: ba.TimeType = TimeType.SIM,\n"
" timeformat: ba.TimeFormat = TimeFormat.SECONDS)\n" " timeformat: ba.TimeFormat = TimeFormat.SECONDS)\n"
" -> <varies>\n" " -> <varies>\n"
"\n" "\n"
"Return the current time.\n" "Return the current time.\n"
"\n" "\n"
"Category: General Utility Functions\n" "Category: General Utility Functions\n"
"\n" "\n"
"The time returned depends on the current ba.Context and timetype.\n" "The time returned depends on the current ba.Context and timetype.\n"
"\n" "\n"
"timetype can be either SIM, BASE, or REAL. It defaults to\n" "timetype can be either SIM, BASE, or REAL. It defaults to\n"
"SIM. Types are explained below:\n" "SIM. Types are explained below:\n"
"\n" "\n"
"SIM time maps to local simulation time in ba.Activity or ba.Session\n" "SIM time maps to local simulation time in ba.Activity or ba.Session\n"
"Contexts. This means that it may progress slower in slow-motion play\n" "Contexts. This means that it may progress slower in slow-motion "
"modes, stop when the game is paused, etc. This time type is not\n" "play\n"
"available in UI contexts.\n" "modes, stop when the game is paused, etc. This time type is not\n"
"\n" "available in UI contexts.\n"
"BASE time is also linked to gameplay in ba.Activity or ba.Session\n" "\n"
"Contexts, but it progresses at a constant rate regardless of\n " "BASE time is also linked to gameplay in ba.Activity or ba.Session\n"
"slow-motion states or pausing. It can, however, slow down or stop\n" "Contexts, but it progresses at a constant rate regardless of\n "
"in certain cases such as network outages or game slowdowns due to\n" "slow-motion states or pausing. It can, however, slow down or stop\n"
"cpu load. Like 'sim' time, this is unavailable in UI contexts.\n" "in certain cases such as network outages or game slowdowns due to\n"
"\n" "cpu load. Like 'sim' time, this is unavailable in UI contexts.\n"
"REAL time always maps to actual clock time with a bit of filtering\n" "\n"
"added, regardless of Context. (the filtering prevents it from going\n" "REAL time always maps to actual clock time with a bit of filtering\n"
"backwards or jumping forward by large amounts due to the app being\n" "added, regardless of Context. (the filtering prevents it from "
"backgrounded, system time changing, etc.)\n" "going\n"
"\n" "backwards or jumping forward by large amounts due to the app being\n"
"the 'timeformat' arg defaults to SECONDS which returns float seconds,\n" "backgrounded, system time changing, etc.)\n"
"but it can also be MILLISECONDS to return integer milliseconds.\n" "\n"
"\n" "the 'timeformat' arg defaults to SECONDS which returns float "
"Note: If you need pure unfiltered clock time, just use the standard\n" "seconds,\n"
"Python functions such as time.time()."}, "but it can also be MILLISECONDS to return integer milliseconds.\n"
"\n"
"Note: If you need pure unfiltered clock time, just use the standard\n"
"Python functions such as time.time()."},
{"pushcall", (PyCFunction)PyPushCall, METH_VARARGS | METH_KEYWORDS, {"pushcall", (PyCFunction)PyPushCall, METH_VARARGS | METH_KEYWORDS,
"pushcall(call: Callable, from_other_thread: bool = False,\n" "pushcall(call: Callable, from_other_thread: bool = False,\n"
" suppress_other_thread_warning: bool = False ) -> None\n" " suppress_other_thread_warning: bool = False ) -> None\n"
"\n" "\n"
"Pushes a call onto the event loop to be run during the next cycle.\n" "Pushes a call onto the event loop to be run during the next cycle.\n"
"\n" "\n"
"Category: General Utility Functions\n" "Category: General Utility Functions\n"
"\n" "\n"
"This can be handy for calls that are disallowed from within other\n" "This can be handy for calls that are disallowed from within other\n"
"callbacks, etc.\n" "callbacks, etc.\n"
"\n" "\n"
"This call expects to be used in the game thread, and will automatically\n" "This call expects to be used in the game thread, and will "
"save and restore the ba.Context to behave seamlessly.\n" "automatically\n"
"\n" "save and restore the ba.Context to behave seamlessly.\n"
"If you want to push a call from outside of the game thread,\n" "\n"
"however, you can pass 'from_other_thread' as True. In this case\n" "If you want to push a call from outside of the game thread,\n"
"the call will always run in the UI context on the game thread."}, "however, you can pass 'from_other_thread' as True. In this case\n"
"the call will always run in the UI context on the game thread."},
{"getactivity", (PyCFunction)PyGetActivity, METH_VARARGS | METH_KEYWORDS, {"getactivity", (PyCFunction)PyGetActivity,
"getactivity(doraise: bool = True) -> <varies>\n" METH_VARARGS | METH_KEYWORDS,
"\n" "getactivity(doraise: bool = True) -> <varies>\n"
"Return the current ba.Activity instance.\n" "\n"
"\n" "Return the current ba.Activity instance.\n"
"Category: Gameplay Functions\n" "\n"
"\n" "Category: Gameplay Functions\n"
"Note that this is based on context; thus code run in a timer generated\n" "\n"
"in Activity 'foo' will properly return 'foo' here, even if another\n" "Note that this is based on context; thus code run in a timer "
"Activity has since been created or is transitioning in.\n" "generated\n"
"If there is no current Activity, raises a ba.ActivityNotFoundError.\n" "in Activity 'foo' will properly return 'foo' here, even if another\n"
"If doraise is False, None will be returned instead in that case."}, "Activity has since been created or is transitioning in.\n"
"If there is no current Activity, raises a ba.ActivityNotFoundError.\n"
"If doraise is False, None will be returned instead in that case."},
{"newactivity", (PyCFunction)PyNewActivity, METH_VARARGS | METH_KEYWORDS, {"newactivity", (PyCFunction)PyNewActivity,
"newactivity(activity_type: Type[ba.Activity],\n" METH_VARARGS | METH_KEYWORDS,
" settings: dict = None) -> ba.Activity\n" "newactivity(activity_type: Type[ba.Activity],\n"
"\n" " settings: dict = None) -> ba.Activity\n"
"Instantiates a ba.Activity given a type object.\n" "\n"
"\n" "Instantiates a ba.Activity given a type object.\n"
"Category: General Utility Functions\n" "\n"
"\n" "Category: General Utility Functions\n"
"Activities require special setup and thus cannot be directly\n" "\n"
"instantiated; you must go through this function."}, "Activities require special setup and thus cannot be directly\n"
"instantiated; you must go through this function."},
{"get_foreground_host_session", (PyCFunction)PyGetForegroundHostSession, {"get_foreground_host_session", (PyCFunction)PyGetForegroundHostSession,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_foreground_host_session() -> Optional[ba.Session]\n" "get_foreground_host_session() -> Optional[ba.Session]\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Return the ba.Session currently being displayed, or None if there is\n" "Return the ba.Session currently being displayed, or None if there "
"none."}, "is\n"
"none."},
{"register_activity", (PyCFunction)PyRegisterActivity, {"register_activity", (PyCFunction)PyRegisterActivity,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"register_activity(activity: ba.Activity) -> ActivityData\n" "register_activity(activity: ba.Activity) -> ActivityData\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"register_session", (PyCFunction)PyRegisterSession, {"register_session", (PyCFunction)PyRegisterSession,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"register_session(session: ba.Session) -> SessionData\n" "register_session(session: ba.Session) -> SessionData\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"is_in_replay", (PyCFunction)PyIsInReplay, METH_VARARGS | METH_KEYWORDS, {"is_in_replay", (PyCFunction)PyIsInReplay,
"is_in_replay() -> bool\n" METH_VARARGS | METH_KEYWORDS,
"\n" "is_in_replay() -> bool\n"
"(internal)"}, "\n"
"(internal)"},
{"new_replay_session", (PyCFunction)PyNewReplaySession, {"new_replay_session", (PyCFunction)PyNewReplaySession,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"new_replay_session(file_name: str) -> None\n" "new_replay_session(file_name: str) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"new_host_session", (PyCFunction)PyNewHostSession, {"new_host_session", (PyCFunction)PyNewHostSession,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"new_host_session(sessiontype: Type[ba.Session],\n" "new_host_session(sessiontype: Type[ba.Session],\n"
" benchmark_type: str = None) -> None\n" " benchmark_type: str = None) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"getsession", (PyCFunction)PyGetSession, METH_VARARGS | METH_KEYWORDS, {"getsession", (PyCFunction)PyGetSession, METH_VARARGS | METH_KEYWORDS,
"getsession(doraise: bool = True) -> <varies>\n" "getsession(doraise: bool = True) -> <varies>\n"
"\n" "\n"
"Category: Gameplay Functions\n" "Category: Gameplay Functions\n"
"\n" "\n"
"Returns the current ba.Session instance.\n" "Returns the current ba.Session instance.\n"
"Note that this is based on context; thus code being run in the UI\n" "Note that this is based on context; thus code being run in the UI\n"
"context will return the UI context here even if a game Session also\n" "context will return the UI context here even if a game Session also\n"
"exists, etc. If there is no current Session, an Exception is raised, " "exists, etc. If there is no current Session, an Exception is raised, "
"or\n" "or\n"
"if doraise is False then None is returned instead."}, "if doraise is False then None is returned instead."},
};
{nullptr, nullptr, 0, nullptr}}; }
#pragma clang diagnostic pop #pragma clang diagnostic pop

View File

@ -3,14 +3,16 @@
#ifndef BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_APP_H_ #ifndef BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_APP_H_
#define BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_APP_H_ #define BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_APP_H_
#include "ballistica/python/python_sys.h" #include <vector>
#include "ballistica/ballistica.h"
namespace ballistica { namespace ballistica {
/// App related individual python methods for our module. /// App related individual python methods for our module.
class PythonMethodsApp { class PythonMethodsApp {
public: public:
static PyMethodDef methods_def[]; static auto GetMethods() -> std::vector<PyMethodDef>;
}; };
} // namespace ballistica } // namespace ballistica

View File

@ -4,7 +4,6 @@
#include <list> #include <list>
#include <string> #include <string>
#include <vector>
#include "ballistica/app/app.h" #include "ballistica/app/app.h"
#include "ballistica/dynamics/bg/bg_dynamics.h" #include "ballistica/dynamics/bg/bg_dynamics.h"
@ -23,6 +22,7 @@
#include "ballistica/platform/platform.h" #include "ballistica/platform/platform.h"
#include "ballistica/python/python.h" #include "ballistica/python/python.h"
#include "ballistica/python/python_context_call_runnable.h" #include "ballistica/python/python_context_call_runnable.h"
#include "ballistica/python/python_sys.h"
#include "ballistica/scene/node/node.h" #include "ballistica/scene/node/node.h"
#include "ballistica/scene/node/node_type.h" #include "ballistica/scene/node/node_type.h"
#include "ballistica/scene/scene.h" #include "ballistica/scene/scene.h"
@ -601,166 +601,174 @@ auto PyGetRandomNames(PyObject* self, PyObject* args) -> PyObject* {
BA_PYTHON_CATCH; BA_PYTHON_CATCH;
} }
PyMethodDef PythonMethodsGameplay::methods_def[] = { auto PythonMethodsGameplay::GetMethods() -> std::vector<PyMethodDef> {
{"get_random_names", PyGetRandomNames, METH_VARARGS, return {
"get_random_names() -> list\n" {"get_random_names", PyGetRandomNames, METH_VARARGS,
"\n" "get_random_names() -> list\n"
"(internal)\n" "\n"
"\n" "(internal)\n"
"Returns the random names used by the game."}, "\n"
"Returns the random names used by the game."},
{"reset_random_player_names", (PyCFunction)PyResetRandomPlayerNames, {"reset_random_player_names", (PyCFunction)PyResetRandomPlayerNames,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"reset_random_player_names() -> None\n" "reset_random_player_names() -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"reset_game_activity_tracking", (PyCFunction)PyResetGameActivityTracking, {"reset_game_activity_tracking", (PyCFunction)PyResetGameActivityTracking,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"reset_game_activity_tracking() -> None\n" "reset_game_activity_tracking() -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"set_replay_speed_exponent", PySetReplaySpeedExponent, METH_VARARGS, {"set_replay_speed_exponent", PySetReplaySpeedExponent, METH_VARARGS,
"set_replay_speed_exponent(speed: int) -> None\n" "set_replay_speed_exponent(speed: int) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Set replay speed. Actual displayed speed is pow(2,speed)."}, "Set replay speed. Actual displayed speed is pow(2,speed)."},
{"get_replay_speed_exponent", PyGetReplaySpeedExponent, METH_VARARGS, {"get_replay_speed_exponent", PyGetReplaySpeedExponent, METH_VARARGS,
"get_replay_speed_exponent() -> int\n" "get_replay_speed_exponent() -> int\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Returns current replay speed value. Actual displayed speed is " "Returns current replay speed value. Actual displayed speed is "
"pow(2,speed)."}, "pow(2,speed)."},
{"set_debug_speed_exponent", PySetDebugSpeedExponent, METH_VARARGS, {"set_debug_speed_exponent", PySetDebugSpeedExponent, METH_VARARGS,
"set_debug_speed_exponent(speed: int) -> None\n" "set_debug_speed_exponent(speed: int) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Sets the debug speed scale for the game. Actual speed is pow(2,speed)."}, "Sets the debug speed scale for the game. Actual speed is "
"pow(2,speed)."},
{"get_scores_to_beat", (PyCFunction)PyGetScoresToBeat, {"get_scores_to_beat", (PyCFunction)PyGetScoresToBeat,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_scores_to_beat(level: str, config: str, callback: Callable) -> None\n" "get_scores_to_beat(level: str, config: str, callback: Callable) -> "
"\n" "None\n"
"(internal)"}, "\n"
"(internal)"},
{"get_game_roster", (PyCFunction)PyGetGameRoster, {"get_game_roster", (PyCFunction)PyGetGameRoster,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_game_roster() -> List[Dict[str, Any]]\n" "get_game_roster() -> List[Dict[str, Any]]\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"get_foreground_host_activity", (PyCFunction)PyGetForegroundHostActivity, {"get_foreground_host_activity", (PyCFunction)PyGetForegroundHostActivity,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_foreground_host_activity() -> Optional[ba.Activity]\n" "get_foreground_host_activity() -> Optional[ba.Activity]\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Returns the ba.Activity currently in the foreground, or None if there\n" "Returns the ba.Activity currently in the foreground, or None if there\n"
"is none.\n"}, "is none.\n"},
{"set_map_bounds", (PyCFunction)PySetMapBounds, {"set_map_bounds", (PyCFunction)PySetMapBounds,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"set_map_bounds(bounds: Tuple[float, float, float, float, float, float])\n" "set_map_bounds(bounds: Tuple[float, float, float, float, float, "
" -> None\n" "float])\n"
"\n" " -> None\n"
"(internal)\n" "\n"
"\n" "(internal)\n"
"Set map bounds. Generally nodes that go outside of this box are " "\n"
"killed."}, "Set map bounds. Generally nodes that go outside of this box are "
"killed."},
{"emitfx", (PyCFunction)PyEmitFx, METH_VARARGS | METH_KEYWORDS, {"emitfx", (PyCFunction)PyEmitFx, METH_VARARGS | METH_KEYWORDS,
"emitfx(position: Sequence[float],\n" "emitfx(position: Sequence[float],\n"
" velocity: Optional[Sequence[float]] = None,\n" " velocity: Optional[Sequence[float]] = None,\n"
" count: int = 10, scale: float = 1.0, spread: float = 1.0,\n" " count: int = 10, scale: float = 1.0, spread: float = 1.0,\n"
" chunk_type: str = 'rock', emit_type: str ='chunks',\n" " chunk_type: str = 'rock', emit_type: str ='chunks',\n"
" tendril_type: str = 'smoke') -> None\n" " tendril_type: str = 'smoke') -> None\n"
"\n" "\n"
"Emit particles, smoke, etc. into the fx sim layer.\n" "Emit particles, smoke, etc. into the fx sim layer.\n"
"\n" "\n"
"Category: Gameplay Functions\n" "Category: Gameplay Functions\n"
"\n" "\n"
"The fx sim layer is a secondary dynamics simulation that runs in\n" "The fx sim layer is a secondary dynamics simulation that runs in\n"
"the background and just looks pretty; it does not affect gameplay.\n" "the background and just looks pretty; it does not affect gameplay.\n"
"Note that the actual amount emitted may vary depending on graphics\n" "Note that the actual amount emitted may vary depending on graphics\n"
"settings, exiting element counts, or other factors."}, "settings, exiting element counts, or other factors."},
{"playsound", (PyCFunction)PyPlaySound, METH_VARARGS | METH_KEYWORDS, {"playsound", (PyCFunction)PyPlaySound, METH_VARARGS | METH_KEYWORDS,
"playsound(sound: Sound, volume: float = 1.0,\n" "playsound(sound: Sound, volume: float = 1.0,\n"
" position: Sequence[float] = None, host_only: bool = False) -> None\n" " position: Sequence[float] = None, host_only: bool = False) -> None\n"
"\n" "\n"
"Play a ba.Sound a single time.\n" "Play a ba.Sound a single time.\n"
"\n" "\n"
"Category: Gameplay Functions\n" "Category: Gameplay Functions\n"
"\n" "\n"
"If position is not provided, the sound will be at a constant volume\n" "If position is not provided, the sound will be at a constant volume\n"
"everywhere. Position should be a float tuple of size 3."}, "everywhere. Position should be a float tuple of size 3."},
{"camerashake", (PyCFunction)PyCameraShake, METH_VARARGS | METH_KEYWORDS, {"camerashake", (PyCFunction)PyCameraShake, METH_VARARGS | METH_KEYWORDS,
"camerashake(intensity: float = 1.0) -> None\n" "camerashake(intensity: float = 1.0) -> None\n"
"\n" "\n"
"Shake the camera.\n" "Shake the camera.\n"
"\n" "\n"
"Category: Gameplay Functions\n" "Category: Gameplay Functions\n"
"\n" "\n"
"Note that some cameras and/or platforms (such as VR) may not display\n" "Note that some cameras and/or platforms (such as VR) may not display\n"
"camera-shake, so do not rely on this always being visible to the\n" "camera-shake, so do not rely on this always being visible to the\n"
"player as a gameplay cue."}, "player as a gameplay cue."},
{"get_collision_info", PyGetCollisionInfo, METH_VARARGS, {"get_collision_info", PyGetCollisionInfo, METH_VARARGS,
"get_collision_info(*args: Any) -> Any\n" "get_collision_info(*args: Any) -> Any\n"
"\n" "\n"
"Return collision related values\n" "Return collision related values\n"
"\n" "\n"
"Category: Gameplay Functions\n" "Category: Gameplay Functions\n"
"\n" "\n"
"Returns a single collision value or tuple of values such as location,\n" "Returns a single collision value or tuple of values such as location,\n"
"depth, nodes involved, etc. Only call this in the handler of a\n" "depth, nodes involved, etc. Only call this in the handler of a\n"
"collision-triggered callback or message"}, "collision-triggered callback or message"},
{"getnodes", PyGetNodes, METH_VARARGS, {"getnodes", PyGetNodes, METH_VARARGS,
"getnodes() -> list\n" "getnodes() -> list\n"
"\n" "\n"
"Return all nodes in the current ba.Context." "Return all nodes in the current ba.Context."
"\n" "\n"
"Category: Gameplay Functions"}, "Category: Gameplay Functions"},
{"printnodes", PyPrintNodes, METH_VARARGS, {"printnodes", PyPrintNodes, METH_VARARGS,
"printnodes() -> None\n" "printnodes() -> None\n"
"\n" "\n"
"Print various info about existing nodes; useful for debugging.\n" "Print various info about existing nodes; useful for debugging.\n"
"\n" "\n"
"Category: Gameplay Functions"}, "Category: Gameplay Functions"},
{"newnode", (PyCFunction)PyNewNode, METH_VARARGS | METH_KEYWORDS, {"newnode", (PyCFunction)PyNewNode, METH_VARARGS | METH_KEYWORDS,
"newnode(type: str, owner: ba.Node = None,\n" "newnode(type: str, owner: ba.Node = None,\n"
"attrs: dict = None, name: str = None, delegate: Any = None)\n" "attrs: dict = None, name: str = None, delegate: Any = None)\n"
" -> Node\n" " -> Node\n"
"\n" "\n"
"Add a node of the given type to the game.\n" "Add a node of the given type to the game.\n"
"\n" "\n"
"Category: Gameplay Functions\n" "Category: Gameplay Functions\n"
"\n" "\n"
"If a dict is provided for 'attributes', the node's initial attributes\n" "If a dict is provided for 'attributes', the node's initial attributes\n"
"will be set based on them.\n" "will be set based on them.\n"
"\n" "\n"
"'name', if provided, will be stored with the node purely for debugging\n" "'name', if provided, will be stored with the node purely for "
"purposes. If no name is provided, an automatic one will be generated\n" "debugging\n"
"such as 'terrain@foo.py:30'.\n" "purposes. If no name is provided, an automatic one will be generated\n"
"\n" "such as 'terrain@foo.py:30'.\n"
"If 'delegate' is provided, Python messages sent to the node will go to\n" "\n"
"that object's handlemessage() method. Note that the delegate is stored\n" "If 'delegate' is provided, Python messages sent to the node will go "
"as a weak-ref, so the node itself will not keep the object alive.\n" "to\n"
"\n" "that object's handlemessage() method. Note that the delegate is "
"if 'owner' is provided, the node will be automatically killed when that\n" "stored\n"
"object dies. 'owner' can be another node or a ba.Actor"}, "as a weak-ref, so the node itself will not keep the object alive.\n"
"\n"
{nullptr, nullptr, 0, nullptr}}; "if 'owner' is provided, the node will be automatically killed when "
"that\n"
"object dies. 'owner' can be another node or a ba.Actor"},
};
}
#pragma clang diagnostic pop #pragma clang diagnostic pop

View File

@ -3,14 +3,16 @@
#ifndef BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_GAMEPLAY_H_ #ifndef BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_GAMEPLAY_H_
#define BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_GAMEPLAY_H_ #define BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_GAMEPLAY_H_
#include "ballistica/python/python_sys.h" #include <vector>
#include "ballistica/ballistica.h"
namespace ballistica { namespace ballistica {
/// Gameplay related individual python methods for our module. /// Gameplay related individual python methods for our module.
class PythonMethodsGameplay { class PythonMethodsGameplay {
public: public:
static PyMethodDef methods_def[]; static auto GetMethods() -> std::vector<PyMethodDef>;
}; };
} // namespace ballistica } // namespace ballistica

View File

@ -10,6 +10,7 @@
#include "ballistica/platform/platform.h" #include "ballistica/platform/platform.h"
#include "ballistica/python/python.h" #include "ballistica/python/python.h"
#include "ballistica/python/python_context_call_runnable.h" #include "ballistica/python/python_context_call_runnable.h"
#include "ballistica/python/python_sys.h"
namespace ballistica { namespace ballistica {
@ -223,92 +224,97 @@ auto PyGetDisplayResolution(PyObject* self, PyObject* args) -> PyObject* {
BA_PYTHON_CATCH; BA_PYTHON_CATCH;
} }
PyMethodDef PythonMethodsGraphics::methods_def[] = { auto PythonMethodsGraphics::GetMethods() -> std::vector<PyMethodDef> {
{"get_display_resolution", PyGetDisplayResolution, METH_VARARGS, return {
"get_display_resolution() -> Optional[Tuple[int, int]]\n" {"get_display_resolution", PyGetDisplayResolution, METH_VARARGS,
"\n" "get_display_resolution() -> Optional[Tuple[int, int]]\n"
"(internal)\n" "\n"
"\n" "(internal)\n"
"Return the currently selected display resolution for fullscreen\n" "\n"
"display. Returns None if resolutions cannot be directly set."}, "Return the currently selected display resolution for fullscreen\n"
"display. Returns None if resolutions cannot be directly set."},
{"has_gamma_control", PyHasGammaControl, METH_VARARGS, {"has_gamma_control", PyHasGammaControl, METH_VARARGS,
"has_gamma_control() -> bool\n" "has_gamma_control() -> bool\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Returns whether the system can adjust overall screen gamma)"}, "Returns whether the system can adjust overall screen gamma)"},
{"add_clean_frame_callback", (PyCFunction)PyAddCleanFrameCallback, {"add_clean_frame_callback", (PyCFunction)PyAddCleanFrameCallback,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"add_clean_frame_callback(call: Callable) -> None\n" "add_clean_frame_callback(call: Callable) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Provide an object to be called once the next non-progress-bar-frame has\n" "Provide an object to be called once the next non-progress-bar-frame "
"been rendered. Useful for queueing things to load in the background\n" "has\n"
"without elongating any current progress-bar-load."}, "been rendered. Useful for queueing things to load in the background\n"
"without elongating any current progress-bar-load."},
{"have_chars", (PyCFunction)PyHaveChars, METH_VARARGS | METH_KEYWORDS, {"have_chars", (PyCFunction)PyHaveChars, METH_VARARGS | METH_KEYWORDS,
"have_chars(text: str) -> bool\n" "have_chars(text: str) -> bool\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"get_string_width", (PyCFunction)PyGetStringWidth, {"get_string_width", (PyCFunction)PyGetStringWidth,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_string_width(string: str, suppress_warning: bool = False) -> float\n" "get_string_width(string: str, suppress_warning: bool = False) -> "
"\n" "float\n"
"(internal)\n" "\n"
"\n" "(internal)\n"
"Given a string, returns its width using the standard small app\n" "\n"
"font."}, "Given a string, returns its width using the standard small app\n"
"font."},
{"get_string_height", (PyCFunction)PyGetStringHeight, {"get_string_height", (PyCFunction)PyGetStringHeight,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_string_height(string: str, suppress_warning: bool = False) -> float\n" "get_string_height(string: str, suppress_warning: bool = False) -> "
"\n" "float\n"
"(internal)\n" "\n"
"\n" "(internal)\n"
"Given a string, returns its height using the standard small app\n" "\n"
"font."}, "Given a string, returns its height using the standard small app\n"
"font."},
{"evaluate_lstr", (PyCFunction)PyEvaluateLstr, METH_VARARGS | METH_KEYWORDS, {"evaluate_lstr", (PyCFunction)PyEvaluateLstr,
"evaluate_lstr(value: str) -> str\n" METH_VARARGS | METH_KEYWORDS,
"\n" "evaluate_lstr(value: str) -> str\n"
"(internal)"}, "\n"
"(internal)"},
{"get_max_graphics_quality", PyGetMaxGraphicsQuality, METH_VARARGS, {"get_max_graphics_quality", PyGetMaxGraphicsQuality, METH_VARARGS,
"get_max_graphics_quality() -> str\n" "get_max_graphics_quality() -> str\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Return the max graphics-quality supported on the current hardware."}, "Return the max graphics-quality supported on the current hardware."},
{"safecolor", (PyCFunction)PySafeColor, METH_VARARGS | METH_KEYWORDS, {"safecolor", (PyCFunction)PySafeColor, METH_VARARGS | METH_KEYWORDS,
"safecolor(color: Sequence[float], target_intensity: float = 0.6)\n" "safecolor(color: Sequence[float], target_intensity: float = 0.6)\n"
" -> Tuple[float, ...]\n" " -> Tuple[float, ...]\n"
"\n" "\n"
"Given a color tuple, return a color safe to display as text.\n" "Given a color tuple, return a color safe to display as text.\n"
"\n" "\n"
"Category: General Utility Functions\n" "Category: General Utility Functions\n"
"\n" "\n"
"Accepts tuples of length 3 or 4. This will slightly brighten very\n" "Accepts tuples of length 3 or 4. This will slightly brighten very\n"
"dark colors, etc."}, "dark colors, etc."},
{"charstr", (PyCFunction)PyCharStr, METH_VARARGS | METH_KEYWORDS, {"charstr", (PyCFunction)PyCharStr, METH_VARARGS | METH_KEYWORDS,
"charstr(char_id: ba.SpecialChar) -> str\n" "charstr(char_id: ba.SpecialChar) -> str\n"
"\n" "\n"
"Get a unicode string representing a special character.\n" "Get a unicode string representing a special character.\n"
"\n" "\n"
"Category: General Utility Functions\n" "Category: General Utility Functions\n"
"\n" "\n"
"Note that these utilize the private-use block of unicode characters\n" "Note that these utilize the private-use block of unicode characters\n"
"(U+E000-U+F8FF) and are specific to the game; exporting or rendering\n" "(U+E000-U+F8FF) and are specific to the game; exporting or rendering\n"
"them elsewhere will be meaningless.\n" "them elsewhere will be meaningless.\n"
"\n" "\n"
"see ba.SpecialChar for the list of available characters."}, "see ba.SpecialChar for the list of available characters."},
};
{nullptr, nullptr, 0, nullptr}}; }
#pragma clang diagnostic pop #pragma clang diagnostic pop

View File

@ -3,14 +3,16 @@
#ifndef BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_GRAPHICS_H_ #ifndef BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_GRAPHICS_H_
#define BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_GRAPHICS_H_ #define BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_GRAPHICS_H_
#include "ballistica/python/python_sys.h" #include <vector>
#include "ballistica/ballistica.h"
namespace ballistica { namespace ballistica {
/// Graphics related individual python methods for our module. /// Graphics related individual python methods for our module.
class PythonMethodsGraphics { class PythonMethodsGraphics {
public: public:
static PyMethodDef methods_def[]; static auto GetMethods() -> std::vector<PyMethodDef>;
}; };
} // namespace ballistica } // namespace ballistica

View File

@ -12,6 +12,7 @@
#include "ballistica/input/input.h" #include "ballistica/input/input.h"
#include "ballistica/platform/platform.h" #include "ballistica/platform/platform.h"
#include "ballistica/python/python.h" #include "ballistica/python/python.h"
#include "ballistica/python/python_sys.h"
#include "ballistica/ui/ui.h" #include "ballistica/ui/ui.h"
namespace ballistica { namespace ballistica {
@ -265,129 +266,131 @@ auto PyGetLocalActiveInputDevicesCount(PyObject* self, PyObject* args,
BA_PYTHON_CATCH; BA_PYTHON_CATCH;
} }
PyMethodDef PythonMethodsInput::methods_def[] = { auto PythonMethodsInput::GetMethods() -> std::vector<PyMethodDef> {
{"get_local_active_input_devices_count", return {
(PyCFunction)PyGetLocalActiveInputDevicesCount, {"get_local_active_input_devices_count",
METH_VARARGS | METH_KEYWORDS, (PyCFunction)PyGetLocalActiveInputDevicesCount,
"get_local_active_input_devices_count() -> int\n" METH_VARARGS | METH_KEYWORDS,
"\n" "get_local_active_input_devices_count() -> int\n"
"(internal)"}, "\n"
"(internal)"},
{"getinputdevice", (PyCFunction)PyGetInputDevice, {"getinputdevice", (PyCFunction)PyGetInputDevice,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"getinputdevice(name: str, unique_id: str, doraise: bool = True)\n" "getinputdevice(name: str, unique_id: str, doraise: bool = True)\n"
" -> <varies>\n" " -> <varies>\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Given a type name and a unique identifier, returns an InputDevice.\n" "Given a type name and a unique identifier, returns an InputDevice.\n"
"Throws an Exception if the input-device is not found, or returns None\n" "Throws an Exception if the input-device is not found, or returns None\n"
"if 'doraise' is False.\n"}, "if 'doraise' is False.\n"},
{"set_ui_input_device", (PyCFunction)PySetUIInputDevice, {"set_ui_input_device", (PyCFunction)PySetUIInputDevice,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"set_ui_input_device(input_device: Optional[ba.InputDevice]) -> None\n" "set_ui_input_device(input_device: Optional[ba.InputDevice]) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Sets the input-device that currently owns the user interface."}, "Sets the input-device that currently owns the user interface."},
{"get_ui_input_device", (PyCFunction)PyGetUIInputDevice, {"get_ui_input_device", (PyCFunction)PyGetUIInputDevice,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_ui_input_device() -> ba.InputDevice\n" "get_ui_input_device() -> ba.InputDevice\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Returns the input-device that currently owns the user interface, or\n" "Returns the input-device that currently owns the user interface, or\n"
"None if there is none."}, "None if there is none."},
{"unlock_all_input", PyUnlockAllInput, METH_VARARGS, {"unlock_all_input", PyUnlockAllInput, METH_VARARGS,
"unlock_all_input() -> None\n" "unlock_all_input() -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Resumes normal keyboard, mouse, and gamepad event processing."}, "Resumes normal keyboard, mouse, and gamepad event processing."},
{"lock_all_input", PyLockAllInput, METH_VARARGS, {"lock_all_input", PyLockAllInput, METH_VARARGS,
"lock_all_input() -> None\n" "lock_all_input() -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Prevents all keyboard, mouse, and gamepad events from being processed."}, "Prevents all keyboard, mouse, and gamepad events from being "
"processed."},
{"release_keyboard_input", PyReleaseKeyboardInput, METH_VARARGS, {"release_keyboard_input", PyReleaseKeyboardInput, METH_VARARGS,
"release_keyboard_input() -> None\n" "release_keyboard_input() -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Resumes normal keyboard event processing."}, "Resumes normal keyboard event processing."},
{"capture_keyboard_input", PyCaptureKeyboardInput, METH_VARARGS, {"capture_keyboard_input", PyCaptureKeyboardInput, METH_VARARGS,
"capture_keyboard_input(call: Callable[[dict], None]) -> None\n" "capture_keyboard_input(call: Callable[[dict], None]) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Add a callable to be called for subsequent keyboard-game-pad events.\n" "Add a callable to be called for subsequent keyboard-game-pad events.\n"
"The method is passed a dict containing info about the event."}, "The method is passed a dict containing info about the event."},
{"release_gamepad_input", PyReleaseGamePadInput, METH_VARARGS, {"release_gamepad_input", PyReleaseGamePadInput, METH_VARARGS,
"release_gamepad_input() -> None\n" "release_gamepad_input() -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Resumes normal gamepad event processing."}, "Resumes normal gamepad event processing."},
{"capture_gamepad_input", PyCaptureGamePadInput, METH_VARARGS, {"capture_gamepad_input", PyCaptureGamePadInput, METH_VARARGS,
"capture_gamepad_input(call: Callable[[dict], None]) -> None\n" "capture_gamepad_input(call: Callable[[dict], None]) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Add a callable to be called for subsequent gamepad events.\n" "Add a callable to be called for subsequent gamepad events.\n"
"The method is passed a dict containing info about the event."}, "The method is passed a dict containing info about the event."},
{"set_touchscreen_editing", PySetTouchscreenEditing, METH_VARARGS, {"set_touchscreen_editing", PySetTouchscreenEditing, METH_VARARGS,
"set_touchscreen_editing(editing: bool) -> None\n" "set_touchscreen_editing(editing: bool) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"get_device_login_id", (PyCFunction)PyGetDeviceLoginID, {"get_device_login_id", (PyCFunction)PyGetDeviceLoginID,
METH_VARARGS | METH_KEYWORDS, "internal"}, METH_VARARGS | METH_KEYWORDS, "internal"},
{"set_device_account", (PyCFunction)PySetDeviceAccount, {"set_device_account", (PyCFunction)PySetDeviceAccount,
METH_VARARGS | METH_KEYWORDS, "internal"}, METH_VARARGS | METH_KEYWORDS, "internal"},
{"stop_listening_for_wii_remotes", PyStopListeningForWiiRemotes, {"stop_listening_for_wii_remotes", PyStopListeningForWiiRemotes,
METH_VARARGS, METH_VARARGS,
"stop_listening_for_wii_remotes() -> None\n" "stop_listening_for_wii_remotes() -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Stop listening for connections from wii remotes."}, "Stop listening for connections from wii remotes."},
{"start_listening_for_wii_remotes", PyStartListeningForWiiRemotes, {"start_listening_for_wii_remotes", PyStartListeningForWiiRemotes,
METH_VARARGS, METH_VARARGS,
"start_listening_for_wii_remotes() -> None\n" "start_listening_for_wii_remotes() -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Start listening for connections from wii remotes."}, "Start listening for connections from wii remotes."},
{"have_touchscreen_input", PyHaveTouchScreenInput, METH_VARARGS, {"have_touchscreen_input", PyHaveTouchScreenInput, METH_VARARGS,
"have_touchscreen_input() -> bool\n" "have_touchscreen_input() -> bool\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Returns whether or not a touch-screen input is present"}, "Returns whether or not a touch-screen input is present"},
{"get_configurable_game_pads", PyGetConfigurableGamePads, METH_VARARGS, {"get_configurable_game_pads", PyGetConfigurableGamePads, METH_VARARGS,
"get_configurable_game_pads() -> list\n" "get_configurable_game_pads() -> list\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Returns a list of the currently connected gamepads that can be\n" "Returns a list of the currently connected gamepads that can be\n"
"configured."}, "configured."},
};
{nullptr, nullptr, 0, nullptr}}; }
#pragma clang diagnostic pop #pragma clang diagnostic pop

View File

@ -3,14 +3,16 @@
#ifndef BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_INPUT_H_ #ifndef BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_INPUT_H_
#define BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_INPUT_H_ #define BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_INPUT_H_
#include "ballistica/python/python_sys.h" #include <vector>
#include "ballistica/ballistica.h"
namespace ballistica { namespace ballistica {
// Input related individual python methods for our module. // Input related individual python methods for our module.
class PythonMethodsInput { class PythonMethodsInput {
public: public:
static PyMethodDef methods_def[]; static auto GetMethods() -> std::vector<PyMethodDef>;
}; };
} // namespace ballistica } // namespace ballistica

View File

@ -16,6 +16,7 @@
#include "ballistica/media/component/sound.h" #include "ballistica/media/component/sound.h"
#include "ballistica/media/component/texture.h" #include "ballistica/media/component/texture.h"
#include "ballistica/python/python.h" #include "ballistica/python/python.h"
#include "ballistica/python/python_sys.h"
#include "ballistica/ui/ui.h" #include "ballistica/ui/ui.h"
namespace ballistica { namespace ballistica {
@ -362,201 +363,208 @@ auto PyIsOSPlayingMusic(PyObject* self, PyObject* args, PyObject* keywds)
BA_PYTHON_CATCH; BA_PYTHON_CATCH;
} }
PyMethodDef PythonMethodsMedia::methods_def[] = { auto PythonMethodsMedia::GetMethods() -> std::vector<PyMethodDef> {
{"is_os_playing_music", (PyCFunction)PyIsOSPlayingMusic, return {
METH_VARARGS | METH_KEYWORDS, {"is_os_playing_music", (PyCFunction)PyIsOSPlayingMusic,
"is_os_playing_music() -> bool\n" METH_VARARGS | METH_KEYWORDS,
"\n" "is_os_playing_music() -> bool\n"
"(internal)\n" "\n"
"\n" "(internal)\n"
"Tells whether the OS is currently playing music of some sort.\n" "\n"
"\n" "Tells whether the OS is currently playing music of some sort.\n"
"(Used to determine whether the game should avoid playing its own)"}, "\n"
"(Used to determine whether the game should avoid playing its own)"},
{"mac_music_app_init", (PyCFunction)PyMacMusicAppInit, {"mac_music_app_init", (PyCFunction)PyMacMusicAppInit,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"mac_music_app_init() -> None\n" "mac_music_app_init() -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"mac_music_app_get_volume", (PyCFunction)PyMacMusicAppGetVolume, {"mac_music_app_get_volume", (PyCFunction)PyMacMusicAppGetVolume,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"mac_music_app_get_volume() -> int\n" "mac_music_app_get_volume() -> int\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"mac_music_app_set_volume", (PyCFunction)PyMacMusicAppSetVolume, {"mac_music_app_set_volume", (PyCFunction)PyMacMusicAppSetVolume,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"mac_music_app_set_volume(volume: int) -> None\n" "mac_music_app_set_volume(volume: int) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"mac_music_app_get_library_source", {"mac_music_app_get_library_source",
(PyCFunction)PyMacMusicAppGetLibrarySource, METH_VARARGS | METH_KEYWORDS, (PyCFunction)PyMacMusicAppGetLibrarySource, METH_VARARGS | METH_KEYWORDS,
"mac_music_app_get_library_source() -> None\n" "mac_music_app_get_library_source() -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"mac_music_app_stop", (PyCFunction)PyMacMusicAppStop, {"mac_music_app_stop", (PyCFunction)PyMacMusicAppStop,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"mac_music_app_stop() -> None\n" "mac_music_app_stop() -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"mac_music_app_play_playlist", (PyCFunction)PyMacMusicAppPlayPlaylist, {"mac_music_app_play_playlist", (PyCFunction)PyMacMusicAppPlayPlaylist,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"mac_music_app_play_playlist(playlist: str) -> bool\n" "mac_music_app_play_playlist(playlist: str) -> bool\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"mac_music_app_get_playlists", (PyCFunction)PyMacMusicAppGetPlaylists, {"mac_music_app_get_playlists", (PyCFunction)PyMacMusicAppGetPlaylists,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"mac_music_app_get_playlists() -> List[str]\n" "mac_music_app_get_playlists() -> List[str]\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"get_qrcode_texture", (PyCFunction)PyGetQRCodeTexture, {"get_qrcode_texture", (PyCFunction)PyGetQRCodeTexture,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_qrcode_texture(url: str) -> ba.Texture\n" "get_qrcode_texture(url: str) -> ba.Texture\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"reload_media", PyReloadMedia, METH_VARARGS, {"reload_media", PyReloadMedia, METH_VARARGS,
"reload_media() -> None\n" "reload_media() -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Reload all currently loaded game media; useful for\n" "Reload all currently loaded game media; useful for\n"
"development/debugging."}, "development/debugging."},
{"music_player_shutdown", (PyCFunction)PyMusicPlayerShutdown, {"music_player_shutdown", (PyCFunction)PyMusicPlayerShutdown,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"music_player_shutdown() -> None\n" "music_player_shutdown() -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Finalizes internal music file playback (for internal use)"}, "Finalizes internal music file playback (for internal use)"},
{"music_player_set_volume", (PyCFunction)PyMusicPlayerSetVolume, {"music_player_set_volume", (PyCFunction)PyMusicPlayerSetVolume,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"music_player_set_volume(volume: float) -> None\n" "music_player_set_volume(volume: float) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Sets internal music player volume (for internal use)"}, "Sets internal music player volume (for internal use)"},
{"music_player_play", (PyCFunction)PyMusicPlayerPlay, {"music_player_play", (PyCFunction)PyMusicPlayerPlay,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"music_player_play(files: Any) -> None\n" "music_player_play(files: Any) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Starts internal music file playback (for internal use)"}, "Starts internal music file playback (for internal use)"},
{"music_player_stop", (PyCFunction)PyMusicPlayerStop, {"music_player_stop", (PyCFunction)PyMusicPlayerStop,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"music_player_stop() -> None\n" "music_player_stop() -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Stops internal music file playback (for internal use)"}, "Stops internal music file playback (for internal use)"},
{"getcollidemodel", (PyCFunction)PyGetCollideModel, {"getcollidemodel", (PyCFunction)PyGetCollideModel,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"getcollidemodel(name: str) -> ba.CollideModel\n" "getcollidemodel(name: str) -> ba.CollideModel\n"
"\n" "\n"
"Return a collide-model, loading it if necessary.\n" "Return a collide-model, loading it if necessary.\n"
"\n" "\n"
"Category: Asset Functions\n" "Category: Asset Functions\n"
"\n" "\n"
"Collide-models are used in physics calculations for such things as\n" "Collide-models are used in physics calculations for such things as\n"
"terrain.\n" "terrain.\n"
"\n" "\n"
"Note that this function returns immediately even if the media has yet\n" "Note that this function returns immediately even if the media has yet\n"
"to be loaded. To avoid hitches, instantiate your media objects in\n" "to be loaded. To avoid hitches, instantiate your media objects in\n"
"advance of when you will be using them, allowing time for them to load\n" "advance of when you will be using them, allowing time for them to "
"in the background if necessary."}, "load\n"
"in the background if necessary."},
{"get_package_collide_model", (PyCFunction)PyGetPackageCollideModel, {"get_package_collide_model", (PyCFunction)PyGetPackageCollideModel,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_package_collide_model(package: ba.AssetPackage, name: str)\n" "get_package_collide_model(package: ba.AssetPackage, name: str)\n"
"-> ba.CollideModel\n" "-> ba.CollideModel\n"
"\n" "\n"
"(internal)\n"}, "(internal)\n"},
{"getmodel", (PyCFunction)PyGetModel, METH_VARARGS | METH_KEYWORDS, {"getmodel", (PyCFunction)PyGetModel, METH_VARARGS | METH_KEYWORDS,
"getmodel(name: str) -> ba.Model\n" "getmodel(name: str) -> ba.Model\n"
"\n" "\n"
"Return a model, loading it if necessary.\n" "Return a model, loading it if necessary.\n"
"\n" "\n"
"Category: Asset Functions\n" "Category: Asset Functions\n"
"\n" "\n"
"Note that this function returns immediately even if the media has yet\n" "Note that this function returns immediately even if the media has yet\n"
"to be loaded. To avoid hitches, instantiate your media objects in\n" "to be loaded. To avoid hitches, instantiate your media objects in\n"
"advance of when you will be using them, allowing time for them to load\n" "advance of when you will be using them, allowing time for them to "
"in the background if necessary."}, "load\n"
"in the background if necessary."},
{"get_package_model", (PyCFunction)PyGetPackageModel, {"get_package_model", (PyCFunction)PyGetPackageModel,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_package_model(package: ba.AssetPackage, name: str) -> ba.Model\n" "get_package_model(package: ba.AssetPackage, name: str) -> ba.Model\n"
"\n" "\n"
"(internal)\n"}, "(internal)\n"},
{"getsound", (PyCFunction)PyGetSound, METH_VARARGS | METH_KEYWORDS, {"getsound", (PyCFunction)PyGetSound, METH_VARARGS | METH_KEYWORDS,
"getsound(name: str) -> ba.Sound\n" "getsound(name: str) -> ba.Sound\n"
"\n" "\n"
"Return a sound, loading it if necessary.\n" "Return a sound, loading it if necessary.\n"
"\n" "\n"
"Category: Asset Functions\n" "Category: Asset Functions\n"
"\n" "\n"
"Note that this function returns immediately even if the media has yet\n" "Note that this function returns immediately even if the media has yet\n"
"to be loaded. To avoid hitches, instantiate your media objects in\n" "to be loaded. To avoid hitches, instantiate your media objects in\n"
"advance of when you will be using them, allowing time for them to load\n" "advance of when you will be using them, allowing time for them to "
"in the background if necessary."}, "load\n"
"in the background if necessary."},
{"get_package_sound", (PyCFunction)PyGetPackageSound, {"get_package_sound", (PyCFunction)PyGetPackageSound,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_package_sound(package: ba.AssetPackage, name: str) -> ba.Sound\n" "get_package_sound(package: ba.AssetPackage, name: str) -> ba.Sound\n"
"\n" "\n"
"(internal).\n"}, "(internal).\n"},
{"getdata", (PyCFunction)PyGetData, METH_VARARGS | METH_KEYWORDS, {"getdata", (PyCFunction)PyGetData, METH_VARARGS | METH_KEYWORDS,
"getdata(name: str) -> ba.Data\n" "getdata(name: str) -> ba.Data\n"
"\n" "\n"
"Return a data, loading it if necessary.\n" "Return a data, loading it if necessary.\n"
"\n" "\n"
"Category: Asset Functions\n" "Category: Asset Functions\n"
"\n" "\n"
"Note that this function returns immediately even if the media has yet\n" "Note that this function returns immediately even if the media has yet\n"
"to be loaded. To avoid hitches, instantiate your media objects in\n" "to be loaded. To avoid hitches, instantiate your media objects in\n"
"advance of when you will be using them, allowing time for them to load\n" "advance of when you will be using them, allowing time for them to "
"in the background if necessary."}, "load\n"
"in the background if necessary."},
{"get_package_data", (PyCFunction)PyGetPackageData, {"get_package_data", (PyCFunction)PyGetPackageData,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_package_data(package: ba.AssetPackage, name: str) -> ba.Data\n" "get_package_data(package: ba.AssetPackage, name: str) -> ba.Data\n"
"\n" "\n"
"(internal).\n"}, "(internal).\n"},
{"gettexture", (PyCFunction)PyGetTexture, METH_VARARGS | METH_KEYWORDS, {"gettexture", (PyCFunction)PyGetTexture, METH_VARARGS | METH_KEYWORDS,
"gettexture(name: str) -> ba.Texture\n" "gettexture(name: str) -> ba.Texture\n"
"\n" "\n"
"Return a texture, loading it if necessary.\n" "Return a texture, loading it if necessary.\n"
"\n" "\n"
"Category: Asset Functions\n" "Category: Asset Functions\n"
"\n" "\n"
"Note that this function returns immediately even if the media has yet\n" "Note that this function returns immediately even if the media has yet\n"
"to be loaded. To avoid hitches, instantiate your media objects in\n" "to be loaded. To avoid hitches, instantiate your media objects in\n"
"advance of when you will be using them, allowing time for them to load\n" "advance of when you will be using them, allowing time for them to "
"in the background if necessary."}, "load\n"
"in the background if necessary."},
{"get_package_texture", (PyCFunction)PyGetPackageTexture, {"get_package_texture", (PyCFunction)PyGetPackageTexture,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_package_texture(package: ba.AssetPackage, name: str) -> ba.Texture\n" "get_package_texture(package: ba.AssetPackage, name: str) -> "
"\n" "ba.Texture\n"
"(internal)"}, "\n"
"(internal)"},
{nullptr, nullptr, 0, nullptr}}; };
}
#pragma clang diagnostic pop #pragma clang diagnostic pop

View File

@ -3,14 +3,16 @@
#ifndef BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_MEDIA_H_ #ifndef BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_MEDIA_H_
#define BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_MEDIA_H_ #define BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_MEDIA_H_
#include "ballistica/python/python_sys.h" #include <vector>
#include "ballistica/ballistica.h"
namespace ballistica { namespace ballistica {
/// Media related individual python methods for our module. /// Media related individual python methods for our module.
class PythonMethodsMedia { class PythonMethodsMedia {
public: public:
static PyMethodDef methods_def[]; static auto GetMethods() -> std::vector<PyMethodDef>;
}; };
} // namespace ballistica } // namespace ballistica

View File

@ -22,6 +22,7 @@
#include "ballistica/platform/platform.h" #include "ballistica/platform/platform.h"
#include "ballistica/python/python.h" #include "ballistica/python/python.h"
#include "ballistica/python/python_context_call_runnable.h" #include "ballistica/python/python_context_call_runnable.h"
#include "ballistica/python/python_sys.h"
#include "ballistica/scene/scene.h" #include "ballistica/scene/scene.h"
namespace ballistica { namespace ballistica {
@ -740,291 +741,297 @@ auto PyApp(PyObject* self, PyObject* args, PyObject* keywds) -> PyObject* {
BA_PYTHON_CATCH; BA_PYTHON_CATCH;
} }
PyMethodDef PythonMethodsSystem::methods_def[] = { auto PythonMethodsSystem::GetMethods() -> std::vector<PyMethodDef> {
{"printobjects", (PyCFunction)PyPrintObjects, METH_VARARGS | METH_KEYWORDS, return {
"printobjects() -> None\n" {"printobjects", (PyCFunction)PyPrintObjects,
"\n" METH_VARARGS | METH_KEYWORDS,
"Print debugging info about game objects.\n" "printobjects() -> None\n"
"\n" "\n"
"Category: General Utility Functions\n" "Print debugging info about game objects.\n"
"\n" "\n"
"This call only functions in debug builds of the game.\n" "Category: General Utility Functions\n"
"It prints various info about the current object count, etc."}, "\n"
"This call only functions in debug builds of the game.\n"
"It prints various info about the current object count, etc."},
{"do_once", (PyCFunction)PyDoOnce, METH_VARARGS | METH_KEYWORDS, {"do_once", (PyCFunction)PyDoOnce, METH_VARARGS | METH_KEYWORDS,
"do_once() -> bool\n" "do_once() -> bool\n"
"\n" "\n"
"Return whether this is the first time running a line of code.\n" "Return whether this is the first time running a line of code.\n"
"\n" "\n"
"Category: General Utility Functions\n" "Category: General Utility Functions\n"
"\n" "\n"
"This is used by 'print_once()' type calls to keep from overflowing\n" "This is used by 'print_once()' type calls to keep from overflowing\n"
"logs. The call functions by registering the filename and line where\n" "logs. The call functions by registering the filename and line where\n"
"The call is made from. Returns True if this location has not been\n" "The call is made from. Returns True if this location has not been\n"
"registered already, and False if it has.\n" "registered already, and False if it has.\n"
"\n" "\n"
"# Example: this print will only fire for the first loop iteration:\n" "# Example: this print will only fire for the first loop iteration:\n"
"for i in range(10):\n" "for i in range(10):\n"
" if ba.do_once():\n" " if ba.do_once():\n"
" print('Hello once from loop!')"}, " print('Hello once from loop!')"},
{"_app", (PyCFunction)PyApp, METH_VARARGS | METH_KEYWORDS, {"_app", (PyCFunction)PyApp, METH_VARARGS | METH_KEYWORDS,
"_app() -> ba.App\n" "_app() -> ba.App\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"android_media_scan_file", (PyCFunction)PyAndroidMediaScanFile, {"android_media_scan_file", (PyCFunction)PyAndroidMediaScanFile,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"android_media_scan_file(file_name: str) -> None\n" "android_media_scan_file(file_name: str) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Refreshes Android MTP Index for a file; use this to get file\n" "Refreshes Android MTP Index for a file; use this to get file\n"
"modifications to be reflected in Android File Transfer."}, "modifications to be reflected in Android File Transfer."},
{"android_get_external_storage_path", {"android_get_external_storage_path",
(PyCFunction)PyAndroidGetExternalStoragePath, METH_VARARGS | METH_KEYWORDS, (PyCFunction)PyAndroidGetExternalStoragePath,
"android_get_external_storage_path() -> str\n" METH_VARARGS | METH_KEYWORDS,
"\n" "android_get_external_storage_path() -> str\n"
"(internal)\n" "\n"
"\n" "(internal)\n"
"Returns the android external storage path, or None if there is none on\n" "\n"
"this device"}, "Returns the android external storage path, or None if there is none "
"on\n"
"this device"},
{"android_show_wifi_settings", (PyCFunction)PyAndroidShowWifiSettings, {"android_show_wifi_settings", (PyCFunction)PyAndroidShowWifiSettings,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"android_show_wifi_settings() -> None\n" "android_show_wifi_settings() -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"is_ouya_build", PyIsOuyaBuild, METH_VARARGS, {"is_ouya_build", PyIsOuyaBuild, METH_VARARGS,
"is_ouya_build() -> bool\n" "is_ouya_build() -> bool\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Returns whether we're running the ouya-specific version"}, "Returns whether we're running the ouya-specific version"},
{"set_internal_language_keys", PySetInternalLanguageKeys, METH_VARARGS, {"set_internal_language_keys", PySetInternalLanguageKeys, METH_VARARGS,
"set_internal_language_keys(listobj: List[Tuple[str, str]],\n" "set_internal_language_keys(listobj: List[Tuple[str, str]],\n"
" random_names_list: List[Tuple[str, str]]) -> None\n" " random_names_list: List[Tuple[str, str]]) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"set_analytics_screen", (PyCFunction)PySetAnalyticsScreen, {"set_analytics_screen", (PyCFunction)PySetAnalyticsScreen,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"set_analytics_screen(screen: str) -> None\n" "set_analytics_screen(screen: str) -> None\n"
"\n" "\n"
"Used for analytics to see where in the app players spend their time.\n" "Used for analytics to see where in the app players spend their time.\n"
"\n" "\n"
"Category: General Utility Functions\n" "Category: General Utility Functions\n"
"\n" "\n"
"Generally called when opening a new window or entering some UI.\n" "Generally called when opening a new window or entering some UI.\n"
"'screen' should be a string description of an app location\n" "'screen' should be a string description of an app location\n"
"('Main Menu', etc.)"}, "('Main Menu', etc.)"},
{"submit_analytics_counts", (PyCFunction)PySubmitAnalyticsCounts, {"submit_analytics_counts", (PyCFunction)PySubmitAnalyticsCounts,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"submit_analytics_counts() -> None\n" "submit_analytics_counts() -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"increment_analytics_count_raw_2", {"increment_analytics_count_raw_2",
(PyCFunction)PyIncrementAnalyticsCountRaw2, METH_VARARGS | METH_KEYWORDS, (PyCFunction)PyIncrementAnalyticsCountRaw2, METH_VARARGS | METH_KEYWORDS,
"increment_analytics_count_raw_2(name: str,\n" "increment_analytics_count_raw_2(name: str,\n"
" uses_increment: bool = True, increment: int = 1) -> None\n" " uses_increment: bool = True, increment: int = 1) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"increment_analytics_counts_raw", {"increment_analytics_counts_raw",
(PyCFunction)PyIncrementAnalyticsCountRaw, METH_VARARGS | METH_KEYWORDS, (PyCFunction)PyIncrementAnalyticsCountRaw, METH_VARARGS | METH_KEYWORDS,
"increment_analytics_counts_raw(name: str, increment: int = 1) -> None\n" "increment_analytics_counts_raw(name: str, increment: int = 1) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"increment_analytics_count", (PyCFunction)PyIncrementAnalyticsCount, {"increment_analytics_count", (PyCFunction)PyIncrementAnalyticsCount,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"increment_analytics_count(name: str, increment: int = 1) -> None\n" "increment_analytics_count(name: str, increment: int = 1) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"mark_log_sent", (PyCFunction)PyMarkLogSent, METH_VARARGS | METH_KEYWORDS, {"mark_log_sent", (PyCFunction)PyMarkLogSent,
"mark_log_sent() -> None\n" METH_VARARGS | METH_KEYWORDS,
"\n" "mark_log_sent() -> None\n"
"(internal)"}, "\n"
"(internal)"},
{"getlog", (PyCFunction)PyGetLog, METH_VARARGS | METH_KEYWORDS, {"getlog", (PyCFunction)PyGetLog, METH_VARARGS | METH_KEYWORDS,
"getlog() -> str\n" "getlog() -> str\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"is_log_full", PyIsLogFull, METH_VARARGS, {"is_log_full", PyIsLogFull, METH_VARARGS,
"is_log_full() -> bool\n" "is_log_full() -> bool\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"get_log_file_path", PyGetLogFilePath, METH_VARARGS, {"get_log_file_path", PyGetLogFilePath, METH_VARARGS,
"get_log_file_path() -> str\n" "get_log_file_path() -> str\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Return the path to the app log file."}, "Return the path to the app log file."},
{"set_platform_misc_read_vals", (PyCFunction)PySetPlatformMiscReadVals, {"set_platform_misc_read_vals", (PyCFunction)PySetPlatformMiscReadVals,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"set_platform_misc_read_vals(mode: str) -> None\n" "set_platform_misc_read_vals(mode: str) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"set_low_level_config_value", (PyCFunction)PySetLowLevelConfigValue, {"set_low_level_config_value", (PyCFunction)PySetLowLevelConfigValue,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"set_low_level_config_value(key: str, value: int) -> None\n" "set_low_level_config_value(key: str, value: int) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"get_low_level_config_value", (PyCFunction)PyGetLowLevelConfigValue, {"get_low_level_config_value", (PyCFunction)PyGetLowLevelConfigValue,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_low_level_config_value(key: str, default_value: int) -> int\n" "get_low_level_config_value(key: str, default_value: int) -> int\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"resolve_appconfig_value", (PyCFunction)PyResolveAppConfigValue, {"resolve_appconfig_value", (PyCFunction)PyResolveAppConfigValue,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"resolve_appconfig_value(key: str) -> Any\n" "resolve_appconfig_value(key: str) -> Any\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"get_appconfig_default_value", (PyCFunction)PyGetAppConfigDefaultValue, {"get_appconfig_default_value", (PyCFunction)PyGetAppConfigDefaultValue,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_appconfig_default_value(key: str) -> Any\n" "get_appconfig_default_value(key: str) -> Any\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"get_appconfig_builtin_keys", (PyCFunction)PyAppConfigGetBuiltinKeys, {"get_appconfig_builtin_keys", (PyCFunction)PyAppConfigGetBuiltinKeys,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_appconfig_builtin_keys() -> List[str]\n" "get_appconfig_builtin_keys() -> List[str]\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"get_replays_dir", (PyCFunction)PyGetReplaysDir, {"get_replays_dir", (PyCFunction)PyGetReplaysDir,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_replays_dir() -> str\n" "get_replays_dir() -> str\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"print_load_info", (PyCFunction)PyPrintLoadInfo, {"print_load_info", (PyCFunction)PyPrintLoadInfo,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"print_load_info() -> None\n" "print_load_info() -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Category: General Utility Functions"}, "Category: General Utility Functions"},
{"print_context", (PyCFunction)PyPrintContext, METH_VARARGS | METH_KEYWORDS, {"print_context", (PyCFunction)PyPrintContext,
"print_context() -> None\n" METH_VARARGS | METH_KEYWORDS,
"\n" "print_context() -> None\n"
"(internal)\n" "\n"
"\n" "(internal)\n"
"Prints info about the current context state; for debugging.\n"}, "\n"
"Prints info about the current context state; for debugging.\n"},
{"debug_print_py_err", PyDebugPrintPyErr, METH_VARARGS, {"debug_print_py_err", PyDebugPrintPyErr, METH_VARARGS,
"debug_print_py_err() -> None\n" "debug_print_py_err() -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Debugging func for tracking leaked Python errors in the C++ layer.."}, "Debugging func for tracking leaked Python errors in the C++ layer.."},
{"value_test", (PyCFunction)PyValueTest, METH_VARARGS | METH_KEYWORDS, {"value_test", (PyCFunction)PyValueTest, METH_VARARGS | METH_KEYWORDS,
"value_test(arg: str, change: float = None, absolute: float = None)\n" "value_test(arg: str, change: float = None, absolute: float = None)\n"
" -> float\n" " -> float\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"has_user_mods", PyHasUserMods, METH_VARARGS, {"has_user_mods", PyHasUserMods, METH_VARARGS,
"has_user_mods() -> bool\n" "has_user_mods() -> bool\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Returns whether the system varies from default configuration\n" "Returns whether the system varies from default configuration\n"
"(by user mods, etc)"}, "(by user mods, etc)"},
{"has_user_run_commands", PyHasUserRunCommands, METH_VARARGS, {"has_user_run_commands", PyHasUserRunCommands, METH_VARARGS,
"has_user_run_commands() -> bool\n" "has_user_run_commands() -> bool\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"get_idle_time", PyGetIdleTime, METH_VARARGS, {"get_idle_time", PyGetIdleTime, METH_VARARGS,
"get_idle_time() -> int\n" "get_idle_time() -> int\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Returns the amount of time since any game input has been processed"}, "Returns the amount of time since any game input has been processed"},
{"set_have_mods", PySetHaveMods, METH_VARARGS, {"set_have_mods", PySetHaveMods, METH_VARARGS,
"set_have_mods(have_mods: bool) -> None\n" "set_have_mods(have_mods: bool) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"ehv", (PyCFunction)PyExtraHashValue, METH_VARARGS | METH_KEYWORDS, {"ehv", (PyCFunction)PyExtraHashValue, METH_VARARGS | METH_KEYWORDS,
"ehv() -> None\n" "ehv() -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"get_thread_name", (PyCFunction)PyGetThreadName, {"get_thread_name", (PyCFunction)PyGetThreadName,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_thread_name() -> str\n" "get_thread_name() -> str\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Returns the name of the current thread.\n" "Returns the name of the current thread.\n"
"This may vary depending on platform and should not be used in logic;\n" "This may vary depending on platform and should not be used in logic;\n"
"only for debugging."}, "only for debugging."},
{"set_thread_name", (PyCFunction)PySetThreadName, {"set_thread_name", (PyCFunction)PySetThreadName,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"set_thread_name(name: str) -> None\n" "set_thread_name(name: str) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Sets the name of the current thread (on platforms where this is\n" "Sets the name of the current thread (on platforms where this is\n"
"available). Thread names are only for debugging and should not be\n" "available). Thread names are only for debugging and should not be\n"
"used in logic, as naming behavior can vary across platforms.\n"}, "used in logic, as naming behavior can vary across platforms.\n"},
{"in_game_thread", (PyCFunction)PyInGameThread, {"in_game_thread", (PyCFunction)PyInGameThread,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"in_game_thread() -> bool\n" "in_game_thread() -> bool\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Returns whether or not the current thread is the game thread."}, "Returns whether or not the current thread is the game thread."},
{"request_permission", (PyCFunction)PyRequestPermission, {"request_permission", (PyCFunction)PyRequestPermission,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"request_permission(permission: ba.Permission) -> None\n" "request_permission(permission: ba.Permission) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"have_permission", (PyCFunction)PyHavePermission, {"have_permission", (PyCFunction)PyHavePermission,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"have_permission(permission: ba.Permission) -> bool\n" "have_permission(permission: ba.Permission) -> bool\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"is_running_on_fire_tv", PyIsRunningOnFireTV, METH_VARARGS, {"is_running_on_fire_tv", PyIsRunningOnFireTV, METH_VARARGS,
"is_running_on_fire_tv() -> bool\n" "is_running_on_fire_tv() -> bool\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"is_running_on_ouya", PyIsRunningOnOuya, METH_VARARGS, {"is_running_on_ouya", PyIsRunningOnOuya, METH_VARARGS,
"is_running_on_ouya() -> bool\n" "is_running_on_ouya() -> bool\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"setup_sigint", (PyCFunction)PySetUpSigInt, METH_NOARGS, {"setup_sigint", (PyCFunction)PySetUpSigInt, METH_NOARGS,
"setup_sigint() -> None\n" "setup_sigint() -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
};
{nullptr, nullptr, 0, nullptr}}; }
#pragma clang diagnostic pop #pragma clang diagnostic pop

View File

@ -3,14 +3,16 @@
#ifndef BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_SYSTEM_H_ #ifndef BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_SYSTEM_H_
#define BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_SYSTEM_H_ #define BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_SYSTEM_H_
#include "ballistica/python/python_sys.h" #include <vector>
#include "ballistica/ballistica.h"
namespace ballistica { namespace ballistica {
/// System related individual python methods for our module. /// System related individual python methods for our module.
class PythonMethodsSystem { class PythonMethodsSystem {
public: public:
static PyMethodDef methods_def[]; static auto GetMethods() -> std::vector<PyMethodDef>;
}; };
} // namespace ballistica } // namespace ballistica

View File

@ -12,6 +12,7 @@
#include "ballistica/game/game.h" #include "ballistica/game/game.h"
#include "ballistica/input/input.h" #include "ballistica/input/input.h"
#include "ballistica/python/python.h" #include "ballistica/python/python.h"
#include "ballistica/python/python_sys.h"
#include "ballistica/ui/root_ui.h" #include "ballistica/ui/root_ui.h"
#include "ballistica/ui/ui.h" #include "ballistica/ui/ui.h"
#include "ballistica/ui/widget/button_widget.h" #include "ballistica/ui/widget/button_widget.h"
@ -2295,441 +2296,454 @@ auto PyIsPartyIconVisible(PyObject* self, PyObject* args, PyObject* keywds)
BA_PYTHON_CATCH; BA_PYTHON_CATCH;
} }
PyMethodDef PythonMethodsUI::methods_def[] = { auto PythonMethodsUI::GetMethods() -> std::vector<PyMethodDef> {
{"is_party_icon_visible", (PyCFunction)PyIsPartyIconVisible, return {
METH_VARARGS | METH_KEYWORDS, {"is_party_icon_visible", (PyCFunction)PyIsPartyIconVisible,
"is_party_icon_visible() -> bool\n" METH_VARARGS | METH_KEYWORDS,
"\n" "is_party_icon_visible() -> bool\n"
"(internal)"}, "\n"
"(internal)"},
{"console_print", PyConsolePrint, METH_VARARGS, {"console_print", PyConsolePrint, METH_VARARGS,
"console_print(*args: Any) -> None\n" "console_print(*args: Any) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Print the provided args to the game console (using str()).\n" "Print the provided args to the game console (using str()).\n"
"For most debugging/info purposes you should just use Python's standard\n" "For most debugging/info purposes you should just use Python's "
"print, which will show up in the game console as well."}, "standard\n"
"print, which will show up in the game console as well."},
{"open_dir_externally", (PyCFunction)PyOpenDirExternally, {"open_dir_externally", (PyCFunction)PyOpenDirExternally,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"open_dir_externally(path: str) -> None\n" "open_dir_externally(path: str) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Open the provided dir in the default external app."}, "Open the provided dir in the default external app."},
{"open_file_externally", (PyCFunction)PyOpenFileExternally, {"open_file_externally", (PyCFunction)PyOpenFileExternally,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"open_file_externally(path: str) -> None\n" "open_file_externally(path: str) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Open the provided file in the default external app."}, "Open the provided file in the default external app."},
{"open_url", (PyCFunction)PyOpenURL, METH_VARARGS | METH_KEYWORDS, {"open_url", (PyCFunction)PyOpenURL, METH_VARARGS | METH_KEYWORDS,
"open_url(address: str) -> None\n" "open_url(address: str) -> None\n"
"\n" "\n"
"Open a provided URL.\n" "Open a provided URL.\n"
"\n" "\n"
"Category: General Utility Functions\n" "Category: General Utility Functions\n"
"\n" "\n"
"Open the provided url in a web-browser, or display the URL\n" "Open the provided url in a web-browser, or display the URL\n"
"string in a window if that isn't possible.\n"}, "string in a window if that isn't possible.\n"},
{"back_press", (PyCFunction)PyBackPress, METH_VARARGS | METH_KEYWORDS, {"back_press", (PyCFunction)PyBackPress, METH_VARARGS | METH_KEYWORDS,
"back_press() -> None\n" "back_press() -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"has_video_ads", (PyCFunction)PyHasVideoAds, METH_VARARGS | METH_KEYWORDS, {"has_video_ads", (PyCFunction)PyHasVideoAds,
"has_video_ads() -> bool\n" METH_VARARGS | METH_KEYWORDS,
"\n" "has_video_ads() -> bool\n"
"(internal)"}, "\n"
"(internal)"},
{"can_show_ad", (PyCFunction)PyCanShowAd, METH_VARARGS | METH_KEYWORDS, {"can_show_ad", (PyCFunction)PyCanShowAd, METH_VARARGS | METH_KEYWORDS,
"can_show_ad() -> bool\n" "can_show_ad() -> bool\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"have_incentivized_ad", (PyCFunction)PyHaveIncentivizedAd, {"have_incentivized_ad", (PyCFunction)PyHaveIncentivizedAd,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"have_incentivized_ad() -> bool\n" "have_incentivized_ad() -> bool\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"get_special_widget", (PyCFunction)PyGetSpecialWidget, {"get_special_widget", (PyCFunction)PyGetSpecialWidget,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_special_widget(name: str) -> Widget\n" "get_special_widget(name: str) -> Widget\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"set_party_window_open", (PyCFunction)PySetPartyWindowOpen, {"set_party_window_open", (PyCFunction)PySetPartyWindowOpen,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"set_party_window_open(value: bool) -> None\n" "set_party_window_open(value: bool) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"get_chat_messages", (PyCFunction)PyGetChatMessages, {"get_chat_messages", (PyCFunction)PyGetChatMessages,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"get_chat_messages() -> List[str]\n" "get_chat_messages() -> List[str]\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"chatmessage", (PyCFunction)PyChatMessage, METH_VARARGS | METH_KEYWORDS, {"chatmessage", (PyCFunction)PyChatMessage, METH_VARARGS | METH_KEYWORDS,
"chatmessage(message: Union[str, ba.Lstr],\n" "chatmessage(message: Union[str, ba.Lstr],\n"
" clients: Sequence[int] = None,\n" " clients: Sequence[int] = None,\n"
" sender_override: str = None) -> None\n" " sender_override: str = None) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"set_party_icon_always_visible", (PyCFunction)PySetPartyIconAlwaysVisible, {"set_party_icon_always_visible",
METH_VARARGS | METH_KEYWORDS, (PyCFunction)PySetPartyIconAlwaysVisible, METH_VARARGS | METH_KEYWORDS,
"set_party_icon_always_visible(value: bool) -> None\n" "set_party_icon_always_visible(value: bool) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"show_invites_ui", (PyCFunction)PyShowInvitesUI, {"show_invites_ui", (PyCFunction)PyShowInvitesUI,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"show_invites_ui() -> None\n" "show_invites_ui() -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Category: General Utility Functions"}, "Category: General Utility Functions"},
{"show_progress_bar", (PyCFunction)PyShowProgressBar, {"show_progress_bar", (PyCFunction)PyShowProgressBar,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"show_progress_bar() -> None\n" "show_progress_bar() -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Category: General Utility Functions"}, "Category: General Utility Functions"},
{"show_app_invite", (PyCFunction)PyShowAppInvite, {"show_app_invite", (PyCFunction)PyShowAppInvite,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"show_app_invite(title: Union[str, ba.Lstr],\n" "show_app_invite(title: Union[str, ba.Lstr],\n"
" message: Union[str, ba.Lstr],\n" " message: Union[str, ba.Lstr],\n"
" code: str) -> None\n" " code: str) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Category: General Utility Functions"}, "Category: General Utility Functions"},
{"show_ad", (PyCFunction)PyShowAd, METH_VARARGS | METH_KEYWORDS, {"show_ad", (PyCFunction)PyShowAd, METH_VARARGS | METH_KEYWORDS,
"show_ad(purpose: str, on_completion_call: Callable[[], None] = None)\n" "show_ad(purpose: str, on_completion_call: Callable[[], None] = None)\n"
" -> None\n" " -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"show_ad_2", (PyCFunction)PyShowAd2, METH_VARARGS | METH_KEYWORDS, {"show_ad_2", (PyCFunction)PyShowAd2, METH_VARARGS | METH_KEYWORDS,
"show_ad_2(purpose: str,\n" "show_ad_2(purpose: str,\n"
" on_completion_call: Callable[[bool], None] = None)\n" " on_completion_call: Callable[[bool], None] = None)\n"
" -> None\n" " -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"fade_screen", (PyCFunction)PyFadeScreen, METH_VARARGS | METH_KEYWORDS, {"fade_screen", (PyCFunction)PyFadeScreen, METH_VARARGS | METH_KEYWORDS,
"fade_screen(to: int = 0, time: float = 0.25,\n" "fade_screen(to: int = 0, time: float = 0.25,\n"
" endcall: Optional[Callable[[], None]] = None) -> None\n" " endcall: Optional[Callable[[], None]] = None) -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Fade the local game screen in our out from black over a duration of\n" "Fade the local game screen in our out from black over a duration of\n"
"time. if \"to\" is 0, the screen will fade out to black. Otherwise it\n" "time. if \"to\" is 0, the screen will fade out to black. Otherwise "
"will fade in from black. If endcall is provided, it will be run after a\n" "it\n"
"completely faded frame is drawn."}, "will fade in from black. If endcall is provided, it will be run after "
"a\n"
"completely faded frame is drawn."},
{"show_online_score_ui", (PyCFunction)PyShowOnlineScoreUI, {"show_online_score_ui", (PyCFunction)PyShowOnlineScoreUI,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"show_online_score_ui(show: str = 'general', game: str = None,\n" "show_online_score_ui(show: str = 'general', game: str = None,\n"
" game_version: str = None) -> None\n" " game_version: str = None) -> None\n"
"\n" "\n"
"(internal)"}, "(internal)"},
{"focus_window", (PyCFunction)PyFocusWindow, METH_VARARGS | METH_KEYWORDS, {"focus_window", (PyCFunction)PyFocusWindow, METH_VARARGS | METH_KEYWORDS,
"focus_window() -> None\n" "focus_window() -> None\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"A workaround for some unintentional backgrounding that occurs on mac"}, "A workaround for some unintentional backgrounding that occurs on mac"},
{"uibounds", (PyCFunction)PyUIBounds, METH_VARARGS | METH_KEYWORDS, {"uibounds", (PyCFunction)PyUIBounds, METH_VARARGS | METH_KEYWORDS,
"uibounds() -> Tuple[float, float, float, float]\n" "uibounds() -> Tuple[float, float, float, float]\n"
"\n" "\n"
"(internal)\n" "(internal)\n"
"\n" "\n"
"Returns a tuple of 4 values: (x-min, x-max, y-min, y-max) representing\n" "Returns a tuple of 4 values: (x-min, x-max, y-min, y-max) "
"the range of values that can be plugged into a root level\n" "representing\n"
"ba.ContainerWidget's stack_offset value while guaranteeing that its\n" "the range of values that can be plugged into a root level\n"
"center remains onscreen.\n"}, "ba.ContainerWidget's stack_offset value while guaranteeing that its\n"
"center remains onscreen.\n"},
{"buttonwidget", (PyCFunction)PyButtonWidget, METH_VARARGS | METH_KEYWORDS, {"buttonwidget", (PyCFunction)PyButtonWidget,
"buttonwidget(edit: ba.Widget = None,\n" METH_VARARGS | METH_KEYWORDS,
" parent: ba.Widget = None,\n" "buttonwidget(edit: ba.Widget = None,\n"
" size: Sequence[float] = None,\n" " parent: ba.Widget = None,\n"
" position: Sequence[float] = None,\n" " size: Sequence[float] = None,\n"
" on_activate_call: Callable = None,\n" " position: Sequence[float] = None,\n"
" label: Union[str, ba.Lstr] = None,\n" " on_activate_call: Callable = None,\n"
" color: Sequence[float] = None,\n" " label: Union[str, ba.Lstr] = None,\n"
" down_widget: ba.Widget = None,\n" " color: Sequence[float] = None,\n"
" up_widget: ba.Widget = None,\n" " down_widget: ba.Widget = None,\n"
" left_widget: ba.Widget = None,\n" " up_widget: ba.Widget = None,\n"
" right_widget: ba.Widget = None,\n" " left_widget: ba.Widget = None,\n"
" texture: ba.Texture = None,\n" " right_widget: ba.Widget = None,\n"
" text_scale: float = None,\n" " texture: ba.Texture = None,\n"
" textcolor: Sequence[float] = None,\n" " text_scale: float = None,\n"
" enable_sound: bool = None,\n" " textcolor: Sequence[float] = None,\n"
" model_transparent: ba.Model = None,\n" " enable_sound: bool = None,\n"
" model_opaque: ba.Model = None,\n" " model_transparent: ba.Model = None,\n"
" repeat: bool = None,\n" " model_opaque: ba.Model = None,\n"
" scale: float = None,\n" " repeat: bool = None,\n"
" transition_delay: float = None,\n" " scale: float = None,\n"
" on_select_call: Callable = None,\n" " transition_delay: float = None,\n"
" button_type: str = None,\n" " on_select_call: Callable = None,\n"
" extra_touch_border_scale: float = None,\n" " button_type: str = None,\n"
" selectable: bool = None,\n" " extra_touch_border_scale: float = None,\n"
" show_buffer_top: float = None,\n" " selectable: bool = None,\n"
" icon: ba.Texture = None,\n" " show_buffer_top: float = None,\n"
" iconscale: float = None,\n" " icon: ba.Texture = None,\n"
" icon_tint: float = None,\n" " iconscale: float = None,\n"
" icon_color: Sequence[float] = None,\n" " icon_tint: float = None,\n"
" autoselect: bool = None,\n" " icon_color: Sequence[float] = None,\n"
" mask_texture: ba.Texture = None,\n" " autoselect: bool = None,\n"
" tint_texture: ba.Texture = None,\n" " mask_texture: ba.Texture = None,\n"
" tint_color: Sequence[float] = None,\n" " tint_texture: ba.Texture = None,\n"
" tint2_color: Sequence[float] = None,\n" " tint_color: Sequence[float] = None,\n"
" text_flatness: float = None,\n" " tint2_color: Sequence[float] = None,\n"
" text_res_scale: float = None,\n" " text_flatness: float = None,\n"
" enabled: bool = None) -> ba.Widget\n" " text_res_scale: float = None,\n"
"\n" " enabled: bool = None) -> ba.Widget\n"
"Create or edit a button widget.\n" "\n"
"\n" "Create or edit a button widget.\n"
"Category: User Interface Functions\n" "\n"
"\n" "Category: User Interface Functions\n"
"Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n" "\n"
"a new one is created and returned. Arguments that are not set to None\n" "Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n"
"are applied to the Widget."}, "a new one is created and returned. Arguments that are not set to None\n"
"are applied to the Widget."},
{"checkboxwidget", (PyCFunction)PyCheckBoxWidget, {"checkboxwidget", (PyCFunction)PyCheckBoxWidget,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"checkboxwidget(edit: ba.Widget = None,\n" "checkboxwidget(edit: ba.Widget = None,\n"
" parent: ba.Widget = None,\n" " parent: ba.Widget = None,\n"
" size: Sequence[float] = None,\n" " size: Sequence[float] = None,\n"
" position: Sequence[float] = None,\n" " position: Sequence[float] = None,\n"
" text: Union[ba.Lstr, str] = None,\n" " text: Union[ba.Lstr, str] = None,\n"
" value: bool = None,\n" " value: bool = None,\n"
" on_value_change_call: Callable[[bool], None] = None,\n" " on_value_change_call: Callable[[bool], None] = None,\n"
" on_select_call: Callable[[], None] = None,\n" " on_select_call: Callable[[], None] = None,\n"
" text_scale: float = None,\n" " text_scale: float = None,\n"
" textcolor: Sequence[float] = None,\n" " textcolor: Sequence[float] = None,\n"
" scale: float = None,\n" " scale: float = None,\n"
" is_radio_button: bool = None,\n" " is_radio_button: bool = None,\n"
" maxwidth: float = None,\n" " maxwidth: float = None,\n"
" autoselect: bool = None,\n" " autoselect: bool = None,\n"
" color: Sequence[float] = None) -> ba.Widget\n" " color: Sequence[float] = None) -> ba.Widget\n"
"\n" "\n"
"Create or edit a check-box widget.\n" "Create or edit a check-box widget.\n"
"\n" "\n"
"Category: User Interface Functions\n" "Category: User Interface Functions\n"
"\n" "\n"
"Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n" "Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n"
"a new one is created and returned. Arguments that are not set to None\n" "a new one is created and returned. Arguments that are not set to None\n"
"are applied to the Widget."}, "are applied to the Widget."},
{"imagewidget", (PyCFunction)PyImageWidget, METH_VARARGS | METH_KEYWORDS, {"imagewidget", (PyCFunction)PyImageWidget, METH_VARARGS | METH_KEYWORDS,
"imagewidget(edit: ba.Widget = None, parent: ba.Widget = None,\n" "imagewidget(edit: ba.Widget = None, parent: ba.Widget = None,\n"
" size: Sequence[float] = None, position: Sequence[float] = None,\n" " size: Sequence[float] = None, position: Sequence[float] = None,\n"
" color: Sequence[float] = None, texture: ba.Texture = None,\n" " color: Sequence[float] = None, texture: ba.Texture = None,\n"
" opacity: float = None, model_transparent: ba.Model = None,\n" " opacity: float = None, model_transparent: ba.Model = None,\n"
" model_opaque: ba.Model = None, has_alpha_channel: bool = True,\n" " model_opaque: ba.Model = None, has_alpha_channel: bool = True,\n"
" tint_texture: ba.Texture = None, tint_color: Sequence[float] = None,\n" " tint_texture: ba.Texture = None, tint_color: Sequence[float] = "
" transition_delay: float = None, draw_controller: ba.Widget = None,\n" "None,\n"
" tint2_color: Sequence[float] = None, tilt_scale: float = None,\n" " transition_delay: float = None, draw_controller: ba.Widget = None,\n"
" mask_texture: ba.Texture = None, radial_amount: float = None)\n" " tint2_color: Sequence[float] = None, tilt_scale: float = None,\n"
" -> ba.Widget\n" " mask_texture: ba.Texture = None, radial_amount: float = None)\n"
"\n" " -> ba.Widget\n"
"Create or edit an image widget.\n" "\n"
"\n" "Create or edit an image widget.\n"
"Category: User Interface Functions\n" "\n"
"\n" "Category: User Interface Functions\n"
"Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n" "\n"
"a new one is created and returned. Arguments that are not set to None\n" "Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n"
"are applied to the Widget."}, "a new one is created and returned. Arguments that are not set to None\n"
"are applied to the Widget."},
{"columnwidget", (PyCFunction)PyColumnWidget, METH_VARARGS | METH_KEYWORDS, {"columnwidget", (PyCFunction)PyColumnWidget,
"columnwidget(edit: ba.Widget = None,\n" METH_VARARGS | METH_KEYWORDS,
" parent: ba.Widget = None,\n" "columnwidget(edit: ba.Widget = None,\n"
" size: Sequence[float] = None,\n" " parent: ba.Widget = None,\n"
" position: Sequence[float] = None,\n" " size: Sequence[float] = None,\n"
" background: bool = None,\n" " position: Sequence[float] = None,\n"
" selected_child: ba.Widget = None,\n" " background: bool = None,\n"
" visible_child: ba.Widget = None,\n" " selected_child: ba.Widget = None,\n"
" single_depth: bool = None,\n" " visible_child: ba.Widget = None,\n"
" print_list_exit_instructions: bool = None,\n" " single_depth: bool = None,\n"
" left_border: float = None,\n" " print_list_exit_instructions: bool = None,\n"
" top_border: float = None,\n" " left_border: float = None,\n"
" bottom_border: float = None,\n" " top_border: float = None,\n"
" selection_loops_to_parent: bool = None,\n" " bottom_border: float = None,\n"
" border: float = None,\n" " selection_loops_to_parent: bool = None,\n"
" margin: float = None,\n" " border: float = None,\n"
" claims_left_right: bool = None,\n" " margin: float = None,\n"
" claims_tab: bool = None) -> ba.Widget\n" " claims_left_right: bool = None,\n"
"\n" " claims_tab: bool = None) -> ba.Widget\n"
"Create or edit a column widget.\n" "\n"
"\n" "Create or edit a column widget.\n"
"Category: User Interface Functions\n" "\n"
"\n" "Category: User Interface Functions\n"
"Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n" "\n"
"a new one is created and returned. Arguments that are not set to None\n" "Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n"
"are applied to the Widget."}, "a new one is created and returned. Arguments that are not set to None\n"
"are applied to the Widget."},
{"containerwidget", (PyCFunction)PyContainerWidget, {"containerwidget", (PyCFunction)PyContainerWidget,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"containerwidget(edit: ba.Widget = None,\n" "containerwidget(edit: ba.Widget = None,\n"
" parent: ba.Widget = None,\n" " parent: ba.Widget = None,\n"
" size: Sequence[float] = None,\n" " size: Sequence[float] = None,\n"
" position: Sequence[float] = None,\n" " position: Sequence[float] = None,\n"
" background: bool = None,\n" " background: bool = None,\n"
" selected_child: ba.Widget = None,\n" " selected_child: ba.Widget = None,\n"
" transition: str = None,\n" " transition: str = None,\n"
" cancel_button: ba.Widget = None,\n" " cancel_button: ba.Widget = None,\n"
" start_button: ba.Widget = None,\n" " start_button: ba.Widget = None,\n"
" root_selectable: bool = None,\n" " root_selectable: bool = None,\n"
" on_activate_call: Callable[[], None] = None,\n" " on_activate_call: Callable[[], None] = None,\n"
" claims_left_right: bool = None,\n" " claims_left_right: bool = None,\n"
" claims_tab: bool = None,\n" " claims_tab: bool = None,\n"
" selection_loops: bool = None,\n" " selection_loops: bool = None,\n"
" selection_loops_to_parent: bool = None,\n" " selection_loops_to_parent: bool = None,\n"
" scale: float = None,\n" " scale: float = None,\n"
" on_outside_click_call: Callable[[], None] = None,\n" " on_outside_click_call: Callable[[], None] = None,\n"
" single_depth: bool = None,\n" " single_depth: bool = None,\n"
" visible_child: ba.Widget = None,\n" " visible_child: ba.Widget = None,\n"
" stack_offset: Sequence[float] = None,\n" " stack_offset: Sequence[float] = None,\n"
" color: Sequence[float] = None,\n" " color: Sequence[float] = None,\n"
" on_cancel_call: Callable[[], None] = None,\n" " on_cancel_call: Callable[[], None] = None,\n"
" print_list_exit_instructions: bool = None,\n" " print_list_exit_instructions: bool = None,\n"
" click_activate: bool = None,\n" " click_activate: bool = None,\n"
" always_highlight: bool = None,\n" " always_highlight: bool = None,\n"
" selectable: bool = None,\n" " selectable: bool = None,\n"
" scale_origin_stack_offset: Sequence[float] = None,\n" " scale_origin_stack_offset: Sequence[float] = None,\n"
" toolbar_visibility: str = None,\n" " toolbar_visibility: str = None,\n"
" on_select_call: Callable[[], None] = None,\n" " on_select_call: Callable[[], None] = None,\n"
" claim_outside_clicks: bool = None,\n" " claim_outside_clicks: bool = None,\n"
" claims_up_down: bool = None) -> ba.Widget\n" " claims_up_down: bool = None) -> ba.Widget\n"
"\n" "\n"
"Create or edit a container widget.\n" "Create or edit a container widget.\n"
"\n" "\n"
"Category: User Interface Functions\n" "Category: User Interface Functions\n"
"\n" "\n"
"Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n" "Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n"
"a new one is created and returned. Arguments that are not set to None\n" "a new one is created and returned. Arguments that are not set to None\n"
"are applied to the Widget."}, "are applied to the Widget."},
{"rowwidget", (PyCFunction)PyRowWidget, METH_VARARGS | METH_KEYWORDS, {"rowwidget", (PyCFunction)PyRowWidget, METH_VARARGS | METH_KEYWORDS,
"rowwidget(edit: Widget = None, parent: Widget = None,\n" "rowwidget(edit: Widget = None, parent: Widget = None,\n"
" size: Sequence[float] = None,\n" " size: Sequence[float] = None,\n"
" position: Sequence[float] = None,\n" " position: Sequence[float] = None,\n"
" background: bool = None, selected_child: Widget = None,\n" " background: bool = None, selected_child: Widget = None,\n"
" visible_child: Widget = None,\n" " visible_child: Widget = None,\n"
" claims_left_right: bool = None,\n" " claims_left_right: bool = None,\n"
" claims_tab: bool = None,\n" " claims_tab: bool = None,\n"
" selection_loops_to_parent: bool = None) -> Widget\n" " selection_loops_to_parent: bool = None) -> Widget\n"
"\n" "\n"
"Create or edit a row widget.\n" "Create or edit a row widget.\n"
"\n" "\n"
"Category: User Interface Functions\n" "Category: User Interface Functions\n"
"\n" "\n"
"Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n" "Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n"
"a new one is created and returned. Arguments that are not set to None\n" "a new one is created and returned. Arguments that are not set to None\n"
"are applied to the Widget."}, "are applied to the Widget."},
{"scrollwidget", (PyCFunction)PyScrollWidget, METH_VARARGS | METH_KEYWORDS, {"scrollwidget", (PyCFunction)PyScrollWidget,
"scrollwidget(edit: ba.Widget = None, parent: ba.Widget = None,\n" METH_VARARGS | METH_KEYWORDS,
" size: Sequence[float] = None, position: Sequence[float] = None,\n" "scrollwidget(edit: ba.Widget = None, parent: ba.Widget = None,\n"
" background: bool = None, selected_child: ba.Widget = None,\n" " size: Sequence[float] = None, position: Sequence[float] = None,\n"
" capture_arrows: bool = False, on_select_call: Callable = None,\n" " background: bool = None, selected_child: ba.Widget = None,\n"
" center_small_content: bool = None, color: Sequence[float] = None,\n" " capture_arrows: bool = False, on_select_call: Callable = None,\n"
" highlight: bool = None, border_opacity: float = None,\n" " center_small_content: bool = None, color: Sequence[float] = None,\n"
" simple_culling_v: float = None,\n" " highlight: bool = None, border_opacity: float = None,\n"
" selection_loops_to_parent: bool = None,\n" " simple_culling_v: float = None,\n"
" claims_left_right: bool = None,\n" " selection_loops_to_parent: bool = None,\n"
" claims_up_down: bool = None,\n" " claims_left_right: bool = None,\n"
" claims_tab: bool = None,\n" " claims_up_down: bool = None,\n"
" autoselect: bool = None) -> ba.Widget\n" " claims_tab: bool = None,\n"
"\n" " autoselect: bool = None) -> ba.Widget\n"
"Create or edit a scroll widget.\n" "\n"
"\n" "Create or edit a scroll widget.\n"
"Category: User Interface Functions\n" "\n"
"\n" "Category: User Interface Functions\n"
"Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n" "\n"
"a new one is created and returned. Arguments that are not set to None\n" "Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n"
"are applied to the Widget."}, "a new one is created and returned. Arguments that are not set to None\n"
"are applied to the Widget."},
{"hscrollwidget", (PyCFunction)PyHScrollWidget, {"hscrollwidget", (PyCFunction)PyHScrollWidget,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"hscrollwidget(edit: ba.Widget = None, parent: ba.Widget = None,\n" "hscrollwidget(edit: ba.Widget = None, parent: ba.Widget = None,\n"
" size: Sequence[float] = None, position: Sequence[float] = None,\n" " size: Sequence[float] = None, position: Sequence[float] = None,\n"
" background: bool = None, selected_child: ba.Widget = None,\n" " background: bool = None, selected_child: ba.Widget = None,\n"
" capture_arrows: bool = None,\n" " capture_arrows: bool = None,\n"
" on_select_call: Callable[[], None] = None,\n" " on_select_call: Callable[[], None] = None,\n"
" center_small_content: bool = None, color: Sequence[float] = None,\n" " center_small_content: bool = None, color: Sequence[float] = None,\n"
" highlight: bool = None, border_opacity: float = None,\n" " highlight: bool = None, border_opacity: float = None,\n"
" simple_culling_h: float = None,\n" " simple_culling_h: float = None,\n"
" claims_left_right: bool = None,\n" " claims_left_right: bool = None,\n"
" claims_up_down: bool = None,\n" " claims_up_down: bool = None,\n"
" claims_tab: bool = None) -> ba.Widget\n" " claims_tab: bool = None) -> ba.Widget\n"
"\n" "\n"
"Create or edit a horizontal scroll widget.\n" "Create or edit a horizontal scroll widget.\n"
"\n" "\n"
"Category: User Interface Functions\n" "Category: User Interface Functions\n"
"\n" "\n"
"Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n" "Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n"
"a new one is created and returned. Arguments that are not set to None\n" "a new one is created and returned. Arguments that are not set to None\n"
"are applied to the Widget."}, "are applied to the Widget."},
{"textwidget", (PyCFunction)PyTextWidget, METH_VARARGS | METH_KEYWORDS, {"textwidget", (PyCFunction)PyTextWidget, METH_VARARGS | METH_KEYWORDS,
"textwidget(edit: Widget = None, parent: Widget = None,\n" "textwidget(edit: Widget = None, parent: Widget = None,\n"
" size: Sequence[float] = None, position: Sequence[float] = None,\n" " size: Sequence[float] = None, position: Sequence[float] = None,\n"
" text: Union[str, ba.Lstr] = None, v_align: str = None,\n" " text: Union[str, ba.Lstr] = None, v_align: str = None,\n"
" h_align: str = None, editable: bool = None, padding: float = None,\n" " h_align: str = None, editable: bool = None, padding: float = None,\n"
" on_return_press_call: Callable[[], None] = None,\n" " on_return_press_call: Callable[[], None] = None,\n"
" on_activate_call: Callable[[], None] = None,\n" " on_activate_call: Callable[[], None] = None,\n"
" selectable: bool = None, query: Widget = None, max_chars: int = None,\n" " selectable: bool = None, query: Widget = None, max_chars: int = "
" color: Sequence[float] = None, click_activate: bool = None,\n" "None,\n"
" on_select_call: Callable[[], None] = None,\n" " color: Sequence[float] = None, click_activate: bool = None,\n"
" always_highlight: bool = None, draw_controller: Widget = None,\n" " on_select_call: Callable[[], None] = None,\n"
" scale: float = None, corner_scale: float = None,\n" " always_highlight: bool = None, draw_controller: Widget = None,\n"
" description: Union[str, ba.Lstr] = None,\n" " scale: float = None, corner_scale: float = None,\n"
" transition_delay: float = None, maxwidth: float = None,\n" " description: Union[str, ba.Lstr] = None,\n"
" max_height: float = None, flatness: float = None,\n" " transition_delay: float = None, maxwidth: float = None,\n"
" shadow: float = None, autoselect: bool = None, rotate: float = None,\n" " max_height: float = None, flatness: float = None,\n"
" enabled: bool = None, force_internal_editing: bool = None,\n" " shadow: float = None, autoselect: bool = None, rotate: float = "
" always_show_carat: bool = None, big: bool = None,\n" "None,\n"
" extra_touch_border_scale: float = None, res_scale: float = None)\n" " enabled: bool = None, force_internal_editing: bool = None,\n"
" -> Widget\n" " always_show_carat: bool = None, big: bool = None,\n"
"\n" " extra_touch_border_scale: float = None, res_scale: float = None)\n"
"Create or edit a text widget.\n" " -> Widget\n"
"\n" "\n"
"Category: User Interface Functions\n" "Create or edit a text widget.\n"
"\n" "\n"
"Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n" "Category: User Interface Functions\n"
"a new one is created and returned. Arguments that are not set to None\n" "\n"
"are applied to the Widget."}, "Pass a valid existing ba.Widget as 'edit' to modify it; otherwise\n"
"a new one is created and returned. Arguments that are not set to None\n"
"are applied to the Widget."},
{"widget", (PyCFunction)PyWidgetCall, METH_VARARGS | METH_KEYWORDS, {"widget", (PyCFunction)PyWidgetCall, METH_VARARGS | METH_KEYWORDS,
"widget(edit: ba.Widget = None, up_widget: ba.Widget = None,\n" "widget(edit: ba.Widget = None, up_widget: ba.Widget = None,\n"
" down_widget: ba.Widget = None, left_widget: ba.Widget = None,\n" " down_widget: ba.Widget = None, left_widget: ba.Widget = None,\n"
" right_widget: ba.Widget = None, show_buffer_top: float = None,\n" " right_widget: ba.Widget = None, show_buffer_top: float = None,\n"
" show_buffer_bottom: float = None, show_buffer_left: float = None,\n" " show_buffer_bottom: float = None, show_buffer_left: float = None,\n"
" show_buffer_right: float = None, autoselect: bool = None) -> None\n" " show_buffer_right: float = None, autoselect: bool = None) -> None\n"
"\n" "\n"
"Edit common attributes of any widget.\n" "Edit common attributes of any widget.\n"
"\n" "\n"
"Category: User Interface Functions\n" "Category: User Interface Functions\n"
"\n" "\n"
"Unlike other UI calls, this can only be used to edit, not to create.\n"}, "Unlike other UI calls, this can only be used to edit, not to "
"create.\n"},
{nullptr, nullptr, 0, nullptr}}; };
}
#pragma clang diagnostic pop #pragma clang diagnostic pop

View File

@ -3,14 +3,16 @@
#ifndef BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_UI_H_ #ifndef BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_UI_H_
#define BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_UI_H_ #define BALLISTICA_PYTHON_METHODS_PYTHON_METHODS_UI_H_
#include "ballistica/python/python_sys.h" #include <vector>
#include "ballistica/ballistica.h"
namespace ballistica { namespace ballistica {
/// UI related individual python methods for our module. /// UI related individual python methods for our module.
class PythonMethodsUI { class PythonMethodsUI {
public: public:
static PyMethodDef methods_def[]; static auto GetMethods() -> std::vector<PyMethodDef>;
}; };
} // namespace ballistica } // namespace ballistica

View File

@ -25,6 +25,7 @@
#include "ballistica/python/class/python_class_activity_data.h" #include "ballistica/python/class/python_class_activity_data.h"
#include "ballistica/python/class/python_class_collide_model.h" #include "ballistica/python/class/python_class_collide_model.h"
#include "ballistica/python/class/python_class_context.h" #include "ballistica/python/class/python_class_context.h"
#include "ballistica/python/class/python_class_context_call.h"
#include "ballistica/python/class/python_class_data.h" #include "ballistica/python/class/python_class_data.h"
#include "ballistica/python/class/python_class_input_device.h" #include "ballistica/python/class/python_class_input_device.h"
#include "ballistica/python/class/python_class_material.h" #include "ballistica/python/class/python_class_material.h"
@ -34,8 +35,16 @@
#include "ballistica/python/class/python_class_session_player.h" #include "ballistica/python/class/python_class_session_player.h"
#include "ballistica/python/class/python_class_sound.h" #include "ballistica/python/class/python_class_sound.h"
#include "ballistica/python/class/python_class_texture.h" #include "ballistica/python/class/python_class_texture.h"
#include "ballistica/python/class/python_class_timer.h"
#include "ballistica/python/class/python_class_vec3.h" #include "ballistica/python/class/python_class_vec3.h"
#include "ballistica/python/class/python_class_widget.h" #include "ballistica/python/class/python_class_widget.h"
#include "ballistica/python/methods/python_methods_app.h"
#include "ballistica/python/methods/python_methods_gameplay.h"
#include "ballistica/python/methods/python_methods_graphics.h"
#include "ballistica/python/methods/python_methods_input.h"
#include "ballistica/python/methods/python_methods_media.h"
#include "ballistica/python/methods/python_methods_system.h"
#include "ballistica/python/methods/python_methods_ui.h"
#include "ballistica/python/python_command.h" #include "ballistica/python/python_command.h"
#include "ballistica/python/python_context_call_runnable.h" #include "ballistica/python/python_context_call_runnable.h"
#include "ballistica/scene/node/node_attribute.h" #include "ballistica/scene/node/node_attribute.h"
@ -928,7 +937,7 @@ void Python::Reset(bool do_init) {
// Set up system paths on our embedded platforms. // Set up system paths on our embedded platforms.
SetupPythonHome(); SetupPythonHome();
AppInternalInitModule(); AppInternalInitPythonModule();
Py_Initialize(); Py_Initialize();
@ -971,7 +980,7 @@ void Python::Reset(bool do_init) {
// Import and grab all the Python stuff we use. // Import and grab all the Python stuff we use.
#include "generated/ballistica/binding.inc" #include "generated/ballistica/binding.inc"
AppInternalPythonInit2(); AppInternalPythonPostInit();
// Alright I guess let's pull ba in to main, since pretty // Alright I guess let's pull ba in to main, since pretty
// much all interactive commands will be using it. // much all interactive commands will be using it.
@ -997,6 +1006,60 @@ void Python::Reset(bool do_init) {
} }
} }
auto Python::GetModuleMethods() -> std::vector<PyMethodDef> {
std::vector<PyMethodDef> all_methods;
for (auto&& methods : {
PythonMethodsUI::GetMethods(),
PythonMethodsInput::GetMethods(),
PythonMethodsApp::GetMethods(),
PythonMethodsGameplay::GetMethods(),
PythonMethodsGraphics::GetMethods(),
PythonMethodsMedia::GetMethods(),
PythonMethodsSystem::GetMethods(),
}) {
all_methods.insert(all_methods.end(), methods.begin(), methods.end());
}
return all_methods;
}
template <class T>
auto AddClass(PyObject* module) -> PyObject* {
T::SetupType(&T::type_obj);
BA_PRECONDITION(PyType_Ready(&T::type_obj) == 0);
Py_INCREF(&T::type_obj);
int r = PyModule_AddObject(module, T::type_name(),
reinterpret_cast<PyObject*>(&T::type_obj));
BA_PRECONDITION(r == 0);
return reinterpret_cast<PyObject*>(&T::type_obj);
}
auto Python::InitModuleClasses(PyObject* module) -> void {
// Init our classes and add them to our module.
AddClass<PythonClassNode>(module);
AddClass<PythonClassWidget>(module);
AddClass<PythonClassSessionPlayer>(module);
AddClass<PythonClassSessionData>(module);
AddClass<PythonClassActivityData>(module);
AddClass<PythonClassContext>(module);
AddClass<PythonClassContextCall>(module);
AddClass<PythonClassInputDevice>(module);
AddClass<PythonClassTimer>(module);
AddClass<PythonClassMaterial>(module);
AddClass<PythonClassTexture>(module);
AddClass<PythonClassSound>(module);
AddClass<PythonClassData>(module);
AddClass<PythonClassModel>(module);
AddClass<PythonClassCollideModel>(module);
PyObject* vec3 = AddClass<PythonClassVec3>(module);
// Register our vec3 as an abc.Sequence
auto register_call =
PythonRef(PyImport_ImportModule("collections.abc"), PythonRef::kSteal)
.GetAttr("Sequence")
.GetAttr("register");
PythonRef args(Py_BuildValue("(O)", vec3), PythonRef::kSteal);
BA_PRECONDITION(register_call.Call(args).exists());
}
void Python::PushObjCall(ObjID obj_id) { void Python::PushObjCall(ObjID obj_id) {
g_game->PushCall([obj_id] { g_game->PushCall([obj_id] {
ScopedSetContext cp(g_game->GetUIContext()); ScopedSetContext cp(g_game->GetUIContext());

View File

@ -80,6 +80,10 @@ class Python {
void Reset(bool init = true); void Reset(bool init = true);
/// Add classes to the newly created ba module.
static auto InitModuleClasses(PyObject* module) -> void;
static auto GetModuleMethods() -> std::vector<PyMethodDef>;
auto GetContextBaseString() -> std::string; auto GetContextBaseString() -> std::string;
auto GetControllerValue(InputDevice* input_device, auto GetControllerValue(InputDevice* input_device,
const std::string& value_name) -> int; const std::string& value_name) -> int;