2010年1月1日 星期五

利用python的執行期建立函數功能簡化Keyboard event宣告

Panda3D的Keyboard event可以從下列網址參考
主要是用self.accept( event_name, function ) 將event與function連結起來。
以下是一個例子:
import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject

class keyHandler(DirectObject):
    def __init__(self):
        self.CallBackFuncRefMap = {}
        self.accept('a', self.KeyHandle_a)

    def AddKeyHandle(self, keyString, funcRef):
        self.CallBackFuncRefMap[keyString] = funcRef

    def KeyHandle_a(self):
        self.CallBackFuncRefMap['a']()


# testing
def callBack_a():
    print "exec: callBack_a"

test_keyHandler = keyHandler()
# bind callBack_a with keyboard event-'a'
test_keyHandler.AddKeyHandle('a', callBack_a)

run()
self.accept('a', self.KeyHandle_a)將鍵盤事件'a'與KeyHandle_a連結。
self.CallBackFuncRefMap是一個call back函數(call back函數不一定會宣告在keyHandler類別內)的hash table,以鍵盤事件名稱為key。經由AddKeyHandle函數新增此hash table的內容,如此便可在self.KeyHandle_a內呼叫。
新增鍵盤事件時,除了增加self.accept( event_name, function )之外,對應於event_name的function也得新增,如同上面的self.accept('a', self.KeyHandle_a)與KeyHandle_a,然而對應的function的內容有很大部分是相同的。因此可利用python於runtime建立函數的功能,將keyHandler類別改寫如下:
class keyHandler(DirectObject):
    def __init__(self):
        self.CallBackFuncRefMap = {}

    def AddKeyHandle(self, keyString, funcRef):
        self.CallBackFuncRefMap[keyString] = funcRef
        def callBackFunc():
            self.CallBackFuncRefMap[keyString]()
        self.accept(keyString, callBackFunc)
於AddKeyHandle函數內建立callBackFunc,並執行self.accept(keyString, callBackFunc)完成鍵盤事件與call back函數的連結。如此新增鍵盤事件只要呼叫AddKeyHandle,而不用在keyHandler類別內新增對程式碼了。

沒有留言: