Disclaimer: I have never used Angelscript in any "real" Project which is why the following answer should be taken with a grain of salt. It worked in the small test code i set up for it and most code snippets were explained in some detail in the official manual, but this is absolutly no guarantee whatsoever that it is a sound design and can be employed reasonably in your game.
The relevant parts to accomplish your goal are, I believe, described pretty well in the official manual:
Using this information, we could potentially write a simplistic wrapper class, that on construction, creates an instance of a certain class and releases it on destruction, whilst providing member functions that call the respective members of the script class:
(Note: For the sake of brevity, I omitted all error handling and some other important practices, like the Rule of Tree(The class below cannot be copied without breaking a lot...))
Header:
class Card
{
public:
Card(asIScriptEngine *engine, asIScriptContext *ctx, const std::string &module_name, const std::string &class_name);
~Card();
void PreDrawPhase();
void PostDrawPhase();
private:
asIScriptContext *ctx;
asIScriptObject *obj;
asIScriptFunction *PreDrawPhaseFunc, *PostDrawPhaseFunc;
};
Implementation:
Card::Card(asIScriptEngine *engine, asIScriptContext *ctx, const std::string &module_name, const std::string &class_name):
ctx(ctx)
{
asIScriptModule *module = engine->GetModule(module_name.c_str());
auto type_id=module->GetTypeIdByDecl(class_name.c_str());
asIObjectType *type = engine->GetObjectTypeById(type_id);
PreDrawPhaseFunc=type->GetMethodByDecl("void PreDrawPhase()");
PostDrawPhaseFunc=type->GetMethodByDecl("void PostDrawPhase()");
asIScriptFunction *factory = type->GetFactoryByDecl((class_name+" @"+class_name+"()").c_str());
ctx->Prepare(factory);
ctx->Execute();
obj=*(asIScriptObject**)ctx->GetAddressOfReturnValue();
obj->AddRef();
}
Card::~Card()
{
obj->Release();
}
void Card::PreDrawPhase()
{
ctx->Prepare(PreDrawPhaseFunc);
ctx->SetObject(obj);
ctx->Execute();
}
void Card::PostDrawPhase()
{
ctx->Prepare(PostDrawPhaseFunc);
ctx->SetObject(obj);
ctx->Execute();
}
I believe the code is pretty self explanatory(correct me if i am wrong and i will try to elaborate), therefore I will just describe the basic idea:
- Each instance of Card holds a pointer to some Angelscript object that is of some arbitrary type implementing the desired interface(The only way this is enforced currently is by crashing if something went wrong, which is kind of bad).
- On construction, this is created(from the passed in engine, context and names) and pointers to its member functions are accuired, on destruction it is released.
- Whenever a member is called, it forwards to the respective member of the Angelscript object.
As mentioned in the beginning, i am everything but experienced regarding Angelscript, so this may indeed be a very suboptimal method and it is quite propable better solutions do exist.