I'm new to Lua and LuaBridge and I'm trying to figure out if it's possible to register a templated function? I've looked online and through the LuaBridge manual to no avail. What I tried was creating a pointer to the base class, but then found out later that there's no way to cast in Lua. If anyone has any ideas on the best way to resolve this issue it would be appreciated.
template<typename T>
T* GetComponentByType()
{
try
{
for (ComponentVectorWrapper::t_Component_Iter iter = m_Components_.begin(); iter != m_Components_.end(); ++iter)
if (*iter != nullptr)
if (T* type = dynamic_cast<T*>(*iter))
return type;
throw ComponentMissingException();
}
catch (ComponentMissingException& e)
{
std::cout << e.what() << std::endl;
__debugbreak();
}
}
Component* getComponentByType(std::string type)
{
if (type == "Transform")
return GetComponentByType<TransformComponent>();
return nullptr;
}
static void registerLua(lua_State* L)
{
using namespace luabridge;
getGlobalNamespace(L)
.beginClass<GameObject>("GameObject")
.addConstructor<void(*)(const char* name)>()
.addData<const char*>("name", &GameObject::m_Name_, false)
.addData<TransformComponent*>("transform", &GameObject::m_Transform)
.addFunction("addComponent", &GameObject::registerComponent)
.addFunction("getComponent", &GameObject::getComponentByType)
.addFunction("removeComponent", &GameObject::removeComponent)
.endClass();
}
Solution
Forgot to post this earlier but the solution is to determine the type from a string, from there you need to set a global in Lua and then return a reference to that global.
luabridge::LuaRef GameObject::luaGetComponent(std::string type)
{
// Return component
return luaGetComponentHelper(type, false, "");
}
luabridge::LuaRef GameObject::luaGetComponentHelper(std::string type, bool findAll, const char* tag)
{
lua_State* L = (&LuaEngine::getInstance())->L();
// Find component type
if (type == "TransformComponent")
LuaHelper::GetGlobalComponent<TransformComponent>(*this, findAll, m_CompName, tag);
else if (type == "CameraComponent")
LuaHelper::GetGlobalComponent<CameraComponent>(*this, findAll, m_CompName, tag);
else if (type == "FirstPersonCameraComponent")
LuaHelper::GetGlobalComponent<FirstPersonCameraComponent>(*this, findAll, m_CompName, tag);
else if (type == "RenderComponent")
LuaHelper::GetGlobalComponent<RenderComponent>(*this, findAll, m_CompName, tag);
else if (type == "ThirdPersonCameraComponent")
LuaHelper::GetGlobalComponent<ThirdPersonCameraComponent>(*this, findAll, m_CompName, tag);
else if (type == "CanvasComponent")
LuaHelper::GetGlobalComponent<CanvasComponent>(*this, findAll, m_CompName, tag);
else if (type == "RigidBody")
LuaHelper::GetGlobalComponent<RigidBody>(*this, findAll, m_CompName, tag);
else if (type == "BoxCollider")
LuaHelper::GetGlobalComponent<BoxCollider>(*this, findAll, m_CompName, tag);
else
{
luabridge::setGlobal(L, nullptr, m_CompName); // Prevents errors
LuaEngine::printError("Component not found.");
}
// Return component
return luabridge::getGlobal(L, m_CompName);
}
template<typename T>
static luabridge::LuaRef GetGlobalComponent(GameObject& go, bool findAll, const char* globalName, const char* tag)
{
// Get lua state
auto L = LuaEngine::getInstance().L();
// Register global
if (findAll)
{
auto vec = go.GetComponentsByType<T>();
// Check for tag
if (tag != "")
{
// Find by tag
std::vector<T*> elements;
for (auto& e : vec)
{
if (static_cast<Component*>(e)->getTag() == tag)
elements.push_back(e);
}
luabridge::setGlobal(L, LuaHelper::ToTable(elements), globalName);
}
else
luabridge::setGlobal(L, LuaHelper::ToTable(vec), globalName);
}
else
luabridge::setGlobal(L, go.GetComponentByType<T>(), globalName);
return luabridge::getGlobal(L, globalName);
}