静态虚函数
2015-1-17 7:2:34
收藏:0
阅读:103
评论:1
好的,我知道静态虚函数由于几个原因而不存在。然而,我认为我找到了一种类似它们的情况可能会很有用。作为课程小组项目的一部分,我们必须为游戏引擎设计脚本核心。为了保持解耦,我们希望一个类能够注册其元表(函数、成员等)到LuaState中。此外,由于这是我第一次尝试实现此类事物,我可能完全错误。
因此,为了保持通用,我们有一个IScriptStateManager界面,其中包含纯虚函数以将对象注册到脚本语言的全局状态中,执行初始化和关闭功能,并具有一些其他功能DoFile和DoString。然后我们有一个实现此界面功能的LuaStateManager类。
现在,为了允许大多数游戏对象在脚本中创建而不预先知道它们,我们还创建了一个IScriptObject接口。如果要使对象由脚本系统表示,应实现此接口。此接口包括一个方法,其中包含register称为的方法,派生类可以实现并将设置其元表。因此,一切都像这样:
bool LuaStateManager::Register(IScriptObject* obj)
{
if (未在全局状态中注册 obj)
{
obj->Register();
return true;
}
返回假;
}
我相信您可以看到问题。首先,首先我们需要一个实际的实例来注册一个对象。由于这个原因,我们可能会为一个特定类型的对象多次调用此函数,只有第一次返回真,其他每次都返回假。虽然这样做的开销很小,但它是设计有误的明显迹象。
因此,问题出现了。在这种特殊情况下,我们需要静态方法和虚方法的功能。可以授予我们的草案。虽然我们可以简单地手动向每个类添加静态方法,然后调用那些方法一次,但这会将对象与脚本系统耦合。任何提示或帮助都将不胜感激。谢谢
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
通过 API 类或 namespace 中的一组函数提供对 IScriptStateManager 功能的访问。
ScriptStateManagerAPI.h:
namespace ScriptStateManagerAPI { // 将活动的 ScriptStateManager 注册到函数中。 void setActiveScriptStateManager(IScriptStateManager* scriptStateManager); // 注册 ScriptObject 的函数。 bool registerScriptObject(IScriptObject* obj); }IScriptStateManager.h:
class IScriptStateManager { virtual bool registerScriptObject(IScriptObject* obj) = 0; };ScriptStateManagerAPI.cpp:
#include <IScriptStateManager.h> namespace ScriptStateManagerAPI { static IScriptStateManager* activeScriptStateManager = nullptr; void setActiveScripStatetManager(IScriptStateManager* scriptStateManager) { activeScriptStateManager = scriptStateManager; } bool registerScriptObject(IScriptObject* obj) { if ( activeScriptStateManager ) { return activeScriptStateManager->registerScriptObject(obj); } else { // 处理没有活动 IScriptStateManager 的情况。 return false; } } }LuaScriptManager.h:
#include <IScriptStateManager.h> class LuaScriptManager : public IScriptStateManager { virtual bool registerScriptObject(IScriptObject* obj); };LuaScriptManager.cpp:
namespace { // 在匿名命名空间中的帮助类,用于在启动时将 LuaScriptManager 注册为活动的 IScriptStateManager。 struct Initializer { Initializer(); }; }; // 在启动时构造一个初始化程序。 static Initializer initializer; Initializer::Initializer() { // 注册 LuaScriptManager 为活动的 ScriptStateManager。 ScriptStateAPI::setActiveScriptStateManager(new LuaScriptManager()); } bool LuaScriptManager::registerScriptObject(IScriptObject* obj) { if (obj 还未在全局状态中注册) { obj->Register(); return true; } return false; }您可以在应用程序中使用另一个
ScriptStateManager。然后,您必须选择每次是否只能有一个ScriptStateManager。如果您的应用程序需要同时使用多个ScriptStateManager,则可以更改ScriptStateManagerAPI中的static数据以及接口ScriptStateManagerAPI.h:
namespace ScriptStateManagerAPI { // 注册活动的 ScriptStateManager 的函数。 void registerActiveScriptStateManager(IScriptStateManager* scriptStateManager); // 注册 ScriptObject 的函数。 bool registerScriptObject(IScriptObject* obj); }ScriptStateManagerAPI.cpp:
#include <IScriptStateManager.h> namespace ScriptStateManagerAPI { static std::set<IScriptStateManager*> activeScriptStateManagers; void registerActiveScripStatetManager(IScriptStateManager* scriptStateManager) { activeScriptStateManagers.insert(scriptStateManager); } bool registerScriptObject(IScriptObject* obj) { // 找出如何管理每个 activeScriptManager 的返回值。 for ( auto activeScriptManager, activeScriptStateManagers) { activeScriptManager->registerScriptObject(obj); } return true; //???? } }