這一篇我們來(lái)聊聊關(guān)于事件的派發(fā)機(jī)制,狀態(tài)機(jī)要真正的被激活進(jìn)行相應(yīng)的處理是需要事件的輸入的??梢园阉醋魇鞘录南M(fèi)者,事件的生產(chǎn)者和消費(fèi)者之間不能通過(guò)共享全局變量的方式來(lái)進(jìn)行信息交換,這好像是我們前面講的QP開(kāi)發(fā)應(yīng)用程序的第一條準(zhǔn)則,因此需要有人來(lái)承接事件傳輸?shù)娜蝿?wù),這個(gè)由QF框架來(lái)負(fù)責(zé)。
QF框架提供了兩種事件的派發(fā)機(jī)制:
第一種、直接發(fā)送事件機(jī)制。這種是最實(shí)用的機(jī)制,他的原理很簡(jiǎn)單,事件產(chǎn)生者,直接將事件發(fā)送給事件的消費(fèi)者(活動(dòng)對(duì)象)事件的生產(chǎn)者有很多,例如ISR、設(shè)備驅(qū)動(dòng)代碼、運(yùn)行在框架之外的代碼。但是事件的消費(fèi)者只能是活動(dòng)對(duì)象,為什么?因?yàn)槭录g的通信是異步的,只有活動(dòng)對(duì)象擁有事件隊(duì)列。QPC6.9.1中給出了三種直接發(fā)送事件的API,如下圖:
然而其API中,關(guān)于這個(gè)函數(shù)有什么區(qū)別以及怎么用只是很簡(jiǎn)單的提了提,并不是很詳細(xì),所以我們?nèi)炙阉髁苏麄€(gè)源碼包中,所有使用到的API,挑幾個(gè)有代表性的應(yīng)用是來(lái)看下:
第二種、發(fā)行-訂閱機(jī)制。這一種是比較高級(jí)的用法,假如你第一次接觸QP并且沒(méi)有RTOS編程的經(jīng)驗(yàn),第一次接觸QP建議你先忽略掉這種方法,會(huì)第一種就足夠了,你在實(shí)際應(yīng)用中完全可以通過(guò)第一種用法,解決繁瑣問(wèn)題,當(dāng)然有些場(chǎng)合應(yīng)用第二種方法會(huì)簡(jiǎn)便很多,例如一個(gè)活動(dòng)對(duì)象要發(fā)送一個(gè)事件給很多其它的活動(dòng)對(duì)象時(shí),應(yīng)用第一種,你需要知道每個(gè)活動(dòng)對(duì)象的名字(指針)這樣要進(jìn)行很多次的發(fā)送操作,然而應(yīng)用第二種時(shí),你只需要告訴QF框架,你要發(fā)行某個(gè)事件,至于發(fā)給誰(shuí)那就要QF框架自己看看都有誰(shuí)(哪個(gè)活動(dòng)對(duì)象訂閱了這個(gè)事件了)
發(fā)行訂閱機(jī)制有個(gè)需要注意的點(diǎn),就是QF框架需要記住訂閱者的信息, 當(dāng)接收到某事件發(fā)行的信號(hào)時(shí),需要查找這個(gè)記錄集合,找到某事件對(duì)應(yīng)的活動(dòng)對(duì)象,這樣才能完成指定的發(fā)送。這個(gè)記錄的結(jié)構(gòu)體集合在QPC6.9.1的說(shuō)明,如下圖:
講到這里了,其實(shí)可以筆鋒一轉(zhuǎn),接著講API ,然后后面是例子中的應(yīng)用了,但是甘心嗎?你不想知道這個(gè)發(fā)行訂閱機(jī)制是怎么實(shí)現(xiàn)的嗎?哈哈,雖然可能會(huì)有點(diǎn)混亂,但是那就讓我們混亂下去吧,接下來(lái)讓我們深度解析一下,這個(gè)我不推薦新手用的發(fā)行訂閱機(jī)制,QF框架是怎么找到對(duì)應(yīng)活動(dòng)對(duì)象的(面對(duì)疾風(fēng)吧~?。?/strong>,其實(shí),他是通過(guò)查表法來(lái)實(shí)現(xiàn)的,先來(lái)講原理,看一下他的表圖構(gòu)造:
首先這是一個(gè)二維表,縱向是事件,不同的事件放在不同的位置上,橫向的每個(gè)bit上代表活動(dòng)狀態(tài)機(jī)的優(yōu)先級(jí),因?yàn)榛顒?dòng)對(duì)象的優(yōu)先級(jí)是唯一的,所以可以通過(guò)它找到對(duì)應(yīng)的對(duì)象,在QP量子編程中,一個(gè)應(yīng)用里面最多有64個(gè)狀態(tài)機(jī),一個(gè)應(yīng)用會(huì)有多少個(gè)事件呢,好像沒(méi)有嚴(yán)格限制。接下來(lái)看一下這個(gè)結(jié)構(gòu)集合的定義:
從上面可以看到他定位的是一個(gè)一維表,或者叫一維數(shù)組,他只有活動(dòng)對(duì)象方向,并不完整,它還需要縱向的事件維度,這里其實(shí)它把控制權(quán)交給了我們的應(yīng)用,因?yàn)槟阕畲笮枰嗛啂讉€(gè)事件,那么你就定義一個(gè)特定大小的數(shù)組,如下:
定義好了我們的事件-對(duì)象二維表以后,在使用前,我們需要先把他初始化,QF提供了專門(mén)的API來(lái)完成該部分內(nèi)容:
完成初始化以后,我們就可以使用訂閱API函數(shù),訂閱某個(gè)事件了,同樣也可以使用發(fā)行事件API,進(jìn)行事件的發(fā)布:
對(duì)于發(fā)行-訂閱機(jī)制,又訂閱就有解除訂閱,解除訂閱可以是為某個(gè)活動(dòng)對(duì)象解除特定事件的訂閱,也可以清空某個(gè)對(duì)象的所有訂閱,如下:
到這里關(guān)于事件的派發(fā)機(jī)制相關(guān)內(nèi)容都分析完了,看到這里如果你也很感興趣,不妨自己找個(gè)demo實(shí)踐一下筆記中給大家講解的相關(guān)理論是否正確,下篇再見(jiàn)。