C++混合编程之idlcpp教程Lua篇(7)

上一篇在这 C++混合编程之idlcpp教程Lua篇(6)

第一篇在这 C++混合编程之idlcpp教程(一)

与LuaTutorial4工程相似,工程LuaTutorial5中,同样加入了四个文件:LuaTutorial5.cpp, Tutorial5.cpp, Tutorial5.i, tutorial5.lua。其中LuaTutorial5.cpp的内容基本和LuaTutorial4.cpp雷同,不再赘述。

首先看一下Tutorial5.i的内容:

#import "../../paf/src/pafcore/Reference.i"
$$#include <vector>

namespace tutorial
{
    struct Point
    {
        float x;
        float y;
        Point();
        Point(float a, float b);
    meta:
        Point(const Point ref pt);
    };

    export class Shape : Reference
    {
        export abstract float getArea();
        $$        virtual ~Shape() {}
    };

    class ShapeManager(value_object)
    {
        void addShape(Shape ptr shape);
        float getTotalArea();
        static ShapeManager ptr GetInstance();
        $*
        ~ShapeManager();
    private:
        std::vector<Shape*> m_shapes;
        *$
    };

    class Triangle : Shape
    {
        Point m_vertices[$3];
    meta:
        Triangle();
        $$virtual float getArea();
    };

}

与Tutorial4.i相比,大部分内容是一样的,不同之处在于类型Shape的声明以及其下的纯虚函数getArea;

export class Shape : Reference

export abstract float getArea();

在这两处声明的最前面都多了一个关键字export。这个关键字和C++中的export意义完全不一样,只是想在C++中找一个现成的关键字直接使用而已,其实这个也不太合适,暂时先用着。此处的写法意味着可以在脚本代码中写一个类型,让它“派生”自Shape,并且能够“覆盖”虚函数getArea。当然实际上是通过idlcpp生成的一个派生类配合脚本插件代码来完成类似的任务。

通过在类型的声明class 前加上关键字export 表示此类型可以被脚本“派生”,在虚函数声明的关键字virtual 或 abstract前加上关键字export 表示此虚函数可以被脚本“覆盖”。

在宿主语言和脚本的混合使用中,一个常见的用法是在宿主语言中根据一定的条件向外发出事件,而用脚本语言来编写事件处理代码,例如在WOW中用一个XML文件描述GUI界面,同时注明事件处理函数对应的Lua函数名。idlcpp提供的脚本继承C++类然后重写虚函数的功能可以很好的实现类似的需求。

编译后生成的Tutorial5.h的内容如下:

//DO NOT EDIT THIS FILE, it is generated by idlcpp
//http://www.idlcpp.org

#pragma once

#include "./Tutorial5.h"
#include "../../paf/src/pafcore/Reference.h"
namespace tutorial{ class ShapeManager; }
namespace tutorial{ class Triangle; }
#include <vector>

namespace tutorial
{
    struct Point
    {
    public:

        float x;
        float y;
        Point();
        Point(float a,float b);
    public:
        static Point* New();
        static Point* New(float a,float b);
        static Point* NewArray(unsigned int count);
        static Point* Clone(const Point& pt);

    };

    class Shape : public ::pafcore::Reference
    {
    public:
        virtual ::pafcore::Type* getType();

        virtual float getArea() = 0 ;
        virtual ~Shape() {}
    };

    class ShapeManager
    {
    public:

        void addShape(Shape* shape);
        float getTotalArea();
        static ShapeManager* GetInstance();

        ~ShapeManager();
    private:
        std::vector<Shape*> m_shapes;

    };

    class Triangle : public Shape
    {
    public:
        virtual ::pafcore::Type* getType();

        Point m_vertices[3];
    public:
        static Triangle* New();
        static Triangle* NewARC();
        static Triangle* NewArray(unsigned int count);
        static Triangle* NewArrayARC(unsigned int count);

virtual float getArea();
    };

}

这里生成的代码和Tutorial4.h基本一致。

最后看一下Tutorial5.lua的内容

Circle = {}
Circle.__index = Circle;

function Circle.New()
    circle= {radius = 1.0}
    setmetatable(circle, Circle);
    circle.shape = paf.tutorial.Shape._Derive_(circle);
    return circle;
end

function Circle:getArea()
    return self.radius * self.radius * 3.1415926;
end

circle = Circle.New();
circle.radius = 2.0;
shapeManager = paf.tutorial.ShapeManager.GetInstance();
shapeManager:addShape(circle.shape);
print(shapeManager:getTotalArea()._);

triangle = paf.tutorial.Triangle();
triangle.m_vertices[0] = paf.tutorial.Point(0,0);
triangle.m_vertices[1] = paf.tutorial.Point(0,1);
triangle.m_vertices[2] = paf.tutorial.Point(1,1);
shapeManager:addShape(triangle);
print(shapeManager:getTotalArea()._);

在上面的代码中,写了一个类型Circle。在函数Circle.New 通过下面这一行

circle.shape = paf.tutorial.Shape._Derive_(circle);

