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
あと、余談だけど、しばらく、更新停止します。
短い間ですが、ありがとうございました。