2015-05-12 09:20:54 +02:00
-- BindingsProcessor.lua
-- Implements additional processing that is done while generating the Lua bindings
local access = { public = 0 , protected = 1 , private = 2 }
--- Defines classes that have a custom manual Push() implementation and should not generate the automatic one
-- Map of classname -> true
local g_HasCustomPushImplementation =
{
cEntity = true
}
function parser_hook ( s )
local container = classContainer.curr -- get the current container
-- process access-specifying labels (public, private, etc)
do
local b , e , label = string.find ( s , "^%s*(%w*)%s*:[^:]" ) -- we need to check for [^:], otherwise it would match 'namespace::type'
if b then
-- found a label, get the new access value from the global 'access' table
if access [ label ] then
container.curr_member_access = access [ label ]
end -- else ?
return strsub ( s , e ) -- normally we would use 'e+1', but we need to preserve the [^:]
end
end
end
--- Outputs the helper files supplementing the cLuaState class
-- Writes:
-- LuaState_Declaration.inc
-- LuaState_Implementation.cpp
-- LuaState_Typedefs.inc
local function OutputLuaStateHelpers ( a_Package )
-- Collect all class types from ToLua:
local types = {}
for idx , item in ipairs ( a_Package ) do
local mt = getmetatable ( item ) or {}
if ( mt.classtype == "class" ) then
table.insert ( types , { name = item.name , lname = item.lname })
end
end
table.sort ( types ,
function ( a_Item1 , a_Item2 )
return ( a_Item1.name : lower () < a_Item2.name : lower ())
end
)
-- Output the typedefs:
do
local f = assert ( io.open ( "LuaState_Typedefs.inc" , "w" ))
f : write ( " \n // LuaState_Typedefs.inc \n\n // This file is generated along with the Lua bindings by ToLua. Do not edit manually, do not commit to repo. \n " )
f : write ( "// Provides a forward declaration and a typedef for a pointer to each class exported to the Lua API. \n " )
f : write ( " \n\n\n\n\n " )
for _ , item in ipairs ( types ) do
if not ( item.name : match ( ".*<.*" )) then -- Skip templates altogether
-- Classes start with a "c", everything else is a struct:
if ( item.name : sub ( 1 , 1 ) == "c" ) then
f : write ( "class " .. item.name .. "; \n " )
else
f : write ( "struct " .. item.name .. "; \n " )
end
end
end
f : write ( " \n\n\n\n\n " )
for _ , item in ipairs ( types ) do
f : write ( "typedef " .. item.name .. " * Ptr" .. item.lname .. "; \n " )
end
f : write ( " \n\n\n\n\n " )
f : close ()
end
-- Output the Push() and GetStackValue() function declarations:
do
local f = assert ( io.open ( "LuaState_Declaration.inc" , "w" ))
f : write ( " \n // LuaState_Declaration.inc \n\n // This file is generated along with the Lua bindings by ToLua. Do not edit manually, do not commit to repo. \n " )
f : write ( "// Implements a Push() and GetStackValue() function for each class exported to the Lua API. \n " )
f : write ( "// This file expects to be included form inside the cLuaState class definition \n " )
f : write ( " \n\n\n\n\n " )
for _ , item in ipairs ( types ) do
2015-06-18 23:30:41 +02:00
if not ( g_HasCustomPushImplementation [ item.name ]) then
f : write ( "void Push(" .. item.name .. " * a_Value); \n " )
end
2015-05-12 09:20:54 +02:00
end
for _ , item in ipairs ( types ) do
2015-05-19 15:25:18 +01:00
f : write ( "bool GetStackValue(int a_StackPos, Ptr" .. item.lname .. " & a_ReturnedVal); \n " )
2015-05-12 09:20:54 +02:00
end
f : write ( " \n\n\n\n\n " )
f : close ()
end
-- Output the Push() and GetStackValue() function implementations:
do
local f = assert ( io.open ( "LuaState_Implementation.cpp" , "w" ))
f : write ( " \n // LuaState_Implementation.cpp \n\n // This file is generated along with the Lua bindings by ToLua. Do not edit manually, do not commit to repo. \n " )
f : write ( "// Implements a Push() and GetStackValue() function for each class exported to the Lua API. \n " )
f : write ( "// This file expects to be compiled as a separate translation unit \n " )
f : write ( " \n\n\n\n\n " )
f : write ( "#include \" Globals.h \"\n #include \" LuaState.h \"\n #include \" tolua++/include/tolua++.h \"\n " )
f : write ( " \n\n\n\n\n " )
for _ , item in ipairs ( types ) do
if not ( g_HasCustomPushImplementation [ item.name ]) then
f : write ( "void cLuaState::Push(" .. item.name .. " * a_Value) \n { \n\t ASSERT(IsValid()); \n " )
f : write ( " \t tolua_pushusertype(m_LuaState, a_Value, \" " .. item.name .. " \" ); \n " );
f : write ( " \t m_NumCurrentFunctionArgs += 1; \n " )
f : write ( "} \n\n\n\n\n\n " )
end
end
for _ , item in ipairs ( types ) do
2015-05-19 15:25:18 +01:00
f : write ( "bool cLuaState::GetStackValue(int a_StackPos, Ptr" .. item.lname .. " & a_ReturnedVal) \n { \n\t ASSERT(IsValid()); \n " )
2015-05-12 09:20:54 +02:00
f : write ( " \t if (lua_isnil(m_LuaState, a_StackPos)) \n\t { \n " )
2015-05-19 15:25:18 +01:00
f : write ( " \t\t a_ReturnedVal = nullptr; \n " )
f : write ( " \t\t return false; \n\t } \n " )
2015-05-12 09:20:54 +02:00
f : write ( " \t tolua_Error err; \n " )
f : write ( " \t if (tolua_isusertype(m_LuaState, a_StackPos, \" " .. item.name .. " \" , false, &err)) \n " )
f : write ( " \t { \n " )
2015-05-19 15:25:18 +01:00
f : write ( " \t\t a_ReturnedVal = *(reinterpret_cast<" .. item.name .. " **>(lua_touserdata(m_LuaState, a_StackPos))); \n " )
f : write ( " \t\t return true; \n " );
2015-05-12 09:20:54 +02:00
f : write ( " \t } \n " )
2015-05-19 15:25:18 +01:00
f : write ( " \t return false; \n " )
2015-05-12 09:20:54 +02:00
f : write ( "} \n\n\n\n\n\n " )
end
f : close ()
end
end
function pre_output_hook ( a_Package )
OutputLuaStateHelpers ( a_Package )
end
function post_output_hook ()
print ( "Bindings have been generated." )
end