simplifying c++ bootstrapping

This commit is contained in:
Eric 2022-09-11 10:32:02 -07:00
parent b837d3707e
commit 014a996933
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
39 changed files with 319 additions and 346 deletions

View File

@ -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"
}

View File

@ -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.

View File

@ -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(

View File

@ -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;

View File

@ -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

View File

@ -94,7 +94,6 @@ class AppConfig {
std::string name_;
};
static void Init();
AppConfig();
// Given specific ids, returns resolved values (fastest access).

View File

@ -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

View File

@ -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] {

View File

@ -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

View File

@ -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());

View File

@ -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_;

View File

@ -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
}

View File

@ -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.

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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();
}

View File

@ -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

View File

@ -123,7 +123,7 @@ class NetClientThread;
class NetGraph;
class Networking;
class NetworkReader;
class NetworkWriteModule;
class NetworkWriter;
class Node;
class NodeType;
class NodeAttribute;

View File

@ -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

View File

@ -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};

View File

@ -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_;

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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()) {

View File

@ -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

View File

@ -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).

View File

@ -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 {

View File

@ -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;

View File

@ -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.

View File

@ -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()) {

View File

@ -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:

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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() {

View File

@ -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_;