首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何向LuaBridge注册模板化函数?

如何向LuaBridge注册模板化函数?
EN

Stack Overflow用户
提问于 2017-04-27 15:03:10
回答 1查看 816关注 0票数 3

我是Lua和LuaBridge的新手,我想知道是否可以注册一个模板化的函数?我在网上查看过,并通过LuaBridge手册,但没有结果。我尝试的是创建一个指向基类的指针,但后来发现在Lua中无法进行转换。如果有人对解决这一问题的最佳方式有任何想法,我们将不胜感激。

代码语言:javascript
复制
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中设置一个全局的,然后返回对那个全局的引用。

代码语言:javascript
复制
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);
}
EN

回答 1

Stack Overflow用户

发布于 2017-04-28 03:01:59

无法注册模板函数。您必须注册显式实例化。

代码语言:javascript
复制
#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 )。

代码语言:javascript
复制
#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);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43661455

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档