在TouchGFX中,Callback模板的描述放在Callback.hpp文件中,在此定義了兩組模板:GenericCallback與 Callback模板。
GenericCallback模板組
GenericCallback為Callback模板的模板基類。在GenericCallback模板中,定義了兩個接口函數:isValid與execute;其中isValid是來檢測Callback是否被初始化過,而execute函數用于調用實際要執行的函數。GenericCallback模板組總共定義了4個模板,模板之間的差別在于execute函數的參數個數不同,4個模板分別對應execute函數帶有0個參數,1個參數,2個參數與3個參數。本文中僅列出execute帶一個參數的情況。
下面是execute函數帶1個參數的GenericCallback模板:
Callback模板組
Callback模板由GenericCallback派生而來。Callback模板組也有4個模板,分別對應于包含不同參數個數execute函數的GenericCallback模板,繼承關系如下圖:
下面是execute函數帶1個參數的Callback模板:
在Callback結構中定義了兩個私有的成員指針,pobject為dest_type類型對象的指針,pmemfun_1為dest_type對象的成員函數指針,是指向dest_type類型的成員函數。這樣當Callback結構初始化好了以后,再調用execute函數時,就是直接調用了dest_type類型對象的成員函數pmemfun_1。
在使用Callback模板時,根據模板的特性,C++編譯器會自動選擇最準確的模板匹配,來生成對應的模板類或模板函數。因此在使用Callback模板時,可以使用不同的類型參數個數來匹配使用不同的模板。
頁面切換 - pendingScreenTransitionCallback
在TouchGFX啟動過程中會初始化MVPApplication對象,在MVPApplication類中定義了一個成員pendingScreenTransitionCallback,它是GenericCallback<>*類型的指針,并初始化為0;
TouchGFX會調用handlePendingScreenTransition函數進行頁面切換,最終調用evaluatePendingScreenTransition函數,在此函數中會用isValid()函數來檢查Callback是否已經初始化;如果初始化了,就調用execute函數 (因為Callback為GenericCallback<>*類型,因此execute函數不帶參數) 。
具體的頁面切換過程(進入第一個screen):
在TouchGFX初始化過程中,會初始化FrontendApplication對象app,在此對象的基類中包含一個transitionCallback成員,其類型為:
touchgfx::Callback<FrontendApplicationBase> transitionCallback
在進入第一個Screen時,會調用app.gotoScreen1ScreenNoTransition(),在此函數中,會將pendingScreenTransitionCallback設置為指向transitionCallback的指針,最終由TouchGFX框架調用execute函數,執行makeTransition完成頁面的切換。
// 初始化FrontendApplicationBase::transitionCallback,transitionCallback的私有成員初始化:
// pobject賦值為this(指向FrontendApplicationBase)
// pmemfun_1賦值為 &FrontendApplication::gotoScreen1ScreenNoTransitionImpl
//execute函數內實際執行的函數(pobject->*pmemfun_1)(),即為如下函數:
按鍵響應 - flexButtonCallback
在TouchGFX designer中創建一個Flex Button,并設置interaction后,會在MainViewBase類中創建兩個私有成員:
//按鍵響應函數,實現用戶的動作響應
void flexButtonCallbackHandler(const touchgfx::AbstractButtonContainer& src)
//Callback對象
touchgfx::Callback<MainViewBase, const touchgfx::AbstractButtonContainer&> flexButtonCallback
以及一個按鍵成員(在designer中通過Add Style添加了Image與Text屬性),例如flexButton1:
touchgfx::TextButtonStyle< touchgfx::ImageButtonStyle< touchgfx::ClickButtonTrigger > > flexButton1;
在MainViewBase的構造函數中,會初始化flexButtonCallback成員,并且調用flexButton1->setAction函數,設置此按鍵的AbstractButton::action為flexButtonCallback,
MainViewBase::MainViewBase():flexButtonCallback(this, MainViewBase::flexButtonCallbackHandler)
其中:
flexButtonCallback的pobject成員初始化為this(指向MainViewBase的指針)
flexButtonCallback的pmemfun_1成員初始化為&MainViewBase::flexButtonCallbackHandler
由于flexButtonCallback的類型是
struct Callback<dest_type, T1, void, void> : public GenericCallback<T1>
因此flexButtonCallback的execute函數帶有一個參數,參數類型為const touchgfx::AbstractButtonContainer&,最終此參數會傳遞給flexButtonCallbackHandler函數。
在程序運行時,點擊按鍵后,TouchGFX框架會捕獲此事件,并在AbstractButton::handleClickEvent函數中調用action->execute(*this)函數,最終即執行了flexButtonCallbackHandler函數,實現了用戶的動作響應。