Luaでc++のvectorを扱う方法への考察

Luaで、c++vectorを使いたい時。
Lua側にてvectorイテレータを扱うというのも考えもの。


というので、以下のようなのは、いかが?


ソースは語る。


しーぷらぷらのそーす(はぁと

// Project      LuaVect
// Source       luavect.cpp
// Date         081106
// Author       yamahara
// Environment  Bcc - Lua
// Etc          Copyright(C) 2008 sansuido. All rights reserved.

#include        <windows.h>
#include        <vector>
#include        <string>
#include        <list>

#include        "lua\lua.hpp"

using namespace std;

class Obj {
private:
        string  name_;
        double  x_;
        double  y_;
public:
        Obj() : x_(0), y_(0) {}
        virtual ~Obj() {}
        
        string  getName() { return name_; }
        void    setName(string name) { name_ = name; }
        double  getX() { return x_; }
        void    setX(double x) { x_ = x; }
        double  getY() { return y_; }
        void    setY(double y) { y_ = y; }
};

class Task {
private:
        
public:
        vector<Obj>     array;
        vector<int>     count;
};

Task *          lua_getTaskPtr(
                // タスクをゲット
lua_State *     L
)

{
        lua_getglobal(L, "__TASK__");
        Task *  taskPtr = (Task *)lua_touserdata(L, -1);
        lua_remove(L, -1);
        return taskPtr;
}

int             lua_pushObj(
                // オブジェクトをプッシュ
lua_State *     L
)

{
        Task *  taskPtr = lua_getTaskPtr(L);
        Obj     obj;
        obj.setName(luaL_optstring(L, 1, ""));
        obj.setX(luaL_optnumber(L, 2, 0));
        obj.setY(luaL_optnumber(L, 3, 0));
        lua_settop(L, 0);
        taskPtr->array.push_back(obj);
        
        return 0;
}

int             lua_drawObj(
lua_State *     L
)

{
        Task *  taskPtr = lua_getTaskPtr(L);
        int     no = lua_tonumber(L, 1);
        Obj *   objPtr = &taskPtr->array.at(no);
        lua_settop(L, 0);
        printf("Name:%s\tX:%.0f\tY:%.0f\n", objPtr->getName().c_str(), objPtr->getX(), objPtr->getY());
        
        return 0;
}

int             lua_getObjOfCount(
lua_State *     L
)

{
        Task *  taskPtr = lua_getTaskPtr(L);
        int     no = taskPtr->count.at(lua_tonumber(L, 1));
        lua_settop(L, 0);
        lua_pushnumber(L, no);
        return 1;
}

int             lua_countObj(
lua_State *     L
)

{
        Task *  taskPtr = lua_getTaskPtr(L);
        taskPtr->count.clear();
        string  name = luaL_optstring(L, 1, "");
        lua_settop(L, 0);
        vector<Obj>::iterator   it = taskPtr->array.begin();
        int     no = 0;
        while (it != taskPtr->array.end()) {
                if (!name.size() ||
                        it->getName() == name) {
                        
                        taskPtr->count.push_back(no);
                }
                
                it++;
                no++;
        }
        lua_pushnumber(L, taskPtr->count.size());
        return 1;
}

int             lua_drawString(
lua_State *     L
)

{
        string  str = luaL_optstring(L, 1, "");
        lua_settop(L, 0);
        puts(str.c_str());
        return 0;
}

int             main(
                // メイン
int             argc,
char *          argv[]
)

{
        Task *          taskPtr = new Task();
        lua_State *     L;
        L = luaL_newstate();
        luaL_openlibs(L);
        lua_pushlightuserdata(L, taskPtr);
        lua_setglobal(L, "__TASK__");
        lua_register(L, "pushObj", lua_pushObj);
        lua_register(L, "drawObj", lua_drawObj);
        lua_register(L, "countObj", lua_countObj);
        lua_register(L, "getObjOfCount", lua_getObjOfCount);
        lua_register(L, "drawString", lua_drawString);
        
        if (luaL_dofile(L, "./luavect.lua")) {
                puts(lua_tostring(L, -1));
        }
        lua_close(L);
        
        delete taskPtr;
        
        return 0;
}


ぅあのそーす(はぁと

pushObj("item", 10, 10)
pushObj("player", 11, 11)
pushObj("enemy", 12, 12)
pushObj("item", 13, 13)
pushObj("enemy", 14, 14)

drawString("--------------------------------")
drawString("enemyをカウント")
drawString("--------------------------------")
local	count = countObj("enemy")
for i = 0, count - 1 do
	drawObj(getObjOfCount(i))
end

drawString("--------------------------------")
drawString("playerをカウント")
drawString("--------------------------------")
local	count = countObj("player")
for i = 0, count - 1 do
	drawObj(getObjOfCount(i))
end

drawString("--------------------------------")
drawString("全体をカウント")
drawString("--------------------------------")
local	count = countObj()
for i = 0, count - 1 do
	drawObj(getObjOfCount(i))
end


じっこうけっか(はぁと

--------------------------------
enemyをカウント
--------------------------------
Name:enemy      X:12    Y:12
Name:enemy      X:14    Y:14
--------------------------------
playerをカウント
--------------------------------
Name:player     X:11    Y:11
--------------------------------
全体をカウント
--------------------------------
Name:item       X:10    Y:10
Name:player     X:11    Y:11
Name:enemy      X:12    Y:12
Name:item       X:13    Y:13
Name:enemy      X:14    Y:14


あと、余談だけど、しばらく、更新停止します。
短い間ですが、ありがとうございました。