diff --git a/.efrocachemap b/.efrocachemap index 43f04760..c5a2542a 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -3995,26 +3995,26 @@ "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/c2/cb/1e9b2d26994e9dcd55d1df152b19", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4a/ae/c8878226f4a2d507f4ff5f377859", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/18/0f/9abd66eae1925271ab132163f2e0", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/54/c0/bb411385e3aefb55ca3fb4150e60", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/3c/61/37d143c8b14fb05990c0b8bc8f52", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f6/61/3958823929bcf2cdd9ca694d0ad7", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d5/73/b714b3e9a36076dee085fcdc7db2", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/fc/42/8ad2896d59013850516d54f49b7d", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d1/7c/c554ffc1f8c71bc08d4b025ccf4e", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/48/a9/94778472d1c43f556fee5e93c0ab", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/aa/f1/1c36c23d4d5bd6516adddc206514", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/af/76/63cfa6cc0915d35583bcaf30a2e0", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/2f/bb/8bfbea820878f58c5cb9cc702ff0", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4b/06/d72c7d9965890905dd3291c7f2c6", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c1/02/c9cfaf45b9003df94a2a8e277075", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4c/47/a66e6ce399dc00ade26e761f876f", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/b4/a4/6c844726fc0fb13925622b754cc9", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/4b/39/91b9746101e23fd615424b1721e5", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/31/07/5e49d34cd8bc204fb38e920f133c", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/6d/b1/6c593726c41a32066ba34ccf2ff5", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/eb/f0/36d00e5087e6d76d79672b018cc8", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f2/40/9f3c84455aac48d733b30df6b5b7", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2e/d3/aeacdcc49c0a4954afef6755f560", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/86/b2/80a8128225146f9515ad45c73de1", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ca/59/cbb3fe58cbaabf413340dec12e1a", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ec/94/076e15d29f647b7eb6b902f37198", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/55/77/07c16135863548bf52cd4cf2b0db", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/0c/c0/9ccb23d2b58d57d66dfa95346b32", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ca/13/d71a2a3d204b62ec4cc23a54e384", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c7/f0/f8c0d2e3162111499f60806b29e6", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/66/82/8fdb20a2f00ea4920ec048193f97", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a1/fe/ddc0c3dd421f421494b8e6a0c0cd", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/18/7b/3ccdfcb541be04196f489d8517d6", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/2a/02/d4bb405140bda1c17517717adda8", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/54/74/53d8c3f6b0faa4518dbac71ddff6", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f7/76/1bd98e4b273ef56d9d4051b8e170", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/56/18/d70ca8c1ed2ad1c0d05d082da786", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/00/11/19c14108e432a9dfca5a9ef32ec2", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/a6/34/d209303ed932c0c1fb1c9b480103", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/6b/7b/9f4c160d3d0e6198089898741957", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/81/60/37044e17e52ca125c1d48af83d03", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fb/47/d505c3feea40888985dd335dc8c4", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4f/3d/20c78e744ac26a13b7418166d675", @@ -4031,14 +4031,14 @@ "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3b/79/592c41691e94807d23a783723861", "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/13/d9/36f4cf8527494f419db74ae6c78f", "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ee/e5/7f0677e6fb8d7cfa169930579712", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/8c/4c/3bb058268312359ad8be98f35d9a", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/0a/09/1708ba819095ed0d708fdf4db96a", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/51/79/b0cccbb7292b56b00a9298d1a22f", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/20/2a/30500076cd30d44260a8365c02b5", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/88/a2/ca9e4011d6fa8b366159838b53a1", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/af/b2/b3a702920a14288ceb1603f1f091", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/70/57/1c725a736ebba2035fe3a3ec64df", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/ba/b8/e952aa9d40f5453db0acd4361f10", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/f1/e9/a36a2743cc11e888e4d877341724", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/4b/cd/accbffc3bd13d11b4266cad62b44", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/91/c1/fe42b2d9442edffed30f42dbcb1e", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/3b/d3/dc7bf863a0f7a986f8c88024cbe7", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/2b/2a/13183d1ae34b5e46baf5c2cd51eb", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/0d/98/59f17b4afffc44e0fdd7bc3fd6de", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/7e/f0/1946bfea786757842991e01e7749", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/33/68/499d8ceb69645456ee7e25d93a3c", "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" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 8602aef4..37f2286c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.7 (build 20829, api 7, 2022-09-12) +### 1.7.7 (build 20831, api 7, 2022-09-12) - 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. diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py index fdd14841..340dae7a 100644 --- a/assets/src/ba_data/python/ba/_bootstrap.py +++ b/assets/src/ba_data/python/ba/_bootstrap.py @@ -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 = 20829 + expected_build = 20831 running_build: int = env['build_number'] if running_build != expected_build: print( diff --git a/src/ballistica/assets/assets_server.cc b/src/ballistica/assets/assets_server.cc index 815318c9..b905ca03 100644 --- a/src/ballistica/assets/assets_server.cc +++ b/src/ballistica/assets/assets_server.cc @@ -22,10 +22,10 @@ AssetsServer::AssetsServer() { } auto AssetsServer::OnAppStart() -> void { - thread_->PushCallSynchronous([this] { StartInThread(); }); + thread_->PushCallSynchronous([this] { OnAppStartInThread(); }); } -auto AssetsServer::StartInThread() -> void { +auto AssetsServer::OnAppStartInThread() -> void { assert(InAssetsThread()); // get our thread to give us periodic processing time... process_timer_ = diff --git a/src/ballistica/assets/assets_server.h b/src/ballistica/assets/assets_server.h index 1875c2d2..e9be2e6a 100644 --- a/src/ballistica/assets/assets_server.h +++ b/src/ballistica/assets/assets_server.h @@ -22,7 +22,7 @@ class AssetsServer { auto thread() const -> Thread* { return thread_; } private: - auto StartInThread() -> void; + auto OnAppStartInThread() -> void; void Process(); void WriteReplayMessages(); Thread* thread_{}; diff --git a/src/ballistica/audio/audio_server.cc b/src/ballistica/audio/audio_server.cc index 074ee8d4..21dcee95 100644 --- a/src/ballistica/audio/audio_server.cc +++ b/src/ballistica/audio/audio_server.cc @@ -331,10 +331,10 @@ AudioServer::AudioServer() : impl_{new AudioServer::Impl()} { } auto AudioServer::OnAppStart() -> void { - thread_->PushCallSynchronous([this] { StartInThread(); }); + thread_->PushCallSynchronous([this] { OnAppStartInThread(); }); } -auto AudioServer::StartInThread() -> void { +auto AudioServer::OnAppStartInThread() -> void { assert(InAudioThread()); thread()->AddPauseCallback(NewLambdaRunnableRaw([this] { OnThreadPause(); })); thread()->AddResumeCallback( diff --git a/src/ballistica/audio/audio_server.h b/src/ballistica/audio/audio_server.h index 4b9bad0c..9efb480a 100644 --- a/src/ballistica/audio/audio_server.h +++ b/src/ballistica/audio/audio_server.h @@ -70,7 +70,7 @@ class AudioServer { class ThreadSource; struct Impl; - auto StartInThread() -> void; + auto OnAppStartInThread() -> void; ~AudioServer(); auto OnThreadPause() -> void; diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 6e2515fe..e8964397 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -32,7 +32,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20829; +const int kAppBuildNumber = 20831; const char* kAppVersion = "1.7.7"; // Our standalone globals. @@ -102,7 +102,8 @@ auto BallisticaMain(int argc, char** argv) -> int { g_app = new App(argc, argv); // Create a Thread wrapper around the current (main) thread. - g_main_thread = new Thread(ThreadIdentifier::kMain, ThreadType::kMain); + g_main_thread = + new Thread(ThreadIdentifier::kMain, ThreadSource::kWrapMain); Thread::UpdateMainThreadID(); // Bootstrap our Python environment as early as we can (depends on diff --git a/src/ballistica/core/thread.cc b/src/ballistica/core/thread.cc index 1b277acc..e7559344 100644 --- a/src/ballistica/core/thread.cc +++ b/src/ballistica/core/thread.cc @@ -95,24 +95,24 @@ void Thread::WaitForNextEvent(bool single_cycle) { millisecs_t wait_time = timers_.GetTimeToNextExpire(real_time); if (wait_time > 0) { std::unique_lock lock(thread_message_mutex_); - if (thread_message_count_ == 0) { + if (thread_messages_.empty()) { thread_message_cv_.wait_for(lock, std::chrono::milliseconds(wait_time), [this] { // Go back to sleep on spurious wakeups // if we didn't wind up with any new // messages. - return (thread_message_count_ > 0); + return !thread_messages_.empty(); }); } } } else { // Not running timers; just wait indefinitely for the next message. std::unique_lock lock(thread_message_mutex_); - if (thread_message_count_ == 0) { + if (thread_messages_.empty()) { thread_message_cv_.wait(lock, [this] { // Go back to sleep on spurious wakeups // (if we didn't wind up with any new messages). - return (thread_message_count_ > 0); + return !(thread_messages_.empty()); }); } } @@ -202,20 +202,16 @@ void Thread::GetThreadMessages(std::list* messages) { // Make sure they passed an empty one in. assert(messages->empty()); - if (thread_message_count_ > 0) { - std::unique_lock lock(thread_message_mutex_); - assert(thread_messages_.size() == thread_message_count_); + std::scoped_lock lock(thread_message_mutex_); + if (!thread_messages_.empty()) { messages->swap(thread_messages_); - thread_message_count_ = 0; } } -Thread::Thread(ThreadIdentifier identifier_in, ThreadType type_in) - : type_(type_in), identifier_(identifier_in) { - switch (type_) { - case ThreadType::kStandard: { - // Lock down until the thread is up and running. It'll unlock us when - // it's ready to go. +Thread::Thread(ThreadIdentifier identifier_in, ThreadSource source) + : source_(source), identifier_(identifier_in) { + switch (source_) { + case ThreadSource::kCreate: { int (*func)(void*); switch (identifier_) { case ThreadIdentifier::kLogic: @@ -254,7 +250,7 @@ Thread::Thread(ThreadIdentifier identifier_in, ThreadType type_in) break; } - case ThreadType::kMain: { + case ThreadSource::kWrapMain: { // We've got no thread of our own to launch // so we run our setup stuff right here instead of off in some. assert(std::this_thread::get_id() == g_app->main_thread_id); @@ -274,7 +270,7 @@ Thread::Thread(ThreadIdentifier identifier_in, ThreadType type_in) auto Thread::ThreadMain() -> int { try { - assert(type_ == ThreadType::kStandard); + assert(source_ == ThreadSource::kCreate); thread_id_ = std::this_thread::get_id(); const char* name; const char* id_string; @@ -321,10 +317,7 @@ auto Thread::ThreadMain() -> int { // Mark ourself as bootstrapped and signal listeners so // anyone waiting for us to spin up can move along. - { - std::scoped_lock lock(client_listener_mutex_); - bootstrapped_ = true; - } + bootstrapped_ = true; client_listener_cv_.notify_all(); // Now just run our loop until we die. @@ -358,14 +351,16 @@ auto Thread::ThreadMain() -> int { } void Thread::SetAcquiresPythonGIL() { + assert(!acquires_python_gil_); // This should be called exactly once. + assert(IsCurrent()); acquires_python_gil_ = true; g_python->AcquireGIL(); } // Explicitly kill the main thread. void Thread::Quit() { - assert(type_ == ThreadType::kMain); - if (type_ == ThreadType::kMain) { + assert(source_ == ThreadSource::kWrapMain); + if (source_ == ThreadSource::kWrapMain) { done_ = true; } } @@ -431,13 +426,10 @@ void Thread::PushThreadMessage(const ThreadMessage& t) { // Plop the data on to the list; we're assuming the mutex is locked. thread_messages_.push_back(t); - // Keep our own count; apparently size() on an stl list involves - // iterating. + // Keep our own count; apparently size() on an stl list involves iterating. // FIXME: Actually I don't think this is the case anymore; should check. - thread_message_count_++; - assert(thread_message_count_ == thread_messages_.size()); - // Show message count states. + // Debugging: show message count states. if (explicit_bool(false)) { static int one_off = 0; static int foo = 0; @@ -445,7 +437,7 @@ void Thread::PushThreadMessage(const ThreadMessage& t) { one_off++; // Show momemtary spikes. - if (thread_message_count_ > 100 && one_off > 100) { + if (thread_messages_.size() > 100 && one_off > 100) { one_off = 0; foo = 999; } @@ -453,11 +445,11 @@ void Thread::PushThreadMessage(const ThreadMessage& t) { // Show count periodically. if ((std::this_thread::get_id() == g_app->main_thread_id) && foo > 100) { foo = 0; - Log("MSG COUNT " + std::to_string(thread_message_count_)); + Log("MSG COUNT " + std::to_string(thread_messages_.size())); } } - if (thread_message_count_ > 1000) { + if (thread_messages_.size() > 1000) { static bool sent_error = false; if (!sent_error) { sent_error = true; @@ -468,9 +460,9 @@ void Thread::PushThreadMessage(const ThreadMessage& t) { } // Prevent runaway mem usage if the list gets out of control. - if (thread_message_count_ > 10000) { - throw Exception("KILLING APP: ThreadMessage list > 10000 in thread: " - + GetCurrentThreadName()); + if (thread_messages_.size() > 10000) { + FatalError("ThreadMessage list > 10000 in thread: " + + GetCurrentThreadName()); } // Unlock thread-message list and inform thread that there's something @@ -617,5 +609,12 @@ auto Thread::CheckPushSafety() -> bool { return CheckPushRunnableSafety(); } } +auto Thread::CheckPushRunnableSafety() -> bool { + std::scoped_lock lock(client_listener_mutex_); + + // We first complain when we get to 1000 queued messages so + // let's consider things unsafe when we're halfway there. + return (thread_messages_.size() < kThreadMessageSafetyThreshold); +} } // namespace ballistica diff --git a/src/ballistica/core/thread.h b/src/ballistica/core/thread.h index c994997c..df24bad4 100644 --- a/src/ballistica/core/thread.h +++ b/src/ballistica/core/thread.h @@ -24,7 +24,7 @@ const int kThreadMessageSafetyThreshold{500}; class Thread { public: explicit Thread(ThreadIdentifier id, - ThreadType type_in = ThreadType::kStandard); + ThreadSource source = ThreadSource::kCreate); virtual ~Thread(); auto ClearCurrentThreadName() -> void; @@ -57,12 +57,6 @@ class Thread { auto RunEventLoop(bool single_cycle = false) -> int; auto identifier() const -> ThreadIdentifier { return identifier_; } - auto CheckPushRunnableSafety() -> bool { - // We first complain when we get to 1000 queued messages so - // let's consider things unsafe when we're halfway there. - return (thread_message_count_ < kThreadMessageSafetyThreshold); - } - // Register a timer to run on the thread. auto NewTimer(millisecs_t length, bool repeat, const Object::Ref& runnable) -> Timer*; @@ -116,7 +110,7 @@ class Thread { explicit ThreadMessage(Type type, Runnable* runnable, bool* completion_flag) : type(type), runnable(runnable), completion_flag{completion_flag} {} }; - + auto CheckPushRunnableSafety() -> bool; auto SetInternalThreadName(const std::string& name) -> void; auto WaitForNextEvent(bool single_cycle) -> void; auto LoopUpkeep(bool once) -> void; @@ -132,7 +126,7 @@ class Thread { int messages_since_paused_{}; millisecs_t last_paused_message_report_time_{}; bool done_{}; - ThreadType type_; + ThreadSource source_; int listen_sd_{}; std::thread::id thread_id_{}; ThreadIdentifier identifier_{ThreadIdentifier::kInvalid}; @@ -162,7 +156,6 @@ class Thread { auto RunPauseCallbacks() -> void; auto RunResumeCallbacks() -> void; - int thread_message_count_{}; bool bootstrapped_{}; std::list> runnables_; std::list pause_callbacks_; diff --git a/src/ballistica/core/types.h b/src/ballistica/core/types.h index ab64b1d2..71ab11ef 100644 --- a/src/ballistica/core/types.h +++ b/src/ballistica/core/types.h @@ -986,11 +986,11 @@ enum class NodeAttributeType { kCollideModelArray }; -enum class ThreadType { +enum class ThreadSource { /// A normal thread spun up by us. - kStandard, + kCreate, /// For wrapping a ballistica thread around the existing main thread. - kMain + kWrapMain }; /// Used for module-thread identification. diff --git a/src/ballistica/logic/logic.cc b/src/ballistica/logic/logic.cc index 4a54876f..ce1a5456 100644 --- a/src/ballistica/logic/logic.cc +++ b/src/ballistica/logic/logic.cc @@ -76,23 +76,24 @@ Logic::Logic() // Spin up our thread. thread_ = new Thread(ThreadIdentifier::kLogic); g_app->pausable_threads.push_back(thread_); - // 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_->SetAcquiresPythonGIL(); } auto Logic::OnAppStart() -> void { - thread_->PushCallSynchronous([this] { StartInThread(); }); + thread_->PushCallSynchronous([this] { OnAppStartInThread(); }); } -auto Logic::StartInThread() -> void { +auto Logic::OnAppStartInThread() -> void { try { + // Our thread should hold the Python GIL any time it is running. + // 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_->SetAcquiresPythonGIL(); + // We want to be informed when our thread is pausing. thread()->AddPauseCallback( NewLambdaRunnableRaw([this] { OnThreadPause(); })); - g_ui->LogicThreadInit(); + g_ui->OnAppStart(); // Init python and apply our settings immediately. // This way we can get started loading stuff in the background diff --git a/src/ballistica/logic/logic.h b/src/ballistica/logic/logic.h index def5a310..7fcd4163 100644 --- a/src/ballistica/logic/logic.h +++ b/src/ballistica/logic/logic.h @@ -245,7 +245,7 @@ class Logic { auto thread() const -> Thread* { return thread_; } private: - auto StartInThread() -> void; + auto OnAppStartInThread() -> void; auto HandleQuitOnIdle() -> void; auto InitSpecialChars() -> void; auto Draw() -> void; diff --git a/src/ballistica/ui/ui.cc b/src/ballistica/ui/ui.cc index b33fe840..7ddf8c4b 100644 --- a/src/ballistica/ui/ui.cc +++ b/src/ballistica/ui/ui.cc @@ -52,7 +52,9 @@ UI::UI() { } } -auto UI::LogicThreadInit() -> void { +auto UI::OnAppStart() -> void { + assert(InLogicThread()); + root_ui_ = new RootUI(); // Make sure we know when forced-ui-scale is enabled. if (force_scale_) { diff --git a/src/ballistica/ui/ui.h b/src/ballistica/ui/ui.h index 08dd7228..95d3e537 100644 --- a/src/ballistica/ui/ui.h +++ b/src/ballistica/ui/ui.h @@ -31,7 +31,7 @@ namespace ballistica { class UI : public ContextTarget { public: UI(); - auto LogicThreadInit() -> void; + auto OnAppStart() -> void; ~UI() override; auto Reset() -> void;