[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/jacereda/daScript/master/examples/tutorial/tutorial04.cpp [Back]  [Original]

#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;
}

Web Proxy Viewer  |  New URL  |  Original Page