首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从C++类继承的Angelscript

从C++类继承的Angelscript
EN

Stack Overflow用户
提问于 2014-09-04 06:32:06
回答 1查看 526关注 0票数 0

这件事我已经绞尽脑汁好几天了,我想你们可能有个更好的主意。

从本质上讲,我想定义一个标准接口,然后在Angelscript类中继承它。例如,假设我有一个像Magic The Gathering这样的纸牌游戏,我的基类可能如下所示:

代码语言:javascript
复制
class Card
{
public:
    virtual void PreDrawPhase() = 0;
    virtual void PostDrawPhase() = 0;
    // etc....
};

然后我希望能够在Angelscript中定义新的卡片和它们各自的行为,同时能够在C++中处理它们(通过处理接口)。我如何才能做到这一点?

EN

回答 1

Stack Overflow用户

发布于 2014-09-05 03:32:47

免责声明:我从来没有在任何“真正的”项目中使用过Angelscript,这就是为什么下面的答案应该持保留态度。它在我为它设置的小测试代码中工作,大多数代码片段在 中都有一些详细的解释,但这绝对不能保证它是一个合理的设计,并且可以在你的游戏中合理地使用。

我相信,实现目标的相关部分在official manual中描述得很好:

  • This描述了如何定义和使用Interface.
  • This,描述了如何从C++中实例化和使用“脚本类”。

使用这些信息,我们可能会编写一个简单的包装类,它在构造时创建某个类的实例,并在销毁时释放它,同时提供调用script类的各个成员的成员函数:

(注意:为了简洁起见,我省略了所有的错误处理和其他一些重要的实践,比如(下面的类在不破坏的情况下无法复制...))

标题:

代码语言:javascript
复制
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;
};

实施:

代码语言:javascript
复制
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一无所知,但经验丰富,所以这可能确实是一种非常次优的方法,而且确实存在更好的解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25654658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档