Original Post
I'm rewriting part of my engine (here's the dev journal) to support pluggable components for the window manager, renderer, audio etc... I haven't yet arrived at a satisfying implementation for it though, and that's why I'm asking for your opinions and suggestions. Note that the engine's not really structured exactly like this, I'm simplifying a bit to make the point clear. At first, components were structured like this:
engine
components
audio
dummy
openal
renderer
dummy
opengl
mesh
When a component was loaded, its module or package was copied to the root level. In effect, something like: engine.renderer = components.renderer.opengl The problem with this approach was that you couldn't import anything from inside packages. Ie. from renderer.mesh import TriangleMesh wouldn't work; instead, you'd have to write TriangleMesh = renderer.mesh.TriangleMesh. I wasn't happy with this, and researched alternatives. Then I found/remembered the __path__ attribute of packages, which you can modify to alter the paths considered part of the package. So, I restructured the engine by moving the component packages to the top level. Components were now loaded by modifying the __path__ attribute of the component category package and copying component-level attributes to the component category package. In other words, like this: engine.renderer.__path__ += "engine/renderer/opengl" engine.renderer.__dict__.update(engine.renderer.opengl.__dict__) I was initially happy with the solution, but discovered a different problem with the new approach. Copying the attributes means that modules inside the component (for example, opengl.mesh) don't see the updated component-level attributes anymore, they see the attributes inside the opengl package. For example, calling renderer.init(), which updates renderer.max_texture_units; results in renderer.opengl.max_texture_units to remain at the old value, and this is the value which the component modules see. This is where I'm stuck currently. One option would be to simply not allow component-level attributes, but I don't think that's a good solution. Do you have any new ideas for implementing plugin loading, or suggestions for fixing the problem with component-level attributes? If any part of the explanation is unclear, please ask for more information. [smile] Thanks.