加载lua脚本的热更新探测

Posted qianbo_insist

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了加载lua脚本的热更新探测相关的知识,希望对你有一定的参考价值。

上一篇文章

c++与lua socket 高级调用
下面要进行热更新的文件调用,要做到更改lua文件时,重新启动脚本。这样不用重启c++服务。根据探测几种方式,最终认为使用libuv的文件监控比较简单,跨平台,QT也可以使用QT自身带的文件监控功能。

linux 文件监控

inotify,比较好用,和windowsapi类似

int inotify_init(void);
int inotify_add_watch(int fd, const char *pathname, uint32_t mask);
int inotify_rm_watch(int fd, uint32_t wd);

windows文件监控

可以使用windows 的api 来监控文件夹,ReadDirectoryChangesW ,主要代码如下所示

  HANDLE hDir; 
  char notify1024; 
  DWORD cbBytes,i; 
  char AnsiChar3; 
  wchar_t UnicodeChar2; 
  CString path;
 
  FILE_NOTIFY_INFORMATION *pnotify=(FILE_NOTIFY_INFORMATION *)notify; 
  FILE_NOTIFY_INFORMATION *tmp; 
 
  GetCurrentDirectory(MAX_PATH,path.GetBuffer(MAX_PATH+1));
  hDir = CreateFile( path, FILE_LIST_DIRECTORY,
    FILE_SHARE_READ | 
    FILE_SHARE_WRITE | 
    FILE_SHARE_DELETE, NULL, 
    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | 
    FILE_FLAG_OVERLAPPED, NULL); 
  if (hDir == INVALID_HANDLE_VALUE) 
   
 
    dlg->m_edit.ReplaceSel("hDir:INVALID_HANDLE_VALUE\\r\\n");
    return 0;
   
 
  while (TRUE) 
   
    if(ReadDirectoryChangesW(hDir, ¬ify, sizeof(notify),
      FALSE, FILE_NOTIFY_CHANGE_FILE_NAME| FILE_NOTIFY_CHANGE_LAST_WRITE, 
      &cbBytes, NULL, NULL)) 
     
 
      tmp = pnotify; 
 
      switch(tmp->Action) 
       
      case FILE_ACTION_ADDED: 
 
        dlg->m_edit.ReplaceSel("Directory/File added (添加文件)- \\r\\n");
        break; 
      case FILE_ACTION_REMOVED:
        dlg->m_edit.ReplaceSel("Directory/File removed (删除文件)- \\r\\n");
        break; 
      case FILE_ACTION_MODIFIED: 
        dlg->m_edit.ReplaceSel("Directory/File modified (修改文件内容)- \\r\\n");
        break; 
      case FILE_ACTION_RENAMED_OLD_NAME: 
        dlg->m_edit.ReplaceSel("Directory/File old name (修改文件名字)- \\r\\n");
        break; 
      case FILE_ACTION_RENAMED_NEW_NAME: 
        dlg->m_edit.ReplaceSel("Directory/File new name - \\r\\n");
        break; 
      default: 
        break;

QT

QT可以使用QFileSystemWatcher* watcher 来监视文件,还是比较好用的

使用libuv

使用libuv的好处是跨平台,异步,非常好用,比QT的监控更加简单

#include <iostream>
#include <assert.h>
#include <stdio.h>
#include <fcntl.h>

#ifndef _WIN32
#include <unistd.h>
#endif
#include <uv.h>
#ifdef  _WIN32
#include <WinSock2.h>
#include <windows.h>
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"psapi.lib")
#pragma comment(lib,"Iphlpapi.lib")
#pragma comment(lib,"Userenv.lib")
#endif



uv_loop_t* loop;
const char* command;

void run_command(uv_fs_event_t* handle, const char* filename, int events, int status) 
    char path[1024];
    size_t size = 1023;
    // Does not handle error if path is longer than 1023.
    uv_fs_event_getpath(handle, path, &size);
    path[size] = '\\0';

    fprintf(stderr, "Change detected in %s: ", path);
    if (events & UV_RENAME)
        fprintf(stderr, "renamed");
    if (events & UV_CHANGE)
        fprintf(stderr, "changed");

    fprintf(stderr, " %s\\n", filename ? filename : "");
   // system(command);


int main(int argc, char** argv) 

    loop = uv_default_loop();
    command = "dir";// argv[1];
    const char* file = "udp.lua";
  
        fprintf(stderr, "Adding watch on %s\\n", file);
        uv_fs_event_t* fs_event_req = (uv_fs_event_t * )malloc(sizeof(uv_fs_event_t));
        uv_fs_event_init(loop, fs_event_req);
        // The recursive flag watches subdirectories too.
        uv_fs_event_start(fs_event_req, run_command,file , UV_FS_EVENT_RECURSIVE);
  
    return uv_run(loop, UV_RUN_DEFAULT);

以下为lua脚本

local socket = require("socket.core")
 local udp = socket.udp()
 local host = host or '127.0.0.1'
 local port = '6000'
 udp:settimeout(10)
 --local udpbind = udp:bind(host,port)
 udp:setsockname(host, port)
 print('waiting client connect')
 while 1 do
     local revbuff,receip,receport = udp:receivefrom()
     if (revbuff and receip and receport) then
         recv(revbuff)
     else
         print('waiting client connect-1')
     end
 end
 udp:close()

当我们修改lua脚本时

可以监控到文件改变,这时候可以停止lua运行,然后重启线程,做到热更新,这个下一次再实验。

以上是关于加载lua脚本的热更新探测的主要内容,如果未能解决你的问题,请参考以下文章

waxpatch实现上线app的热更新

从js到lua

菜鸟学习 - Unity中的热更新 - LuaInterface用户指南

Unity3D热更新之LuaFramework篇[05]--Lua脚本调用c#以及如何在Lua中使用Dotween

ios app 实现热更新(无需发新版本实现app添加新功能)

(转载)笨木头Lua专栏基础补充20:面向对象——类和继承