docs tweaks

This commit is contained in:
Eric 2023-05-17 14:03:11 -07:00
parent 898a2af477
commit c3cbb6343e
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98

View File

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