【问题标题】:How to automatically initialize component parameters?如何自动初始化组件参数?
【发布时间】:2021-07-25 00:53:33
【问题描述】:

在做一个使用 .lua 文件来读取参数值的游戏引擎时,当我不得不读取这些值并将它们分配给 C++ 中每个组件的参数时,我陷入了困境。我试图调查 Unity 的工作方式,但没有找到(我开始怀疑 Unity 是否必须这样做)。

我希望参数自动初始化,无需用户执行

myComponentParameter = readFromLuaFile("myParameterName")

每个参数。

我最初的想法是使用 std::variant 类型,并存储一个变体数组以便自动读取它们。我的问题是:

  • 首先,我不知道如何知道std::variant目前存储的类型(尝试使用std::variant::type,但它不适用于模板),在为了从无类型的 .lua 值转换为 C++ 值。作为参考,我的组件初始化如下所示:
bool init(luabridge::LuaRef parameterTable)
{
    myIntParameter = readVariable<int>(parameterTable, "myIntParameter");
    myStringParameter = readVariable<std::string>(parameterTable, "myStringParameter");
    return true;
}

(readVariable 函数已经写好了in this question,如果你好奇的话)

  • 第二个问题是用户在想要访问变体存储的值时必须编写 std::get(myIntParameter); ,这听起来比制作更糟糕用户读取参数值。

  • 第三个问题是我无法创建 std::variant 的数组,这是为了自动初始化参数而我想做的。 p>

对于这种不需要init函数,用户不需要手动设置参数值的情况,有什么好的解决方案吗?

提前致谢。

【问题讨论】:

  • 哪个代码应该知道值的类型?
  • @spectras 我需要参数初始化时的值类型(当我使用 readVariable 时),因为 Lua 是一种无类型语言,我需要转换为C++ 类型。例如,我想做以下事情:readVariable&lt;myVariant.type&gt;( ... )
  • 是的。并且要实际使用特定值(例如,假设您有一些 timeout 变量),您最终需要将其转换为一个数字 - 比如说 int。因此,您的一段代码必须嵌入timeout 的正确类型是int 的知识。该部分通常会测试类型是否正确并提取值。

标签: c++ lua components game-engine


【解决方案1】:

让我们扩展我的评论。简而言之,你需要从

  • “我有一些用户在某个文件中输入的内容”

到:

  • “客户端代码可以在没有 std::get 的情况下读取值”
    …大致翻译为:
    “输入验证已完成,值已准备好直接使用。”

...这意味着您不会将变量存储在变体中。


归根结底,这是一个设计问题。某个模块必须知道存在哪些变量名、每个变量的类型以及有效值。

  • 该模块的输入将是未经验证的值。

  • 模块的输出可能是一些常规的 c++ 结构。

  • 并且该模块的主体可能会有一堆:

    config.foo = readVariable<int>("foo");
    config.bar = readVariable<std::string>("bar");
    // you also want to validate values there - all ints may not be valid values for foo,
    // maybe bar must follow some specific rules, etc
    

    假设在其他地方它被定义为:

    struct Configuration {
        int fooVariable;
        std::string bar;
    };
    

该模块所在的位置取决于您的应用程序。如果所有预期类型都已知,则没有理由使用 variant,只需立即解析即可。

如果有些事情直到以后才有意义,您会阅读变体。例如,如果您想读取插件将使用的配置值,那么您还无法理解它们。

(实际上即使稍后重新解析文件,或者只是将值保存为文本以供以后解析也可以)

【讨论】:

  • 这解决了我所说的问题。但是,我认为我会坚持我以前的实现,因为我看不出使用这种具有多个字段的 Configuration 结构对用户来说比简单调用 readVariable 更清晰——也许还有一些错误处理。
  • 这是一种设计选择。在这种情况下,知道哪个变量接受哪个类型和哪个值将在用户代码中。所以用户代码必须每次都指定它,基本上就是你所做的。这也很好,如果您想分离这些知识并将其放在一个地方,这只是一种替代解决方案,从而无需将用户代码及其相关的 get/validate/etc 撒在其中。
猜你喜欢
  • 2017-07-21
  • 2019-09-05
  • 1970-01-01
  • 2019-01-24
  • 1970-01-01
  • 1970-01-01
  • 2014-09-29
  • 1970-01-01
  • 2017-07-12
相关资源
最近更新 更多