wax lua 指令碼升級練習(2),waxlua

來源:互聯網
上載者:User

wax lua 指令碼升級練習(2),waxlua

wax lua 指令碼升級練習(1)介紹了object-c通過調用lua中的Function Compute兩值乘積並返回顯示。

這一篇將介紹通過點擊按鈕下載新的lua指令檔,並且熱載入lua,使起能即時生效。

在寫代碼前需要做一點點準備。

1.啟動原生Apache服務,作為新lua指令碼的存放位置

開啟“終端(terminal)”,輸入sudo apachectl start(可能需要輸入機器秘密),開啟Safari瀏覽器地址欄輸入 “127.0.0.1”,可以看到內容為“It works!”的頁面.

其位於“/Library(資產庫)/WebServer/Documents/”下,這就是Apache的預設根目錄。

在這個目錄下建立檔案夾script,回頭這個目錄下存放新指令碼。

( 停止:sudo apachectl stop 重啟:sudo apachectl restart)


2.下載第三方庫ZipArchive。用於解壓從網路擷取的指令檔。

將ZipArchive.m,ZipArchive.h,crypt.h,ioapi.c,ioapi.h,mztools.c,mztools.h,unzip.c,unzip.h,zip.c,zip.h檔案載入到工程中。

option+command+A 添加檔案到工程,選中Copy items into destination group's folder ,點擊Add。

這個時候運行程式可能會報錯,因為有的檔案不支援ARC。方法:

 (工程->taggets->build Phases 可以看到Compile Sources裡都是你工程中的類.m檔案,雙擊你不使用ARC的檔案, 輸入 -fno-objc-arc )


然後才開始寫代碼。
“下載新指令碼”按鈕對應的函數 (IBAction)downlodNewLua:(id)sender需要添加如下代碼
- (IBAction)downlodNewLua:(id)sender {    [[luaMain shareInstance] ExecLua:@{@"cmd":LUA_EVENT_DOWNLOAD_NEN_SCRIPT, @"param":@{}}];}



添加一個新類luaCallBak,用於lua調用oc代碼到介面

luaCallBak.m

#import "luaCallBak.h"@implementation luaCallBak+ (luaCallBak*) shareInstance{    static luaCallBak* _this = nil;        static dispatch_once_t onceTokenInit;    dispatch_once(&onceTokenInit, ^{        _this = [[luaCallBak alloc] init];    });        return _this;} - (NSString *) temdir{   NSString * tem= NSTemporaryDirectory();    return tem;}- (NSString * )DocumentsDir{   return  [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];}@end


修改main.lua檔案的exeLuaCode函數
function exeLuaCode( param )-- bodyprint('exeLuaCode')if (not param) thenreturn nil;endlocal dict_param = wax.json.parse(param);if dict_param thenlocal cmd = dict_param['cmd'];if cmd == '10000' thenreturn multiply(dict_param['param']) elseif cmd == '10001' then updateScriptStatus()--下載新指令碼endendend



在main.lua檔案的尾部添加如下內容
local Script_URL ='http://192.168.1.102/script/new_script.zip';--新指令檔的網路地址function updateScriptStatus()-- bodywax.http.request{Script_URL, format = 'binary', callback = function ( retvalue, retresponse )-- bodylocal ret_obj2 = retvalue;--通過網路地址下載下來的二進位檔案內容if retresponse and retresponse:statusCode() == 200 and ret_obj2 thenprintLog('start UnZip')if not scriptUnZip(ret_obj2) then --將二進位檔案內容解壓return;endprintLog('start move Script')if not moveTemScriptToScript() then--移動新指令碼到固定位置return;endreload_script_files();--載入新指令碼elseprintLog('request err')endend}endfunction scriptUnZip(zipdata)-- bodylocal  tmp_dir =  luaCallBak:shareInstance():temdir();--調用oc的temdir函數,擷取存放臨時檔案的臨時路徑local temPath = tmp_dir ..'/video_analyze_script';local  scriptUpdateDir = tmp_dirlocal zipfile = scriptUpdateDir .. '/download_video_analyze_script';zipdata:writeToFile_atomically(zipfile, 0);--將記憶體中的二進位內容寫成臨時檔案local bexist = NSFileManager:defaultManager():fileExistsAtPath(zipfile);--檢查檔案寫成功否if not bexist thenprintLog('zipfile failed');return;end-- unzip file 解壓檔案到temPath目錄local ziparchine = ZipArchive:init();if not ziparchine thenprintLog('ziparchine nill');return;endif not ziparchine:UnzipOpenFile(zipfile) thenprintLog('open zip file failed');return;endif not ziparchine:UnzipFileTo_overWrite(temPath, 1) thenprintLog('unzip file failed');return;endziparchine:UnzipCloseFile();return 1end--移動指令碼搞這麼複雜,是防止指令碼移動過程中出錯。影響現有指令碼工作function moveTemScriptToScript()-- body--printLog('moveTemScriptToScript')local scriptDir = luaCallBak:shareInstance():DocumentsDir();--scriptDir存放升級後指令碼的路徑scriptDir = scriptDir .. '/video_analyze_script'local  tmp_dir = luaCallBak:shareInstance():temdir();local temPath = tmp_dir ..'/video_analyze_script';local backScriptDir = temPath ..'_bak';local fm =NSFileManager:defaultManager();local b = nil;local bexist = NSFileManager:defaultManager():fileExistsAtPath(scriptDir);--檢查該路徑是否有指令碼printLog(scriptDir)printLog(bexist)if not bexist thenb = fm:moveItemAtPath_toPath_error(temPath,scriptDir,nil);--沒有指令碼,將下載解壓後的檔案移動到scriptDir位置elsefm:removeItemAtPath_error(backScriptDir,nil);--移除現有指令碼的備份的檔案夾 b = fm:moveItemAtPath_toPath_error(scriptDir,backScriptDir,nil);--將現有指令檔夾改名字,作為備份 if b then b = fm:moveItemAtPath_toPath_error(temPath,scriptDir,nil);--將下載解壓後的檔案移動到scriptDir位置 if b then fm:removeItemAtPath_error(backScriptDir,nil);--移動成功,移除現有指令碼到備份檔案夾printLog('remove old ScriptDir') elsefm:moveItemAtPath_toPath_error(backScriptDir,scriptDir,nil);--移動失敗,將現有指令碼到備份檔案夾改為現有指令檔夾名end endendreturn bendfunction reload_script_files( ... )-- body    printLog( "[reload_script_files...]")local scriptDir = luaCallBak:shareInstance():DocumentsDir();--調用oc函數,擷取Documents路徑,用於存放新指令碼scriptDir = scriptDir .. '/video_analyze_script'--設定lua到環境變數,require 新指令碼的時候用local m_package_path = package.path  printLog(m_package_path)if not string.find(m_package_path, 'video_analyze_script') thenpackage.path = string.format("%s/?.lua",scriptDir)endprintLog(package.path)package.loaded['main'] = nil   require('main')   printLog( "[reload_script_files...done]")    return "reload ok"end

