如何处理这种情况(需要用变量参数注册函数)

How to handle this situation (need to register functions with variable arguments)

本文关键字:变量 参数 函数 注册 何处理 处理 情况      更新时间:2023-10-16

我正在寻找如何处理这种情况的建议,因为到目前为止我想到的任何方法都不起作用。

我正在制作一款RPG游戏,目前正在开发图像系统。我的图形系统由一系列按特定顺序排列的屏幕堆栈组成,然后绘制。

一个ScreenStack基本上只是一个相关屏幕的集合,伴随着一个唯一的id和一个绘制顺序。

class ScreenStack
{
//Constructors, getters/setters etc.
private:
    std::string StackName;
    int DrawPriority;
    int UID;
    bool Valid;
    bool DrawStack;
    bool UpdateStack;
    bool SendInputs;
    bool DeleteStack;
    std::vector<screen_ptr> OwnedScreens; //screen_ptr is a shared_ptr around a Screen object
};

屏幕是一个简单的图形层,负责可视化游戏的某些部分,例如有一个屏幕显示玩家库存,团队概述,战斗中的团队状态,敌人团队等。

我有一个屏幕管理器,负责存储用于创建屏幕堆栈的各种功能(例如,创建战斗堆栈的功能将为玩家一方,敌人一方,攻击动画屏幕,背景和用户界面制作屏幕)。每个不同的屏幕堆栈创建函数都需要一组不同的参数来构造它。我现在要做的是根据需要手动向屏幕管理器添加堆栈创建函数。例如,现在屏幕管理器有一个功能来创建标题屏幕堆栈,开始菜单堆栈,战斗堆栈,世界堆栈,磁贴图堆栈等。

这可以工作,但是很麻烦和混乱。我想要做的是让屏幕管理器外部的文件能够注册屏幕管理器的堆栈创建函数,然后我就可以查找屏幕创建函数,而不必为我需要创建的每个堆栈添加一个新函数到屏幕管理器。

我最初尝试添加一个unordered_map<std::string, StackCreationFunction>与StackCreationFunction被定义为

boost::function<ScreenStack (Engine& engine, ScreenManager& manager, const std::string screenName, const int StackID, const std::vector<std::string>& TryToCopyScreens, ...)> 

…是来自cstdargs。这个想法是,每个ScreenStack将添加它自己的StackCreationFunction到这个映射。然而,这不起作用,因为boost::函数无效…

所以本质上我想做的是允许外部文件/屏幕能够注册自己的创建函数(有变量参数)与屏幕管理器,理想情况下能够在编译时/启动后立即做到这一点。这感觉应该可以用预处理器,但我不确定如何做到这一点。我被困在这里了,我真的想要一个更好的解决方案,而不是在屏幕管理器中添加许多堆栈创建器功能,把它弄得一团糟。

任何建议/更好的解决方案将不胜感激,如果以上不够清楚,我可以提供更多的细节

谢谢

每个不同的屏幕堆栈创建函数都需要一组不同的参数来构造它。

我认为这就是问题所在,你需要在这里想出一个抽象的概念来让你的地图工作。毕竟,调用代码实际上是如何提供这些额外参数的?当调用代码知道实例化了哪个类并可以提供参数时,就不需要映射了。如果不是,则映射就没有用处,因为您无法告诉要向堆栈创建函数提供哪些参数。

最可能的解决方案是boost::bind away你的StackCreatorFunction的所有参数,通常会进入...参数和注册这个绑定版本的函数在无序映射,这可以释放...

我建议让系统调用外部实体,而不是将外部实体注册到系统中。在这种情况下,您的系统将定位并加载一系列具有特定入口点的插件。你需要使用一些常规的容器来创建可变长度的参数列表;数组或数据结构。

我不确定这是否回答了您的问题,但如果您关心的是从类似解释器的代码中调用不同签名的各种函数,那么您可以(至少在GNU/Linux下)使用LibFFI(用于外部函数接口的库)。