mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-24 16:06:51 +08:00
simplifying c++ bootstrapping
This commit is contained in:
parent
b837d3707e
commit
014a996933
@ -3995,50 +3995,50 @@
|
||||
"assets/src/ba_data/python/ba/_generated/__init__.py": "https://files.ballistica.net/cache/ba1/ee/e8/cad05aa531c7faf7ff7b96db7f6e",
|
||||
"assets/src/ba_data/python/ba/_generated/enums.py": "https://files.ballistica.net/cache/ba1/b2/e5/0ee0561e16257a32830645239f34",
|
||||
"ballisticacore-windows/Generic/BallisticaCore.ico": "https://files.ballistica.net/cache/ba1/89/c0/e32c7d2a35dc9aef57cc73b0911a",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c7/7c/11757954adb7da34c0e8cb6a6470",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/30/4e/361603ee5faf75168ddefd070b44",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b6/2e/e3bd12f2c9e7baa173479686485d",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1e/fe/0f73516a00159f6cd4b4791f010d",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/60/a4/f6798a377123b4f0ea58067173b9",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/60/0d/772009d20e18def687f6b76021f8",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ec/98/ca24d22fa6870cf2fa4b1dc81e2a",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ab/71/616a553794306a406be45697895c",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/41/14/bae7db8e7361d538096253c36792",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/91/5f/d2bfb2b30befdae9270a119d51b5",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d8/07/bd414612e9bf05f2a3c0b531a552",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/49/64/5943868e08758fc103e8ce70f334",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/1a/a9/bae1d4c1840d6e4c1931c529e4f8",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/22/a9/75669c9a475fc8080ce422ce2baa",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e1/87/95cbc6fc53e43e206f43eb3a1c61",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a4/1b/9a6145a32ef40fd3b8357cfbfb30",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/6a/a5/5afd24a1043a652af8ae76ec33ea",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/dd/3a/71c400bbac9edc5fa7b63e099ae7",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/dc/18/7e47d66f054e81314b39c14b26dc",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/43/25/36e8e8fc1eac369727f9639bbcf9",
|
||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e7/25/6fb628f1f5260834692bdeab63b0",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/e4/55/ec1e32f714af2ad914ea2c5e35b0",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c2/29/5c9ef7b0c3b068c700835f62abe6",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/60/30/248f57b0e0950c74aef828fe3667",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/62/3c/1b789be64fa12c6dd4609271c0b8",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ca/bf/66e24379dff682f1fb33d96b8c72",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ce/e9/e578aecdd0146a4a242dacbef95d",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/11/b8/76cf26f61214c4b75e8515f0766a",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d8/c0/74a187c3ebddec6313ea6385343d",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/90/74/0e809006cb921253e92b78d87ec8",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/7c/de/d2ceb7f9d52f78a33792395c4f2e",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/51/71/1a249c35f5a9459322c546b1ec5a",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d5/0a/56f81ecbdc45218159edf9c08aeb",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/25/5d/4569f3ae73cfa0a33427885ef5b4",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/74/2e/c987767fca3cc4b5bb738e259b0a",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6b/8a/79e987afa129e07d36486cad1602",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b1/c0/46efd467c46e3ad8ed64d3893e1e",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/f8/51/80d6f06fb1579a95f79796e14235",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/32/6d/9190219d7454f5cc2d75bcaa7084",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/fc/39/4f03d2ebf27e521d4d8b3cc6313d",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/9d/22/8e1aa2c9ac9c589985b7ff6d744f",
|
||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d9/e3/5491d9859e329f629adb139e1c02",
|
||||
"build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/86/d2/d18cbc017a7d64001f96718cc5ed",
|
||||
"build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8e/e5/cfbcc97e2b8c7ee46d0422e54380",
|
||||
"build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d3/5f/a6501aae21bc6dbda5503cd3ed74",
|
||||
"build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/06/70/9e5becbdf873ea42fae9541dd123",
|
||||
"build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0d/18/6a515fce87613b2293a8f7bf1a35",
|
||||
"build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/94/19/7c70a5388ab5dc9f8b4cd2a643bd",
|
||||
"build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a3/47/f46d4455e6ee1ebb397508495d90",
|
||||
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/14/49/890119e5ff8800edf3b3cda113df",
|
||||
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/53/63/891be47740b031ad1e08f6fe9c77",
|
||||
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4c/32/de6296fdbd72d6a82d47a2403efd",
|
||||
"build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/89/94/c90bb234585a62a097c6f6642e7d",
|
||||
"build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e6/be/16d22d7d53a87ad6c9e1b7835950",
|
||||
"build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/39/2c/773ff4c64734bcd6205080a0563d",
|
||||
"build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0c/18/4a032d351000cf732bb7494d85f7",
|
||||
"build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/24/a6/eb221317cdae775c195aa81a2f0c",
|
||||
"build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4b/9d/be9915b6f1f1a0d83ae11885bd42",
|
||||
"build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/31/d2/e658b66d64c828f85d84a9b0d482",
|
||||
"build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4b/84/6074d1f32482e5a1914aac08747f",
|
||||
"build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/31/26/5c531133795d1381ced85e519b10",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/24/4f/c0a11a834ae10e9706bf92879d23",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0d/75/0044708d9f8af5ba85bbe9709f92",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a3/c6/d9b0509fe23a07de2ccee6ba1fd4",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/1b/93/23b7d341894fb875acaefe0804c5",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/86/e1/65b4096af71168842a99278708da",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/d8/91/3b918141edeaeb3034e558f54246",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/74/ff/12db4137ed498dbbffd892c5000f",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/41/0a/18695d2503c1062d7b2f47c88380",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/2d/59/5bd72f8f691f041059cab3df99d5",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/3b/63/7eeb46b7832e1135e58345866abf",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/89/e4/0b7890024077f73e328b20b543f5",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/16/a1/0283e8d4c813236f30f558fe7152",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/80/76/3f3b0aa3ee0c39b276d55adf31f5",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/32/39/1a7d9be4330f5c74f67c6f7e22d8",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/1c/c6/59922c32624d3a93be2080c1ff7d",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/9f/4e/4e6d977fb3bff4746d3c599e7567",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/7f/28/36b8586b6b139ccb052accc29d2b",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/8c/b6/99368c99f9b63242df1f1875b5b5",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/74/9c/09e7f929fbcf075d41b976200950",
|
||||
"src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/7d/3e/229a581cb2454ed856f1d8b564a7",
|
||||
"src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/98/12/571b2160d69d42580e8f31fa6a8d"
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
### 1.7.7 (build 20809, api 7, 2022-09-10)
|
||||
### 1.7.7 (build 20821, api 7, 2022-09-11)
|
||||
- Added `ba.app.meta.load_exported_classes()` for loading classes discovered by the meta subsystem cleanly in a background thread.
|
||||
- Improved logging of missing playlist game types.
|
||||
- Some ba.Lstr functionality can now be used in background threads.
|
||||
@ -23,6 +23,7 @@
|
||||
- Renamed C++ App to AppFlavor and AppGlobals to App.
|
||||
- Renamed C++ Media to Assets.
|
||||
- Removed 'scores to beat' list in coop which was only ever functional in limited cases on the Mac version. Perhaps that feature can reappear in a cross-platform way sometime.
|
||||
- Simplified C++ bootstrapping to allocate all globals in one place.
|
||||
|
||||
### 1.7.6 (build 20687, api 7, 2022-08-11)
|
||||
- Cleaned up da MetaSubsystem code.
|
||||
|
||||
@ -38,7 +38,7 @@ def bootstrap() -> None:
|
||||
|
||||
# Give a soft warning if we're being used with a different binary
|
||||
# version than we expect.
|
||||
expected_build = 20809
|
||||
expected_build = 20821
|
||||
running_build: int = env['build_number']
|
||||
if running_build != expected_build:
|
||||
print(
|
||||
|
||||
@ -13,24 +13,15 @@
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
// The first thing the engine does is allocate an instance of this as g_globals.
|
||||
// As much as possible, previously static/global values should be moved to here,
|
||||
// ideally as a temporary measure until they can be placed as non-static members
|
||||
// in the proper classes.
|
||||
// Any use of non-trivial global/static values such as class instances should be
|
||||
// avoided since it can introduce ambiguities during init and teardown.
|
||||
// For more explanation, see the 'Static and Global Variables' section in the
|
||||
// Google C++ Style Guide.
|
||||
// The first thing the engine does is allocate an instance of this as g_app.
|
||||
class App {
|
||||
public:
|
||||
App(int argc, char** argv);
|
||||
|
||||
/// Program argument count (on applicable platforms).
|
||||
// The following are misc values that should be migrated to applicable
|
||||
// subsystem classes.
|
||||
int argc{};
|
||||
|
||||
/// Program argument values (on applicable platforms).
|
||||
char** argv{};
|
||||
|
||||
bool threads_paused{};
|
||||
std::unordered_map<std::string, NodeType*> node_types;
|
||||
std::unordered_map<int, NodeType*> node_types_by_id;
|
||||
|
||||
@ -8,8 +8,6 @@
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
void AppConfig::Init() { new AppConfig(); }
|
||||
|
||||
auto AppConfig::Entry::FloatValue() const -> float {
|
||||
throw Exception("not a float entry");
|
||||
}
|
||||
@ -137,12 +135,7 @@ class AppConfig::BoolEntry : public AppConfig::Entry {
|
||||
bool default_value_{};
|
||||
};
|
||||
|
||||
AppConfig::AppConfig() {
|
||||
// (We're a singleton).
|
||||
assert(g_app_config == nullptr);
|
||||
g_app_config = this;
|
||||
SetupEntries();
|
||||
}
|
||||
AppConfig::AppConfig() { SetupEntries(); }
|
||||
|
||||
// Clion think all calls of this are unreachable.
|
||||
#pragma clang diagnostic push
|
||||
|
||||
@ -94,7 +94,6 @@ class AppConfig {
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
static void Init();
|
||||
AppConfig();
|
||||
|
||||
// Given specific ids, returns resolved values (fastest access).
|
||||
|
||||
@ -607,20 +607,8 @@ void Assets::MarkComponentForLoad(AssetComponentData* c) {
|
||||
// once it makes it back to us we can delete the ref (in
|
||||
// ClearPendingLoadsDoneList)
|
||||
|
||||
auto asset_ptr = new Object::Ref<AssetComponentData>(c);
|
||||
|
||||
g_assets_server->thread()->PushCall([asset_ptr] {
|
||||
assert(InAssetsThread());
|
||||
|
||||
// add our pointer to one of the preload lists and shake our preload thread
|
||||
// to wake it up
|
||||
if ((**asset_ptr).GetAssetType() == AssetType::kSound) {
|
||||
g_assets_server->pending_preloads_audio_.push_back(asset_ptr);
|
||||
} else {
|
||||
g_assets_server->pending_preloads_.push_back(asset_ptr);
|
||||
}
|
||||
g_assets_server->process_timer_->SetLength(0);
|
||||
});
|
||||
auto asset_ref_ptr = new Object::Ref<AssetComponentData>(c);
|
||||
g_assets_server->PushPendingPreload(asset_ref_ptr);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
|
||||
@ -12,21 +12,45 @@
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
AssetsServer::AssetsServer(Thread* thread)
|
||||
: thread_(thread),
|
||||
writing_replay_(false),
|
||||
AssetsServer::AssetsServer()
|
||||
: writing_replay_(false),
|
||||
replay_message_bytes_(0),
|
||||
replays_broken_(false),
|
||||
replay_out_file_(nullptr) {
|
||||
// We're a singleton; make sure we don't already exist.
|
||||
assert(g_assets_server == nullptr);
|
||||
g_assets_server = this;
|
||||
|
||||
// get our thread to give us periodic processing time...
|
||||
process_timer_ = this->thread()->NewTimer(
|
||||
1000, true, NewLambdaRunnable([this] { Process(); }));
|
||||
// Spin up our thread.
|
||||
thread_ = new Thread(ThreadIdentifier::kAssets);
|
||||
g_app->pausable_threads.push_back(thread_);
|
||||
}
|
||||
|
||||
AssetsServer::~AssetsServer() = default;
|
||||
auto AssetsServer::Start() -> void {
|
||||
thread_->PushCallSynchronous([this] { StartInThread(); });
|
||||
}
|
||||
|
||||
auto AssetsServer::StartInThread() -> void {
|
||||
assert(InAssetsThread());
|
||||
// get our thread to give us periodic processing time...
|
||||
process_timer_ =
|
||||
thread()->NewTimer(1000, true, NewLambdaRunnable([this] { Process(); }));
|
||||
}
|
||||
|
||||
auto AssetsServer::PushPendingPreload(
|
||||
Object::Ref<AssetComponentData>* asset_ref_ptr) -> void {
|
||||
thread()->PushCall([this, asset_ref_ptr] {
|
||||
assert(InAssetsThread());
|
||||
|
||||
// Add our pointer to one of the preload lists and shake our preload thread
|
||||
// to wake it up
|
||||
if ((**asset_ref_ptr).GetAssetType() == AssetType::kSound) {
|
||||
pending_preloads_audio_.push_back(asset_ref_ptr);
|
||||
} else {
|
||||
pending_preloads_.push_back(asset_ref_ptr);
|
||||
}
|
||||
process_timer_->SetLength(0);
|
||||
});
|
||||
}
|
||||
|
||||
void AssetsServer::PushBeginWriteReplayCall() {
|
||||
thread()->PushCall([this] {
|
||||
|
||||
@ -12,14 +12,17 @@ namespace ballistica {
|
||||
|
||||
class AssetsServer {
|
||||
public:
|
||||
explicit AssetsServer(Thread* thread);
|
||||
~AssetsServer();
|
||||
void PushBeginWriteReplayCall();
|
||||
void PushEndWriteReplayCall();
|
||||
void PushAddMessageToReplayCall(const std::vector<uint8_t>& data);
|
||||
AssetsServer();
|
||||
auto Start() -> void;
|
||||
auto PushBeginWriteReplayCall() -> void;
|
||||
auto PushEndWriteReplayCall() -> void;
|
||||
auto PushAddMessageToReplayCall(const std::vector<uint8_t>& data) -> void;
|
||||
auto PushPendingPreload(Object::Ref<AssetComponentData>* asset_ref_ptr)
|
||||
-> void;
|
||||
auto thread() const -> Thread* { return thread_; }
|
||||
|
||||
private:
|
||||
auto StartInThread() -> void;
|
||||
void Process();
|
||||
void WriteReplayMessages();
|
||||
Thread* thread_{};
|
||||
@ -32,8 +35,6 @@ class AssetsServer {
|
||||
Timer* process_timer_{};
|
||||
std::vector<Object::Ref<AssetComponentData>*> pending_preloads_;
|
||||
std::vector<Object::Ref<AssetComponentData>*> pending_preloads_audio_;
|
||||
friend struct PreloadRunnable;
|
||||
friend class Assets;
|
||||
};
|
||||
|
||||
} // namespace ballistica
|
||||
|
||||
@ -9,13 +9,7 @@
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
Audio::Audio() { assert(InLogicThread()); }
|
||||
|
||||
void Audio::Init() {
|
||||
// Init our singleton.
|
||||
assert(g_audio == nullptr);
|
||||
g_audio = new Audio();
|
||||
}
|
||||
Audio::Audio() {}
|
||||
|
||||
void Audio::Reset() {
|
||||
assert(InLogicThread());
|
||||
|
||||
@ -15,14 +15,15 @@ namespace ballistica {
|
||||
/// used by the game and/or other threads.
|
||||
class Audio {
|
||||
public:
|
||||
static void Init();
|
||||
void Reset();
|
||||
Audio();
|
||||
auto Reset() -> void;
|
||||
|
||||
void SetVolumes(float music_volume, float sound_volume);
|
||||
auto SetVolumes(float music_volume, float sound_volume) -> void;
|
||||
|
||||
void SetListenerPosition(const Vector3f& p);
|
||||
void SetListenerOrientation(const Vector3f& forward, const Vector3f& up);
|
||||
void SetSoundPitch(float pitch);
|
||||
auto SetListenerPosition(const Vector3f& p) -> void;
|
||||
auto SetListenerOrientation(const Vector3f& forward, const Vector3f& up)
|
||||
-> void;
|
||||
auto SetSoundPitch(float pitch) -> void;
|
||||
|
||||
// Return a pointer to a locked sound source, or nullptr if they're all busy.
|
||||
// The sound source will be reset to standard settings (no loop, fade 1, pos
|
||||
@ -41,9 +42,9 @@ class Audio {
|
||||
auto IsSoundPlaying(uint32_t play_id) -> bool;
|
||||
|
||||
// Simple one-shot play functions.
|
||||
void PlaySound(SoundData* s, float volume = 1.0f);
|
||||
void PlaySoundAtPosition(SoundData* sound, float volume, float x, float y,
|
||||
float z);
|
||||
auto PlaySound(SoundData* s, float volume = 1.0f) -> void;
|
||||
auto PlaySoundAtPosition(SoundData* sound, float volume, float x, float y,
|
||||
float z) -> void;
|
||||
|
||||
// Call this if you want to prevent repeated plays of the same sound. It'll
|
||||
// tell you if the sound has been played recently. The one-shot sound-play
|
||||
@ -51,19 +52,17 @@ class Audio {
|
||||
auto ShouldPlay(SoundData* s) -> bool;
|
||||
|
||||
// Hmm; shouldn't these be accessed through the Source class?
|
||||
void PushSourceFadeOutCall(uint32_t play_id, uint32_t time);
|
||||
void PushSourceStopSoundCall(uint32_t play_id);
|
||||
auto PushSourceFadeOutCall(uint32_t play_id, uint32_t time) -> void;
|
||||
auto PushSourceStopSoundCall(uint32_t play_id) -> void;
|
||||
|
||||
void AddClientSource(AudioSource* source);
|
||||
auto AddClientSource(AudioSource* source) -> void;
|
||||
|
||||
void MakeSourceAvailable(AudioSource* source);
|
||||
auto MakeSourceAvailable(AudioSource* source) -> void;
|
||||
auto available_sources_mutex() -> std::mutex& {
|
||||
return available_sources_mutex_;
|
||||
}
|
||||
|
||||
private:
|
||||
Audio();
|
||||
|
||||
// Flat list of client sources indexed by id.
|
||||
std::vector<AudioSource*> client_sources_;
|
||||
|
||||
|
||||
@ -30,10 +30,10 @@ extern "C" void opensl_resume_playback();
|
||||
extern std::string g_rift_audio_device_name;
|
||||
#endif
|
||||
|
||||
const int kAudioProcessIntervalNormal = 500;
|
||||
const int kAudioProcessIntervalFade = 50;
|
||||
const int kAudioProcessIntervalPendingLoad = 1;
|
||||
const bool kShowInUseSounds = false;
|
||||
const int kAudioProcessIntervalNormal{500};
|
||||
const int kAudioProcessIntervalFade{50};
|
||||
const int kAudioProcessIntervalPendingLoad{1};
|
||||
const bool kShowInUseSounds{};
|
||||
|
||||
int AudioServer::al_source_count_ = 0;
|
||||
|
||||
@ -55,7 +55,7 @@ class AudioServer::ThreadSource : public Object {
|
||||
// not be used.
|
||||
ThreadSource(AudioServer* audio_thread, int id, bool* valid);
|
||||
~ThreadSource() override;
|
||||
void Reset() {
|
||||
auto Reset() -> void {
|
||||
SetIsMusic(false);
|
||||
SetPositional(true);
|
||||
SetPosition(0, 0, 0);
|
||||
@ -66,18 +66,18 @@ class AudioServer::ThreadSource : public Object {
|
||||
|
||||
/// Set whether a sound is "music".
|
||||
/// This influences which volume controls affect it.
|
||||
void SetIsMusic(bool m);
|
||||
auto SetIsMusic(bool m) -> void;
|
||||
|
||||
/// Set whether a source is positional.
|
||||
/// A non-positional source's position coords are always relative to the
|
||||
/// listener - ie: 0, 0, 0 will always be centered.
|
||||
void SetPositional(bool p);
|
||||
void SetPosition(float x, float y, float z);
|
||||
void SetGain(float g);
|
||||
void SetFade(float f);
|
||||
void SetLooping(bool loop);
|
||||
auto SetPositional(bool p) -> void;
|
||||
auto SetPosition(float x, float y, float z) -> void;
|
||||
auto SetGain(float g) -> void;
|
||||
auto SetFade(float f) -> void;
|
||||
auto SetLooping(bool loop) -> void;
|
||||
auto Play(const Object::Ref<SoundData>* s) -> uint32_t;
|
||||
void Stop();
|
||||
auto Stop() -> void;
|
||||
auto play_count() -> uint32_t { return play_count_; }
|
||||
auto is_streamed() const -> bool { return is_streamed_; }
|
||||
auto current_is_music() const -> bool { return current_is_music_; }
|
||||
@ -93,34 +93,34 @@ class AudioServer::ThreadSource : public Object {
|
||||
return source_sound_ ? source_sound_->get() : nullptr;
|
||||
}
|
||||
|
||||
void UpdatePitch();
|
||||
void UpdateVolume();
|
||||
void ExecStop();
|
||||
void ExecPlay();
|
||||
void Update();
|
||||
auto UpdatePitch() -> void;
|
||||
auto UpdateVolume() -> void;
|
||||
auto ExecStop() -> void;
|
||||
auto ExecPlay() -> void;
|
||||
auto Update() -> void;
|
||||
|
||||
private:
|
||||
bool looping_ = false;
|
||||
bool looping_{};
|
||||
std::unique_ptr<AudioSource> client_source_;
|
||||
float fade_ = 1.0f;
|
||||
float gain_ = 1.0f;
|
||||
AudioServer* audio_thread_;
|
||||
bool valid_ = false;
|
||||
const Object::Ref<SoundData>* source_sound_ = nullptr;
|
||||
int id_;
|
||||
uint32_t play_count_ = 0;
|
||||
bool is_actually_playing_ = false;
|
||||
bool want_to_play_ = false;
|
||||
float fade_{1.0f};
|
||||
float gain_{1.0f};
|
||||
AudioServer* audio_thread_{};
|
||||
bool valid_{};
|
||||
const Object::Ref<SoundData>* source_sound_{};
|
||||
int id_{};
|
||||
uint32_t play_count_{};
|
||||
bool is_actually_playing_{};
|
||||
bool want_to_play_{};
|
||||
#if BA_ENABLE_AUDIO
|
||||
ALuint source_ = 0;
|
||||
ALuint source_{};
|
||||
#endif
|
||||
bool is_streamed_ = false;
|
||||
bool is_streamed_{};
|
||||
|
||||
/// Whether we should be designated as "music" next time we play.
|
||||
bool is_music_ = false;
|
||||
bool is_music_{};
|
||||
|
||||
/// Whether currently playing as music.
|
||||
bool current_is_music_ = false;
|
||||
bool current_is_music_{};
|
||||
|
||||
#if BA_ENABLE_AUDIO
|
||||
Object::Ref<AudioStreamer> streamer_;
|
||||
@ -321,24 +321,34 @@ void AudioServer::PushSetListenerOrientationCall(const Vector3f& forward,
|
||||
});
|
||||
}
|
||||
|
||||
AudioServer::AudioServer(Thread* thread)
|
||||
: thread_(thread), impl_{new AudioServer::Impl()} {
|
||||
// we're a singleton...
|
||||
AudioServer::AudioServer() : impl_{new AudioServer::Impl()} {
|
||||
// We're a singleton; make sure we don't already exist.
|
||||
assert(g_audio_server == nullptr);
|
||||
g_audio_server = this;
|
||||
|
||||
thread->AddPauseCallback(NewLambdaRunnableRaw([this] { OnThreadPause(); }));
|
||||
thread->AddResumeCallback(NewLambdaRunnableRaw([this] { OnThreadResume(); }));
|
||||
// Spin up our thread.
|
||||
thread_ = new Thread(ThreadIdentifier::kAudio);
|
||||
g_app->pausable_threads.push_back(thread_);
|
||||
}
|
||||
|
||||
auto AudioServer::Start() -> void {
|
||||
thread_->PushCallSynchronous([this] { StartInThread(); });
|
||||
}
|
||||
|
||||
auto AudioServer::StartInThread() -> void {
|
||||
assert(InAudioThread());
|
||||
thread()->AddPauseCallback(NewLambdaRunnableRaw([this] { OnThreadPause(); }));
|
||||
thread()->AddResumeCallback(
|
||||
NewLambdaRunnableRaw([this] { OnThreadResume(); }));
|
||||
|
||||
// Get our thread to give us periodic processing time.
|
||||
process_timer_ = thread->NewTimer(kAudioProcessIntervalNormal, true,
|
||||
NewLambdaRunnable([this] { Process(); }));
|
||||
process_timer_ = thread()->NewTimer(kAudioProcessIntervalNormal, true,
|
||||
NewLambdaRunnable([this] { Process(); }));
|
||||
|
||||
#if BA_ENABLE_AUDIO
|
||||
|
||||
// Bring up OpenAL stuff.
|
||||
{
|
||||
const char* alDeviceName = nullptr;
|
||||
const char* al_device_name = nullptr;
|
||||
|
||||
// On the rift build in vr mode we need to make sure we open the rift audio
|
||||
// device.
|
||||
@ -363,7 +373,7 @@ AudioServer::AudioServer(Thread* thread)
|
||||
// These names seem to be things like "OpenAL Soft on FOO"
|
||||
// ..we should be able to search for FOO.
|
||||
if (strstr(device, g_rift_audio_device_name.c_str())) {
|
||||
alDeviceName = device;
|
||||
al_device_name = device;
|
||||
}
|
||||
len = strlen(device);
|
||||
device += (len + 1);
|
||||
@ -376,7 +386,7 @@ AudioServer::AudioServer(Thread* thread)
|
||||
#endif // BA_RIFT_BUILD
|
||||
|
||||
ALCdevice* device;
|
||||
device = alcOpenDevice(alDeviceName);
|
||||
device = alcOpenDevice(al_device_name);
|
||||
BA_PRECONDITION(device);
|
||||
impl_->alc_context_ = alcCreateContext(device, nullptr);
|
||||
BA_PRECONDITION(impl_->alc_context_);
|
||||
@ -702,7 +712,9 @@ AudioServer::ThreadSource::ThreadSource(AudioServer* audio_thread_in, int id_in,
|
||||
CHECK_AL_ERROR;
|
||||
}
|
||||
*valid_out = valid_;
|
||||
if (valid_) al_source_count_++;
|
||||
if (valid_) {
|
||||
al_source_count_++;
|
||||
}
|
||||
|
||||
#endif // BA_ENABLE_AUDIO
|
||||
}
|
||||
|
||||
@ -22,45 +22,47 @@ class AudioServer {
|
||||
return play_id >> 16u;
|
||||
}
|
||||
|
||||
explicit AudioServer(Thread* o);
|
||||
AudioServer();
|
||||
auto Start() -> void;
|
||||
|
||||
void PushSetVolumesCall(float music_volume, float sound_volume);
|
||||
void PushSetSoundPitchCall(float val);
|
||||
void PushSetPausedCall(bool pause);
|
||||
auto PushSetVolumesCall(float music_volume, float sound_volume) -> void;
|
||||
auto PushSetSoundPitchCall(float val) -> void;
|
||||
auto PushSetPausedCall(bool pause) -> void;
|
||||
|
||||
static void BeginInterruption();
|
||||
static void EndInterruption();
|
||||
static auto BeginInterruption() -> void;
|
||||
static auto EndInterruption() -> void;
|
||||
|
||||
void PushSetListenerPositionCall(const Vector3f& p);
|
||||
void PushSetListenerOrientationCall(const Vector3f& forward,
|
||||
const Vector3f& up);
|
||||
void PushResetCall();
|
||||
void PushHavePendingLoadsCall();
|
||||
void PushComponentUnloadCall(
|
||||
const std::vector<Object::Ref<AssetComponentData>*>& components);
|
||||
auto PushSetListenerPositionCall(const Vector3f& p) -> void;
|
||||
auto PushSetListenerOrientationCall(const Vector3f& forward,
|
||||
const Vector3f& up) -> void;
|
||||
auto PushResetCall() -> void;
|
||||
auto PushHavePendingLoadsCall() -> void;
|
||||
auto PushComponentUnloadCall(
|
||||
const std::vector<Object::Ref<AssetComponentData>*>& components) -> void;
|
||||
|
||||
/// For use by g_game_module().
|
||||
void ClearSoundRefDeleteList();
|
||||
auto ClearSoundRefDeleteList() -> void;
|
||||
|
||||
auto paused() const -> bool { return paused_; }
|
||||
|
||||
// Client sources use these to pass settings to the server.
|
||||
void PushSourceSetIsMusicCall(uint32_t play_id, bool val);
|
||||
void PushSourceSetPositionalCall(uint32_t play_id, bool val);
|
||||
void PushSourceSetPositionCall(uint32_t play_id, const Vector3f& p);
|
||||
void PushSourceSetGainCall(uint32_t play_id, float val);
|
||||
void PushSourceSetFadeCall(uint32_t play_id, float val);
|
||||
void PushSourceSetLoopingCall(uint32_t play_id, bool val);
|
||||
void PushSourcePlayCall(uint32_t play_id, Object::Ref<SoundData>* sound);
|
||||
void PushSourceStopCall(uint32_t play_id);
|
||||
void PushSourceEndCall(uint32_t play_id);
|
||||
auto PushSourceSetIsMusicCall(uint32_t play_id, bool val) -> void;
|
||||
auto PushSourceSetPositionalCall(uint32_t play_id, bool val) -> void;
|
||||
auto PushSourceSetPositionCall(uint32_t play_id, const Vector3f& p) -> void;
|
||||
auto PushSourceSetGainCall(uint32_t play_id, float val) -> void;
|
||||
auto PushSourceSetFadeCall(uint32_t play_id, float val) -> void;
|
||||
auto PushSourceSetLoopingCall(uint32_t play_id, bool val) -> void;
|
||||
auto PushSourcePlayCall(uint32_t play_id, Object::Ref<SoundData>* sound)
|
||||
-> void;
|
||||
auto PushSourceStopCall(uint32_t play_id) -> void;
|
||||
auto PushSourceEndCall(uint32_t play_id) -> void;
|
||||
|
||||
// Fade a playing sound out over the given time. If it is already
|
||||
// fading or does not exist, does nothing.
|
||||
void FadeSoundOut(uint32_t play_id, uint32_t time);
|
||||
auto FadeSoundOut(uint32_t play_id, uint32_t time) -> void;
|
||||
|
||||
// Stop a sound from playing if it exists.
|
||||
void StopSound(uint32_t play_id);
|
||||
auto StopSound(uint32_t play_id) -> void;
|
||||
|
||||
auto thread() const -> Thread* { return thread_; }
|
||||
|
||||
@ -68,16 +70,17 @@ class AudioServer {
|
||||
class ThreadSource;
|
||||
struct Impl;
|
||||
|
||||
auto StartInThread() -> void;
|
||||
~AudioServer();
|
||||
|
||||
auto OnThreadPause() -> void;
|
||||
auto OnThreadResume() -> void;
|
||||
|
||||
void SetPaused(bool paused);
|
||||
auto SetPaused(bool paused) -> void;
|
||||
|
||||
void SetMusicVolume(float volume);
|
||||
void SetSoundVolume(float volume);
|
||||
void SetSoundPitch(float pitch);
|
||||
auto SetMusicVolume(float volume) -> void;
|
||||
auto SetSoundVolume(float volume) -> void;
|
||||
auto SetSoundPitch(float pitch) -> void;
|
||||
auto music_volume() -> float { return music_volume_; }
|
||||
auto sound_volume() -> float { return sound_volume_; }
|
||||
auto sound_pitch() -> float { return sound_pitch_; }
|
||||
@ -85,22 +88,22 @@ class AudioServer {
|
||||
/// If a sound play id is currently playing, return the sound.
|
||||
auto GetPlayingSound(uint32_t play_id) -> ThreadSource*;
|
||||
|
||||
void Reset();
|
||||
void Process();
|
||||
auto Reset() -> void;
|
||||
auto Process() -> void;
|
||||
|
||||
/// Send a component to the audio thread to delete.
|
||||
void DeleteAssetComponent(AssetComponentData* c);
|
||||
auto DeleteAssetComponent(AssetComponentData* c) -> void;
|
||||
|
||||
void UpdateTimerInterval();
|
||||
void UpdateAvailableSources();
|
||||
void UpdateMusicPlayState();
|
||||
void ProcessSoundFades();
|
||||
auto UpdateTimerInterval() -> void;
|
||||
auto UpdateAvailableSources() -> void;
|
||||
auto UpdateMusicPlayState() -> void;
|
||||
auto ProcessSoundFades() -> void;
|
||||
|
||||
// Some threads such as audio hold onto allocated Media-Component-Refs to keep
|
||||
// media components alive that they need. Media-Component-Refs, however, must
|
||||
// be disposed of in the game thread, so they are passed back to it through
|
||||
// this function.
|
||||
void AddSoundRefDelete(const Object::Ref<SoundData>* c);
|
||||
auto AddSoundRefDelete(const Object::Ref<SoundData>* c) -> void;
|
||||
|
||||
// Note: should use unique_ptr for this, but build fails on raspberry pi
|
||||
// (gcc 8.3.0). Works on Ubuntu 9.3 so should try again later.
|
||||
|
||||
@ -4,26 +4,33 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "ballistica/app/app_config.h"
|
||||
#include "ballistica/app/app_flavor.h"
|
||||
#include "ballistica/assets/assets.h"
|
||||
#include "ballistica/assets/assets_server.h"
|
||||
#include "ballistica/audio/audio.h"
|
||||
#include "ballistica/audio/audio_server.h"
|
||||
#include "ballistica/core/context.h"
|
||||
#include "ballistica/core/fatal_error.h"
|
||||
#include "ballistica/core/logging.h"
|
||||
#include "ballistica/core/thread.h"
|
||||
#include "ballistica/dynamics/bg/bg_dynamics_server.h"
|
||||
#include "ballistica/game/v1_account.h"
|
||||
#include "ballistica/graphics/graphics_server.h"
|
||||
#include "ballistica/graphics/text/text_graphics.h"
|
||||
#include "ballistica/input/input.h"
|
||||
#include "ballistica/internal/app_internal.h"
|
||||
#include "ballistica/networking/network_writer.h"
|
||||
#include "ballistica/networking/networking.h"
|
||||
#include "ballistica/platform/platform.h"
|
||||
#include "ballistica/python/python.h"
|
||||
#include "ballistica/scene/scene.h"
|
||||
#include "ballistica/ui/ui.h"
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
// These are set automatically via script; don't modify them here.
|
||||
const int kAppBuildNumber = 20809;
|
||||
const int kAppBuildNumber = 20821;
|
||||
const char* kAppVersion = "1.7.7";
|
||||
|
||||
// Our standalone globals.
|
||||
@ -40,6 +47,7 @@ Audio* g_audio{};
|
||||
AudioServer* g_audio_server{};
|
||||
BGDynamics* g_bg_dynamics{};
|
||||
BGDynamicsServer* g_bg_dynamics_server{};
|
||||
Context* g_context{};
|
||||
Game* g_game{};
|
||||
Graphics* g_graphics{};
|
||||
GraphicsServer* g_graphics_server{};
|
||||
@ -49,7 +57,7 @@ Assets* g_assets{};
|
||||
AssetsServer* g_assets_server{};
|
||||
NetworkReader* g_network_reader{};
|
||||
Networking* g_networking{};
|
||||
NetworkWriteModule* g_network_writer{};
|
||||
NetworkWriter* g_network_writer{};
|
||||
Platform* g_platform{};
|
||||
Python* g_python{};
|
||||
StdInputModule* g_std_input_module{};
|
||||
@ -93,28 +101,35 @@ auto BallisticaMain(int argc, char** argv) -> int {
|
||||
|
||||
// Bootstrap our Python environment as early as we can (depends on
|
||||
// g_platform for locating OS-specific paths).
|
||||
assert(g_python == nullptr);
|
||||
g_python = new Python();
|
||||
|
||||
// Create a Thread wrapper around the current (main) thread.
|
||||
g_main_thread = new Thread(ThreadIdentifier::kMain, ThreadType::kMain);
|
||||
Thread::UpdateMainThreadID();
|
||||
|
||||
// Spin up our specific app variation (VR, headless, regular, etc.)
|
||||
// Spin up our specific app and graphics variations
|
||||
// (VR, headless, regular, etc.)
|
||||
g_app_flavor = g_platform->CreateAppFlavor();
|
||||
g_app_flavor->PostInit();
|
||||
g_graphics = g_platform->CreateGraphics();
|
||||
|
||||
// Various other subsystems.
|
||||
g_graphics_server = new GraphicsServer();
|
||||
g_audio = new Audio();
|
||||
g_audio_server = new AudioServer();
|
||||
g_context = new Context(nullptr);
|
||||
g_text_graphics = new TextGraphics();
|
||||
g_app_config = new AppConfig();
|
||||
g_v1_account = new V1Account();
|
||||
g_utils = new Utils();
|
||||
g_assets = new Assets();
|
||||
g_assets_server = new AssetsServer();
|
||||
g_ui = Object::NewUnmanaged<UI>();
|
||||
g_networking = new Networking();
|
||||
g_input = new Input();
|
||||
g_app_internal = GetAppInternal();
|
||||
Scene::Init();
|
||||
|
||||
// Spin up our other standard threads.
|
||||
auto* assets_thread{new Thread(ThreadIdentifier::kAssets)};
|
||||
g_app->pausable_threads.push_back(assets_thread);
|
||||
auto* audio_thread{new Thread(ThreadIdentifier::kAudio)};
|
||||
g_app->pausable_threads.push_back(audio_thread);
|
||||
auto* logic_thread{new Thread(ThreadIdentifier::kLogic)};
|
||||
g_app->pausable_threads.push_back(logic_thread);
|
||||
auto* network_write_thread{new Thread(ThreadIdentifier::kNetworkWrite)};
|
||||
@ -123,14 +138,8 @@ auto BallisticaMain(int argc, char** argv) -> int {
|
||||
// Spin up our subsystems in those threads.
|
||||
logic_thread->PushCallSynchronous(
|
||||
[logic_thread] { new Game(logic_thread); });
|
||||
network_write_thread->PushCallSynchronous([network_write_thread] {
|
||||
new NetworkWriteModule(network_write_thread);
|
||||
});
|
||||
assets_thread->PushCallSynchronous(
|
||||
[assets_thread] { new AssetsServer(assets_thread); });
|
||||
new GraphicsServer(g_main_thread);
|
||||
audio_thread->PushCallSynchronous(
|
||||
[audio_thread] { new AudioServer(audio_thread); });
|
||||
network_write_thread->PushCallSynchronous(
|
||||
[network_write_thread] { new NetworkWriter(network_write_thread); });
|
||||
|
||||
// Now let the platform spin up any other threads/modules it uses.
|
||||
// (bg-dynamics in non-headless builds, stdin/stdout where applicable,
|
||||
@ -144,6 +153,9 @@ auto BallisticaMain(int argc, char** argv) -> int {
|
||||
// Phase 2: Set things in motion.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
g_audio_server->Start();
|
||||
g_assets_server->Start();
|
||||
|
||||
// Let the app and platform do whatever else it wants here such as adding
|
||||
// initial input devices/etc.
|
||||
g_app_flavor->OnBootstrapComplete();
|
||||
|
||||
@ -122,7 +122,7 @@ extern Assets* g_assets;
|
||||
extern AssetsServer* g_assets_server;
|
||||
extern Networking* g_networking;
|
||||
extern NetworkReader* g_network_reader;
|
||||
extern NetworkWriteModule* g_network_writer;
|
||||
extern NetworkWriter* g_network_writer;
|
||||
extern Platform* g_platform;
|
||||
extern Python* g_python;
|
||||
extern StdInputModule* g_std_input_module;
|
||||
|
||||
@ -8,14 +8,6 @@
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
// Dynamically allocate this; don't want it torn down on quit.
|
||||
Context* g_context = nullptr;
|
||||
|
||||
void Context::Init() {
|
||||
assert(!g_context);
|
||||
g_context = new Context(nullptr);
|
||||
}
|
||||
|
||||
ContextTarget::ContextTarget() = default;
|
||||
ContextTarget::~ContextTarget() = default;
|
||||
|
||||
|
||||
@ -14,8 +14,6 @@ namespace ballistica {
|
||||
// effects properly apply to the place they came from.
|
||||
class Context {
|
||||
public:
|
||||
static void Init();
|
||||
|
||||
static auto current() -> const Context& {
|
||||
assert(g_context);
|
||||
|
||||
|
||||
@ -84,7 +84,7 @@ void Thread::WaitForNextEvent(bool single_cycle) {
|
||||
}
|
||||
|
||||
// While we're waiting, allow other python threads to run.
|
||||
if (owns_python_) {
|
||||
if (holds_python_gil_) {
|
||||
g_python->ReleaseGIL();
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ void Thread::WaitForNextEvent(bool single_cycle) {
|
||||
}
|
||||
}
|
||||
|
||||
if (owns_python_) {
|
||||
if (holds_python_gil_) {
|
||||
g_python->AcquireGIL();
|
||||
}
|
||||
}
|
||||
@ -357,8 +357,8 @@ auto Thread::ThreadMain() -> int {
|
||||
}
|
||||
}
|
||||
|
||||
void Thread::SetOwnsPython() {
|
||||
owns_python_ = true;
|
||||
void Thread::SetHoldsPythonGIL() {
|
||||
holds_python_gil_ = true;
|
||||
g_python->AcquireGIL();
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ class Thread {
|
||||
// Used to quit the main thread.
|
||||
void Quit();
|
||||
|
||||
void SetOwnsPython();
|
||||
void SetHoldsPythonGIL();
|
||||
|
||||
void SetPaused(bool paused);
|
||||
auto thread_id() const -> std::thread::id { return thread_id_; }
|
||||
@ -137,7 +137,7 @@ class Thread {
|
||||
std::thread::id thread_id_{};
|
||||
ThreadIdentifier identifier_{ThreadIdentifier::kInvalid};
|
||||
millisecs_t last_complaint_time_{};
|
||||
bool owns_python_{};
|
||||
bool holds_python_gil_{};
|
||||
|
||||
// FIXME: Should generalize this to some sort of PlatformThreadData class.
|
||||
#if BA_XCODE_BUILD
|
||||
|
||||
@ -123,7 +123,7 @@ class NetClientThread;
|
||||
class NetGraph;
|
||||
class Networking;
|
||||
class NetworkReader;
|
||||
class NetworkWriteModule;
|
||||
class NetworkWriter;
|
||||
class Node;
|
||||
class NodeType;
|
||||
class NodeAttribute;
|
||||
|
||||
@ -73,45 +73,27 @@ Game::Game(Thread* thread)
|
||||
g_game = this;
|
||||
|
||||
try {
|
||||
// Spin up some other game-thread-based stuff.
|
||||
AppConfig::Init();
|
||||
assert(g_graphics == nullptr);
|
||||
g_graphics = g_platform->CreateGraphics();
|
||||
TextGraphics::Init();
|
||||
Audio::Init();
|
||||
// Our thread should hold the Python GIL by default.
|
||||
// TODO(ericf): It could be better to have each individual Python call
|
||||
// we make acquire the GIL. Then we're not holding it during long
|
||||
// bits of C++ logic.
|
||||
thread->SetHoldsPythonGIL();
|
||||
|
||||
if (!HeadlessMode()) {
|
||||
BGDynamics::Init();
|
||||
}
|
||||
|
||||
InitSpecialChars();
|
||||
|
||||
Context::Init();
|
||||
|
||||
// We want to be informed when our thread is pausing.
|
||||
thread->AddPauseCallback(NewLambdaRunnableRaw([this] { OnThreadPause(); }));
|
||||
|
||||
// Waaah does UI need to be a bs::Object?
|
||||
// Update: yes it does in order to be a context target.
|
||||
// (need to be able to create weak-refs to it).
|
||||
assert(g_ui == nullptr);
|
||||
g_ui = Object::NewUnmanaged<UI>();
|
||||
g_ui->PostInit();
|
||||
|
||||
assert(g_networking == nullptr);
|
||||
g_networking = new Networking();
|
||||
|
||||
assert(g_input == nullptr);
|
||||
g_input = new Input();
|
||||
|
||||
g_app_internal = GetAppInternal();
|
||||
g_ui->LogicThreadInit();
|
||||
|
||||
// Init python and apply our settings immediately.
|
||||
// This way we can get started loading stuff in the background
|
||||
// and it'll come in with the correct texture quality etc.
|
||||
g_python->Reset(true);
|
||||
|
||||
// We're the thread that 'owns' python so we need to wrangle the GIL.
|
||||
thread->SetOwnsPython();
|
||||
} catch (const std::exception& e) {
|
||||
// If anything went wrong, trigger a deferred error.
|
||||
// This way it is more likely we can show a fatal error dialog
|
||||
|
||||
@ -324,7 +324,7 @@ class Game {
|
||||
int last_kick_votes_needed_{-1};
|
||||
Object::WeakRef<ConnectionToClient> kick_vote_starter_;
|
||||
Object::WeakRef<ConnectionToClient> kick_vote_target_;
|
||||
bool public_party_enabled_{false};
|
||||
bool public_party_enabled_{};
|
||||
int public_party_size_{1}; // Always count ourself (is that what we want?).
|
||||
int public_party_max_size_{8};
|
||||
int public_party_player_count_{0};
|
||||
|
||||
@ -87,8 +87,8 @@ class HostActivity : public ContextTarget {
|
||||
auto StepScene() -> void;
|
||||
|
||||
Object::WeakRef<GlobalsNode> globals_node_;
|
||||
bool allow_kick_idle_players_ = false;
|
||||
Timer* step_scene_timer_ = nullptr;
|
||||
bool allow_kick_idle_players_{};
|
||||
Timer* step_scene_timer_{};
|
||||
std::unordered_map<std::string, Object::WeakRef<Texture> > textures_;
|
||||
std::unordered_map<std::string, Object::WeakRef<Sound> > sounds_;
|
||||
std::unordered_map<std::string, Object::WeakRef<Data> > datas_;
|
||||
@ -96,18 +96,18 @@ class HostActivity : public ContextTarget {
|
||||
collide_models_;
|
||||
std::unordered_map<std::string, Object::WeakRef<Model> > models_;
|
||||
std::list<Object::WeakRef<Material> > materials_;
|
||||
bool shutting_down_ = false;
|
||||
bool shutting_down_{};
|
||||
|
||||
// Our list of python calls created in the context of this activity;
|
||||
// we clear them as we are shutting down and ensure nothing runs after
|
||||
// that point.
|
||||
std::list<Object::WeakRef<PythonContextCall> > python_calls_;
|
||||
millisecs_t next_prune_time_ = 0;
|
||||
bool _started = false;
|
||||
int out_of_bounds_in_a_row_ = 0;
|
||||
bool paused_ = false;
|
||||
float game_speed_ = 0.0f;
|
||||
millisecs_t base_time_ = 0;
|
||||
millisecs_t next_prune_time_{};
|
||||
bool _started{};
|
||||
int out_of_bounds_in_a_row_{};
|
||||
bool paused_{};
|
||||
float game_speed_{};
|
||||
millisecs_t base_time_{};
|
||||
Object::Ref<Scene> scene_;
|
||||
Object::WeakRef<HostSession> host_session_;
|
||||
PythonRef py_activity_weak_ref_;
|
||||
|
||||
@ -147,7 +147,7 @@ class Player : public Object {
|
||||
|
||||
// Player's position for use by input devices and whatnot for guides.
|
||||
// FIXME: This info should be acquired through the player node.
|
||||
bool have_position_{false};
|
||||
bool have_position_{};
|
||||
Vector3f position_{0.0f, 0.0f, 0.0f};
|
||||
|
||||
// These should be destructed before the rest of our class goes down,
|
||||
|
||||
@ -16,7 +16,7 @@ namespace ballistica {
|
||||
/// should not know or care about V2 accounts.
|
||||
class PlayerSpec {
|
||||
public:
|
||||
/// Init an invalid player-spec
|
||||
/// Create an invalid player-spec.
|
||||
PlayerSpec();
|
||||
auto operator==(const PlayerSpec& spec) const -> bool;
|
||||
|
||||
|
||||
@ -85,8 +85,8 @@ class ClientSession : public Session {
|
||||
virtual auto OnReset(bool rewind) -> void;
|
||||
virtual auto FetchMessages() -> void {}
|
||||
virtual void Error(const std::string& description);
|
||||
void End();
|
||||
void DumpFullState(SceneStream* out) override;
|
||||
auto End() -> void;
|
||||
auto DumpFullState(SceneStream* out) -> void override;
|
||||
|
||||
/// Reset target base time to equal current. This can be used during command
|
||||
/// buffer underruns to cause playback to pause momentarily instead of
|
||||
@ -95,8 +95,8 @@ class ClientSession : public Session {
|
||||
auto ResetTargetBaseTime() -> void { target_base_time_ = base_time_; }
|
||||
|
||||
private:
|
||||
void ClearSessionObjs();
|
||||
void AddCommand(const std::vector<uint8_t>& command);
|
||||
auto ClearSessionObjs() -> void;
|
||||
auto AddCommand(const std::vector<uint8_t>& command) -> void;
|
||||
|
||||
auto ReadByte() -> uint8_t;
|
||||
auto ReadInt32() -> int32_t;
|
||||
|
||||
@ -30,10 +30,9 @@ void GraphicsServer::FullscreenCheck() {
|
||||
}
|
||||
#endif
|
||||
|
||||
GraphicsServer::GraphicsServer(Thread* thread) : thread_(thread) {
|
||||
// We're a singleton.
|
||||
GraphicsServer::GraphicsServer() : thread_(g_main_thread) {
|
||||
// We're a singleton; make sure we don't already exist.
|
||||
assert(g_graphics_server == nullptr);
|
||||
g_graphics_server = this;
|
||||
|
||||
// For janky old non-event-push mode, just fall back on a timer for rendering.
|
||||
if (!g_platform->IsEventPushMode()) {
|
||||
|
||||
@ -18,7 +18,7 @@ namespace ballistica {
|
||||
// Graphics
|
||||
class GraphicsServer {
|
||||
public:
|
||||
explicit GraphicsServer(Thread* thread);
|
||||
GraphicsServer();
|
||||
auto PushSetScreenGammaCall(float gamma) -> void;
|
||||
auto PushSetScreenPixelScaleCall(float pixel_scale) -> void;
|
||||
auto PushSetVSyncCall(bool sync, bool auto_sync) -> void;
|
||||
@ -61,18 +61,22 @@ class GraphicsServer {
|
||||
// init the modelview matrix to look here
|
||||
auto SetCamera(const Vector3f& eye, const Vector3f& target,
|
||||
const Vector3f& up) -> void;
|
||||
|
||||
auto SetOrthoProjection(float left, float right, float bottom, float top,
|
||||
float near, float far) -> void;
|
||||
|
||||
auto ModelViewReset() -> void {
|
||||
model_view_matrix_ = kMatrix44fIdentity;
|
||||
model_view_projection_matrix_dirty_ = model_world_matrix_dirty_ = true;
|
||||
model_view_stack_.clear();
|
||||
}
|
||||
|
||||
auto SetProjectionMatrix(const Matrix44f& p) -> void {
|
||||
projection_matrix_ = p;
|
||||
model_view_projection_matrix_dirty_ = true;
|
||||
projection_matrix_state_++;
|
||||
}
|
||||
|
||||
auto projection_matrix_state() -> uint32_t {
|
||||
return projection_matrix_state_;
|
||||
}
|
||||
@ -85,9 +89,11 @@ class GraphicsServer {
|
||||
light_shadow_projection_matrix_state_++;
|
||||
}
|
||||
}
|
||||
|
||||
auto light_shadow_projection_matrix_state() const -> uint32_t {
|
||||
return light_shadow_projection_matrix_state_;
|
||||
}
|
||||
|
||||
auto light_shadow_projection_matrix() const -> const Matrix44f& {
|
||||
return light_shadow_projection_matrix_;
|
||||
}
|
||||
@ -270,6 +276,13 @@ class GraphicsServer {
|
||||
model_world_matrix_dirty_ = false;
|
||||
}
|
||||
}
|
||||
auto SetScreen(bool fullscreen, int width, int height,
|
||||
TextureQuality texture_quality,
|
||||
GraphicsQuality graphics_quality,
|
||||
const std::string& android_res) -> void;
|
||||
#if BA_OSTYPE_MACOS && BA_XCODE_BUILD
|
||||
void FullscreenCheck();
|
||||
#endif
|
||||
#if BA_ENABLE_OPENGL
|
||||
std::unique_ptr<GLContext> gl_context_;
|
||||
#endif
|
||||
@ -291,7 +304,6 @@ class GraphicsServer {
|
||||
bool fullscreen_enabled_{};
|
||||
float target_res_x_{800.0f};
|
||||
float target_res_y_{600.0f};
|
||||
|
||||
Matrix44f model_view_matrix_{kMatrix44fIdentity};
|
||||
Matrix44f view_world_matrix_{kMatrix44fIdentity};
|
||||
Matrix44f projection_matrix_{kMatrix44fIdentity};
|
||||
@ -314,18 +326,11 @@ class GraphicsServer {
|
||||
std::list<MeshData*> mesh_datas_;
|
||||
bool v_sync_{};
|
||||
bool auto_vsync_{};
|
||||
auto SetScreen(bool fullscreen, int width, int height,
|
||||
TextureQuality texture_quality,
|
||||
GraphicsQuality graphics_quality,
|
||||
const std::string& android_res) -> void;
|
||||
Timer* render_timer_{};
|
||||
Renderer* renderer_{};
|
||||
FrameDef* frame_def_{};
|
||||
bool initial_screen_created_{};
|
||||
int render_hold_{};
|
||||
#if BA_OSTYPE_MACOS && BA_XCODE_BUILD
|
||||
void FullscreenCheck();
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace ballistica
|
||||
|
||||
@ -19,12 +19,6 @@ class TextGraphics::TextSpanBoundsCacheEntry : public Object {
|
||||
std::list<Object::Ref<TextSpanBoundsCacheEntry>>::iterator list_iterator_;
|
||||
};
|
||||
|
||||
void TextGraphics::Init() {
|
||||
assert(InLogicThread());
|
||||
assert(g_text_graphics == nullptr);
|
||||
g_text_graphics = new TextGraphics();
|
||||
}
|
||||
|
||||
TextGraphics::TextGraphics() {
|
||||
// Init glyph values for our custom font pages
|
||||
// (just a 5x5 array currently).
|
||||
|
||||
@ -22,8 +22,6 @@ const float kTextRowHeight = 32.0f;
|
||||
// Encapsulates text-display functionality used by the game thread.
|
||||
class TextGraphics {
|
||||
public:
|
||||
static void Init();
|
||||
|
||||
TextGraphics();
|
||||
|
||||
enum class FontPage {
|
||||
|
||||
@ -318,17 +318,7 @@ static const char* const scancode_names[SDL_NUM_SCANCODES] = {
|
||||
};
|
||||
#endif // BA_SDL2_BUILD || BA_MINSDL_BUILD
|
||||
|
||||
Input::Input() {
|
||||
// We're a singleton.
|
||||
// assert(g_input == nullptr);
|
||||
// g_input = this;
|
||||
|
||||
assert(InLogicThread());
|
||||
|
||||
// Config should have always been read by this point; right?
|
||||
// assert(g_python);
|
||||
// UpdateEnabledControllerSubsystems();
|
||||
}
|
||||
Input::Input() {}
|
||||
|
||||
void Input::PushCreateKeyboardInputDevices() {
|
||||
g_game->thread()->PushCall([this] { CreateKeyboardInputDevices(); });
|
||||
@ -362,8 +352,6 @@ void Input::DestroyKeyboardInputDevices() {
|
||||
keyboard_input_2_ = nullptr;
|
||||
}
|
||||
|
||||
Input::~Input() = default;
|
||||
|
||||
auto Input::GetInputDevice(int id) -> InputDevice* {
|
||||
if (id < 0 || id >= static_cast<int>(input_devices_.size())) {
|
||||
return nullptr;
|
||||
|
||||
@ -18,7 +18,6 @@ namespace ballistica {
|
||||
class Input {
|
||||
public:
|
||||
Input();
|
||||
virtual ~Input();
|
||||
|
||||
// Add an input device. Must be called from the game thread; otherwise use
|
||||
// PushAddInputDeviceCall.
|
||||
|
||||
@ -8,14 +8,14 @@
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
NetworkWriteModule::NetworkWriteModule(Thread* thread) : thread_(thread) {
|
||||
NetworkWriter::NetworkWriter(Thread* thread) : thread_(thread) {
|
||||
// we're a singleton
|
||||
assert(g_network_writer == nullptr);
|
||||
g_network_writer = this;
|
||||
}
|
||||
|
||||
void NetworkWriteModule::PushSendToCall(const std::vector<uint8_t>& msg,
|
||||
const SockAddr& addr) {
|
||||
void NetworkWriter::PushSendToCall(const std::vector<uint8_t>& msg,
|
||||
const SockAddr& addr) {
|
||||
// Avoid buffer-full errors if something is causing us to write too often;
|
||||
// these are unreliable messages so its ok to just drop them.
|
||||
if (!thread()->CheckPushSafety()) {
|
||||
|
||||
@ -10,10 +10,10 @@
|
||||
namespace ballistica {
|
||||
|
||||
// A subsystem handling outbound network traffic.
|
||||
class NetworkWriteModule {
|
||||
class NetworkWriter {
|
||||
public:
|
||||
void PushSendToCall(const std::vector<uint8_t>& msg, const SockAddr& addr);
|
||||
explicit NetworkWriteModule(Thread* thread);
|
||||
explicit NetworkWriter(Thread* thread);
|
||||
auto thread() const -> Thread* { return thread_; }
|
||||
|
||||
private:
|
||||
|
||||
@ -17,12 +17,7 @@ struct Networking::ScanResultsEntryPriv {
|
||||
millisecs_t last_contact_time{};
|
||||
};
|
||||
|
||||
Networking::Networking() {
|
||||
assert(InLogicThread());
|
||||
Resume();
|
||||
}
|
||||
|
||||
Networking::~Networking() = default;
|
||||
Networking::Networking() {}
|
||||
|
||||
// Note: for now we're making our host-scan network calls directly from the game
|
||||
// thread. This is generally not a good idea since it appears that even in
|
||||
@ -232,7 +227,9 @@ void Networking::EndHostScanning() {
|
||||
}
|
||||
|
||||
void Networking::Pause() {
|
||||
if (!running_) Log("Networking::pause() called with running_ already false");
|
||||
if (!running_) {
|
||||
Log("Networking::pause() called with running_ already false");
|
||||
}
|
||||
running_ = false;
|
||||
|
||||
// Game is going into background or whatnot. Kill any sockets/etc.
|
||||
|
||||
@ -120,7 +120,6 @@ class Networking {
|
||||
// will do this there.
|
||||
static void SendTo(const std::vector<uint8_t>& buffer, const SockAddr& addr);
|
||||
Networking();
|
||||
~Networking();
|
||||
|
||||
// Run a cycle of host scanning (basically sending out a broadcast packet to
|
||||
// see who's out there).
|
||||
@ -147,7 +146,7 @@ class Networking {
|
||||
std::mutex scan_results_mutex_;
|
||||
uint32_t next_scan_query_id_{};
|
||||
int scan_socket_{-1};
|
||||
bool running_{};
|
||||
bool running_{true};
|
||||
};
|
||||
|
||||
} // namespace ballistica
|
||||
|
||||
@ -657,26 +657,31 @@ auto Platform::CreateAppFlavor() -> AppFlavor* {
|
||||
SDLApp::InitSDL();
|
||||
#endif
|
||||
|
||||
AppFlavor* app_flavor{};
|
||||
|
||||
#if BA_HEADLESS_BUILD
|
||||
return new AppFlavorHeadless(g_main_thread);
|
||||
app_flavor = new AppFlavorHeadless(g_main_thread);
|
||||
#elif BA_RIFT_BUILD
|
||||
// Rift build can spin up in either VR or regular mode.
|
||||
if (g_app->vr_mode) {
|
||||
return new AppFlavorVR(g_main_thread);
|
||||
app_flavor = new AppFlavorVR(g_main_thread);
|
||||
} else {
|
||||
return new SDLApp(g_main_thread);
|
||||
app_flavor = new SDLApp(g_main_thread);
|
||||
}
|
||||
#elif BA_CARDBOARD_BUILD
|
||||
return new AppFlavorVR(g_main_thread);
|
||||
app_flavor = new AppFlavorVR(g_main_thread);
|
||||
#elif BA_SDL_BUILD
|
||||
return new SDLApp(g_main_thread);
|
||||
app_flavor = new SDLApp(g_main_thread);
|
||||
#else
|
||||
return new AppFlavor(g_main_thread);
|
||||
app_flavor = new AppFlavor(g_main_thread);
|
||||
#endif
|
||||
|
||||
assert(app_flavor);
|
||||
app_flavor->PostInit();
|
||||
return app_flavor;
|
||||
}
|
||||
|
||||
auto Platform::CreateGraphics() -> Graphics* {
|
||||
assert(InLogicThread());
|
||||
#if BA_VR_BUILD
|
||||
return new VRGraphics();
|
||||
#else
|
||||
|
||||
@ -27,25 +27,19 @@ UI::UI() {
|
||||
|
||||
// Allow overriding via an environment variable.
|
||||
auto* ui_override = getenv("BA_UI_SCALE");
|
||||
bool force_test_small{};
|
||||
bool force_test_medium{};
|
||||
bool force_test_large{};
|
||||
if (ui_override) {
|
||||
if (ui_override == std::string("small")) {
|
||||
force_test_small = true;
|
||||
scale_ = UIScale::kSmall;
|
||||
force_scale_ = true;
|
||||
} else if (ui_override == std::string("medium")) {
|
||||
force_test_medium = true;
|
||||
scale_ = UIScale::kMedium;
|
||||
force_scale_ = true;
|
||||
} else if (ui_override == std::string("large")) {
|
||||
force_test_large = true;
|
||||
scale_ = UIScale::kLarge;
|
||||
force_scale_ = true;
|
||||
}
|
||||
}
|
||||
if (force_test_small) {
|
||||
scale_ = UIScale::kSmall;
|
||||
} else if (force_test_medium) {
|
||||
scale_ = UIScale::kMedium;
|
||||
} else if (force_test_large) {
|
||||
scale_ = UIScale::kLarge;
|
||||
} else {
|
||||
if (!force_scale_) {
|
||||
// Use automatic val.
|
||||
if (g_buildconfig.iircade_build()) { // NOLINT(bugprone-branch-clone)
|
||||
scale_ = UIScale::kMedium;
|
||||
@ -56,17 +50,24 @@ UI::UI() {
|
||||
scale_ = g_platform->GetUIScale();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto UI::LogicThreadInit() -> void {
|
||||
root_ui_ = new RootUI();
|
||||
// Make sure we know when forced-ui-scale is enabled.
|
||||
if (force_test_small) {
|
||||
ScreenMessage("FORCING SMALL UI FOR TESTING", Vector3f(1, 0, 0));
|
||||
Log("FORCING SMALL UI FOR TESTING");
|
||||
} else if (force_test_medium) {
|
||||
ScreenMessage("FORCING MEDIUM UI FOR TESTING", Vector3f(1, 0, 0));
|
||||
Log("FORCING MEDIUM UI FOR TESTING");
|
||||
} else if (force_test_large) {
|
||||
ScreenMessage("FORCING LARGE UI FOR TESTING", Vector3f(1, 0, 0));
|
||||
Log("FORCING LARGE UI FOR TESTING");
|
||||
if (force_scale_) {
|
||||
if (scale_ == UIScale::kSmall) {
|
||||
ScreenMessage("FORCING SMALL UI FOR TESTING", Vector3f(1, 0, 0));
|
||||
Log("FORCING SMALL UI FOR TESTING");
|
||||
} else if (scale_ == UIScale::kMedium) {
|
||||
ScreenMessage("FORCING MEDIUM UI FOR TESTING", Vector3f(1, 0, 0));
|
||||
Log("FORCING MEDIUM UI FOR TESTING");
|
||||
} else if (scale_ == UIScale::kLarge) {
|
||||
ScreenMessage("FORCING LARGE UI FOR TESTING", Vector3f(1, 0, 0));
|
||||
Log("FORCING LARGE UI FOR TESTING");
|
||||
} else {
|
||||
FatalError("Unhandled scale.");
|
||||
}
|
||||
}
|
||||
|
||||
step_scene_timer_ =
|
||||
@ -75,8 +76,6 @@ UI::UI() {
|
||||
scene_ = Object::New<Scene>(0);
|
||||
}
|
||||
|
||||
auto UI::PostInit() -> void { root_ui_ = new RootUI(); }
|
||||
|
||||
// Currently the UI never dies so we don't bother doing a clean tear-down..
|
||||
// (verifying scene cleanup, etc)
|
||||
UI::~UI() {
|
||||
|
||||
@ -31,7 +31,7 @@ namespace ballistica {
|
||||
class UI : public ContextTarget {
|
||||
public:
|
||||
UI();
|
||||
auto PostInit() -> void;
|
||||
auto LogicThreadInit() -> void;
|
||||
~UI() override;
|
||||
auto Reset() -> void;
|
||||
|
||||
@ -142,6 +142,7 @@ class UI : public ContextTarget {
|
||||
Object::Ref<RootWidget> root_widget_;
|
||||
int ui_lock_count_{};
|
||||
UIScale scale_{UIScale::kLarge};
|
||||
bool force_scale_{};
|
||||
|
||||
// Media loaded in the UI context.
|
||||
std::unordered_map<std::string, Object::WeakRef<Texture> > textures_;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user