完全在 Lua 脚本中运行客户端

介绍

构建客户端程序,常见的选项可能包括mfc、wtl、qt等。最近很多公司也选择使用CEF3来构建他们的客户端程序。由于 CEF3 正是一个浏览器核心,大部分工作都可以通过 JavaScript 来完成,这使得它在资源占用巨大的情况下具有极大的灵活性。虽然一些新的 UI 框架也提供了脚本模块,但它们不能提供程序员可以像 CEF3 那样仅基于脚本完成项目的能力。我想,一个脚本能力完整、体积小巧、效率高的客户端框架应该是客户端程序的不错选择。

代码模块

在源码包中,我们提供了soui4.08.slnsoui4.22.sln。选择一个喜欢的 sln 来打开并构建所有模块,然后运行​​SLuaDemo.ex。你会看到它是如何工作的。 

整个解决方案包括八个模块:

  1. utilities4,该模块提供了一些基本的工具类,例如SStringASStringWSXml (的包装pugixml)。
  2. soui-system-resource,该模块是一个简单的资源容器。
  3. soui4,模块为核心模块,提供直接的UI框架。
  4. imgdecoder-gdipgdiplus用于进行图像解码的模块。在整个 git repo 中还有其他替代品,例如 wic、stb、png。
  5. render-gdi,渲染模块,基于GDI api将绘图渲染到位图。render-skia在整个 git repo 中可用,它提供了比 gdi 高得多的效率。
  6. lua-54,lua引擎。在这里,我们使用的是 lua 5.4.4。
  7. ScriptModule-lua, 将使用的 COM 接口导出到 lua 的模块。我们使用lua_tinker ( https://github.com/zupet/LuaTinker ) 将我们的接口导出到 lua。我们更新lua_tinker支持x64,在Visual Studio 2008可以支持WINAPI等调用模式(好像2015+没有这个问题)。
  8. SLuaDemo,可执行模块,它演示了如何集成上述模块来构建客户端程序并在 lua 脚本中执行所有逻辑。

下面_tWinMain展示了如何开始演示。这些代码只合成了组成演示的必要组件,没有做任何实际的逻辑。

C++

所有实际逻辑都位于main.lua. 在解释代码之前main.lua,我先简单解释一下资源包和布局XML。在soui中,所有可绘制对象都定义为ISkinObj

C++

资源包的主要用途之一是定义ISkinObj由 XML 和图像文件描述。

由于我们已经定义了必要drawable(ISkinObj)的,我们可以ISkinObj在布局 XML 中按名称引用它们。soui 布局的语法与 Android 布局非常相似。Soui 提供了三种主要的布局类型,包括线性布局gridlayout和锚点布局。Anchor 布局类似于 Android 中的相对布局,但在我看来更灵活。例如,空白布局可能如下所示:

XML

所有资源文件都在uires.idx文件中编制索引。
定义好 UI 布局后,我们可以在main.lua.

卢阿

从上面的lua脚本中,我们可以看到基本的步骤包括:

  1. 创建一个resprovider对象并根据resprovider创建的类型使用文件路径或其他源对其进行初始化。资源类型可以是文件路径、DLL 或 zip 文件等。然后将其添加到应用程序中。
  2. 创建一个宿主窗口对象,并使用之前资源包中定义的资源名称对其进行初始化。然后调用hostWnd:create创建一个hwnd并调用hostWnd:ShowWindow显示。
  3. 按名称查找子项并将其事件连接到响应函数。

好的,仅此而已!

如何将 C++ 对象导出到 Lua

我们lua_tinker用来做这项工作。类似的代码可能包括luabind、tolua++等。其他包我不熟悉。在使用中lua_tinker,我发现如果我尝试导出复杂的类,例如一个类有多个基类,它可能会做错事。幸运的是,我们已经使用 COM 实现了所有接口,并且lua_tinker支持 COM 足以将它们导出到 lua。如果你想知道在 lua 脚本中可以使用哪些类或 API,请查看 module 的源代码scriptmodule-lua。您将看到如下代码:

C++

使用该代码,我们导出了一个名为的 COM 接口IObjRef,其中包含三个方法。因此,如果我们得到一个IObjRef对象并将其存储到变量obj中,我们可以调用obj:AddRef来添加对该对象的引用。

完整的 soui4 存储库

在源代码包中,这里只展示了使用的模块。soui 的重要思想之一是为看起来像插件的外部模块提供可替换的模块。您可以在完整的 git 存储库中找到许多功能相似的模块。我们将 soui4 存储在 github 中,GitHub - soui4/soui

结论和兴趣点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Lua脚本是Redis引入的一种功能,允许开发者使用Lua语言编写脚本传到Redis执行。使用Lua脚本有以下好处:减少网络开销,可以将多个请求通过脚本的形式一次发送,减少网络时延;原子操作,Redis会将整个脚本作为一个整体执行,间不会被其他请求插入,因此在脚本运行过程无需担心会出现竞态条件,无需使用事务;复用,客户端发送的脚本会永久存在Redis,这样其他客户端可以复用这一脚本,而不需要使用代码完成相同的逻辑。 Redis引入Lua脚本的原因是为了满足特定领域对于原子性执行若干指令的需求。虽然Redis提供了丰富的指令集,但是在某些场景下,仅使用原生命令无法满足需求。用户可以通过向Redis发送Lua脚本来执行自定义动作,并获取脚本的响应数据。Redis服务器会单线程原子性地执行Lua脚本,保证在处理脚本过程不会被其他请求打断。 如果正在运行脚本已经执行过写操作,即使执行SCRIPT KILL命令也无法将其杀死,因为这违反了Lua脚本的原子性执行原则。在这种情况下,唯一可行的办法是使用SHUTDOWN NOSAVE命令,通过停止整个Redis进程来停止脚本运行,并防止不完整的信息被写入数据库。 要将Lua脚本添加到Redis服务器的脚本缓存,并返回给定脚本的SHA1校验和,可以使用SCRIPT LOAD命令。如果给定的脚本已经在缓存,则不会执行任何操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值