2018年9月30日 星期日

Lua 5.1 __gc

__gc

lua 5.2 開始有 __gc 這個元函數可以知道什麼時候被釋放掉
當 table 被回收時會呼叫這個函數
我們可以在這個函數中處理資源釋放等操作
不過 lua 5.1 中對於 table 并不支援,我們先看一下在 lua 5.2 中
這個 __gc 怎麼使用

-- lua 5.2

local teseTtable = {

name = "test table"

};

local mt = {

__gc = function(tb)

print("gc execute! name => ", tb.name);

end

};

local newTable = setmetatable(teseTtable, mt);

collectgarbage("collect");

上面測試代碼的結果為:

gc execute! name => test table

lua 5.1 如何使用 __gc

[官方文件][id]明確的指出 The __gc metamethod is not called for tables.
__gc 是 UserData 結構的時候會呼叫的
因此我們可以利用這個條件來觸發 __gc 函數
程式碼為:

-- lua 5.1

-- 拿上面的變數來使用

local teseTtable = {

name = "test table"

};

local mt = {

__gc = function(tb)

print("gc execute! name => ", tb.name);

end

};

local function setMetatableByProxy(ourTable, mt)

-- 建立代理,這個 newProxy 就是一個 UserData

local proxy = newproxy(true);

-- 我們利用 UserData 的 metadata 來註冊

getmetatable(proxy).__gc = function()

mt.__gc(ourTable);

end

end

-- 開始測試

setMetatableByProxy(teseTtable, mt);

collectgarbage("collect");

上面測試代碼的結果為:

-- lua 5.1

gc execute! name => test table

2018年8月26日 星期日

VSCode Task 變數

變數說明

在寫 Task 的時候會需要一些變數,這邊記錄一下
  • ${workspaceRoot}VS中打開的文件夾的路徑
  • ${workspaceRootFolderName}VS中打開的文件夾名稱沒有任何斜杠(/)
  • ${file}當前打開的文件
  • ${relativeFile}相對於當前打開的文件workspaceRoot
  • ${fileBasename}打開的文件的基本名稱
  • ${fileBasenameNoExtension}當前打開的文件的基本名稱,不帶擴展名
  • ${fileDirname}打開的文件的目錄名
  • ${fileExtname}當前打開的文件的擴展名
  • ${cwd}啟動時任務運行器當前的工作目錄
  • ${lineNumber}活動文件中當前所選的行號

參考

Vscode Task 說明

2018年8月20日 星期一

Git rename

有時候我們會需要對Git上的檔案做更名
簡單的做法是在系統直接修改就好
但是我們也是可以用SourceTree操作
  1. 在檔案上按下滑鼠右鍵,選擇"Move"
  2. 跳出的對話框中有一個"Destination"輸入框
  3. 填入新的檔案名稱
  4. 完成
  5. 收工

2018年8月19日 星期日

SSH

目前公司使用Git還是用賬號密碼來登入
最近的專案中有用到三個submodule
造成每次Push就是要輸入四次賬密,實在饒人
決定使用SSH登入比較簡單
詳細步驟如下
  1. 打開Terminal視窗
  2. 先來看一下有沒有可以用的SSH public key
  3. 輸入
    $ls -al ~/.ssh
    
  4. 如果出現 “No such file or directory” 表示沒有建立過 Key
  5. 如果沒有建立過Key請輸入(有其他文字的話跳過這個步驟)
    $ssh-keygen -t rsa -C "XXXX@gmail.com"
    
    後面的mail是範例,請改成自己想輸出的賬號
  6. 會出現輸入賬密的功能,由於我是本機使用,我全部按Enter跳過
  7. 完成之後再次輸入看結果
    $ls -al ~/.ssh
    
  8. 如果有類似下列的文字出現表示成功建立了
    XXXX是賬號
    total 24
    drwx------ 5 XXXX staff 160  8 20 10:54 .
    drwxr-xr-x+ 50 XXXX staff  1600  8 20 10:53 ..
    -rw------- 1 XXXX staff  1675  8 20 10:53 id_rsa
    -rw-r--r-- 1 XXXX staff 407  8 20 10:53 id_rsa.pub
    -rw-r--r-- 1 XXXX staff 175  8 20 10:54 known_hosts
    
  9. 接在我們就要取得我們的Key了,再輸入下列指令
    $cat ~/.ssh/id_rsa.pub
    
    成功之後會看見我們的Key
    ssh-rsa AAAA......
    
    這樣就OK
  10. 將這個Key貼到Git中存放SSA Key的地方就完成
  11. 搞定! 收工!

Unity Shader Graphic

今天看見Unity Blog的文章
現在的Shader都不用寫的嗎?
Shader Graphic
文章中提到:
  • 動畫都可以處理
  • 可以針對動畫的時間做細部的微調

2018年8月15日 星期三

Lua三元運算子

問題

最近在寫Lua的時候遇到一個有趣的問題
關於短路求值,我們看一下下面的程式碼
 local result = a and b or c;
上面是 Lua 的三元運算,看起來相當合理
如果 a 的判斷是 true 那麼 result 就是 b 不然就是 c
但是在 Lua 中,如果 b 剛好是 nil 或是 false 的話,result 的結果會是 c
這個不是我們要的答案
必須想個辦法解決

為什麼

這個問題的原因是因為 and 和 or 是短路求值
短路求值可以有效的處理下面的程式碼
 -- 只有 dog 這個物件存在才會去判斷 dog 是否在睡覺
 if dog and dog:isSleep() then
  ...
  ...
 end
