mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-19 21:37:57 +08:00
work on user-defined dev-console tabs
This commit is contained in:
parent
50f91361f4
commit
f25f31cce4
60
.efrocachemap
generated
60
.efrocachemap
generated
@ -4056,26 +4056,26 @@
|
||||
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
|
||||
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
|
||||
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "fdcef1a7c77ad3cb23d7339fb1be2bf0",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "da17b5cc5f83bed3a0df7d238ba52d62",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "f550cb252d584f5ad7a100d9bb65d07a",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "6ce0af256949280a4820b96388e9d33c",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "65d75cd5909aa24e5c554c39d8aa7425",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "7e2267b47b1075da9737005d3d6821a3",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "6429f3fbddc8f71a29588486c9e0135f",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "48e5146f5a93e62d0c42d902d928f123",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "497c7b622b63b47268a4e55f439b00b1",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "2d54d79c942f48f6de4f07496b5c7d9c",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "0959c5af017a58f487d353d56cfb3fc5",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "ce4e095b7f36cf0f1c5d39bd196087a6",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "3afafa7c2b660d60c740bc152898f1b8",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "db0e1929b4fcfc55295fd401a8c19e3a",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "78c06393fc28e1d5ba8dac8ab97ba07e",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "fbada26a44865ad20b621641d4f1bf47",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "63d57d508d8f9ae21e05ceda181e1a2d",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "2c4f7247938de3d3fbb65b5766263866",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "85ef605dc94c4be74aac5b15a8931da5",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "a39d6180a89b83463fc44f1b006ebc7d",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "06130b0dfceeb424ba1b66414cf6d930",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "9ea9b12078443053eee0e0be5137492d",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "31f82f74a30d97d6bc66b2fa8d3abbcd",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "7ba3fa11b4e22b42aa16b8f0f904ea70",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "230141db6263d696c28ad00c011f0f9e",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "1e0a508a1fbd20f7e8a1ed79e361ecc6",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "ad6f15fdb1b3956b08d73abb4a0b240d",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "49edc04b213fd8bb10d3227e27921fe8",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "169375157927ea3a826d06a2f3339ccc",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "ed4a2bf5ef5c9e90c4a34a94e82e1752",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "4a8df3bd047824c139d271cb82db06d5",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "a4b0933ce9220822302d660865766891",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "a22db827c37da85d73d248be95f07523",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "49bb13ad22a1f5a75246a21830689998",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "98aa51efb0554fadd446f48b8cb6f31e",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "4450820bb5a73e7b83004a3fe78a50d6",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "cff958f088a5bea303a846dbd0d96e14",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "b2cbf2eee4db47d8d4e1ce0df1c80214",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "3aa845292833b423a7b96263b368bb13",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "2b2a64c6fb1d73d6ddfc19dc597a0947",
|
||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "6ce4983e76e1cc2d2803fe306d08ad58",
|
||||
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "4ea0cf78901f994215f215aebb0af1dc",
|
||||
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "6ce4983e76e1cc2d2803fe306d08ad58",
|
||||
@ -4092,18 +4092,18 @@
|
||||
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "de83e1b384abb333f457f2c9646f810f",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "0149ef8dae7720330416846919a834e7",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "de83e1b384abb333f457f2c9646f810f",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "e3ad15ecc9656a1a268582b14336bed7",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "fce3fd45ed78f84592ef914450817778",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "feeb14560de0fa18d8b7654aa43534ea",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "7896041f53b6f076d032388d661413b0",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "a5b84aaf028c8b13d55d2d99f3853f5d",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "4a8387851909f5cedabb5972b397a7b1",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "53fa53d605a009a6ab592e30d45629a8",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "2988d1791814f0ec0d64914d691a100e",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "163fbb4576a5218685919cf04de63cc6",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "66bbf458c1778685d38d6a2a537f6012",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "1ff129f72dc2dddc24d4dcdfb9b2826a",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "12d9566016a1bbd2aeb873d598d9ceed",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "ba99295cfbcbb3f6da27e4fad8227d74",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "8d53587d097910667fcb7f4958e55384",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "4f3e5d9578c0b0c3bd1203755fe8d464",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "ab834d0257bec7c972a2587a0b34eeff",
|
||||
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
|
||||
"src/assets/ba_data/python/babase/_mgen/enums.py": "f8cd3af311ac63147882590123b78318",
|
||||
"src/ballistica/base/mgen/pyembed/binding_base.inc": "c81b2b1f3a14b4cd20a7b93416fe893a",
|
||||
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "b67add3e1346f63491bf3450148e60d4",
|
||||
"src/ballistica/base/mgen/pyembed/binding_base.inc": "9f71f171464dc004dbaab87e9bb4b03b",
|
||||
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "a521bc86a7e98e56fec14cea029996f8",
|
||||
"src/ballistica/classic/mgen/pyembed/binding_classic.inc": "3ceb412513963f0818ab39c58bf292e3",
|
||||
"src/ballistica/core/mgen/pyembed/binding_core.inc": "9d0a3c9636138e35284923e0c8311c69",
|
||||
"src/ballistica/core/mgen/pyembed/env.inc": "8be46e5818f360d10b7b0224a9e91d07",
|
||||
|
||||
3
.idea/dictionaries/ericf.xml
generated
3
.idea/dictionaries/ericf.xml
generated
@ -2923,6 +2923,8 @@
|
||||
<w>syslogmodule</w>
|
||||
<w>sysresponse</w>
|
||||
<w>tabdefs</w>
|
||||
<w>tabentry</w>
|
||||
<w>tabname</w>
|
||||
<w>tabtype</w>
|
||||
<w>tabtypes</w>
|
||||
<w>tabval</w>
|
||||
@ -3351,6 +3353,7 @@
|
||||
<w>xcworkspacedata</w>
|
||||
<w>xdrlib</w>
|
||||
<w>xhdpi</w>
|
||||
<w>xhost</w>
|
||||
<w>xinput</w>
|
||||
<w>xjtp</w>
|
||||
<w>xmlbuilder</w>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
### 1.7.28 (build 21401, api 8, 2023-09-29)
|
||||
### 1.7.28 (build 21405, api 8, 2023-10-02)
|
||||
|
||||
- Massively cleaned up code related to rendering and window systems (OpenGL,
|
||||
SDL, etc). This code had been growing into a nasty tangle for 15 years
|
||||
|
||||
12
Makefile
12
Makefile
@ -135,6 +135,7 @@ resources-clean:
|
||||
cd src/resources && $(MAKE) clean
|
||||
|
||||
# Build our generated sources.
|
||||
#
|
||||
# Meta builds can affect sources used by asset builds, resource builds, and
|
||||
# compiles, so it should be listed as a dependency of any of those.
|
||||
meta: prereqs
|
||||
@ -146,8 +147,8 @@ meta-clean:
|
||||
rm -f $(LAZYBUILDDIR)/meta
|
||||
cd src/meta && $(MAKE) clean
|
||||
|
||||
# Remove ALL files and directories that aren't managed by git
|
||||
# (except for a few things such as localconfig.json).
|
||||
# Remove ALL files and directories that aren't managed by git (except for a
|
||||
# few things such as localconfig.json).
|
||||
clean:
|
||||
$(CHECK_CLEAN_SAFETY)
|
||||
rm -rf build # Handle this part ourself; can confuse git.
|
||||
@ -160,9 +161,10 @@ clean-list:
|
||||
git clean -dnx $(ROOT_CLEAN_IGNORES)
|
||||
|
||||
# Build/update dummy python modules.
|
||||
# IMPORTANT - building this target can kick off full builds/cleans and so
|
||||
# it should not be built in parallel with other targets.
|
||||
# See py_check_prereqs target for more info.
|
||||
#
|
||||
# IMPORTANT - building this target can kick off full builds/cleans and so it
|
||||
# should not be built in parallel with other targets. See py_check_prereqs
|
||||
# target for more info.
|
||||
dummymodules: prereqs meta
|
||||
@$(PCOMMAND) lazybuild dummymodules_src $(LAZYBUILDDIR)/$@ \
|
||||
rm -rf build/dummymodules \&\& $(PCOMMAND) gen_dummy_modules
|
||||
|
||||
3
ballisticakit-cmake/.idea/dictionaries/ericf.xml
generated
3
ballisticakit-cmake/.idea/dictionaries/ericf.xml
generated
@ -1733,6 +1733,8 @@
|
||||
<w>syscalls</w>
|
||||
<w>sysresponse</w>
|
||||
<w>tabdefs</w>
|
||||
<w>tabentry</w>
|
||||
<w>tabname</w>
|
||||
<w>tabtype</w>
|
||||
<w>tabtypes</w>
|
||||
<w>talloc</w>
|
||||
@ -1972,6 +1974,7 @@
|
||||
<w>xcrun</w>
|
||||
<w>xdiff</w>
|
||||
<w>xdist</w>
|
||||
<w>xhost</w>
|
||||
<w>xinput</w>
|
||||
<w>xmax</w>
|
||||
<w>xmin</w>
|
||||
|
||||
@ -51,11 +51,6 @@ if (HEADLESS)
|
||||
endif ()
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(OpenAL REQUIRED)
|
||||
if (APPLE)
|
||||
# On mac this sets an include path that we don't need since
|
||||
# we're using the system framework... should clean this up.
|
||||
set(OPENAL_INCLUDE_DIR "")
|
||||
endif ()
|
||||
find_library(OGG_LIBRARY ogg)
|
||||
find_library(VORBISFILE_LIBRARY vorbisfile)
|
||||
if (NOT OGG_LIBRARY)
|
||||
@ -77,8 +72,7 @@ endif ()
|
||||
# on Raspberry Pi builds. We never need to care about C++ abi compatibility
|
||||
# so just silencing them for now. Can maybe remove this later if they stop.
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
||||
set(CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -Wno-psabi")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-psabi")
|
||||
endif()
|
||||
|
||||
set(BA_SRC_ROOT ../src)
|
||||
@ -800,11 +794,6 @@ target_link_libraries(ballisticakitbin PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/prefablib/libballisticaplus.a ode pthread ${Python_LIBRARIES}
|
||||
${SDL2_LIBRARIES} ${EXTRA_LIBRARIES} dl)
|
||||
|
||||
# Hack for building on rpi; need to update my pi so I can remove this.
|
||||
if(EXISTS "/home/pi")
|
||||
target_link_libraries(ballisticakitbin PRIVATE dl util stdc++fs)
|
||||
endif()
|
||||
|
||||
|
||||
# BallisticaKit modular shared library
|
||||
# (for use with vanilla Python interpreters).
|
||||
|
||||
@ -98,7 +98,7 @@
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef;../../src/external/qrencode-3.4.4</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef;../../src/external/qrencode-3.4.4</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
@ -122,7 +122,7 @@
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
@ -147,7 +147,7 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
@ -172,7 +172,7 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
|
||||
@ -100,7 +100,7 @@
|
||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
@ -122,7 +122,7 @@
|
||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
@ -144,7 +144,7 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
@ -168,7 +168,7 @@
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../src;../../src/external/windows/include/SDL2;../../src/external/windows/include/AL;../../src/external/windows/include/python;../../src/external/windows/include;../../src/external/open_dynamics_engine-ef</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
"ba_data/python/babase/__pycache__/_assetmanager.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/babase/__pycache__/_asyncio.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/babase/__pycache__/_cloud.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/babase/__pycache__/_devconsole.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/babase/__pycache__/_emptyappmode.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/babase/__pycache__/_env.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/babase/__pycache__/_error.cpython-311.opt-1.pyc",
|
||||
@ -43,6 +44,7 @@
|
||||
"ba_data/python/babase/_assetmanager.py",
|
||||
"ba_data/python/babase/_asyncio.py",
|
||||
"ba_data/python/babase/_cloud.py",
|
||||
"ba_data/python/babase/_devconsole.py",
|
||||
"ba_data/python/babase/_emptyappmode.py",
|
||||
"ba_data/python/babase/_env.py",
|
||||
"ba_data/python/babase/_error.py",
|
||||
|
||||
@ -172,6 +172,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \
|
||||
$(BUILD_DIR)/ba_data/python/babase/_assetmanager.py \
|
||||
$(BUILD_DIR)/ba_data/python/babase/_asyncio.py \
|
||||
$(BUILD_DIR)/ba_data/python/babase/_cloud.py \
|
||||
$(BUILD_DIR)/ba_data/python/babase/_devconsole.py \
|
||||
$(BUILD_DIR)/ba_data/python/babase/_emptyappmode.py \
|
||||
$(BUILD_DIR)/ba_data/python/babase/_env.py \
|
||||
$(BUILD_DIR)/ba_data/python/babase/_error.py \
|
||||
@ -445,6 +446,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
|
||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_assetmanager.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_asyncio.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_cloud.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_devconsole.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_emptyappmode.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_env.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_error.cpython-311.opt-1.pyc \
|
||||
|
||||
@ -114,6 +114,11 @@ from babase._apputils import (
|
||||
AppHealthMonitor,
|
||||
)
|
||||
from babase._cloud import CloudSubsystem
|
||||
from babase._devconsole import (
|
||||
DevConsoleTab,
|
||||
DevConsoleTabEntry,
|
||||
DevConsoleSubsystem,
|
||||
)
|
||||
from babase._emptyappmode import EmptyAppMode
|
||||
from babase._error import (
|
||||
print_exception,
|
||||
@ -206,6 +211,9 @@ __all__ = [
|
||||
'ContextError',
|
||||
'ContextRef',
|
||||
'DelegateNotFoundError',
|
||||
'DevConsoleTab',
|
||||
'DevConsoleTabEntry',
|
||||
'DevConsoleSubsystem',
|
||||
'DisplayTime',
|
||||
'displaytime',
|
||||
'displaytimer',
|
||||
|
||||
@ -24,6 +24,7 @@ from babase._appcomponent import AppComponentSubsystem
|
||||
from babase._appmodeselector import AppModeSelector
|
||||
from babase._appintent import AppIntentDefault, AppIntentExec
|
||||
from babase._stringedit import StringEditSubsystem
|
||||
from babase._devconsole import DevConsoleSubsystem
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import asyncio
|
||||
@ -164,6 +165,7 @@ class App:
|
||||
self.workspaces = WorkspaceSubsystem()
|
||||
self.components = AppComponentSubsystem()
|
||||
self.stringedit = StringEditSubsystem()
|
||||
self.devconsole = DevConsoleSubsystem()
|
||||
|
||||
# This is incremented any time the app is backgrounded or
|
||||
# foregrounded; can be a simple way to determine if network data
|
||||
|
||||
144
src/assets/ba_data/python/babase/_devconsole.py
Normal file
144
src/assets/ba_data/python/babase/_devconsole.py
Normal file
@ -0,0 +1,144 @@
|
||||
# Released under the MIT License. See LICENSE for details.
|
||||
#
|
||||
"""Dev-Console functionality."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from dataclasses import dataclass
|
||||
import logging
|
||||
|
||||
import _babase
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Callable, Any, Literal
|
||||
|
||||
|
||||
class DevConsoleTab:
|
||||
"""Defines behavior for a tab in the dev-console."""
|
||||
|
||||
def refresh(self) -> None:
|
||||
"""Called when the tab should refresh itself."""
|
||||
|
||||
def request_refresh(self) -> None:
|
||||
"""The tab can call this to request that it be refreshed."""
|
||||
_babase.dev_console_request_refresh()
|
||||
|
||||
def button(
|
||||
self,
|
||||
label: str,
|
||||
pos: tuple[float, float],
|
||||
size: tuple[float, float],
|
||||
call: Callable[[], Any] | None = None,
|
||||
h_anchor: Literal['left', 'center', 'right'] = 'center',
|
||||
label_scale: float = 1.0,
|
||||
corner_radius: float = 8.0,
|
||||
) -> None:
|
||||
"""Add a button to the tab being refreshed."""
|
||||
assert _babase.app.devconsole.is_refreshing
|
||||
_babase.dev_console_add_button(
|
||||
label,
|
||||
pos[0],
|
||||
pos[1],
|
||||
size[0],
|
||||
size[1],
|
||||
call,
|
||||
h_anchor,
|
||||
label_scale,
|
||||
corner_radius,
|
||||
)
|
||||
|
||||
def python_terminal(self) -> None:
|
||||
"""Add a Python Terminal to the tab being refreshed."""
|
||||
assert _babase.app.devconsole.is_refreshing
|
||||
_babase.dev_console_add_python_terminal()
|
||||
|
||||
@property
|
||||
def width(self) -> float:
|
||||
"""Return the current tab width. Only call during refreshes."""
|
||||
assert _babase.app.devconsole.is_refreshing
|
||||
return _babase.dev_console_tab_width()
|
||||
|
||||
@property
|
||||
def height(self) -> float:
|
||||
"""Return the current tab height. Only call during refreshes."""
|
||||
assert _babase.app.devconsole.is_refreshing
|
||||
return _babase.dev_console_tab_height()
|
||||
|
||||
@property
|
||||
def base_scale(self) -> float:
|
||||
"""A scale value set depending on the app's UI scale.
|
||||
|
||||
Dev-console tabs can incorporate this into their UI sizes and
|
||||
positions if they desire. This must be done manually however.
|
||||
"""
|
||||
assert _babase.app.devconsole.is_refreshing
|
||||
return _babase.dev_console_base_scale()
|
||||
|
||||
|
||||
class DevConsoleTabPython(DevConsoleTab):
|
||||
"""The Python dev-console tab."""
|
||||
|
||||
def refresh(self) -> None:
|
||||
self.python_terminal()
|
||||
|
||||
|
||||
class DevConsoleTabTest(DevConsoleTab):
|
||||
"""Test dev-console tab."""
|
||||
|
||||
def refresh(self) -> None:
|
||||
import random
|
||||
|
||||
self.button(
|
||||
f'FLOOP-{random.randrange(200)}',
|
||||
pos=(10, 10),
|
||||
size=(100, 30),
|
||||
h_anchor='left',
|
||||
call=self.request_refresh,
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class DevConsoleTabEntry:
|
||||
"""Represents a distinct tab in the dev-console."""
|
||||
|
||||
name: str
|
||||
factory: Callable[[], DevConsoleTab]
|
||||
|
||||
|
||||
class DevConsoleSubsystem:
|
||||
"""Wrangles the dev console."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
# All tabs in the dev-console. Add your own stuff here via
|
||||
# plugins or whatnot.
|
||||
self.tabs: list[DevConsoleTabEntry] = [
|
||||
DevConsoleTabEntry('Python', DevConsoleTabPython),
|
||||
DevConsoleTabEntry('Test', DevConsoleTabTest),
|
||||
]
|
||||
self.is_refreshing = False
|
||||
|
||||
def do_refresh_tab(self, tabname: str) -> None:
|
||||
"""Called by the C++ layer when a tab should be filled out."""
|
||||
assert _babase.in_logic_thread()
|
||||
|
||||
# FIXME: We currently won't handle multiple tabs with the same
|
||||
# name. We should give a clean error or something in that case.
|
||||
tab: DevConsoleTab | None = None
|
||||
for tabentry in self.tabs:
|
||||
if tabentry.name == tabname:
|
||||
tab = tabentry.factory()
|
||||
break
|
||||
|
||||
if tab is None:
|
||||
logging.error(
|
||||
'DevConsole got refresh request for tab'
|
||||
" '%s' which does not exist.",
|
||||
tabname,
|
||||
)
|
||||
return
|
||||
|
||||
self.is_refreshing = True
|
||||
try:
|
||||
tab.refresh()
|
||||
finally:
|
||||
self.is_refreshing = False
|
||||
@ -372,3 +372,8 @@ def string_edit_adapter_can_be_replaced(adapter: StringEditAdapter) -> bool:
|
||||
|
||||
assert isinstance(adapter, StringEditAdapter)
|
||||
return adapter.can_be_replaced()
|
||||
|
||||
|
||||
def get_dev_console_tab_names() -> list[str]:
|
||||
"""Return the current set of dev-console tab names."""
|
||||
return [t.name for t in _babase.app.devconsole.tabs]
|
||||
|
||||
@ -52,7 +52,7 @@ if TYPE_CHECKING:
|
||||
|
||||
# Build number and version of the ballistica binary we expect to be
|
||||
# using.
|
||||
TARGET_BALLISTICA_BUILD = 21401
|
||||
TARGET_BALLISTICA_BUILD = 21405
|
||||
TARGET_BALLISTICA_VERSION = '1.7.28'
|
||||
|
||||
|
||||
|
||||
@ -13,12 +13,12 @@
|
||||
#include <OpenAL/al.h>
|
||||
#include <OpenAL/alc.h>
|
||||
#else
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <al.h>
|
||||
#include <alc.h>
|
||||
#endif
|
||||
|
||||
#if BA_OSTYPE_ANDROID
|
||||
#include <AL/alext.h>
|
||||
#include <alext.h>
|
||||
#endif
|
||||
|
||||
#define CHECK_AL_ERROR _check_al_error(__FILE__, __LINE__)
|
||||
|
||||
@ -1,15 +1,12 @@
|
||||
// Released under the MIT License. See LICENSE for details.
|
||||
|
||||
#if BA_ENABLE_OPENGL
|
||||
|
||||
#include "ballistica/base/graphics/gl/renderer_gl.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
|
||||
#include "ballistica/base/graphics/component/special_component.h"
|
||||
#include "ballistica/base/graphics/gl/framebuffer_object_gl.h"
|
||||
#include "ballistica/base/graphics/gl/gl_sys.h"
|
||||
#include "ballistica/base/graphics/gl/mesh/mesh_asset_data_gl.h"
|
||||
#include "ballistica/base/graphics/gl/mesh/mesh_data_dual_texture_full_gl.h"
|
||||
#include "ballistica/base/graphics/gl/mesh/mesh_data_gl.h"
|
||||
@ -29,11 +26,6 @@
|
||||
#include "ballistica/base/graphics/gl/render_target_gl.h"
|
||||
#include "ballistica/base/graphics/gl/texture_data_gl.h"
|
||||
#include "ballistica/base/platform/base_platform.h"
|
||||
#include "ballistica/shared/buildconfig/buildconfig_common.h"
|
||||
|
||||
#if BA_OSTYPE_IOS_TVOS
|
||||
#include "ballistica/base/platform/apple/apple_utils.h"
|
||||
#endif
|
||||
|
||||
// Turn this off to see how much blend overdraw is occurring.
|
||||
#define BA_GL_ENABLE_BLEND 1
|
||||
@ -64,22 +56,6 @@ namespace ballistica::base {
|
||||
|
||||
bool RendererGL::funky_depth_issue_set_{};
|
||||
bool RendererGL::funky_depth_issue_{};
|
||||
bool RendererGL::draws_shields_funny_{};
|
||||
bool RendererGL::draws_shields_funny_set_{};
|
||||
|
||||
// FIXME - move this stuff to the renderer class.
|
||||
// GLint g_combined_texture_image_unit_count{};
|
||||
// bool g_anisotropic_support{};
|
||||
// bool g_vao_support{};
|
||||
// float g_max_anisotropy{};
|
||||
// bool g_discard_framebuffer_support{};
|
||||
// bool g_invalidate_framebuffer_support{};
|
||||
// bool g_blit_framebuffer_support{};
|
||||
// bool g_framebuffer_multisample_support{};
|
||||
// bool g_running_es3{};
|
||||
// bool g_seamless_cube_maps{};
|
||||
// int g_msaa_max_samples_rgb565{};
|
||||
// int g_msaa_max_samples_rgb8{};
|
||||
|
||||
#if BA_OSTYPE_ANDROID
|
||||
bool RendererGL::is_speedy_android_device_{};
|
||||
@ -108,8 +84,11 @@ void RendererGL::CheckGLError(const char* file, int line) {
|
||||
GLenum err = glGetError();
|
||||
if (err != GL_NO_ERROR) {
|
||||
const char* version = (const char*)glGetString(GL_VERSION);
|
||||
BA_PRECONDITION_FATAL(version);
|
||||
const char* vendor = (const char*)glGetString(GL_VENDOR);
|
||||
BA_PRECONDITION_FATAL(vendor);
|
||||
const char* renderer = (const char*)glGetString(GL_RENDERER);
|
||||
BA_PRECONDITION_FATAL(renderer);
|
||||
Log(LogLevel::kError,
|
||||
"OpenGL Error at " + std::string(file) + " line " + std::to_string(line)
|
||||
+ ": " + GLErrorToString(err) + "\nrenderer: " + renderer
|
||||
@ -177,11 +156,27 @@ void RendererGL::CheckGLCapabilities_() {
|
||||
BA_DEBUG_CHECK_GL_ERROR;
|
||||
assert(g_base->app_adapter->InGraphicsContext());
|
||||
|
||||
draws_shields_funny_set_ = true;
|
||||
|
||||
const char* renderer = (const char*)glGetString(GL_RENDERER);
|
||||
BA_PRECONDITION_FATAL(renderer);
|
||||
const char* vendor = (const char*)glGetString(GL_VENDOR);
|
||||
BA_PRECONDITION_FATAL(vendor);
|
||||
const char* version_str = (const char*)glGetString(GL_VERSION);
|
||||
BA_PRECONDITION_FATAL(version_str);
|
||||
|
||||
// Do a rough check to make sure we're running 3 or newer of GL/GLES.
|
||||
// This query should be available even on older versions.
|
||||
if (version_str[0] != '3' && version_str[0] != '4') {
|
||||
FatalError(std::string("Invalid OpenGL version found (") + version_str
|
||||
+ "). We require 3.0 or later.");
|
||||
}
|
||||
|
||||
// Now fetch exact major/minor versions. This query requires version 3.0
|
||||
// or newer which is why we checked that above.
|
||||
glGetError(); // Clear any existing error so we don't die on it here.
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &gl_version_major_);
|
||||
BA_PRECONDITION_FATAL(glGetError() == GL_NO_ERROR);
|
||||
glGetIntegerv(GL_MINOR_VERSION, &gl_version_minor_);
|
||||
BA_PRECONDITION_FATAL(glGetError() == GL_NO_ERROR);
|
||||
|
||||
const char* basestr;
|
||||
if (gl_is_es()) {
|
||||
@ -200,28 +195,20 @@ void RendererGL::CheckGLCapabilities_() {
|
||||
std::vector<std::string> extensions;
|
||||
bool used_num_extensions{};
|
||||
|
||||
// On the ES side we still support ES 2 which does not support the modern
|
||||
// GL_NUM_EXTENSIONS route. Though I suppose we could just try it on ES
|
||||
// and do the fallback if we get GL_INVALID_ENUM.
|
||||
#if !BA_OPENGL_IS_ES
|
||||
{
|
||||
GLint num_extensions{};
|
||||
glGetError(); // Clear any existing error.
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
|
||||
if (glGetError() == GL_NO_ERROR) {
|
||||
used_num_extensions = true;
|
||||
extensions.reserve(num_extensions);
|
||||
for (int i = 0; i < num_extensions; ++i) {
|
||||
const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, i);
|
||||
BA_PRECONDITION(extension);
|
||||
extensions.push_back(extension);
|
||||
}
|
||||
// Do the modern gl thing of looking through a list of extensions; not a
|
||||
// single string.
|
||||
if (auto num_extensions = GLGetIntOptional(GL_NUM_EXTENSIONS)) {
|
||||
used_num_extensions = true;
|
||||
extensions.reserve(*num_extensions);
|
||||
for (int i = 0; i < num_extensions; ++i) {
|
||||
const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, i);
|
||||
BA_PRECONDITION(extension);
|
||||
extensions.push_back(extension);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fall back on parsing the single giant string if need be.
|
||||
if (!used_num_extensions) {
|
||||
} else {
|
||||
Log(LogLevel::kWarning, "Falling back on legacy GL_EXTENSIONS parsing.");
|
||||
// Fall back on parsing the single giant string if need be.
|
||||
// (Can probably kill this).
|
||||
auto* ex = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
|
||||
BA_DEBUG_CHECK_GL_ERROR;
|
||||
BA_PRECONDITION_FATAL(ex);
|
||||
@ -349,13 +336,15 @@ void RendererGL::CheckGLCapabilities_() {
|
||||
|
||||
std::list<TextureCompressionType> c_types;
|
||||
assert(g_base->graphics);
|
||||
if (CheckGLExtension(extensions, "texture_compression_s3tc"))
|
||||
if (CheckGLExtension(extensions, "texture_compression_s3tc")) {
|
||||
c_types.push_back(TextureCompressionType::kS3TC);
|
||||
}
|
||||
|
||||
// Limiting pvr support to iOS for the moment.
|
||||
if (!g_buildconfig.ostype_android()) {
|
||||
if (CheckGLExtension(extensions, "texture_compression_pvrtc"))
|
||||
if (CheckGLExtension(extensions, "texture_compression_pvrtc")) {
|
||||
c_types.push_back(TextureCompressionType::kPVR);
|
||||
}
|
||||
}
|
||||
|
||||
// All android devices should support etc1.
|
||||
@ -375,33 +364,14 @@ void RendererGL::CheckGLCapabilities_() {
|
||||
|
||||
g_base->graphics_server->SetTextureCompressionTypes(c_types);
|
||||
|
||||
// Check whether we support high-quality mode (requires a few things like
|
||||
// depth textures) For now lets also disallow high-quality in some VR
|
||||
// environments.
|
||||
|
||||
// Both GL 3.2 and GL ES 3.0 support depth textures.
|
||||
// if (!gl_is_es()) {
|
||||
// supports_depth_textures_ = true;
|
||||
// Both GL 3 and GL ES 3.0 support depth textures (and thus our high
|
||||
// quality mode) as a core feature.
|
||||
g_base->graphics->SetSupportsHighQualityGraphics(true);
|
||||
|
||||
// } else {
|
||||
// if (CheckGLExtension(extensions, "depth_texture")) {
|
||||
// supports_depth_textures_ = true;
|
||||
// if (g_buildconfig.cardboard_build()) {
|
||||
// g_base->graphics->SetSupportsHighQualityGraphics(false);
|
||||
// } else {
|
||||
// g_base->graphics->SetSupportsHighQualityGraphics(true);
|
||||
// }
|
||||
// } else {
|
||||
// supports_depth_textures_ = false;
|
||||
// g_base->graphics->SetSupportsHighQualityGraphics(false);
|
||||
// }
|
||||
// }
|
||||
|
||||
// Store the tex-compression type we support.
|
||||
BA_DEBUG_CHECK_GL_ERROR;
|
||||
|
||||
// Anisotropic sampling is still an extension as of both GL 3.2 and ES 3,
|
||||
// Anisotropic sampling is still an extension as of both GL 3 and ES 3,
|
||||
// so we need to test for it.
|
||||
anisotropic_support_ =
|
||||
CheckGLExtension(extensions, "texture_filter_anisotropic");
|
||||
@ -411,40 +381,6 @@ void RendererGL::CheckGLCapabilities_() {
|
||||
|
||||
BA_DEBUG_CHECK_GL_ERROR;
|
||||
|
||||
// VAO support is everywhere now.
|
||||
// #if BA_OPENGL_IS_ES
|
||||
// // We can run with our without VAOs but they're nice to have.
|
||||
// g_vao_support =
|
||||
// (glGenVertexArrays != nullptr && glDeleteVertexArrays != nullptr
|
||||
// && glBindVertexArray != nullptr
|
||||
// && (g_running_es3
|
||||
// || CheckGLExtension(extensions, "vertex_array_object")));
|
||||
// #else
|
||||
// g_vao_support = true;
|
||||
// #endif
|
||||
|
||||
// #if !BA_OPENGL_IS_ES
|
||||
// Both of these are standard in GL 3.2 and GL ES 3; hooray!
|
||||
// g_blit_framebuffer_support = true;
|
||||
// g_framebuffer_multisample_support = true;
|
||||
// #else
|
||||
// #if BA_OSTYPE_IOS_TVOS
|
||||
// g_blit_framebuffer_support = false;
|
||||
// g_framebuffer_multisample_support = false;
|
||||
// #elif BA_OSTYPE_MACOS
|
||||
// g_blit_framebuffer_support = CheckGLExtension(extensions,
|
||||
// "framebuffer_blit"); g_framebuffer_multisample_support = false;
|
||||
// #else
|
||||
// g_blit_framebuffer_support =
|
||||
// (glBlitFramebuffer != nullptr
|
||||
// && (g_running_es3 || CheckGLExtension(ex, "framebuffer_blit")));
|
||||
// g_framebuffer_multisample_support =
|
||||
// (glRenderbufferStorageMultisample != nullptr
|
||||
// && (g_running_es3 || (CheckGLExtension(ex,
|
||||
// "framebuffer_multisample"))));
|
||||
// #endif
|
||||
// #endif
|
||||
|
||||
if (gl_is_es()) {
|
||||
// GL ES 3 has glInvalidateFramebuffer as part of the standard.
|
||||
invalidate_framebuffer_support_ = true;
|
||||
@ -454,68 +390,25 @@ void RendererGL::CheckGLCapabilities_() {
|
||||
invalidate_framebuffer_support_ = false;
|
||||
}
|
||||
|
||||
// #if BA_OSTYPE_IOS_TVOS || BA_OSTYPE_ANDROID
|
||||
// #if BA_OSTYPE_IOS_TVOS
|
||||
// g_discard_framebuffer_support = CheckGLExtension(ex,
|
||||
// "discard_framebuffer");
|
||||
// #else
|
||||
// g_discard_framebuffer_support =
|
||||
// (glDiscardFramebufferEXT != nullptr
|
||||
// && CheckGLExtension(ex, "discard_framebuffer"));
|
||||
// #endif
|
||||
|
||||
// g_invalidate_framebuffer_support =
|
||||
// (g_running_es3 && glInvalidateFramebuffer != nullptr);
|
||||
// #else
|
||||
// g_discard_framebuffer_support = false;
|
||||
// g_invalidate_framebuffer_support = false;
|
||||
// #endif
|
||||
|
||||
// g_seamless_cube_maps = CheckGLExtension(ex, "seamless_cube_map");
|
||||
|
||||
// #if BA_OSTYPE_WINDOWS
|
||||
// // The vmware gl driver breaks horrifically with VAOs turned on.
|
||||
// const char* vendor = (const char*)glGetString(GL_VENDOR);
|
||||
// if (strstr(vendor, "VMware")) {
|
||||
// g_vao_support = false;
|
||||
// }
|
||||
// #endif
|
||||
|
||||
// #if BA_OSTYPE_ANDROID
|
||||
// // VAOs currently break my poor kindle fire hd to the point of rebooting
|
||||
// it if (!g_running_es3 && !is_tegra_4_) {
|
||||
// g_vao_support = false;
|
||||
// }
|
||||
|
||||
// // also they seem to be problematic on zenfone2's gpu.
|
||||
// if (strstr(renderer, "PowerVR Rogue G6430")) {
|
||||
// g_vao_support = false;
|
||||
// }
|
||||
// #endif
|
||||
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
|
||||
&combined_texture_image_unit_count_);
|
||||
combined_texture_image_unit_count_ =
|
||||
GLGetInt(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
|
||||
|
||||
// If we're running ES3, ask about our max multisample counts and whether we
|
||||
// can enable MSAA.
|
||||
// enable_msaa_ = false; // start pessimistic
|
||||
msaa_max_samples_rgb565_ = msaa_max_samples_rgb8_ = 0; // start pessimistic
|
||||
|
||||
// FIXME - NEED TO CHECK DESKTOP GL VERSION TO USE THIS THERE.
|
||||
#if BA_OSTYPE_ANDROID || BA_RIFT_BUILD
|
||||
bool check_msaa = false;
|
||||
bool have_gl_get_internal_format_iv{};
|
||||
if (gl_is_es()) {
|
||||
// This is available on ES 3.
|
||||
have_gl_get_internal_format_iv = true;
|
||||
} else {
|
||||
// This is available on GL 4.2 or newer.
|
||||
if (gl_version_major() == 4 && gl_version_minor() >= 2) {
|
||||
have_gl_get_internal_format_iv = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if BA_OSTYPE_ANDROID
|
||||
// if (g_running_es3) {
|
||||
check_msaa = true;
|
||||
// }
|
||||
#endif // BA_OSTYPE_ANDROID
|
||||
|
||||
#if BA_RIFT_BUILD
|
||||
check_msaa = true;
|
||||
#endif // BA_RIFT_BUILD
|
||||
|
||||
if (check_msaa) {
|
||||
if (have_gl_get_internal_format_iv) {
|
||||
GLint count;
|
||||
glGetInternalformativ(GL_RENDERBUFFER, GL_RGB565, GL_NUM_SAMPLE_COUNTS, 1,
|
||||
&count);
|
||||
@ -543,10 +436,17 @@ void RendererGL::CheckGLCapabilities_() {
|
||||
BA_LOG_ONCE(LogLevel::kError, "Got 0 samplecounts for RGB8");
|
||||
msaa_max_samples_rgb8_ = 0;
|
||||
}
|
||||
} else {
|
||||
// For older GL (which includes all Macs) it sounds like this is the way
|
||||
// to query max samples?.. but I don't know for sure if this applies to
|
||||
// renderbuffer targets or just the default drawable. Will it ever be
|
||||
// different?
|
||||
auto max_samples = GLGetIntOptional(GL_MAX_SAMPLES);
|
||||
if (max_samples.has_value()) {
|
||||
msaa_max_samples_rgb565_ = msaa_max_samples_rgb8_ = *max_samples;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BA_OSTYPE_ANDROID
|
||||
|
||||
BA_DEBUG_CHECK_GL_ERROR;
|
||||
|
||||
first_extension_check_ = false;
|
||||
@ -639,7 +539,7 @@ void RendererGL::BindTextureUnit(uint32_t tex_unit) {
|
||||
assert(tex_unit >= 0 && tex_unit < kMaxGLTexUnitsUsed);
|
||||
if (active_tex_unit_ != -1) {
|
||||
// Make sure our internal state stays correct.
|
||||
assert(DebugGLGetInt(GL_ACTIVE_TEXTURE) == GL_TEXTURE0 + active_tex_unit_);
|
||||
assert(GLGetInt(GL_ACTIVE_TEXTURE) == GL_TEXTURE0 + active_tex_unit_);
|
||||
}
|
||||
if (active_tex_unit_ != tex_unit) {
|
||||
active_tex_unit_ = tex_unit;
|
||||
@ -649,18 +549,39 @@ void RendererGL::BindTextureUnit(uint32_t tex_unit) {
|
||||
}
|
||||
}
|
||||
|
||||
auto RendererGL::DebugGLGetInt(GLenum name) -> int {
|
||||
// This is probably inefficient so make sure we don't leave it on in
|
||||
// release builds.
|
||||
assert(g_buildconfig.debug_build());
|
||||
auto RendererGL::GLGetInt(GLenum name) -> int {
|
||||
assert(g_base->app_adapter->InGraphicsContext());
|
||||
|
||||
// Clear any error coming in; don't want to die for something that's not
|
||||
// ours.
|
||||
BA_DEBUG_CHECK_GL_ERROR;
|
||||
// Clear any error coming in; don't want to fail for something that's not
|
||||
// our problem.
|
||||
if (g_buildconfig.debug_build()) {
|
||||
BA_DEBUG_CHECK_GL_ERROR;
|
||||
} else {
|
||||
glGetError();
|
||||
}
|
||||
GLint val;
|
||||
glGetIntegerv(name, &val);
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
if (glGetError() != GL_NO_ERROR) {
|
||||
FatalError("Unable to fetch GL int " + std::to_string(name));
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
auto RendererGL::GLGetIntOptional(GLenum name) -> std::optional<int> {
|
||||
assert(g_base->app_adapter->InGraphicsContext());
|
||||
|
||||
// Clear any error coming in; don't want to fail for something that's not
|
||||
// our problem.
|
||||
if (g_buildconfig.debug_build()) {
|
||||
BA_DEBUG_CHECK_GL_ERROR;
|
||||
} else {
|
||||
glGetError();
|
||||
}
|
||||
GLint val;
|
||||
glGetIntegerv(name, &val);
|
||||
if (glGetError() != GL_NO_ERROR) {
|
||||
return {};
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -669,14 +590,14 @@ void RendererGL::BindFramebuffer(GLuint fb) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
||||
active_framebuffer_ = fb;
|
||||
} else {
|
||||
assert(DebugGLGetInt(GL_FRAMEBUFFER_BINDING) == fb);
|
||||
assert(GLGetInt(GL_FRAMEBUFFER_BINDING) == fb);
|
||||
}
|
||||
}
|
||||
|
||||
void RendererGL::BindArrayBuffer(GLuint b) {
|
||||
if (active_array_buffer_ != -1) {
|
||||
// Make sure our internal state stays correct.
|
||||
assert(DebugGLGetInt(GL_ARRAY_BUFFER_BINDING) == active_array_buffer_);
|
||||
assert(GLGetInt(GL_ARRAY_BUFFER_BINDING) == active_array_buffer_);
|
||||
}
|
||||
if (active_array_buffer_ != b) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, b);
|
||||
@ -702,7 +623,7 @@ void RendererGL::BindTexture_(GLuint type, GLuint tex, GLuint tex_unit) {
|
||||
if (g_buildconfig.debug_build()) {
|
||||
if (bound_textures_2d_[tex_unit] != -1) {
|
||||
BindTextureUnit(tex_unit);
|
||||
assert(DebugGLGetInt(GL_TEXTURE_BINDING_2D)
|
||||
assert(GLGetInt(GL_TEXTURE_BINDING_2D)
|
||||
== bound_textures_2d_[tex_unit]);
|
||||
}
|
||||
}
|
||||
@ -718,7 +639,7 @@ void RendererGL::BindTexture_(GLuint type, GLuint tex, GLuint tex_unit) {
|
||||
if (g_buildconfig.debug_build()) {
|
||||
if (bound_textures_cube_map_[tex_unit] != -1) {
|
||||
BindTextureUnit(tex_unit);
|
||||
assert(DebugGLGetInt(GL_TEXTURE_BINDING_CUBE_MAP)
|
||||
assert(GLGetInt(GL_TEXTURE_BINDING_CUBE_MAP)
|
||||
== bound_textures_cube_map_[tex_unit]);
|
||||
}
|
||||
}
|
||||
@ -825,7 +746,6 @@ void RendererGL::InvalidateFramebuffer(bool color, bool depth,
|
||||
|
||||
// Currently this is ES only for us.
|
||||
#if BA_OPENGL_IS_ES
|
||||
// #if BA_OSTYPE_IOS_TVOS || BA_OSTYPE_ANDROID
|
||||
|
||||
if (invalidate_framebuffer_support()) {
|
||||
GLenum attachments[5];
|
||||
@ -834,11 +754,9 @@ void RendererGL::InvalidateFramebuffer(bool color, bool depth,
|
||||
if (active_framebuffer_ == 0 && !target_read_framebuffer) {
|
||||
if (color) {
|
||||
attachments[count++] = GL_COLOR;
|
||||
// attachments[count++] = GL_COLOR_EXT;
|
||||
}
|
||||
if (depth) {
|
||||
attachments[count++] = GL_DEPTH;
|
||||
// attachments[count++] = GL_DEPTH_EXT;
|
||||
}
|
||||
} else {
|
||||
if (color) {
|
||||
@ -848,29 +766,16 @@ void RendererGL::InvalidateFramebuffer(bool color, bool depth,
|
||||
attachments[count++] = GL_DEPTH_ATTACHMENT;
|
||||
}
|
||||
|
||||
// Apparently the oculus docs say glInvalidateFramebuffer errors on a
|
||||
// mali es3 implementation so they always use glDiscard when present.
|
||||
// if () {
|
||||
// #if BA_OSTYPE_IOS_TVOS
|
||||
// throw Exception(); // shouldnt happen
|
||||
// #else
|
||||
glInvalidateFramebuffer(
|
||||
target_read_framebuffer ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER, count,
|
||||
attachments);
|
||||
// #endif
|
||||
}
|
||||
// } else {
|
||||
// // If we've got a read-framebuffer, we should have invalidate too.
|
||||
// assert(!target_read_framebuffer);
|
||||
// glDiscardFramebufferEXT(GL_FRAMEBUFFER, count, attachments);
|
||||
// }
|
||||
BA_DEBUG_CHECK_GL_ERROR;
|
||||
}
|
||||
#else
|
||||
// Make noise if we should be doing this here too...
|
||||
// Make noise if we should be doing this here too at some point.
|
||||
assert(!invalidate_framebuffer_support());
|
||||
#endif // BA_OPENGL_IS_ES
|
||||
// #endif // BA_OSTYPE_IOS_TVOS || BA_OSTYPE_ANDROID
|
||||
}
|
||||
|
||||
RendererGL::~RendererGL() {
|
||||
@ -2701,8 +2606,7 @@ void RendererGL::Load() {
|
||||
// Grab the current framebuffer and consider that to be our 'screen'
|
||||
// framebuffer. This can be 0 for the main framebuffer or can be
|
||||
// something else.
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING,
|
||||
reinterpret_cast<GLint*>(&screen_framebuffer_));
|
||||
screen_framebuffer_ = GLGetInt(GL_FRAMEBUFFER_BINDING);
|
||||
}
|
||||
Renderer::Load();
|
||||
int high_qual_pp_flag =
|
||||
@ -3340,9 +3244,7 @@ void RendererGL::VREyeRenderBegin() {
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
#endif // BA_RIFT_BUILD
|
||||
|
||||
GLuint fb;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, reinterpret_cast<GLint*>(&fb));
|
||||
screen_framebuffer_ = fb;
|
||||
screen_framebuffer_ = GLGetInt(GL_FRAMEBUFFER_BINDING);
|
||||
}
|
||||
|
||||
#if BA_VR_BUILD
|
||||
|
||||
@ -217,7 +217,14 @@ class RendererGL : public Renderer {
|
||||
#endif
|
||||
}
|
||||
|
||||
auto DebugGLGetInt(GLenum name) -> int;
|
||||
auto gl_version_minor() const { return gl_version_minor_; }
|
||||
auto gl_version_major() const { return gl_version_major_; }
|
||||
|
||||
// Wraps glGetIntegerv(). Triggers FatalError if get fails.
|
||||
auto GLGetInt(GLenum name) -> int;
|
||||
|
||||
// Wraps glGetIntegerv(); returns empty value if get fails.
|
||||
auto GLGetIntOptional(GLenum name) -> std::optional<int>;
|
||||
|
||||
private:
|
||||
static auto GetFunkyDepthIssue_() -> bool;
|
||||
@ -251,18 +258,28 @@ class RendererGL : public Renderer {
|
||||
void BindArrayBuffer(GLuint b);
|
||||
void SetBlend(bool b);
|
||||
void SetBlendPremult(bool b);
|
||||
millisecs_t dof_update_time_{};
|
||||
std::vector<Object::Ref<FramebufferObjectGL> > blur_buffers_;
|
||||
// bool supports_depth_textures_{};
|
||||
|
||||
bool blend_{};
|
||||
bool blend_premult_{};
|
||||
bool first_extension_check_{true};
|
||||
bool is_tegra_4_{};
|
||||
bool is_tegra_k1_{};
|
||||
bool is_recent_adreno_{};
|
||||
bool is_adreno_{};
|
||||
bool enable_msaa_{};
|
||||
bool draw_at_equal_depth_{};
|
||||
bool depth_writing_enabled_{};
|
||||
bool depth_testing_enabled_{};
|
||||
bool data_loaded_{};
|
||||
bool draw_front_{};
|
||||
bool got_screen_framebuffer_{};
|
||||
bool double_sided_{};
|
||||
bool invalidate_framebuffer_support_{};
|
||||
GLint gl_version_major_{};
|
||||
GLint gl_version_minor_{};
|
||||
int last_blur_res_count_{};
|
||||
float last_cam_buffer_width_{};
|
||||
float last_cam_buffer_height_{};
|
||||
int last_blur_res_count_{};
|
||||
float vignette_tex_outer_r_{};
|
||||
float vignette_tex_outer_g_{};
|
||||
float vignette_tex_outer_b_{};
|
||||
@ -271,13 +288,7 @@ class RendererGL : public Renderer {
|
||||
float vignette_tex_inner_b_{};
|
||||
float depth_range_min_{};
|
||||
float depth_range_max_{};
|
||||
bool draw_at_equal_depth_{};
|
||||
bool depth_writing_enabled_{};
|
||||
bool depth_testing_enabled_{};
|
||||
bool data_loaded_{};
|
||||
bool draw_front_{};
|
||||
bool got_screen_framebuffer_{};
|
||||
GLuint screen_framebuffer_{};
|
||||
GLint screen_framebuffer_{};
|
||||
GLuint random_tex_{};
|
||||
GLuint vignette_tex_{};
|
||||
GraphicsQuality vignette_quality_{};
|
||||
@ -285,6 +296,8 @@ class RendererGL : public Renderer {
|
||||
GLint viewport_y_{};
|
||||
GLint viewport_width_{};
|
||||
GLint viewport_height_{};
|
||||
millisecs_t dof_update_time_{};
|
||||
std::vector<Object::Ref<FramebufferObjectGL> > blur_buffers_;
|
||||
std::vector<std::unique_ptr<ProgramGL> > shaders_;
|
||||
ProgramSimpleGL* simple_color_prog_{};
|
||||
ProgramSimpleGL* simple_tex_prog_{};
|
||||
@ -326,24 +339,18 @@ class RendererGL : public Renderer {
|
||||
ProgramPostProcessGL* postprocess_distort_prog_{};
|
||||
static bool funky_depth_issue_set_;
|
||||
static bool funky_depth_issue_;
|
||||
static bool draws_shields_funny_set_;
|
||||
static bool draws_shields_funny_;
|
||||
#if BA_OSTYPE_ANDROID
|
||||
static bool is_speedy_android_device_;
|
||||
static bool is_extra_speedy_android_device_;
|
||||
#endif
|
||||
ProgramGL* current_program_{};
|
||||
bool double_sided_{};
|
||||
std::vector<Rect> scissor_rects_;
|
||||
GLuint current_vertex_array_{};
|
||||
bool vertex_attrib_arrays_enabled_[kVertexAttrCount]{};
|
||||
int active_tex_unit_{};
|
||||
int active_framebuffer_{};
|
||||
int active_array_buffer_{};
|
||||
int bound_textures_2d_[kMaxGLTexUnitsUsed]{};
|
||||
int bound_textures_cube_map_[kMaxGLTexUnitsUsed]{};
|
||||
bool blend_{};
|
||||
bool blend_premult_{};
|
||||
std::unique_ptr<MeshDataSimpleFullGL> screen_mesh_;
|
||||
std::vector<MeshDataSimpleSplitGL*> recycle_mesh_datas_simple_split_;
|
||||
std::vector<MeshDataObjectSplitGL*> recycle_mesh_datas_object_split_;
|
||||
@ -355,7 +362,6 @@ class RendererGL : public Renderer {
|
||||
GLint combined_texture_image_unit_count_{};
|
||||
GLint anisotropic_support_{};
|
||||
GLfloat max_anisotropy_{};
|
||||
bool invalidate_framebuffer_support_{};
|
||||
int msaa_max_samples_rgb565_{-1};
|
||||
int msaa_max_samples_rgb8_{-1};
|
||||
};
|
||||
|
||||
@ -105,6 +105,8 @@ class BasePython {
|
||||
kAppPushApplyAppConfigCall,
|
||||
kStringEditAdapterCanBeReplacedCall,
|
||||
kDevConsoleStringEditAdapterClass,
|
||||
kGetDevConsoleTabNamesCall,
|
||||
kAppDevConsoleDoRefreshTabCall,
|
||||
kLast // Sentinel; must be at end.
|
||||
};
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "ballistica/base/python/base_python.h"
|
||||
#include "ballistica/base/python/class/python_class_simple_sound.h"
|
||||
#include "ballistica/base/support/app_config.h"
|
||||
#include "ballistica/base/ui/dev_console.h"
|
||||
#include "ballistica/base/ui/ui.h"
|
||||
#include "ballistica/shared/generic/utils.h"
|
||||
|
||||
@ -1450,6 +1451,169 @@ static PyMethodDef PyFatalErrorDef = {
|
||||
"however, Exceptions should be preferred.",
|
||||
};
|
||||
|
||||
// ------------------------- dev_console_add_button ----------------------------
|
||||
|
||||
static auto PyDevConsoleAddButton(PyObject* self, PyObject* args) -> PyObject* {
|
||||
BA_PYTHON_TRY;
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
auto* dev_console = g_base->ui->dev_console();
|
||||
BA_PRECONDITION(dev_console);
|
||||
BA_PRECONDITION(dev_console->IsActive());
|
||||
const char* label;
|
||||
float x;
|
||||
float y;
|
||||
float width;
|
||||
float height;
|
||||
PyObject* call;
|
||||
const char* h_anchor;
|
||||
float label_scale;
|
||||
float corner_radius;
|
||||
if (!PyArg_ParseTuple(args, "sffffOsff", &label, &x, &y, &width, &height,
|
||||
&call, &h_anchor, &label_scale, &corner_radius)) {
|
||||
return nullptr;
|
||||
}
|
||||
dev_console->AddButton(label, x, y, width, height, call, h_anchor,
|
||||
label_scale, corner_radius);
|
||||
Py_RETURN_NONE;
|
||||
BA_PYTHON_CATCH;
|
||||
}
|
||||
|
||||
static PyMethodDef PyDevConsoleAddButtonDef = {
|
||||
"dev_console_add_button", // name
|
||||
(PyCFunction)PyDevConsoleAddButton, // method
|
||||
METH_VARARGS, // flags
|
||||
|
||||
"dev_console_add_button(\n"
|
||||
" label: str,\n"
|
||||
" x: float,\n"
|
||||
" y: float,\n"
|
||||
" width: float,\n"
|
||||
" height: float,\n"
|
||||
" call: Callable[[], Any] | None,\n"
|
||||
" h_anchor: str,\n"
|
||||
" label_scale: float,\n"
|
||||
" corner_radius: float,\n"
|
||||
") -> None\n"
|
||||
"\n"
|
||||
"(internal)",
|
||||
};
|
||||
|
||||
// -------------------- dev_console_add_python_terminal ------------------------
|
||||
|
||||
static auto PyDevConsoleAddPythonTerminal(PyObject* self, PyObject* args)
|
||||
-> PyObject* {
|
||||
BA_PYTHON_TRY;
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
auto* dev_console = g_base->ui->dev_console();
|
||||
BA_PRECONDITION(dev_console);
|
||||
BA_PRECONDITION(dev_console->IsActive());
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
dev_console->AddPythonTerminal();
|
||||
Py_RETURN_NONE;
|
||||
BA_PYTHON_CATCH;
|
||||
}
|
||||
|
||||
static PyMethodDef PyDevConsoleAddPythonTerminalDef = {
|
||||
"dev_console_add_python_terminal", // name
|
||||
(PyCFunction)PyDevConsoleAddPythonTerminal, // method
|
||||
METH_VARARGS, // flags
|
||||
|
||||
"dev_console_add_python_terminal() -> None\n"
|
||||
"\n"
|
||||
"(internal)",
|
||||
};
|
||||
|
||||
// ------------------------ dev_console_tab_width ------------------------------
|
||||
|
||||
static auto PyDevConsoleTabWidth(PyObject* self) -> PyObject* {
|
||||
BA_PYTHON_TRY;
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
auto* dev_console = g_base->ui->dev_console();
|
||||
BA_PRECONDITION(dev_console);
|
||||
BA_PRECONDITION(dev_console->IsActive());
|
||||
return PyFloat_FromDouble(dev_console->Width());
|
||||
BA_PYTHON_CATCH;
|
||||
}
|
||||
|
||||
static PyMethodDef PyDevConsoleTabWidthDef = {
|
||||
"dev_console_tab_width", // name
|
||||
(PyCFunction)PyDevConsoleTabWidth, // method
|
||||
METH_NOARGS, // flags
|
||||
|
||||
"dev_console_tab_width() -> float\n"
|
||||
"\n"
|
||||
"(internal)",
|
||||
};
|
||||
|
||||
// ------------------------ dev_console_tab_height -----------------------------
|
||||
|
||||
static auto PyDevConsoleTabHeight(PyObject* self) -> PyObject* {
|
||||
BA_PYTHON_TRY;
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
auto* dev_console = g_base->ui->dev_console();
|
||||
BA_PRECONDITION(dev_console);
|
||||
BA_PRECONDITION(dev_console->IsActive());
|
||||
return PyFloat_FromDouble(dev_console->Height());
|
||||
BA_PYTHON_CATCH;
|
||||
}
|
||||
|
||||
static PyMethodDef PyDevConsoleTabHeightDef = {
|
||||
"dev_console_tab_height", // name
|
||||
(PyCFunction)PyDevConsoleTabHeight, // method
|
||||
METH_NOARGS, // flags
|
||||
|
||||
"dev_console_tab_height() -> float\n"
|
||||
"\n"
|
||||
"(internal)",
|
||||
};
|
||||
|
||||
// ----------------------- dev_console_base_scale ------------------------------
|
||||
|
||||
static auto PyDevConsoleBaseScale(PyObject* self) -> PyObject* {
|
||||
BA_PYTHON_TRY;
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
auto* dev_console = g_base->ui->dev_console();
|
||||
BA_PRECONDITION(dev_console);
|
||||
BA_PRECONDITION(dev_console->IsActive());
|
||||
return PyFloat_FromDouble(dev_console->BaseScale());
|
||||
BA_PYTHON_CATCH;
|
||||
}
|
||||
|
||||
static PyMethodDef PyDevConsoleBaseScaleDef = {
|
||||
"dev_console_base_scale", // name
|
||||
(PyCFunction)PyDevConsoleBaseScale, // method
|
||||
METH_NOARGS, // flags
|
||||
|
||||
"dev_console_base_scale() -> float\n"
|
||||
"\n"
|
||||
"(internal)",
|
||||
};
|
||||
|
||||
// -------------------- dev_console_request_refresh ----------------------------
|
||||
|
||||
static auto PyDevConsoleRequestRefresh(PyObject* self) -> PyObject* {
|
||||
BA_PYTHON_TRY;
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
auto* dev_console = g_base->ui->dev_console();
|
||||
BA_PRECONDITION(dev_console);
|
||||
BA_PRECONDITION(dev_console->IsActive());
|
||||
dev_console->RequestRefresh();
|
||||
Py_RETURN_NONE;
|
||||
BA_PYTHON_CATCH;
|
||||
}
|
||||
|
||||
static PyMethodDef PyDevConsoleRequestRefreshDef = {
|
||||
"dev_console_request_refresh", // name
|
||||
(PyCFunction)PyDevConsoleRequestRefresh, // method
|
||||
METH_NOARGS, // flags
|
||||
|
||||
"dev_console_request_refresh() -> None\n"
|
||||
"\n"
|
||||
"(internal)",
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
auto PythonMethodsMisc::GetMethods() -> std::vector<PyMethodDef> {
|
||||
@ -1505,6 +1669,12 @@ auto PythonMethodsMisc::GetMethods() -> std::vector<PyMethodDef> {
|
||||
PyNativeStackTraceDef,
|
||||
PyOpenDirExternallyDef,
|
||||
PyFatalErrorDef,
|
||||
PyDevConsoleAddButtonDef,
|
||||
PyDevConsoleAddPythonTerminalDef,
|
||||
PyDevConsoleTabWidthDef,
|
||||
PyDevConsoleTabHeightDef,
|
||||
PyDevConsoleBaseScaleDef,
|
||||
PyDevConsoleRequestRefreshDef,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include "ballistica/core/core.h"
|
||||
#include "ballistica/core/platform/support/min_sdl.h"
|
||||
#include "ballistica/shared/foundation/event_loop.h"
|
||||
#include "ballistica/shared/foundation/macros.h"
|
||||
#include "ballistica/shared/generic/utils.h"
|
||||
#include "ballistica/shared/python/python_command.h"
|
||||
#include "ballistica/shared/python/python_sys.h"
|
||||
@ -103,7 +104,8 @@ class DevConsole::Button_ : public DevConsole::Widget_ {
|
||||
|
||||
template <typename F>
|
||||
Button_(const std::string& label, float text_scale, DevButtonAttach_ attach,
|
||||
float x, float y, float width, float height, const F& lambda)
|
||||
float x, float y, float width, float height, float corner_radius,
|
||||
const F& lambda)
|
||||
: attach{attach},
|
||||
x{x},
|
||||
y{y},
|
||||
@ -112,14 +114,10 @@ class DevConsole::Button_ : public DevConsole::Widget_ {
|
||||
call{NewLambdaRunnable(lambda)},
|
||||
text_scale{text_scale},
|
||||
mesh(0.0f, 0.0f, 0.0f, width, height,
|
||||
NinePatchMesh::BorderForRadius(kDevConsoleButtonCornerRadius,
|
||||
width, height),
|
||||
NinePatchMesh::BorderForRadius(kDevConsoleButtonCornerRadius,
|
||||
height, width),
|
||||
NinePatchMesh::BorderForRadius(kDevConsoleButtonCornerRadius,
|
||||
width, height),
|
||||
NinePatchMesh::BorderForRadius(kDevConsoleButtonCornerRadius,
|
||||
height, width)) {
|
||||
NinePatchMesh::BorderForRadius(corner_radius, width, height),
|
||||
NinePatchMesh::BorderForRadius(corner_radius, height, width),
|
||||
NinePatchMesh::BorderForRadius(corner_radius, width, height),
|
||||
NinePatchMesh::BorderForRadius(corner_radius, height, width)) {
|
||||
text_group.SetText(label, TextMesh::HAlign::kCenter,
|
||||
TextMesh::VAlign::kCenter);
|
||||
}
|
||||
@ -309,9 +307,10 @@ class DevConsole::TabButton_ : public DevConsole::Widget_ {
|
||||
}
|
||||
};
|
||||
|
||||
class DevConsole::Line_ {
|
||||
class DevConsole::OutputLine_ {
|
||||
public:
|
||||
Line_(std::string s_in, double c) : creation_time(c), s(std::move(s_in)) {}
|
||||
OutputLine_(std::string s_in, double c)
|
||||
: creation_time(c), s(std::move(s_in)) {}
|
||||
double creation_time;
|
||||
std::string s;
|
||||
auto GetText() -> TextGroup& {
|
||||
@ -340,43 +339,112 @@ DevConsole::DevConsole() {
|
||||
title_text_group_.SetText(title);
|
||||
built_text_group_.SetText("Built: " __DATE__ " " __TIME__);
|
||||
prompt_text_group_.SetText(">");
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void DevConsole::Refresh() {
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
buttons_.clear();
|
||||
tab_buttons_.clear();
|
||||
RefreshTabsButtons_();
|
||||
DevConsole::~DevConsole() = default;
|
||||
|
||||
if (active_tab_ == "Python") {
|
||||
float bs = PythonConsoleBaseScale_();
|
||||
buttons_.emplace_back(std::make_unique<Button_>(
|
||||
"Exec", 0.75f * bs, DevButtonAttach_::kRight, -33.0f * bs, 15.95f * bs,
|
||||
32.0f * bs, 13.0f * bs, [this] { Exec(); }));
|
||||
void DevConsole::RefreshTabButtons_() {
|
||||
// Ask the Python layer for the latest set of tabs.
|
||||
tabs_ = g_base->python->objs()
|
||||
.Get(BasePython::ObjID::kGetDevConsoleTabNamesCall)
|
||||
.Call()
|
||||
.ValueAsStringSequence();
|
||||
// If we have tabs and none of them are selected, select the first.
|
||||
if (!tabs_.empty()) {
|
||||
bool found{};
|
||||
for (auto&& tab : tabs_) {
|
||||
if (active_tab_ == tab) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
active_tab_ = tabs_.front();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DevConsole::RefreshTabsButtons_() {
|
||||
float bs = PythonConsoleBaseScale_();
|
||||
// Now rebuild our buttons for them.
|
||||
tab_buttons_.clear();
|
||||
float bs = BaseScale();
|
||||
float bwidth = 90.0f * bs;
|
||||
float bheight = 26.0f * bs;
|
||||
float bscale = 0.8f * bs;
|
||||
float total_width = tabs_.size() * bwidth;
|
||||
float x = total_width * -0.5f;
|
||||
|
||||
for (auto&& tab : tabs_) {
|
||||
tab_buttons_.emplace_back(std::make_unique<TabButton_>(
|
||||
tab, active_tab_ == tab, bscale, DevButtonAttach_::kCenter, x, -bheight,
|
||||
bwidth, bheight, [this, tab] {
|
||||
active_tab_ = tab;
|
||||
Refresh();
|
||||
RefreshTabButtons_();
|
||||
RefreshTabContents_();
|
||||
}));
|
||||
x += bwidth;
|
||||
}
|
||||
}
|
||||
DevConsole::~DevConsole() = default;
|
||||
|
||||
void DevConsole::RefreshTabContents_() {
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
|
||||
// Consider any refresh requests fulfilled. Subsequent refresh-requests
|
||||
// will generate a new refresh at this point.
|
||||
refresh_pending_ = false;
|
||||
|
||||
// Clear to an empty slate.
|
||||
buttons_.clear();
|
||||
python_terminal_visible_ = false;
|
||||
|
||||
// Now ask the Python layer to fill this tab in.
|
||||
PythonRef args(Py_BuildValue("(s)", active_tab_.c_str()), PythonRef::kSteal);
|
||||
g_base->python->objs()
|
||||
.Get(BasePython::ObjID::kAppDevConsoleDoRefreshTabCall)
|
||||
.Call(args);
|
||||
}
|
||||
|
||||
void DevConsole::AddButton(const char* label, float x, float y, float width,
|
||||
float height, PyObject* call, const char* h_anchor,
|
||||
float label_scale, float corner_radius) {
|
||||
assert(g_base->InLogicThread());
|
||||
|
||||
DevButtonAttach_ anchor;
|
||||
if (!strcmp(h_anchor, "left")) {
|
||||
anchor = DevButtonAttach_::kLeft;
|
||||
} else if (!strcmp(h_anchor, "right")) {
|
||||
anchor = DevButtonAttach_::kRight;
|
||||
} else {
|
||||
assert(!strcmp(h_anchor, "center"));
|
||||
anchor = DevButtonAttach_::kCenter;
|
||||
}
|
||||
|
||||
// auto call_obj = PythonRef::Acquired(call);
|
||||
buttons_.emplace_back(std::make_unique<Button_>(
|
||||
label, label_scale, anchor, x, y, width, height, corner_radius,
|
||||
[this, call_obj = PythonRef::Acquired(call)] {
|
||||
if (call_obj.Get() != Py_None) {
|
||||
call_obj.Call();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
void DevConsole::AddPythonTerminal() {
|
||||
float bs = BaseScale();
|
||||
buttons_.emplace_back(std::make_unique<Button_>(
|
||||
"Exec", 0.75f * bs, DevButtonAttach_::kRight, -33.0f * bs, 15.95f * bs,
|
||||
32.0f * bs, 13.0f * bs, 2.0 * bs, [this] { Exec(); }));
|
||||
python_terminal_visible_ = true;
|
||||
}
|
||||
|
||||
void DevConsole::RequestRefresh() {
|
||||
assert(g_base->InLogicThread());
|
||||
|
||||
// Schedule a refresh. If one is already scheduled but hasn't run, do
|
||||
// nothing.
|
||||
if (refresh_pending_) {
|
||||
return;
|
||||
}
|
||||
refresh_pending_ = true;
|
||||
g_base->logic->event_loop()->PushCall([this] { RefreshTabContents_(); });
|
||||
}
|
||||
|
||||
auto DevConsole::HandleMouseDown(int button, float x, float y) -> bool {
|
||||
assert(g_base->InLogicThread());
|
||||
@ -404,13 +472,21 @@ auto DevConsole::HandleMouseDown(int button, float x, float y) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (button == 1) {
|
||||
python_console_pressed_ = true;
|
||||
if (button == 1 && python_terminal_visible_) {
|
||||
python_terminal_pressed_ = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
auto DevConsole::Width() -> float {
|
||||
return g_base->graphics->screen_virtual_width();
|
||||
}
|
||||
|
||||
auto DevConsole::Height() -> float {
|
||||
return g_base->graphics->screen_virtual_height() - Bottom_();
|
||||
}
|
||||
|
||||
void DevConsole::HandleMouseUp(int button, float x, float y) {
|
||||
assert(g_base->InLogicThread());
|
||||
float bottom{Bottom_()};
|
||||
@ -424,8 +500,8 @@ void DevConsole::HandleMouseUp(int button, float x, float y) {
|
||||
}
|
||||
}
|
||||
|
||||
if (button == 1 && python_console_pressed_) {
|
||||
python_console_pressed_ = false;
|
||||
if (button == 1 && python_terminal_pressed_) {
|
||||
python_terminal_pressed_ = false;
|
||||
if (y > bottom) {
|
||||
// If we're not getting fed keyboard events and have a string editor
|
||||
// available, invoke it.
|
||||
@ -548,19 +624,6 @@ auto DevConsole::HandleKeyPress(const SDL_Keysym* keysym) -> bool {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// #if BA_SDL2_BUILD || BA_MINSDL_BUILD
|
||||
// // (in SDL2/Non-SDL we dont' get chars from keypress events;
|
||||
// // they come through as text edit events)
|
||||
// #else // BA_SDL2_BUILD
|
||||
// if (keysym->unicode < 0x80 && keysym->unicode > 0) {
|
||||
// std::vector<uint32_t> unichars =
|
||||
// Utils::UnicodeFromUTF8(input_string_, "cjofrh0");
|
||||
// unichars.push_back(keysym->unicode);
|
||||
// input_string_ = Utils::GetValidUTF8(
|
||||
// Utils::UTF8FromUnicode(unichars).c_str(), "sdkr");
|
||||
// input_text_dirty_ = true;
|
||||
// }
|
||||
// #endif // BA_SDL2_BUILD
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -576,9 +639,9 @@ void DevConsole::Exec() {
|
||||
input_history_position_ = 0;
|
||||
if (input_string_ == "clear") {
|
||||
last_line_.clear();
|
||||
lines_.clear();
|
||||
output_lines_.clear();
|
||||
} else {
|
||||
SubmitCommand_(input_string_);
|
||||
SubmitPythonCommand_(input_string_);
|
||||
}
|
||||
input_history_.push_front(input_string_);
|
||||
if (input_history_.size() > 100) {
|
||||
@ -588,7 +651,7 @@ void DevConsole::Exec() {
|
||||
input_text_dirty_ = true;
|
||||
}
|
||||
|
||||
void DevConsole::SubmitCommand_(const std::string& command) {
|
||||
void DevConsole::SubmitPythonCommand_(const std::string& command) {
|
||||
assert(g_base);
|
||||
g_base->logic->event_loop()->PushCall([command, this] {
|
||||
// These are always run in whichever context is 'visible'.
|
||||
@ -631,9 +694,12 @@ void DevConsole::ToggleState() {
|
||||
switch (state_) {
|
||||
case State_::kInactive:
|
||||
state_ = State_::kMini;
|
||||
RefreshTabButtons_();
|
||||
RefreshTabContents_();
|
||||
break;
|
||||
case State_::kMini:
|
||||
state_ = State_::kFull;
|
||||
RefreshTabContents_();
|
||||
break;
|
||||
case State_::kFull:
|
||||
state_ = State_::kInactive;
|
||||
@ -650,6 +716,9 @@ auto DevConsole::HandleTextEditing(const std::string& text) -> bool {
|
||||
}
|
||||
|
||||
// Ignore back-tick because we use that key to toggle the console.
|
||||
//
|
||||
// FIXME: Perhaps should allow typing it if some control-character is
|
||||
// held?
|
||||
if (text == "`") {
|
||||
return false;
|
||||
}
|
||||
@ -679,9 +748,9 @@ void DevConsole::Print(const std::string& s_in) {
|
||||
|
||||
// Spit out all completed lines and keep the last one as lastline.
|
||||
for (size_t i = 0; i < broken_up.size() - 1; i++) {
|
||||
lines_.emplace_back(broken_up[i], g_base->logic->display_time());
|
||||
if (lines_.size() > kDevConsoleLineLimit) {
|
||||
lines_.pop_front();
|
||||
output_lines_.emplace_back(broken_up[i], g_base->logic->display_time());
|
||||
if (output_lines_.size() > kDevConsoleLineLimit) {
|
||||
output_lines_.pop_front();
|
||||
}
|
||||
}
|
||||
last_line_ = broken_up[broken_up.size() - 1];
|
||||
@ -689,13 +758,18 @@ void DevConsole::Print(const std::string& s_in) {
|
||||
}
|
||||
|
||||
auto DevConsole::Bottom_() const -> float {
|
||||
float bs = PythonConsoleBaseScale_();
|
||||
float vh = g_base->graphics->screen_virtual_height();
|
||||
|
||||
float ratio =
|
||||
(g_base->logic->display_time() - transition_start_) / kTransitionSeconds;
|
||||
float bottom;
|
||||
float mini_size = 90.0f * bs;
|
||||
|
||||
// NOTE: Originally I was tweaking this based on UI scale, but I decided
|
||||
// that it would be a better idea to have a constant value everywhere.
|
||||
// dev-consoles are not meant to be especially pretty and I think it is
|
||||
// more important for them to be able to be written to a known hard-coded
|
||||
// mini-size.
|
||||
float mini_size = 100.0f;
|
||||
if (state_ == State_::kMini) {
|
||||
bottom = vh - mini_size;
|
||||
} else {
|
||||
@ -724,7 +798,7 @@ auto DevConsole::Bottom_() const -> float {
|
||||
}
|
||||
|
||||
void DevConsole::Draw(FrameDef* frame_def) {
|
||||
float bs = PythonConsoleBaseScale_();
|
||||
float bs = BaseScale();
|
||||
RenderPass* pass = frame_def->overlay_front_pass();
|
||||
|
||||
// If we're not yet transitioning in for the first time OR have completed
|
||||
@ -753,7 +827,7 @@ void DevConsole::Draw(FrameDef* frame_def) {
|
||||
c.SetColor(0, 0, 0.1f, 0.9f);
|
||||
c.DrawMesh(&bg_mesh_);
|
||||
c.Submit();
|
||||
if (active_tab_ == "Python") {
|
||||
if (python_terminal_visible_) {
|
||||
c.SetColor(1.0f, 1.0f, 1.0f, 0.1f);
|
||||
c.DrawMesh(&stripe_mesh_);
|
||||
c.Submit();
|
||||
@ -779,7 +853,7 @@ void DevConsole::Draw(FrameDef* frame_def) {
|
||||
}
|
||||
}
|
||||
|
||||
if (active_tab_ == "Python") {
|
||||
if (python_terminal_visible_) {
|
||||
if (input_text_dirty_) {
|
||||
input_text_group_.SetText(input_string_);
|
||||
input_text_dirty_ = false;
|
||||
@ -887,7 +961,7 @@ void DevConsole::Draw(FrameDef* frame_def) {
|
||||
}
|
||||
v += v_inc;
|
||||
}
|
||||
for (auto i = lines_.rbegin(); i != lines_.rend(); i++) {
|
||||
for (auto i = output_lines_.rbegin(); i != output_lines_.rend(); i++) {
|
||||
int elem_count = i->GetText().GetElementCount();
|
||||
for (int e = 0; e < elem_count; e++) {
|
||||
c.SetTexture(i->GetText().GetElementTexture(e));
|
||||
@ -922,7 +996,7 @@ void DevConsole::Draw(FrameDef* frame_def) {
|
||||
}
|
||||
}
|
||||
|
||||
auto DevConsole::PythonConsoleBaseScale_() const -> float {
|
||||
auto DevConsole::BaseScale() const -> float {
|
||||
switch (g_base->ui->scale()) {
|
||||
case UIScale::kLarge:
|
||||
return 1.5f;
|
||||
|
||||
@ -51,24 +51,42 @@ class DevConsole {
|
||||
auto HandleMouseDown(int button, float x, float y) -> bool;
|
||||
void HandleMouseUp(int button, float x, float y);
|
||||
void Exec();
|
||||
void Refresh();
|
||||
|
||||
void AddButton(const char* label, float x, float y, float width, float height,
|
||||
PyObject* call, const char* h_anchor, float label_scale,
|
||||
float corner_radius);
|
||||
void AddPythonTerminal();
|
||||
|
||||
auto Width() -> float;
|
||||
auto Height() -> float;
|
||||
auto BaseScale() const -> float;
|
||||
void RequestRefresh();
|
||||
|
||||
private:
|
||||
class Widget_;
|
||||
class Button_;
|
||||
class ToggleButton_;
|
||||
class TabButton_;
|
||||
class Line_;
|
||||
enum class State_ { kInactive, kMini, kFull };
|
||||
class OutputLine_;
|
||||
enum class State_ : uint8_t { kInactive, kMini, kFull };
|
||||
|
||||
auto Bottom_() const -> float;
|
||||
auto PythonConsoleBaseScale_() const -> float;
|
||||
void SubmitCommand_(const std::string& command);
|
||||
void SubmitPythonCommand_(const std::string& command);
|
||||
void InvokeStringEditor_();
|
||||
void RefreshTabsButtons_();
|
||||
void RefreshTabButtons_();
|
||||
void RefreshTabContents_();
|
||||
|
||||
std::list<std::string> tabs_{"Python", "AppModes", "Logging", "Graphics"};
|
||||
std::string active_tab_{"Python"};
|
||||
bool input_text_dirty_{true};
|
||||
bool input_enabled_{};
|
||||
bool last_line_mesh_dirty_{true};
|
||||
bool python_terminal_visible_{};
|
||||
bool python_terminal_pressed_{};
|
||||
bool refresh_pending_{};
|
||||
State_ state_{State_::kInactive};
|
||||
State_ state_prev_{State_::kInactive};
|
||||
millisecs_t last_input_text_change_time_{};
|
||||
double transition_start_{};
|
||||
int input_history_position_{};
|
||||
ImageMesh bg_mesh_;
|
||||
ImageMesh stripe_mesh_;
|
||||
ImageMesh border_mesh_;
|
||||
@ -76,21 +94,15 @@ class DevConsole {
|
||||
TextGroup title_text_group_;
|
||||
TextGroup prompt_text_group_;
|
||||
TextGroup input_text_group_;
|
||||
millisecs_t last_input_text_change_time_{};
|
||||
bool input_text_dirty_{true};
|
||||
double transition_start_{};
|
||||
State_ state_{State_::kInactive};
|
||||
State_ state_prev_{State_::kInactive};
|
||||
bool input_enabled_{};
|
||||
std::string input_string_;
|
||||
std::list<std::string> input_history_;
|
||||
int input_history_position_{};
|
||||
std::list<Line_> lines_;
|
||||
std::string last_line_;
|
||||
Object::Ref<TextGroup> last_line_mesh_group_;
|
||||
bool last_line_mesh_dirty_{true};
|
||||
bool python_console_pressed_{};
|
||||
std::string input_string_;
|
||||
std::list<std::string> tabs_{"Python", "AppModes", "Logging", "Graphics",
|
||||
"UI"};
|
||||
std::string active_tab_{"Python"};
|
||||
PythonRef string_edit_adapter_;
|
||||
Object::Ref<TextGroup> last_line_mesh_group_;
|
||||
std::list<std::string> input_history_;
|
||||
std::list<OutputLine_> output_lines_;
|
||||
std::vector<std::unique_ptr<Widget_> > buttons_;
|
||||
std::vector<std::unique_ptr<Widget_> > tab_buttons_;
|
||||
};
|
||||
|
||||
@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
|
||||
namespace ballistica {
|
||||
|
||||
// These are set automatically via script; don't modify them here.
|
||||
const int kEngineBuildNumber = 21401;
|
||||
const int kEngineBuildNumber = 21405;
|
||||
const char* kEngineVersion = "1.7.28";
|
||||
const int kEngineApiVersion = 8;
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
#endif
|
||||
|
||||
#define BA_OSTYPE_MACOS 1
|
||||
#define BA_HAVE_FRAMEWORK_OPENAL 1
|
||||
// #define BA_HAVE_FRAMEWORK_OPENAL 1
|
||||
|
||||
#elif __linux__
|
||||
|
||||
|
||||
@ -225,7 +225,7 @@ auto Python::GetPyFloats(PyObject* o) -> std::vector<float> {
|
||||
return vals;
|
||||
}
|
||||
|
||||
auto Python::GetPyStrings(PyObject* o) -> std::list<std::string> {
|
||||
auto Python::GetPyStringSequence(PyObject* o) -> std::list<std::string> {
|
||||
assert(HaveGIL());
|
||||
BA_PRECONDITION_FATAL(o != nullptr);
|
||||
|
||||
|
||||
@ -125,7 +125,7 @@ class Python {
|
||||
static auto GetPyInts(PyObject* o) -> std::vector<int>;
|
||||
static auto GetPyUInts64(PyObject* o) -> std::vector<uint64_t>;
|
||||
static auto GetPyPoint2D(PyObject* o) -> Point2D;
|
||||
static auto GetPyStrings(PyObject* o) -> std::list<std::string>;
|
||||
static auto GetPyStringSequence(PyObject* o) -> std::list<std::string>;
|
||||
|
||||
/// Set Python exception from C++ Exception.
|
||||
static void SetPythonException(const Exception& exc);
|
||||
|
||||
@ -162,6 +162,12 @@ auto PythonRef::ValueAsString() const -> std::string {
|
||||
return Python::GetPyString(obj_);
|
||||
}
|
||||
|
||||
auto PythonRef::ValueAsStringSequence() const -> std::list<std::string> {
|
||||
assert(Python::HaveGIL());
|
||||
ThrowIfUnset();
|
||||
return Python::GetPyStringSequence(obj_);
|
||||
}
|
||||
|
||||
auto PythonRef::ValueAsOptionalInt() const -> std::optional<int64_t> {
|
||||
assert(Python::HaveGIL());
|
||||
ThrowIfUnset();
|
||||
@ -193,7 +199,7 @@ auto PythonRef::ValueAsOptionalStringSequence() const
|
||||
if (obj_ == Py_None) {
|
||||
return {};
|
||||
}
|
||||
return Python::GetPyStrings(obj_);
|
||||
return Python::GetPyStringSequence(obj_);
|
||||
}
|
||||
|
||||
auto PythonRef::ValueAsInt() const -> int64_t {
|
||||
|
||||
@ -166,6 +166,7 @@ class PythonRef {
|
||||
auto ValueAsLString() const -> std::string;
|
||||
|
||||
auto ValueAsString() const -> std::string;
|
||||
auto ValueAsStringSequence() const -> std::list<std::string>;
|
||||
auto ValueAsOptionalString() const -> std::optional<std::string>;
|
||||
auto ValueAsOptionalStringSequence() const
|
||||
-> std::optional<std::list<std::string>>;
|
||||
|
||||
@ -53,6 +53,7 @@ values = [
|
||||
_hooks.do_quit, # kQuitCall
|
||||
_hooks.show_post_purchase_message, # kShowPostPurchaseMessageCall
|
||||
_hooks.string_edit_adapter_can_be_replaced, # kStringEditAdapterCanBeReplacedCall
|
||||
_hooks.get_dev_console_tab_names, # kGetDevConsoleTabNamesCall
|
||||
_language.Lstr, # kLStrClass
|
||||
_general.Call, # kCallClass
|
||||
_apputils.garbage_collect_session_end, # kGarbageCollectSessionEndCall
|
||||
|
||||
@ -19,4 +19,5 @@ values = [
|
||||
app.on_native_shutdown, # kAppOnNativeShutdownCall
|
||||
app.on_native_shutdown_complete, # kAppOnNativeShutdownCompleteCall
|
||||
app.read_config, # kAppReadConfigCall
|
||||
app.devconsole.do_refresh_tab, # kAppDevConsoleDoRefreshTabCall
|
||||
]
|
||||
|
||||
@ -36,7 +36,6 @@ class HostConfig:
|
||||
mosh_shell: str = 'sh'
|
||||
workspaces_root: str = '/home/${USER}/cloudshell_workspaces'
|
||||
sync_perms: bool = True
|
||||
precommand: str | None = None # KILL THIS
|
||||
precommand_noninteractive: str | None = None
|
||||
precommand_interactive: str | None = None
|
||||
managed: bool = False
|
||||
|
||||
@ -728,16 +728,18 @@ def echo() -> None:
|
||||
clrnames = {n for n in dir(clr) if n.isupper() and not n.startswith('_')}
|
||||
first = True
|
||||
out: list[str] = []
|
||||
last_was_tag = False
|
||||
for arg in pcommand.get_args():
|
||||
if arg in clrnames:
|
||||
out.append(getattr(clr, arg))
|
||||
last_was_tag = True
|
||||
else:
|
||||
# Special case: a dot by itself is treated as a period for
|
||||
# the previous arg. This lets us do periods following color
|
||||
# tags.
|
||||
if not first and arg != '.':
|
||||
# Special case: punctuation by itself after a tag doesn't
|
||||
# get a space before it.
|
||||
if not first and not (last_was_tag and arg in ('.', '?', '!')):
|
||||
out.append(' ')
|
||||
first = False
|
||||
last_was_tag = False
|
||||
out.append(arg)
|
||||
out.append(clr.RST)
|
||||
pcommand.clientprint(''.join(out))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user