"""
BGL - Brisbane Gameloft Libs (BeaGLe)
The problem this lib tries to solve is that there are
currently a bunch of python libs (both 3rd party and
in-house) scattered all over the place. Python code
needs to find these modules. This creates scattered
spaghetti-code like dependencies of hard-coded changes
to sys.path and assumed changes to PYTHONPATH. This
makes the python code brittle.
This file attempts to solve that problem by customizing
the way files are loaded in Python by collecting all
the paths to python libs in one place. Here.
We do this by intercepting import calls in python code
and redirecting calls that start with the beagle names
space bgl. Modules are imported on demand.
In order to use this lib we still have to tell python
where to load this file. But that's one hard-coded
path as opposed to many.
This file is also going to be the canonical location
for path constants!
Ultimately it would be nice to physically collect
all the libs together into one place in the dir
structure and throw this module away. The reason
we should get rid of this file is because it uses
some non-obvious python "magic". In the meantime,
hopefully, this will make life a little easier.
FIXME: there's a problem with interdependencies
between the "libs" dirs and the survivor dirs.
There's paths in here that should only be in
survivor and there's back-references in here
to code that should be moved out of the game
dir and into the libs dirs ("rki", "rk", tlib
etc).
"""
import sys
import os
from os.path import abspath, join, dirname
import importlib
#
# Canonical Path Constants
#
# Where the bgl libs live. Work out all the other paths relative to this.
BGL_DIR = abspath(dirname(__file__))
# ../code/3rdParty
THIRD_PARTY_DIR = abspath(join(BGL_DIR, "..", "..", ".."))
# ../code/3rdParty/bne_lib
BNE_LIB_DIR = join(THIRD_PARTY_DIR, "bne_lib")
# ../code/3rdParty/bne_lib/tools
BNE_LIB_TOOLS_DIR = join(BNE_LIB_DIR, "tools")
# ../code/3rdParty/tools/BuildSystem/SConsHome
SCONS_HOME = join("BuildSystem", "SConsHome")
# ../code/3rdParty/tools
THIRD_PARTY_TOOLS_DIR = join(THIRD_PARTY_DIR, "tools")
# ../code/3rdParty/tools/BuildSystem
TOOLS_BUILD_SYSTEM_DIR = join(THIRD_PARTY_TOOLS_DIR, "BuildSystem")
# ../code/3rdParty/tools/Corona
CORONA_DIR = join(THIRD_PARTY_TOOLS_DIR, "Corona")
# ../code/3rdParty/tools/7Zip
SEVEN_ZIP_DIR = join(THIRD_PARTY_TOOLS_DIR, "7Zip")
# ../code/survivor
SURVIVOR_DIR = abspath(join(BGL_DIR, "..", "..", "..", "..", "survivor"))
# ../code/survivor/data/Survivor
SURVIVOR_DATA_DIR = join(SURVIVOR_DIR, "data", "Survivor")
# ../code/survivor/data/Survivor/Data/Runtime
SURVIVOR_DATA_RUNTIME_DIR = join(SURVIVOR_DATA_DIR, "Data", "Runtime")
#
# Executables
#
SEVEN_ZIP = join(SEVEN_ZIP_DIR, "7z.exe")
#
# Expose some environment variables that must be set
#
#if "PYTHONHOME" not in os.environ:
# raise Exception("The PYTHONHOME variable must be set!")
#PYTHON_HOME = os.environ["PYTHONHOME"]
class BGLImporter(object):
"""
Customize Python module loading. Only for modules starting
with bgl. Check out PEP 302 for information about what I'm
doing here.
"""
def __init__(self):
self.jinja2 = None
# Lookup table: "module_name" -> "path_to_module"
self.import_redirects = {
"jinja2": join(BNE_LIB_TOOLS_DIR, "Jinja2-2.8"),
"rk" : SURVIVOR_DATA_RUNTIME_DIR,
"rki" : SURVIVOR_DATA_RUNTIME_DIR,
"utils": BGL_DIR,
# Add more modules here...
}
# Lookup table for modules already imported: "module_name" -> loaded_module_obj
self.imported_modules = {}
return
def find_module(self, module_name, package_path):
"""
Part of the Python Module Loader contract.
We only handle module names starting with "bgl."
"""
if module_name.startswith("bgl."):
return self
return None
def load_module(self, module_name):
"""
Load a module using a redirected path from a lookup table..
"""
# We only care about modules starting with "bgl."
if module_name.startswith("bgl."):
module_name = module_name[4:]
# Do we redirect this module?
if module_name in self.import_redirects.keys():
print module_name
# If we redirect this module have we already loaded it?
if module_name not in self.imported_modules:
# We do redirect this module but haven't done so yet!
# So load the module using the redirected path now.
module_path = self.import_redirects[module_name]
sys.path.append(module_path)
module = importlib.import_module(module_name)
self.imported_modules[module_name] = module
# return the imported module
return self.imported_modules[module_name]
# we don't know how to load this module!
return None
# register BGLImporter to customize module loading
sys.meta_path.append(BGLImporter())