Lua script Szécsi László GraphGame gg014-Script Lua script Szécsi László
Egg/Script ScriptedApp LuaTable Scene::ManagedApp-ból származik Game-et ebből származtathatjuk scriptből hívható metódusokat tartalmaz egyelőre színtérépítéshez leszármaztatott osztályok ezekhez hozzátehetnek LuaTable Lua táblázat formájában adott paraméterek feldolgozásához EnumReflectionMap enum típusú paraméterekhez
Lua script www.lua.org teljes programnyelv nincs main – majd a C++ programból hívunk bele nem erősen típusos x = 3 x = "valami szöveg"
Lua táblázat tablazat = { [1]=2, ["kulcs"]=4, [5]="ertek" } {} között ,-vel elválasztott mezők, minden mező [kulcs]=ertek típusú, a kulcs és az érték is bármilyen típusú lehet ["valami"] helyett írható: valami így fogjuk haszálni (pl. anyag attirbútumai): {name='spotted', technique='textured', pass='textured'}
Lua táblázat tablazat = { [1]=2, ["kulcs"]=4, [5]="ertek" } elem elérése: mivanbenne = tablazat[5] mivanitt = tablazat["kulcs"] utóbbi így is írható: mivanitt = tablazat.kulcs
Lua függvény a függvény is egy típus valtozoaminekfggverteketadok = function(elsoparam, masodikparam) csinaldezt(elsoparam) megezt(masodikparam) end ezután a fggv meghívása valtozoaminekfggverteketadok(1, 2)
Lua és OO nincs objektum-orientáltság de szerephetnek tablázatban értékként függvények, a kulcsuk meg a nevük objektum = {metodus=function(self, masikparam) dosmthg() end } a metódus meghívása objektum.metodus(objektum, 2) de ugyanez rövidebben is írható: objektum:metodus(2)
LuaBind C++ objektum -> Lua táblázat Lua fggv meghívása -> C++ metódus hívódjon + C++-ból tudjunk Lua metódust hívni, Lua táblázatból elemeket kivenni
C++ metódusok regisztrálása a lua „virtuális gép” C++ class neve lua-ban module(luaState) [ class_<ScriptedApp>("ScriptedApp") .def("Material", &ScriptedApp::addMeshMaterial) ]; metódus neve lua-ban metódusra mutató pointer (pointer-to-member)
Ezután a meghívása Lua-ban ehhez a tojás alakú lua változóhoz már hozzá van kötve a ScriptedApp példány ennek a paraméternek itt még nincs funkciója (az _ az egy változó neve) metódus scriptbeli neve O:IndexedMesh(_, {name='giraffe', file='giraffe.obj'} ) attribútumok egy táblázatban
Hogyan csináljunk hierarchiát? legyen a paraméter egy függvény, ami _ nevű paraméterként kapja a szülőt O:Material( _, {name='spotted', technique='textured', pass='textured'}, function(_) O:setSrv(_, {effectVariable='kdTexture', file='giraffe.jpg'}) end ) addMeshMaterial meghívja ezt a függvényt, ami inicializálja a létrehozott Mesh::Material-t
Olvashatóbb verzió: _ mindig a szülő O:IndexedMesh(_, {name='giraffe', file='giraffe.obj'}) O:Material(_, {name='spotted', technique='textured', pass='textured'}, function(_) O:setSrv(_, {effectVariable='kdTexture', file='giraffe.jpg'}) end ) O:MultiMesh(_, {name='giraffe'}, function(_) O:FlipMesh(_, {}, function(_) O:ShadedMesh(_, {mien='basic', indexedMesh='giraffe', material='spotted'})
Hogy néz ki a C++ metódus? Lua táblázatot, Lua függvényt kap, mint paramétert luabind::object a – bármilyen Lua érték lehet luabind::type(a) – típus lekérése a() – lua függvény meghívása C++-ból LuaTable segédosztály: táblázatelemek elérése
Így néz ki a C++ metódus void Script::ScriptedApp::addFlipMeshToMultiMesh( Egg::Mesh::Multi::P multiMesh, //< szülő a hierarchiában, _ a scriptben luabind::object attributes, //< lua táblázat az attributumokkal luabind::object initializer //< ezt kell meghívni a feltöltéshez ) { LuaTable attributeTable(attributes, "FlipMesh"); // táblázatkezelő Egg::Mesh::Flip::P flipMesh = Egg::Mesh::Flip::create(); // új objektum initializer(flipMesh); // visszahívás a scriptbe multiMesh->add(flipMesh); // kész objektumot hozzáadjuk a szülőhöz }
C++ metódus hibakezeléssel void Script::ScriptedApp::addFlipMeshToMultiMesh( Egg::Mesh::Multi::P multiMesh, //< szülő a hierarchiában, _ a scriptben luabind::object attributes, //< lua táblázat az attributumokkal luabind::object initializer //< ezt kell meghívni a feltöltéshez ) { try{ LuaTable attributeTable(attributes, "FlipMesh"); // táblázatkezelő Egg::Mesh::Flip::P flipMesh = Egg::Mesh::Flip::create(); // új objektum initializer(flipMesh); // visszahívás a scriptbe multiMesh->add(flipMesh); // kész objektumot hozzáadjuk a szülőhöz } catch(Egg::HrException exception){ exitWithErrorMessage(exception); } }
ScriptedApp.h /// Lua scripting state. lua_State* luaState; /// Runs a Lua script from a file. /// @param luaFilename the Lua script file to be executed. void runScript(const std::string& luaFilename);
ScriptedApp::createResources using namespace luabind; luaState = lua_open(); open(luaState); luaL_openlibs(luaState); // ide jön a binding int s = luaL_dostring(luaState, "O = nil; _ = nil; function setEgg(egg) O = egg end"); if(s != 0){ std::string errs = lua_tostring(luaState, -1); MessageBoxA( NULL, errs.c_str(), "Lua error!", MB_OK); } call_function<Script::ScriptedApp*>(luaState, "setEgg", this);
Binding module(luaState) [ class_<Mesh::Indexed>("IndexedMesh"), class_<Mesh::Flip>("FlipMesh"), class_<Mesh::Multi>("MultiMesh"), class_<Mesh::Material>("Material"), class_<Script::ScriptedApp>("ScriptedApp") .def("IndexedMesh", &Script::ScriptedApp::addIndexedMesh) .def("Material", &Script::ScriptedApp::addMeshMaterial) .def("setSrv", &Script::ScriptedApp::addSrvToMaterial) .def("MultiMesh", &Script::ScriptedApp::addMultiMesh) .def("FlipMesh", &Script::ScriptedApp::addFlipMeshToMultiMesh) .def("ShadedMesh", &Script::ScriptedApp::addShadedMeshToFlipMesh) .def("MultiMeshFromFile", &Script::ScriptedApp::addMultiMeshFromFile) .def("StaticEntity", &Script::ScriptedApp::addStaticEntity) .def("FirstPersonCam", &Script::ScriptedApp::addFirstPersonCam) ];
Scriptből hívható metódusok legyártása addIndexedMesh addMeshMaterial addSrvToMaterial addMultiMesh addFlipMeshToMultiMesh addMultiMeshFromFile addStaticEntity addFirstPersonCam
Feladatok új project: gg014-Script ScriptedApp-ból származó Game createResources runScript("podScene.lua");
#9.0 podScene.lua O:IndexedMesh(_, {name='giraffe', file='giraffe.obj'}) O:Material(_, {name='spotted', technique='textured', pass='textured'}, function(_) O:setSrv(_, {effectVariable='kdTexture', file='giraffe.jpg'}) end ) O:MultiMesh(_, {name='giraffe'}, function(_) O:FlipMesh(_, {}, function(_) O:ShadedMesh(_, {mien='basic', indexedMesh='giraffe', material='spotted'})
#9.0 podScene.lua O:StaticEntity(_, {name='giraffe0', multiMesh='giraffe', position = { x=2, y=0, z=0} } ) O:FirstPersonCam(_, {name='default', position={x=20, y=20, z=20} } )
Feladatok csináljuk meg scriptből a hátteret full screen quad geometria a ‘quad.x’ betöltésével is legyártható geopod betöltés, példányok létrehozása geopod envmappelt ablakokkal 33 geopod lua ciklussal for var=kezdo,veg,lepes do something end neve: 'ship' .. iShip .. a string konkatenáció operátor