只在有需要的時候才會去執行第二個條件
Lua 做邏輯判斷的時候只有 nil 和 false 是假的,其他都是真的
and 判斷會回傳"假"的那個條件
or 判斷則是回傳"真" 的那個條件
所以
 a and b or c
這個判斷下,如果 a 判斷的結果是真,結果應該會是 b or c
可是 b 的內容卻是 nil 或是 false,所以結果就會是 c 了
如果 a 判斷的結果為假,那麼 and 就不會處理
直接進行 or 判斷,這個時候的結果會是 c
也就是說,只要 b 的內容是 nil 或是 false 的話
這個判斷的結果一定會是 c

解決

有很多方式可以避開這個問題
比如改成
 local result = not a and c or b;
或是
 local result = c;
 if a then
  result = b;
 end
但是這些都是治標不治本(這邊是假設你一定要用三元運算子來處理邏輯)
最好的方式是用 table 將數值包裝起來,等判斷完再取值
 -- best solution
 local result = (a and {b} or {c})[1];
搞定!
回家收工!

參考

短路求值
Lua邏輯判斷

MarkDown 寫blog

# MarkDown 寫blog 我發現直接在Blogger安裝小工具可以利用Markdown格式寫文章 不過缺點就是沒有辦法及時預覽 ### 優點: * 寫文章變簡單 * 格式固定,我不用排版 ### 缺點: * 沒辦法及時預覽,都要按下右側"預覽"按鈕 不過總而來說還是優大於弊啊~

2018年8月14日 星期二

VScode lua region折疊

問題

預設Lua是沒有region這個折疊代碼的功能
我上網找了很多外掛,都沒有支援
唯一找到的外掛就是luaide不過是要錢的
後來上網找到直接修改語言設定的方式支持region折疊
參考網址的電腦是Windows,可是我的是MAC
這邊將我的步驟寫出來,方便MAC的使用者操作
實踐步驟如下:
  1. 打開應用程式目錄
  2. 在Visual Studio Code上按右鍵,點選“顯示套件內容”
  3. 在目錄 Contents/Resources/app/extensions/lua 下有一個 language-configuration.json
  4. 開啟 language-configuration.json
  5. lua不支援 region 這個語法,所以移到檔案的下方
  6. 加上
    
        "folding": {
            "offSide": true,
     "markers": {
         "start": "^\\s*--\\s*region\\b",
         "end": "^\\s*--\\s*endregion\\b"
     }
        }
    
  7. 重開Visual Studio Code

參考網址

Region

2018年8月13日 星期一

hackMD


最近工作上使用很多的共同編輯的文件
目前是使用 Google 文件
不過如果是單純做筆記或是一些文件說明的話
這邊推薦一個工具來建立共同筆記
最重要的是可以使用MarkDown格式啊~

https://hackmd.io/

2018年8月10日 星期五

package.loaded

該如何判斷一個Lua檔案是否下在完成
可以檢查看看 package.loaded 這張表中是否有數值

比如
-- ModuleA.lua
...
...
...

-- Main.lua
require("ModuleA")
for k,v in pairs(package.loaded) do
print(k,v)
end

-- 輸出結果
string table: 00B193B0
debug table: 00B19748
package table: 00B17628
_G table: 00B11A60
src/view/ModuleD table: 00E60118
ModuleA table: 00E60140
io table: 00B19608
os table: 00B19770
table table: 00B174C0
math table: 00B196A8
src/view/ModuleC table: 00E60208
coroutine table: 00B17380
ModuleB table: 00B19B08

可以明顯知道模組已經有下載過了
之後如果我們在別的地方寫 require 
返回的都是同一個值

2018年7月30日 星期一

Cocos2dx require

最近工作上遇到一個問題
公司目前使用的遊戲引擎是 Cocos2dx 2.2.6
別問我為啥不升級,這個牽扯到超多問題,沒辦法動

最近在建立一個小型的專案
專案中用到 Git 的 Submodule 引入別人寫的 Library
問題在別寫的 Lua Code 中有 require

當這個專案被其他人引入并執行時
原本 require 的位置變成了其他專案的根目錄了

執行的時候就會報錯,表示找不到 XXX module

原本我直覺使用 Cocos2dx 提供的 CCFileUtils
裡面有一個函數 addSearchPath
但是呼叫并傳入 search path 卻是沒有用的,還是會出錯

仔細看一下 Cocos2dx 底層的 C++
發現 Cocos2dx 有改寫 Lua 尋找檔案的方式,請見 Cocos2dxLuaLoader.cpp
它在找檔案的時候還是依靠 Lua 的 package.path(http://lua-users.org/wiki/PackagePath)
所以我一直呼叫 C++ 的 addSearchPath 是叫心酸的!!

最后修改的方法如下
local function addSearchPath(searchPath)
return string.format(
"%s;%s?.lua;%s?/init.lua",
package.path, searchPath, searchPath);
end
package.path = addSearchPath("Libs/");
這樣才解決我的問題
Cocos2dx 你還我 30 分鐘啊啊啊!

Lua 5.1 __gc

__gc lua 5.2 開始有 __gc 這個元函數可以知道什麼時候被釋放掉 當 table 被回收時會呼叫這個函數 我們可以在這個函數中處理資源釋放等操作 不過 lua 5.1 中對於 table 并不支援,我們先看一下在 lua 5.2 中 這個 __gc 怎...