Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <lua.hpp>
- #include "cLua.h"
- #pragma once
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // This is a class bind that will be needed for any class that wants to be registered with Lua
- // I have taken this from http://cfc.kizzx2.com/index.php/binding-c-classes-to-lua-a-step-by-step-example-for-beginners/
- // which does a great job at explaining class binding (much better than I can) and
- // this site also uses the same method http://loadcode.blogspot.co.uk/2007/02/wrapping-c-classes-in-lua.html
- // both are great places to start to understand how it all works
- //
- //
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // <summary> is cLua. </summary>
- //
- // <remarks> Chris, 29/07/2012. </remarks>
- //
- // <param name="LS"> [in,out] Lua State. </param>
- // <param name="index"> Zero-based index of the. </param>
- //
- // <returns> null if it fails, else. </returns>
- //
- // <comment> This function is used to obtain a cLua from the heap
- // I am not 100% sure why it has to be a double pointer but I think its
- // explained on the two links at the top
- // the metatable "luaL_cLua" is used to check if it is the correct type or user data
- // since we only want a single pointer we deref and return the pointer
- // </comment>
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- inline cLua* lua_iscLua(lua_State* LS, int index)
- {
- return *(cLua**)luaL_checkudata(LS, index, "luaL_cLua");
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // <summary> Lua pushc lua. </summary>
- //
- // <remarks> Chris, 29/07/2012. </remarks>
- //
- // <param name="LS"> [in,out] Lua State. </param>
- // <param name="object"> [in,out] If non-null, a cLua object. </param>
- //
- // <returns> null if it fails, else. </returns>
- //
- // <comment> This uses the same method for creating a new object but instead of
- // creating it as new a pointer to a similar object is set
- // this will then push a new lua object but it will still be
- // the same as class passed to this function
- // </comment>
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- inline cLua* lua_pushcLua(lua_State* LS, cLua* object)
- {
- //create a new userdata
- cLua** uData = (cLua**)lua_newuserdata(LS, sizeof(cLua*));
- *uData = object; //set that user data to be equal to the passed in object
- luaL_getmetatable(LS, "luaL_cLua"); //get and set the metatable for the new object in lua
- lua_setmetatable(LS, -2);
- return *uData; //return the new userdata if it is needed
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // <summary> cLua new. </summary>
- //
- // <remarks> Chris, 29/07/2012. </remarks>
- //
- // <param name="LS"> [in,out] Lua State. </param>
- //
- // <returns> 1 = true 0 = false. </returns>
- //
- // <comment> To create the object we need a new function that can be called within
- // lua to create a new object
- // in this example as well I have create a vector which I push the new object onto
- // since they are pointers it means that both lua and c++ manipulate the same object
- // the only 2 issues at the moment is that obj1 = obj2 means obj1 == obj2 which
- // is not really what I want to happen i believe a __luathing (i think __newindex)
- // is needed to create a new object but with similar values as obj2
- // im fairly sure thats what is how the = should work rather than making the both
- // equal
- // the other issue at the moment is that there is not proper clean up
- // the gc will work and delete the reference in the lua memory but will not
- // clean it from the myClasses stack so it will still have bad pointers on it
- // so I need to sort out better clean up for that
- // </comment>
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- inline int cLua_new(lua_State* LS)
- {
- //in this case I have allowed for 2 choices of new 1: new() and new(intvalue)
- int arg = lua_gettop(LS); //so i need to check how many arguments have been sent to get the correct setting
- //val will store the values sent to new which will be used to create the object if value was specified
- int val = 0;
- //check arguments
- if (arg == 1)
- {
- val = lua_tointeger(LS, 1);
- }
- //now this is the odd but that im not 100% sure about. it would make sense to me if it was a single poiter but its not
- //in one of the websites it mentioned something about the CRT heap but again I have no idea what that is.
- //I believe lua has an odd way of storing user data which can be accessed as a 2D array but I expect that we really only need
- //a single pointer but lua will use the double pointer to store other bits of data but dont quote me on that I will have to look into it
- cLua** uData = (cLua**)lua_newuserdata(LS, sizeof(cLua*));
- //check the value to see if a value was passed and if so we need to create the object with accordance to the parameters
- if (val)
- *uData = new cLua(val);
- else
- *uData = new cLua();
- //this will get the metatable luaL_cLua which has the reference to all the c functions that are in the luaL_cLua metatable (in this case our class cLua)
- luaL_getmetatable(LS, "luaL_cLua");
- //will set the meta table to the newly created class
- lua_setmetatable(LS, -2);
- //when the new class is created we also may want to manipulate it within c++ so better store a reference to it as well
- //as iv mentioned at the start there is no clean up for this stack so when the pointer is deleted at the moment it will only
- //destroy the lua refernce. to fix this I would add either an autogenerate uID or force the user to create a uID for the object
- //then when the release of lua is called a cleanup of the vector is also needed;
- myClasses.push_back(*uData);
- return 1;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // <summary> cLua hello world. </summary>
- //
- // <remarks> Chris, 29/07/2012. </remarks>
- //
- // <param name="LS"> [in,out] Lua State. </param>
- //
- // <returns> 1 = true 0 = false. </returns>
- //
- // <comment> Nothing wrong with having a little helloworld
- // this will call the helloworld function in the cLua class
- // which prints out hello world
- // </comment>
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- inline int cLua_helloWorld(lua_State* LS)
- {
- //get the cLua object
- cLua* l_cLua = lua_iscLua(LS, 1);
- //call the hello world function
- l_cLua->helloWorld();
- return 1;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // <summary> cLua getvalue. </summary>
- //
- // <remarks> Chris, 29/07/2012. </remarks>
- //
- // <param name="LS"> [in,out] Lua State. </param>
- //
- // <returns> 1 = true 0 = false. </returns>
- //
- // <comment> cLua has a int value variable which can be set and get. this is the get function
- // which obtains value and pushes it onto the stack as a return
- // </comment>
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- inline int cLua_getvalue(lua_State* LS)
- {
- //get the cLua object
- cLua* l_cLua = lua_iscLua(LS, 1);
- //get value
- int i = l_cLua->getvalue();
- //push value onto the stack
- lua_pushinteger(LS, i);
- return 1;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // <summary> cLua set array. </summary>
- //
- // <remarks> Chris, 29/07/2012. </remarks>
- //
- // <param name="LS"> [in,out] Lua State. </param>
- //
- // <returns> 1 = true 0 = false. </returns>
- //
- // <comment> This was to test if arrays could still be sent to classes as well
- // since this will be important for vectors and other things I cant think of
- // off the top of my head
- // it looks complex but its exactly the same as with a non class table call
- // </comment>
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- inline int cLua_setArray(lua_State* LS)
- {
- //cLua_dumpstack(LS);
- //get the cLua Object
- cLua* l_cLua = lua_iscLua(LS, 1);
- //preform the same function as with TestTable in LuaManager.cpp
- int size;
- int* Array;
- if(lua_istable(LS, 2)) //checks to see if the value is a table (table is at -1)
- {
- size = lua_objlen(LS, 2); //this will return the size of the table (or a string) to get the size
- Array = new int[size]; //create a pointer array of that size
- lua_pushnil(LS); //not really sure why nill is needed to be pushed but it is needed to traverse a table
- //Lua_dumpstack(LS);
- while(lua_next(LS, 2) != 0) //this will iterate through the table at -2 since nill has been pushed onto the stack so its table -2 nill -1
- {
- lua_pushvalue(LS, -2); //the value at -2 on the table is now pushed onto the stack so it should be table -2 key -1
- //Lua_dumpstack(LS);
- printf("LUA - index %d = %d \n", lua_tointeger(LS, -1) - 1, lua_tointeger(LS, -2)); //prints out the value and key of the table (change lua_tointeger to lua_tostring if you have alphanumerical keys and data
- Array[lua_tointeger(LS, -1) - 1] = lua_tointeger(LS, -2); //stores the key and value into the array (lua table starts at 1 and not 0 so the key has to be offset by -1)
- //Lua_dumpstack(LS);
- lua_pop(LS, 2); //pop the key back off the stack i belive and move onto the next value
- //Lua_dumpstack(LS);
- }
- lua_pop(LS, 2); //I believe this now pops the table off the stack as it is now un-needed
- }
- else
- return 0;
- //then just set the array to the cLua object
- l_cLua->SetArray(Array);
- return 1;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // <summary> cLua set value. </summary>
- //
- // <remarks> Chris, 29/07/2012. </remarks>
- //
- // <param name="LS"> [in,out] Lua State. </param>
- //
- // <returns> 1 = true 0 = false. </returns>
- //
- // <comment> the setter for the cLua value variable
- // </comment>
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- inline int cLua_setValue(lua_State* LS)
- {
- //get the cLua object
- cLua* l_cLua = lua_iscLua(LS, 1);
- //get the value of the stack
- int value = lua_tointeger(LS, 2);
- //set the value of the cLua Object
- l_cLua->SetValue(value);
- return 1;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // <summary> cLua release. </summary>
- //
- // <remarks> Chris, 29/07/2012. </remarks>
- //
- // <param name="LS"> [in,out] Lua State. </param>
- //
- // <returns> 1 = true 0 = false. </returns>
- //
- // <comment> this is the garbage collector for lua that will be called when cLua is null
- // as iv mentioned twice now the vector will need to have its refernce of the object deleted
- // as well other wise it will break the vector
- // </comment>
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- inline int cLua_Release(lua_State* LS)
- {
- cLua* l_cLua = lua_iscLua(LS, 1);
- delete l_cLua;
- return 0;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // <summary> cLua bind. </summary>
- //
- // <remarks> Chris, 29/07/2012. </remarks>
- //
- // <param name="LS"> [in,out] Lua State. </param>
- //
- // <comment> this is the binding of the cLua Object to Lua
- // </comment>
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- inline void cLua_Bind(lua_State* LS)
- {
- //create a reference for all the functions
- //has to have null null at the end (expect it takes the array
- //as a pointer so there is no real way of knowing the end of the array)
- luaL_Reg cLua_Reg[] =
- {
- { "new", cLua_new },
- { "helloWorld", cLua_helloWorld },
- { "setArray", cLua_setArray },
- { "setValue", cLua_setValue },
- { "getValue", cLua_getvalue },
- { "__gc", cLua_Release },
- { NULL, NULL },
- };
- //create a new metatable which wont be visable to lua but is used to refernce the lua objects
- luaL_newmetatable(LS, "luaL_cLua");
- //register the lua functions
- luaL_register(LS, NULL, cLua_Reg);
- //this pushes the meta table onto the stack so __index can point to itself
- lua_pushvalue(LS, -1);
- lua_setfield(LS, -1, "__index");
- //sets the global name for the class object type
- lua_setglobal(LS, "cLua");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement