1. 程式人生 > >Lua 入門學習教程(二) 函式 與 回撥函式

Lua 入門學習教程(二) 函式 與 回撥函式

還記得開始學C語言的時候,書上就拿兩個數相加 作為例子,來介紹函式。我也拿 Add 來說吧。

函式的簡單寫法就像下面的Add

local function Add( a,b )
	-- body
	print(a+b)
end

Add(10,20)

然後面向物件
local MathTools={}

function MathTools:Add( a,b )
	-- body
	print(a+b)
end

MathTools.Add(self,10,20)
MathTools:Add(10,20)

如果使用 點 來呼叫函式,第一個引數必須是 self ,self的作用是指明函式作用與誰。

如果使用冒號 來呼叫函式,就可以省略self,這是語法糖。

回撥函式 通過遊戲中的網路訊息分發來說吧

比如我遊戲中有一個 NetMsgDispatcher.lua,作為被監聽者存在。遊戲的各個模組觀察者 在一開始會註冊回撥函式。

有兩種解決方法

1、使用匿名函式,像下面這麼寫。

    --NetMsgDispatcher.lua
     
    local NetMsgDispatcher=
    {
    	m_NetMsgCallbackTable={}
    }
     
    --註冊
    function NetMsgDispatcher:RegisterNetMsgCallback(msgindex,callback)
    	-- body
    	if(self.m_NetMsgCallbackTable[msgindex]==nil) then

    		local callbackTable={}
    		table.insert(self.m_NetMsgCallbackTable,msgindex,callbackTable)

    	end
    	local callbackTable = self.m_NetMsgCallbackTable[msgindex]
    	table.insert(callbackTable,callback)
    end
     
    --分發
    function NetMsgDispatcher:DispatchMsg(cmdIndex)
    	-- body
    	for key,value in pairs(self.m_NetMsgCallbackTable) do
     
    		if(key == cmdIndex) then
    			--輸出callbackTable
    			for callbackkey,callbackvalue in pairs(value) do
    				--print("..." .. callbackkey,callbackvalue)
    				callbackvalue()     --回撥;
    			end
    		end
     
    	end
    end
     
    return NetMsgDispatcher

測試程式碼

local GameInstance=
{
	m_name="123"
}

local NetMsgDispatcher = require("NetMsgDispatcher")

print("GameInstance Start")

function GameInstance:Start()
	-- body
	NetMsgDispatcher:RegisterNetMsgCallback(1001,function()
		-- body
		self:callback1001()
	end)

	NetMsgDispatcher:DispatchMsg(1001)
end




function GameInstance:callback1001()
	-- body
	print("1001callback=" .. self.m_name)
end


GameInstance:Start()

return GameInstance

2、註冊回撥函式的時候,把 self 也一起註冊進去

--**************************
-- 檔名:NetMsgDispatcher.lua
-- 檔案描述:NetMsgDispatcher
-- 建立日期:2015/11/15
-- Author:Create by 陳鵬
--**************************


local NetMsgDispatcher=
{
	m_NetMsgCallbackTable={}
}



--註冊原樣返回的
function NetMsgDispatcher:RegisterNetMsgBackCallback(msgindex,this,callback)
	self:RegisterNetMsgCallback(msgindex,this,callback)
end

--註冊返回的
function NetMsgDispatcher:RegisterNetMsgCallback(msgindex,this,callback)
	-- body
	if(self.m_NetMsgCallbackTable[msgindex]==nil) then
	
		--msgindex對應的table,裡面放handler
		local callbackTable={}
		
		--把 callbackTable 新增到 m_NetMsgCallbackTable
		table.insert(self.m_NetMsgCallbackTable,msgindex,callbackTable)
	end
	
	local callbackTable = self.m_NetMsgCallbackTable[msgindex]
	
	table.insert(callbackTable,{m_this=this;m_callback=callback})
end

--反註冊原樣返回的
function NetMsgDispatcher:UnRegisterNetMsgBackCallback(msgindex,callback)
	self:UnRegisterNetMsgBackCallback(msgindex,callback)
end

--反註冊返回
function NetMsgDispatcher:UnRegisterNetMsgCallback(msgindex,callback)
	if self.m_NetMsgCallbackTable[msgindex]~=nil then
		local callbackTable = self.m_NetMsgCallbackTable[msgindex]
		for index=1,table.maxn(callbackTable),1 do
			if callbackTable[index].m_callback==callback then
				callbackTable[index]=nil
				table.remove(callbackTable,index)
				break
			end
		end
	else
		Debug.LogError(tostring(msgindex) .. "has not Register!!donot UnRegister!")
	end
end

--分發
function NetMsgDispatcher:DispatchMsg(cmdIndex)
	-- body

	for key,value in pairs(self.m_NetMsgCallbackTable) do
		if(key == cmdIndex) then
			for callbackkey,callbackvalue in pairs(value) do
				callbackvalue.m_callback(callbackvalue.m_this)     --回撥;
			end
		end
	end
end

return NetMsgDispatcher

測試程式碼

local GameInstance=
{
	m_name="123"
}

local NetMsgDispatcher = require("NetMsgDispatcher")

print("GameInstance Start")

function GameInstance:Start()
	-- body
	NetMsgDispatcher:RegisterNetMsgCallback(1001,self,self.callback1001)

	NetMsgDispatcher:DispatchMsg(1001)
end




function GameInstance:callback1001()
	-- body
	print("1001callback=" .. self.m_name)
end


GameInstance:Start()

return GameInstance

總之遵循一個原理:

如果使用 點 來呼叫函式,第一個引數必須是 self ,self的作用是指明函式作用與誰。回撥函式也是如此!

如果使用冒號 來呼叫函式,就可以省略self,這是語法糖。