来模拟继承,语法:C++类型._Derive_(脚本对象) 用于完成模拟继承的行为。实际上circle.shape才是C++类型Shape的派生类实例的引用,在C++中需要用到Shape类型的地方,将circle.shape传递过去即可,如下面的使用方式。

shapeManager:addShape(circle.shape);

然后在类型Circle中提供一个与C++基类同名的函数getArea用来计数圆的面积即可,最终使用时脚本插件会找到对应函数进行调用。

编译执行,结果如下图:

时间: 2024-12-23 12:56:41

C++混合编程之idlcpp教程Lua篇(7)的相关文章

C++混合编程之idlcpp教程Lua篇(4)

上一篇在这  C++混合编程之idlcpp教程Lua篇(3) 与前面的工程相似,工程LuaTutorial2中,同样加入了三个文件 LuaTutorial2.cpp, Tutorial2.i, tutorial2.lua.其中LuaTutorial2.cpp的内容基本和LuaTutorial1.cpp雷同,不再赘述. 首先看一下Tutorial2.i的内容: namespace tutorial { struct Point { float x; float y; meta: Point();

C++混合编程之idlcpp教程Lua篇(8)

上一篇在这 C++混合编程之idlcpp教程Lua篇(7) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程LuaTutorial6中,同样加入了四个文件:LuaTutorial6.cpp, Tutorial6.cpp, Tutorial6.i, tutorial6.lua.其中LuaTutorial6.cpp的内容基本和LuaTutorial5.cpp雷同,不再赘述. 首先看一下Tutorial6.i的内容: namespace tutorial { template

C++混合编程之idlcpp教程Lua篇(9)

上一篇在这 C++混合编程之idlcpp教程Lua篇(8) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相比,工程LuaTutorial7中除了四个文件LuaTutorial7.cpp, Tutorial7.cpp, Tutorial7.i, tutorial7.lua 外,Tutorial6.cpp也被加入了此工程中.其中LuaTutorial7.cpp的内容基本和LuaTutorial6.cpp雷同,不再赘述. 首先看一下Tutorial7.i的内容: #import "

C++混合编程之idlcpp教程Lua篇(5)

上一篇在这 C++混合编程之idlcpp教程Lua篇(4) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程LuaTutorial3中,同样加入了三个文件:LuaTutorial3.cpp, Tutorial3.i, tutorial3.lua .其中LuaTutorial3.cpp的内容基本和LuaTutorial2.cpp雷同,不再赘述. 首先看一下Tutorial3.i的内容: namespace tutorial { struct Point { float x

C++混合编程之idlcpp教程Lua篇(2)

在上一篇 C++混合编程之idlcpp教程(一) 中介绍了 idlcpp 工具的使用.现在对 idlcpp 所带的示例教程进行讲解,这里针对的 Lua 语言的例子.首先看第一个示例程序 LuaTutorial0.像很多语言的第一个例子一样,是一个打印 Hello world 的程序.用Visual Studio 2015打开解决方案文件 tutorials\LuaTutorials\LuaTutorials.sln,其下已经有多个工程文件. 在工程LuaTutorial0中,已经加入了三个文件,

C++混合编程之idlcpp教程Python篇(7)

上一篇在这 C++混合编程之idlcpp教程Python篇(6) 第一篇在这 C++混合编程之idlcpp教程(一) 与PythonTutorial4工程相似,工程PythonTutorial5中,同样加入了四个文件:PythonTutorial5.cpp, Tutorial5.cpp, Tutorial5.i, tutorial5.py.其中PythonTutorial5.cpp的内容基本和PythonTutorial4.cpp雷同,不再赘述.首先看一下Tutorial5.i的内容: #imp

C++混合编程之idlcpp教程Python篇(8)

上一篇在这 C++混合编程之idlcpp教程Python篇(7) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程PythonTutorial6中,同样加入了四个文件:PythonTutorial6.cpp, Tutorial6.cpp, Tutorial6.i, tutorial6.py.其中PythonTutorial6.cpp的内容基本和PythonTutorial5.cpp雷同,不再赘述.首先看一下Tutorial6.i的内容: #import "../../p

C++混合编程之idlcpp教程Python篇(4)

上一篇在这 C++混合编程之idlcpp教程Python篇(3) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程PythonTutorial2中,同样加入了三个文件 PythonTutorial2.cpp, Tutorial2.i, tutorial2.py.其中PythonTutorial2.cpp的内容基本和PythonTutorial1.cpp雷同,不再赘述.首先看一下Tutorial2.i的内容: namespace tutorial { struct Poi

C++混合编程之idlcpp教程Python篇(3)

上一篇 C++混合编程之idlcpp教程Python篇(2) 是一个 hello world 的例子,仅仅涉及了静态函数的调用.这一篇会有新的内容. 与PythonTutorial0相似,工程PythonTutorial1中,同样加入了三个文件 PythonTutorial1.cpp, Tutorial1.i, tutorial1.py 其中PythonTutorial1.cpp的内容基本和PythonTutorial0.cpp雷同,不再赘述. 首先看一下Tutorial1.i的内容: name