>>4Takes 5 seconds to download for me.
As for features, I'm not sure either, but here are some excerpts from the slides:
D’s usage in our codebase came about thanks to our programmers wanting a rapid iteration system. We settled on compiling native code in to dynamically linked modules. As such, our pipeline is set up so that D source code is actually data that our asset processors will convert in to final binary form.
As we have a ton of C++ code, it was critical to be able to hook in to C++ code and likewise for the C++ code to be able to hook in to the D code. A binding system was created, using #defines on the C++ side to expose interfaces and functions to D; and user-defined attributes and mixin templates to automate the work for exposing interfaces and functions back to C++. String resolves are currently used to match them all up, but that will move over to compile time generated hashes now that our main platform, Visual C++, has decent enough support for const expressions in the 2015 version.
As the system was implemented for rapid iteration, it needed to be able to support reloading the code on the fly. Compile time code inspection and generation was utilised to automatically serialise D structs and classes to JSON, which was then passed back in to an object created from a new DLL instance for deserialisation. Using JSON meant that binary layouts changing aren’t a problem as we string compare to find the correct values to deserialise to.
class DebugGraph
{
Vector2 m_vTopLeft;
Vector2 m_vBottomRight;
enum { Version = 3, RequiredVersion = 2 };
OSP_BEGIN( DebugGraph, Version, RequiredVersion )
OSP_VARIABLE( m_vTopLeft, 2 );
OSP_VARIABLE( m_vBottomRight, 3 );
OSP_END;
};
OSP_DEFINE( DebugGraph );
For reference, this is the boiler plate code required for a C++ object to have reflection capabilities in our code. The variables exist as normal, and then we have to define an OSP block – Object Stream Processor – which defines and adds functions for the declared variables with the declared versions. And further down in the .cpp source file, you need a further define that instantiates all the static data that the OSP block requires. That OSP_DEFINE is something of a bugbear of mine –thanks to templates. We have templated types that need to OSP, and you need an OSP_DEFINE for each template usage explicitly. All of this boilerplate just disappears when using the export class mixin, and thanks to user defined attributes any information needed on a variable such as version numbers gets defined with the variable instead of in a separate block. We also hit natural limits of the compiler, and while our content library uses the OSP extensively we can’t just have all the OSP_DEFINEs in a single file any more.