mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-27 09:23:12 +08:00
more c++ bootstrap refactoring
This commit is contained in:
parent
014a996933
commit
866f9475fb
1194
.efrocachemap
1194
.efrocachemap
File diff suppressed because it is too large
Load Diff
@ -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 = 20821
|
||||
expected_build = 20822
|
||||
running_build: int = env['build_number']
|
||||
if running_build != expected_build:
|
||||
print(
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include "ballistica/core/fatal_error.h"
|
||||
#include "ballistica/core/logging.h"
|
||||
#include "ballistica/core/thread.h"
|
||||
#include "ballistica/dynamics/bg/bg_dynamics.h"
|
||||
#include "ballistica/dynamics/bg/bg_dynamics_server.h"
|
||||
#include "ballistica/game/v1_account.h"
|
||||
#include "ballistica/graphics/graphics_server.h"
|
||||
@ -30,7 +31,7 @@
|
||||
namespace ballistica {
|
||||
|
||||
// These are set automatically via script; don't modify them here.
|
||||
const int kAppBuildNumber = 20821;
|
||||
const int kAppBuildNumber = 20822;
|
||||
const char* kAppVersion = "1.7.7";
|
||||
|
||||
// Our standalone globals.
|
||||
@ -55,8 +56,8 @@ Input* g_input{};
|
||||
Thread* g_main_thread{};
|
||||
Assets* g_assets{};
|
||||
AssetsServer* g_assets_server{};
|
||||
NetworkReader* g_network_reader{};
|
||||
Networking* g_networking{};
|
||||
NetworkReader* g_network_reader{};
|
||||
NetworkWriter* g_network_writer{};
|
||||
Platform* g_platform{};
|
||||
Python* g_python{};
|
||||
@ -99,16 +100,15 @@ auto BallisticaMain(int argc, char** argv) -> int {
|
||||
g_app = new App(argc, argv);
|
||||
g_platform = Platform::Create();
|
||||
|
||||
// Bootstrap our Python environment as early as we can (depends on
|
||||
// g_platform for locating OS-specific paths).
|
||||
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 and graphics variations
|
||||
// (VR, headless, regular, etc.)
|
||||
// Bootstrap our Python environment as early as we can (depends on
|
||||
// g_platform for locating OS-specific paths).
|
||||
g_python = new Python();
|
||||
|
||||
// Spin up our specific app and graphics variations (VR, headless, etc.)
|
||||
g_app_flavor = g_platform->CreateAppFlavor();
|
||||
g_graphics = g_platform->CreateGraphics();
|
||||
|
||||
@ -125,25 +125,21 @@ auto BallisticaMain(int argc, char** argv) -> int {
|
||||
g_assets_server = new AssetsServer();
|
||||
g_ui = Object::NewUnmanaged<UI>();
|
||||
g_networking = new Networking();
|
||||
g_network_writer = new NetworkWriter();
|
||||
g_input = new Input();
|
||||
g_app_internal = GetAppInternal();
|
||||
g_app_internal = CreateAppInternal();
|
||||
g_game = new Game();
|
||||
Scene::Init();
|
||||
if (!HeadlessMode()) {
|
||||
g_bg_dynamics = new BGDynamics();
|
||||
g_bg_dynamics_server = new BGDynamicsServer();
|
||||
}
|
||||
|
||||
// Spin up our other standard threads.
|
||||
auto* logic_thread{new Thread(ThreadIdentifier::kLogic)};
|
||||
g_app->pausable_threads.push_back(logic_thread);
|
||||
auto* network_write_thread{new Thread(ThreadIdentifier::kNetworkWrite)};
|
||||
g_app->pausable_threads.push_back(network_write_thread);
|
||||
// FIXME - move this later but need to init Python earlier then.
|
||||
g_game->Start();
|
||||
|
||||
// Spin up our subsystems in those threads.
|
||||
logic_thread->PushCallSynchronous(
|
||||
[logic_thread] { new Game(logic_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,
|
||||
// etc.)
|
||||
// NOTE TO SELF: this starts reading stdin and py-init hangs if we do
|
||||
// it after here.
|
||||
g_platform->CreateAuxiliaryModules();
|
||||
|
||||
// Ok at this point we can be considered up-and-running.
|
||||
|
||||
@ -84,7 +84,7 @@ void Thread::WaitForNextEvent(bool single_cycle) {
|
||||
}
|
||||
|
||||
// While we're waiting, allow other python threads to run.
|
||||
if (holds_python_gil_) {
|
||||
if (acquires_python_gil_) {
|
||||
g_python->ReleaseGIL();
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ void Thread::WaitForNextEvent(bool single_cycle) {
|
||||
}
|
||||
}
|
||||
|
||||
if (holds_python_gil_) {
|
||||
if (acquires_python_gil_) {
|
||||
g_python->AcquireGIL();
|
||||
}
|
||||
}
|
||||
@ -357,8 +357,8 @@ auto Thread::ThreadMain() -> int {
|
||||
}
|
||||
}
|
||||
|
||||
void Thread::SetHoldsPythonGIL() {
|
||||
holds_python_gil_ = true;
|
||||
void Thread::SetAcquiresPythonGIL() {
|
||||
acquires_python_gil_ = true;
|
||||
g_python->AcquireGIL();
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ class Thread {
|
||||
// Used to quit the main thread.
|
||||
void Quit();
|
||||
|
||||
void SetHoldsPythonGIL();
|
||||
void SetAcquiresPythonGIL();
|
||||
|
||||
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 holds_python_gil_{};
|
||||
bool acquires_python_gil_{};
|
||||
|
||||
// FIXME: Should generalize this to some sort of PlatformThreadData class.
|
||||
#if BA_XCODE_BUILD
|
||||
|
||||
@ -14,15 +14,9 @@
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
void BGDynamics::Init() {
|
||||
// Just init our singleton.
|
||||
new BGDynamics();
|
||||
}
|
||||
|
||||
BGDynamics::BGDynamics() {
|
||||
assert(InLogicThread());
|
||||
// We're a singleton; make sure we don't already exist.
|
||||
assert(g_bg_dynamics == nullptr);
|
||||
g_bg_dynamics = this;
|
||||
}
|
||||
|
||||
void BGDynamics::AddTerrain(CollideModelData* o) {
|
||||
|
||||
@ -48,7 +48,7 @@ class BGDynamicsEmission {
|
||||
// client (game thread) functionality for bg dynamics
|
||||
class BGDynamics {
|
||||
public:
|
||||
static void Init();
|
||||
BGDynamics();
|
||||
|
||||
void Emit(const BGDynamicsEmission& def);
|
||||
void Step(const Vector3f& cam_pos);
|
||||
@ -68,7 +68,6 @@ class BGDynamics {
|
||||
void SetDrawSnapshot(BGDynamicsDrawSnapshot* s);
|
||||
|
||||
private:
|
||||
BGDynamics();
|
||||
void DrawChunks(FrameDef* frame_def, std::vector<Matrix44f>* instances,
|
||||
BGDynamicsChunkType chunk_type);
|
||||
Object::Ref<SpriteMesh> lights_mesh_;
|
||||
|
||||
@ -660,12 +660,15 @@ void BGDynamicsServer::ParticleSet::UpdateAndCreateSnapshot(
|
||||
current_set = !current_set;
|
||||
}
|
||||
|
||||
BGDynamicsServer::BGDynamicsServer(Thread* thread)
|
||||
: thread_(thread),
|
||||
height_cache_(new BGDynamicsHeightCache()),
|
||||
BGDynamicsServer::BGDynamicsServer()
|
||||
: height_cache_(new BGDynamicsHeightCache()),
|
||||
collision_cache_(new CollisionCache) {
|
||||
// We're a singleton; make sure we don't already exist.
|
||||
BA_PRECONDITION(g_bg_dynamics_server == nullptr);
|
||||
g_bg_dynamics_server = this;
|
||||
|
||||
// Spin up our thread.
|
||||
thread_ = new Thread(ThreadIdentifier::kBGDynamics);
|
||||
g_app->pausable_threads.push_back(thread_);
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
|
||||
ode_world_ = dWorldCreate();
|
||||
|
||||
@ -80,7 +80,7 @@ class BGDynamicsServer {
|
||||
std::vector<std::pair<BGDynamicsFuseData*, FuseStepData> > fuse_step_data_;
|
||||
};
|
||||
|
||||
explicit BGDynamicsServer(Thread* thread);
|
||||
BGDynamicsServer();
|
||||
|
||||
auto time() const -> uint32_t { return time_; }
|
||||
auto graphics_quality() const -> GraphicsQuality { return graphics_quality_; }
|
||||
|
||||
@ -17,12 +17,12 @@ CollisionCache::~CollisionCache() {
|
||||
dGeomDestroy(test_box_);
|
||||
}
|
||||
|
||||
void CollisionCache::SetGeoms(const std::vector<dGeomID>& geoms) {
|
||||
auto CollisionCache::SetGeoms(const std::vector<dGeomID>& geoms) -> void {
|
||||
dirty_ = true;
|
||||
geoms_ = geoms;
|
||||
}
|
||||
|
||||
void CollisionCache::Draw(FrameDef* frame_def) {
|
||||
auto CollisionCache::Draw(FrameDef* frame_def) -> void {
|
||||
if (cells_.empty()) {
|
||||
return;
|
||||
}
|
||||
@ -124,7 +124,7 @@ void CollisionCache::Draw(FrameDef* frame_def) {
|
||||
}
|
||||
}
|
||||
|
||||
void CollisionCache::Precalc() {
|
||||
auto CollisionCache::Precalc() -> void {
|
||||
Update();
|
||||
|
||||
if (precalc_index_ >= cells_.size()) {
|
||||
@ -138,8 +138,8 @@ void CollisionCache::Precalc() {
|
||||
TestCell(precalc_index_++, x, z);
|
||||
}
|
||||
|
||||
void CollisionCache::CollideAgainstGeom(dGeomID g1, void* data,
|
||||
dNearCallback* callback) {
|
||||
auto CollisionCache::CollideAgainstGeom(dGeomID g1, void* data,
|
||||
dNearCallback* callback) -> void {
|
||||
// Update bounds, test for quick out against our height map,
|
||||
// and proceed to a full test on a positive result.
|
||||
g1->recomputeAABB();
|
||||
@ -204,7 +204,7 @@ void CollisionCache::CollideAgainstGeom(dGeomID g1, void* data,
|
||||
}
|
||||
}
|
||||
|
||||
void CollisionCache::TestCell(size_t cell_index, int x, int z) {
|
||||
auto CollisionCache::TestCell(size_t cell_index, int x, int z) -> void {
|
||||
int t_count = static_cast<int>(geoms_.size());
|
||||
float top = cells_[cell_index].height_confirmed_empty_;
|
||||
|
||||
@ -252,8 +252,8 @@ void CollisionCache::TestCell(size_t cell_index, int x, int z) {
|
||||
}
|
||||
}
|
||||
|
||||
void CollisionCache::CollideAgainstSpace(dSpaceID space, void* data,
|
||||
dNearCallback* callback) {
|
||||
auto CollisionCache::CollideAgainstSpace(dSpaceID space, void* data,
|
||||
dNearCallback* callback) -> void {
|
||||
// We handle our own testing against trimeshes, so we can bring our fancy
|
||||
// caching into play.
|
||||
if (!geoms_.empty()) {
|
||||
@ -264,7 +264,7 @@ void CollisionCache::CollideAgainstSpace(dSpaceID space, void* data,
|
||||
}
|
||||
}
|
||||
|
||||
void CollisionCache::Update() {
|
||||
auto CollisionCache::Update() -> void {
|
||||
if (!dirty_) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ class CollisionCache {
|
||||
|
||||
// Call this periodically (once per cycle or so) to slowly fill in
|
||||
// the cache so there's less to do during spurts of activity;
|
||||
void Precalc();
|
||||
auto Precalc() -> void;
|
||||
|
||||
private:
|
||||
auto TestCell(size_t cell_index, int x, int z) -> void;
|
||||
|
||||
@ -64,29 +64,33 @@ const int kMaxChatMessages = 40;
|
||||
// Go with 5 minute ban.
|
||||
const int kKickBanSeconds = 5 * 60;
|
||||
|
||||
Game::Game(Thread* thread)
|
||||
: thread_(thread),
|
||||
game_roster_(cJSON_CreateArray()),
|
||||
Game::Game()
|
||||
: game_roster_(cJSON_CreateArray()),
|
||||
realtimers_(new TimerList()),
|
||||
connections_(std::make_unique<ConnectionSet>()) {
|
||||
// We're a singleton; make sure we don't already exist.
|
||||
assert(g_game == nullptr);
|
||||
g_game = this;
|
||||
|
||||
InitSpecialChars();
|
||||
|
||||
// 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 Game::Start() -> void {
|
||||
thread_->PushCallSynchronous([this] { StartInThread(); });
|
||||
}
|
||||
|
||||
auto Game::StartInThread() -> void {
|
||||
try {
|
||||
// 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();
|
||||
|
||||
// We want to be informed when our thread is pausing.
|
||||
thread->AddPauseCallback(NewLambdaRunnableRaw([this] { OnThreadPause(); }));
|
||||
thread()->AddPauseCallback(
|
||||
NewLambdaRunnableRaw([this] { OnThreadPause(); }));
|
||||
|
||||
g_ui->LogicThreadInit();
|
||||
|
||||
|
||||
@ -24,7 +24,8 @@ const int kMaxPartyNameCombinedSize = 25;
|
||||
/// rendering, etc.
|
||||
class Game {
|
||||
public:
|
||||
explicit Game(Thread* thread);
|
||||
Game();
|
||||
auto Start() -> void;
|
||||
|
||||
auto LaunchHostSession(PyObject* session_type_obj,
|
||||
BenchmarkType benchmark_type = BenchmarkType::kNone)
|
||||
@ -244,6 +245,7 @@ class Game {
|
||||
auto thread() const -> Thread* { return thread_; }
|
||||
|
||||
private:
|
||||
auto StartInThread() -> void;
|
||||
auto HandleQuitOnIdle() -> void;
|
||||
auto InitSpecialChars() -> void;
|
||||
auto Draw() -> void;
|
||||
|
||||
@ -24,7 +24,7 @@ void StdInputModule::PushBeginReadCall() {
|
||||
|
||||
while (true) {
|
||||
// Print a prompt if we're a tty.
|
||||
// We send this to the game thread so it happens AFTER the
|
||||
// We send this to the logic thread so it happens AFTER the
|
||||
// results of the last script-command message we may have just sent.
|
||||
if (stdin_is_terminal) {
|
||||
g_game->thread()->PushCall([] {
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
auto GetAppInternal() -> AppInternal*;
|
||||
auto CreateAppInternal() -> AppInternal*;
|
||||
|
||||
class AppInternal {
|
||||
public:
|
||||
|
||||
@ -8,10 +8,13 @@
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
NetworkWriter::NetworkWriter(Thread* thread) : thread_(thread) {
|
||||
// we're a singleton
|
||||
NetworkWriter::NetworkWriter() {
|
||||
// We're a singleton; make sure we don't already exist.
|
||||
assert(g_network_writer == nullptr);
|
||||
g_network_writer = this;
|
||||
|
||||
// Spin up our thread.
|
||||
thread_ = new Thread(ThreadIdentifier::kNetworkWrite);
|
||||
g_app->pausable_threads.push_back(thread_);
|
||||
}
|
||||
|
||||
void NetworkWriter::PushSendToCall(const std::vector<uint8_t>& msg,
|
||||
|
||||
@ -12,8 +12,8 @@ namespace ballistica {
|
||||
// A subsystem handling outbound network traffic.
|
||||
class NetworkWriter {
|
||||
public:
|
||||
NetworkWriter();
|
||||
void PushSendToCall(const std::vector<uint8_t>& msg, const SockAddr& addr);
|
||||
explicit NetworkWriter(Thread* thread);
|
||||
auto thread() const -> Thread* { return thread_; }
|
||||
|
||||
private:
|
||||
|
||||
@ -701,15 +701,6 @@ auto Platform::GetKeyName(int keycode) -> std::string {
|
||||
}
|
||||
|
||||
void Platform::CreateAuxiliaryModules() {
|
||||
#if !BA_HEADLESS_BUILD
|
||||
auto* bg_dynamics_thread = new Thread(ThreadIdentifier::kBGDynamics);
|
||||
g_app->pausable_threads.push_back(bg_dynamics_thread);
|
||||
#endif
|
||||
#if !BA_HEADLESS_BUILD
|
||||
bg_dynamics_thread->PushCallSynchronous(
|
||||
[bg_dynamics_thread] { new BGDynamicsServer(bg_dynamics_thread); });
|
||||
#endif
|
||||
|
||||
if (g_buildconfig.use_stdin_thread()) {
|
||||
// Start listening for stdin commands (on platforms where that makes sense).
|
||||
// Note: this thread blocks indefinitely for input so we don't add it to the
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user