聲明:我從來沒有在任何「真實」的項目中使用Angelscript,這就是爲什麼下面的答案應該採取一粒鹽。它在我設置的小測試代碼中工作,大部分代碼片段在official manual中都有詳細解釋,但絕對不能保證它是一個合理的設計,並且可以在您的遊戲中合理使用。
相關部分來完成你的目標是,我相信,在official manual描述相當不錯:
利用這些信息,我們可能會寫一個簡單的包裝類,即建設,造成一定的階級,並釋放它毀滅的一個實例,同時提供調用腳本類的各個成員的成員函數:
(注:爲了簡潔起見,省略了我所有的錯誤處理和其他一些重要的做法,像Rule of Tree(下面的類不能在不破壞大量複製...))
標題:
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;
};
實現:
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();
}
我相信代碼是非常自我解釋(糾正我,如果我錯了,我會盡量詳細說明),所以我只是描述的基本思路:
- Card的每個實例都包含一個指向一些Angelscript對象的指針,該對象具有一些實現所需接口的任意類型(當前執行的唯一方法是在出現問題時會崩潰,這很糟糕)。
- 在構建時,會創建它(從傳入的引擎,上下文和名稱中),並且指向其成員函數的指針在被銷燬時被引導。
- 每當成員被調用時,它都將轉發給Angelscript對象的相應成員。
正如開頭提到的,我是一切,但經驗豐富的關於Angelscript,所以這可能確實是一個非常不理想的方法,它是相當propable更好的解決方案確實存在。