我是 Lua 和 LuaBridge 的新手,我想知道是否可以注册模板函数?我在网上查看并通过 LuaBridge 手册无济于事。我尝试的是创建一个指向基类的指针,但后来发现没有办法在 Lua 中进行转换。如果有人对解决此问题的最佳方法有任何想法,将不胜感激。
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();
}
解决方案
忘了早点发布,但解决方案是从字符串中确定类型,从那里你需要在 Lua 中设置一个全局,然后返回对该全局的引用。
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);
}