如何在Luabridge注册模板功能



我是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);
}

您无法注册模板功能。您必须注册显式实例。

#include <iostream>
#include <lua.hpp>
#include <LuaBridge.h>
char const script [] =
  "local t = Test()"
  "t:test_int(123)"
  "t:test_str('Hello')";
class Test
{
public:
  template < typename T >
  void test(T t) { std::cout << t << 'n'; }
};
int main()
{
  lua_State* L = luaL_newstate();
  luaL_openlibs(L);
  luabridge::getGlobalNamespace(L)
    .beginClass<Test>("Test")
      .addConstructor<void(*)(void)>()
      .addFunction("test_int", &Test::test<int>)
      .addFunction("test_str", &Test::test<char const *>)
    .endClass();
  if ( luaL_dostring(L, script) != 0)
    std::cerr << lua_tostring(L,-1) << 'n';
}

我建议您使用没有如此可怕语法的sol2(虽然需要C 14(。

#include <iostream>
#include <string>
#include <sol.hpp>
char const script [] =
  "local t = Test.new()"
  "t:test_int(123)"
  "t:test_str('Hello')";
class Test
{
public:
  template < typename T >
  void test(T t) { std::cout << t << 'n'; }
};
int main()
{
  sol::state L;
  L.open_libraries();
  L.new_usertype<Test>("Test",
    "test_int", &Test::test<int>,
    "test_str", &Test::test<std::string>
    );
  L.script(script);
}

相关内容

  • 没有找到相关文章

最新更新