From c3cbb6343ee6b88b3278e8050b7d6d683f0f3aa5 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 17 May 2023 14:03:11 -0700 Subject: [PATCH] docs tweaks --- src/ballistica/README.md | 42 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/ballistica/README.md b/src/ballistica/README.md index d1de811f..b7328b18 100644 --- a/src/ballistica/README.md +++ b/src/ballistica/README.md @@ -15,7 +15,7 @@ and often the Python library itself. Similar to other places in the engine layout, code here is organized based on [feature-sets](../../config/featuresets). Feature-sets make it easy to isolate, -add, and remove functionality from the engine at a high level. The only +add, and remove functionality from a Ballistica app at a high level. The only subdirectory here *not* associated with a feature-set is 'shared'. On the Python side, a feature-set generally (but not always) has a corresponding @@ -26,25 +26,25 @@ functionality it needs from other feature-set packages such as `babase` or an elegant way to split the Python parts of the engine into logical pieces and init each one only when it is needed. -Taking things further, in order to keep things as consistent as possible between -the Python and native layers, our native layer has recently been redesigned to -sit on top of Python's module system. So even though our feature-sets still -often talk to each other directly through native C++ interfaces, they go through -Python's import mechanism to init each other and acquire those interfaces. +In order to keep things as consistent as possible between the Python and native +layers, our native layer has recently been redesigned to sit on top of Python's +module system. So even though our feature-sets still often talk to each other +directly through native C++ interfaces, they go through Python's import +mechanism to init each other and acquire those interfaces. The benefits of this setup are safety and consistency. It does not matter if we do `import bascenev1` in Python or `scene_v1::SceneV1FeatureSet::Import()` from C++; in either case we can be sure that both Python and C++ parts of the `scene_v1` feature-set have been inited and are ready for use. In earlier -iterations of the feature-set system the Python and C++ worlds were more -independent and one had to take care to avoid using certain parts of a -feature-set from C++ if its Python side had not yet been imported, which was +iterations of the feature-set system, the Python and C++ worlds were more +independent; one had to take care to avoid using certain parts of a feature-set +from C++ if that feature-set's Python side had not yet been imported, which was both more confusing and more error prone. ## C++ 'Module' Mechanism Details -At the code level, we use a combination of C++ namespaces and global variables -to 'emulate' Python's module mechanism. +At the C++ level, we use a combination of C++ namespaces and global variables +to mimic Python's module mechanism. Python consists of modules that import other modules (or stuff from within those modules) into their own global namespaces for their own code to use. So when you @@ -71,16 +71,16 @@ do anything in the engine. In the end, the happy-medium solution employed by Ballistica is a combination of globals and namespaces. Each feature-set has its own C++ namespace that is basically thought of as its module namespace in Python. When a feature-set gets -imported, the first thing that it does is import any other feature-sets that it -uses into its own private namespace globals. So the `scene_v1` feature-set, when -imported, might import the `base` feature-set as a `g_base` global. But because -`scene_v1` has its own namespace, this global will actually be -`ballistica::scene_v1::g_base` which will be distinct from any `g_base` global -held by any other feature-set. So as long as each feature-set correctly lives in -its own namespace and uses only its own set of globals, things should behave -pretty much as they do for Python modules; feature-sets simply import what they -use when they themselves are imported and all code throughout the feature-set -can safely use those globals from that point on. +imported, it does a one-time import of any other feature-sets that it uses and +stores pointers to them in its own private namespace globals. So the `scene_v1` +feature-set, when imported, might import the `base` feature-set as a `g_base` +global. But because `scene_v1` has its own namespace, this global will actually +be `ballistica::scene_v1::g_base` which will be distinct from any `g_base` +global held by any other feature-set. So as long as each feature-set correctly +lives in its own namespace and uses only its own set of globals, things should +behave pretty much as they do on the Python layer; feature-sets simply import +what they use when they themselves are imported and all code throughout the +feature-set can safely use those globals from that point on. Check out the [Template Feature Set](template_fs) for examples of wrangling globals and namespaces to implement a feature-set-front-end in C++.