480052c058
All so added error handling for out of range values
164 lines
5.0 KiB
Lua
164 lines
5.0 KiB
Lua
|
|
-- 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
|
|
f:write("void Push(" .. item.name .. " * a_Value);\n")
|
|
end
|
|
for _, item in ipairs(types) do
|
|
f:write("bool GetStackValue(int a_StackPos, Ptr" .. item.lname .. " & a_ReturnedVal);\n")
|
|
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\tASSERT(IsValid());\n")
|
|
f:write("\ttolua_pushusertype(m_LuaState, a_Value, \"" .. item.name .. "\");\n");
|
|
f:write("\tm_NumCurrentFunctionArgs += 1;\n")
|
|
f:write("}\n\n\n\n\n\n")
|
|
end
|
|
end
|
|
for _, item in ipairs(types) do
|
|
f:write("bool cLuaState::GetStackValue(int a_StackPos, Ptr" .. item.lname .. " & a_ReturnedVal)\n{\n\tASSERT(IsValid());\n")
|
|
f:write("\tif (lua_isnil(m_LuaState, a_StackPos))\n\t{\n")
|
|
f:write("\t\ta_ReturnedVal = nullptr;\n")
|
|
f:write("\t\treturn false;\n\t}\n")
|
|
f:write("\ttolua_Error err;\n")
|
|
f:write("\tif (tolua_isusertype(m_LuaState, a_StackPos, \"" .. item.name .. "\", false, &err))\n")
|
|
f:write("\t{\n")
|
|
f:write("\t\ta_ReturnedVal = *(reinterpret_cast<" .. item.name .. " **>(lua_touserdata(m_LuaState, a_StackPos)));\n")
|
|
f:write("\t\treturn true;\n");
|
|
f:write("\t}\n")
|
|
f:write("\treturn false;\n")
|
|
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
|
|
|
|
|
|
|
|
|