在編程中基于事件驅動(dòng)的好處
在這幾天的編程里,我發(fā)現了一個(gè)程序如果是基于事件驅動(dòng)的,那么編程起來(lái)將會(huì )很簡(jiǎn)單。比如在輸入命令行遇到回車(chē)時(shí)向框架發(fā)送一個(gè)ON_CMD_OK消息,那么框架就會(huì )立即處理ON_CMD_OK消息,而無(wú)需再去檢測命令輸入到了什么地方,在框架定時(shí)器到達時(shí),框架也會(huì )呼叫我們事先約定好的處理程序,為我們省略了很多細節的麻煩。 要編寫(xiě)基于事件的程序,首先需要理解函數指針,和char指針一樣,它保存了一個(gè)函數的地址,調用指針指向的函數和調用函數一樣。例如:(我的例程是這樣的) typedef void (*PROC)(MESSAGE_STYLE style,MESSAGE param);// 定義函數類(lèi)型,形參為MESSAGE枚舉; PROC fun; static void nullFunction(MESSAGE_STYLE style,MESSAGE param)// 空函數 { printf("nullFunction is called ."); } void main() { fun = nullFunction;// 將指針指向nullFunction; fun(ON_KEYDOWN,WM_0);// 通過(guò)指針調用函數 } 那么,在這個(gè)主程序里,nullfunction將收到ON_KEYDOWN和WM_0,意思是按鍵0被按下,調用nullFunction處理。 ON_KEY_DOWN是一個(gè)我們預先定義的消息類(lèi)型枚舉,WM_0也一樣。 當然了,在實(shí)際的編程里不會(huì )像這個(gè)那么簡(jiǎn)單,我們需要一個(gè)數組來(lái)保存指針,然后將消息逐個(gè)派遣,讓想知道這個(gè)消息的所有程序都能知道這個(gè)按鍵被按下了,然后進(jìn)行相應的處理。 是否明白點(diǎn)了呢?.... 后來(lái)我有個(gè)重大發(fā)現 一直以來(lái),我都是使用形參來(lái)傳遞消息參數,我的PROC原來(lái)是這樣定義的:PROC (*fun)(MESSAGE_TYPE type, MESSAGE param); 在我的Delegate里,消息通過(guò)send()函數將會(huì )歷遍所有消息回調,如果我在第一個(gè)回調里增加了一個(gè)回調,那么在這個(gè)回調結束后,新增加的回調也會(huì )收到這個(gè)消息,這不是我希望的結果(我在菜單里選擇了2號菜單,而2號菜單是個(gè)命令提示符,那么在增添命令提示符后字符'2'這個(gè)消息會(huì )傳遞給CMD,那么在進(jìn)入CMD程序之前,CMD實(shí)際上已經(jīng)添加了2這個(gè)字符在命令行里)。經(jīng)過(guò)我的反復思考,我參考了C#的做法,把后面兩個(gè)參數改為引用類(lèi)型,改為:PROC (*fun)(MESSAGE_TYPE type, MESSAGE ?m); 那么在第一個(gè)回調里增加另外一個(gè)回調的同時(shí),把param設置為WM_NULL,就不會(huì )發(fā)生上面的情況,而且將更加靈活,我增加了WM_HANDLED,在框架檢測到這個(gè)消息后,會(huì )放棄之后的回調,因為框架已經(jīng)知道這個(gè)消息已經(jīng)不再需要后面的程序處理了。呵呵,總算解決了一個(gè)問(wèn)題。也算是從C#里發(fā)現的一個(gè)重大收獲。經(jīng)過(guò)這樣的改造,CPU占用率更低了,而且深度的內存堆棧也少了些,可以使用更多的內存做別的任務(wù)。 八卦一下 PT2313。這是我的第二個(gè)AVR的作品。我用MEGA8是因為它的功能深深的吸引著(zhù)我。以前用51的時(shí)候,I2C需要單獨來(lái)編寫(xiě)一個(gè)程序來(lái)驅動(dòng),ADC需要外置?,F在好了,MEGA8為我解決了這個(gè)問(wèn)題,使得我現在的版本比以前有了很大的進(jìn)步,無(wú)論是在體積上還是性能上都有顯著(zhù)的提高。讓大家來(lái)分享一下
評論