代碼添加完成了。當點擊下載新指令碼後,函數的調用流程是 

downlodNewLua -》ExecLua -》exeLuaCode -》updateScriptStatus -》scriptUnZip-》moveTemScriptToScript-》reload_script_files


將main.lua壓縮成zip檔案,改名new_script.zip,然後存放到原生/Library/WebServer/Documents/script目錄下

然後將main.lua檔案中multiply函數裡的“*”改為“+”運行程式

點擊“4*3=”按鈕,輸出7,日誌列印

exeLuaCodemultiplyMultiplicand = 4Multiplier = 37

 點擊“下載新指令碼”,日誌列印

exeLuaCodestart UnZip2014-08-02 21:36:39.820 WaxDemo[16316:60b] 1 entries in the zip filestart move Script/Users/zhaoyan/Library/Application Support/iPhone Simulator/7.1/Applications/DCA2AC15-6DE7-4393-9565-345A182906E6/Documents/video_analyze_scripttrueremove old ScriptDir[reload_script_files...]scripts/?.lua;scripts/?/init.lua;scripts/?.dat;?.lua;?/init.lua;?.dat;/Users/zhaoyan/Library/Application Support/iPhone Simulator/7.1/Applications/DCA2AC15-6DE7-4393-9565-345A182906E6/Documents/video_analyze_script/?.lua[reload_script_files...done]

再次點擊“4*3=”按鈕,輸出12,日誌列印

exeLuaCodemultiplyMultiplicand = 4Multiplier = 312

成功!!!


這裡有一個問題沒有處理,重新開啟程式後,載入的還是舊指令碼,就是當關閉程式後再次開啟程式,點擊“4*3=”按鈕,輸出的還是7。






lua指令碼(懂c/c++的也進) 簡單`

確實是Lua格式的指令碼。

spr = Sprite.new("sprite.png", 24, 32, VRAM)
這句是聲明了Sprite類的一個對象。(當然事實上lua的對象都是由table類比的。)

spr:addAnimation({0,1,2,1}, 300) -- Walk up
“:”是Lua對象調用方法的文法,{0,1,2,1}是Lua的特有資料結構table,--是lua的注釋說明。

其他的while迴圈和if條件陳述式和c的含義一樣。

看來這大概就是個控制人物在螢幕移動的指令碼吧。

建議你去找點lua的入門書看看就瞭解的清楚了。
 
LUA指令碼的幾個疑問

關於dostring中的局部變數 這裡剛好是有個特殊情況的
我用的luaforwindows直接啟動並執行 沒dostring 就先用loadstring了
local a = 1print(loadstring("a = 123")())print(a,_G.a)這裡a = 123執行時 不會給局部變數a進行賦值操作,而是修改了全域變數a
對於到底是局部變數還是全域變數的判斷 依據的是 使用這個變數的這個地區 在使用之前 是否有過局部變數的聲明
比如
a = 1print(a)local a = 2print(a,_G.a)這樣就能看到2個不同的a
而在function Msg(x,y)中
是因為x和y是被當作實參傳過來的 函數裡的實參 在函數內部都是作為局部變數來使用 所以xy是局部而a是全域

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.