Today, we take a look at niven's class loader, which is responsible for dynamic instancing of classes from plugins and packages, and is likely to become a core component of the serialization system.
The class loader
The class loader is a component that is tightly coupled with the RTTI
system. I forgot to say last time that the RTTI system with class
instancing has a drawback, you need a default constructor for each class
className ()) - just occured to me when a class that used to
work refused to compile due to a missing default constructor. This
limitation is not as bad as it might sound at first, as most
"interesting" classes don't have parameters in the classes constructor,
and classes that are instanced during serialization have to init from
the source archive and not the construtor anyway. The class loader
supports two ways of loading classes:
- Loading from Packages: A package is a simple DLL file that
getClass-Functions, as described last time. Packages don't need to be initialized before use. A good example of a package file is the application itself. The package contains in this case the classes that contain the application logic. Other packages might include different resource loaders, which could be loaded during runtime (think of shader generators, for example). The package loader is not working yet, but this is only a matter of time, as the second loader works, which supports a super-set of the features needed for package loading.
- Loading from Plugins: A plugin is a DLL file that exports all the same functions as a package, and special plugin-handling functions (init, shutdown and a plugin-info function). Special care has to be taken so these function are always called before using the plugin, and that they are only called once. For the class loader though, it is no difference if it's invoked with a Plugin or a Package, as it assumes that in case of a plugin it has been already properly initialized. The load call itself is the same as in the package case.
There might be more ways sometime, as it is possible to create custom script-driven objects that are loaded by the class loader (objects that contain code that is executed during run-time) The class loader might even be extended for loading a special kind of classes into a VM. At the moment, the Package & Plugin loading is most important though, and other loaders are not planned for the nearest future.
The class loader is completely type-safe: When loading a class, the
loader checks if the class is derived from the one it should be assigned
to. Usually, you don't want to create an instance of a class you know,
but rather of unknown classes. Example: The render driver is located in
a plugin, and the name of the class varies, the only thing that remains
the same is the interface the class implements, namely
load a class, you would use now
loadClass <iRenderer> ("name of the class", the_plugin). This is able
to load any renderer, just as long as it's derived from
you just specify the name and the plugin/package where to find it. The
engine takes care of finding it, checking whether it is a valid derivate
iRenderer and if so, instancing it. This checking turns out to be
rather simple, as the loader is working on the RTTI classes anyway. So
much for today, when I get into serialization, I'll revisit the current
class instancing mechanism, as it'll probably need some tweaking.
Anyway, at the moment, things are looking really good, with those core
services running, I have really good hope the serialization stuff won't
block me too long. I'll take another look at the window handler then,
splitting it up (the window creation is currently bound to the input,
which is altogether bound to the renderer - something I want to break