#include "daScript/daScript.h" // we need RTTI to bind StructInfo * #include "module_builtin_rtti.h" using namespace das; // base class which is part of C++ class hierarchy class BaseClass { public: virtual void update ( float dt ) = 0; virtual float3 getPosition() = 0; }; // list of all objects on the C++ side vector> g_allObjects; // updates all objects and returns average position float3 tick ( float dt ) { // in case of empty list of objects return float3(0,0,0) if ( g_allObjects.empty() ) { return float3(0.0f); } float3 pos = float3(0.0f); for ( auto & obj : g_allObjects ) { obj->update(dt); // call virtual update float3 objPos = obj->getPosition(); // call virtual getPosition pos.x += objPos.x; pos.y += objPos.y; pos.z += objPos.z; } // average the position float iCount = 1.0f / float(g_allObjects.size()); pos.x *= iCount; pos.y *= iCount; pos.z *= iCount; return pos; } // we include generated C++ bindings for the class adapter #include "tutorial04_gen.inc" // here we derive both from the original base class, as well as generated adapter // functions in the generated adapter require classPtr and context to be invoked class BaseClassAdapter : public BaseClass, public TutorialBaseClass { public: // in the constructor we store pointer to the original class and context // we also pass StructInfo of the daScript class to the generated class BaseClassAdapter ( char * pClass, const StructInfo * info, Context * ctx ) : TutorialBaseClass(info), classPtr(pClass), context(ctx) { } virtual void update ( float dt ) override { // we check if daScript class has 'update' function if ( auto fn = get_update(classPtr) ) { // we invoke it and pass it 'dt' invoke_update(context, fn, classPtr, dt); } } virtual float3 getPosition() override { // we check if daScript class has 'get_position' if ( auto fn = get_get_position(classPtr) ) { // we invoke it, and return it's result return invoke_get_position(context, fn, classPtr); } else { return float3(0.0f); } } protected: void * classPtr; // stored pointer to the daScript class Context * context; // stored pointer to the daScript context (its optional, if we know the context by other means) }; // we expose this function to das, so that it can 'register' derived classes with C++ void addObject ( const void * pClass, const StructInfo * info, Context * context ) { auto obj = make_shared((char *)pClass,info,context); g_allObjects.emplace_back(obj); } // we use XDD to convert tutorial04module.das into C++ .inc file #include "tutorial04module.das.inc" // making custom builtin module class Module_Tutorial04 : public Module { public: Module_Tutorial04() : Module("tutorial_04") { // module name, when used from das file ModuleLibrary lib(this); lib.addBuiltInModule(); addBuiltinDependency(lib, Module::require("rtti")); // we add RTTI to ModuleLibrary so that we can bind addObject // add_object is how daScript will 'register' objects with C++ addExtern(*this, lib, "add_object", SideEffects::modifyExternal, "addObject"); // expose tick to daScript, for the purposes of example addExtern(*this, lib, "tick", SideEffects::modifyExternal, "tick"); // add builtin module (tutorial04module.das is converted to .das.inc file and included as embedded string) compileBuiltinModule("tutorial04module.das",tutorial04module_das,sizeof(tutorial04module_das)); } }; // registering module, so that its available via 'NEED_MODULE' macro REGISTER_MODULE(Module_Tutorial04); #define TUTORIAL_NAME "/examples/tutorial/tutorial04.das" #include "tutorial.inc" int main( int, char * [] ) { // request all da-script built in modules NEED_ALL_DEFAULT_MODULES; // request our custom module NEED_MODULE(Module_Tutorial04); // Initialize modules Module::Initialize(); // run the tutorial tutorial(); // shut-down daScript, free all memory Module::Shutdown(); return 0; }