GacUI:初步完成Workflow腳本轉C++的工作
Workflow作為一個腳本語言,他唯一的功能就是跟C++對象通信。所以Workflow對類型的支持也是直接照搬C++。這個腳本語言不僅可以調用C++的類,也可以被C++的類調用,你甚至可以在腳本裡面創建一個類,多重繼承自C++的介面和其他類,最後實例化成一個C++的介面的指針,丟給C++使用。Workflow與C++的交互是完全的。
之所以Workflow需要這麼強大的與C++交互的功能,是因為GacGen.exe會把你的XML文件完全編譯成Workflow腳本。這些腳本的內容其實就是幾個繼承自GuiWindow或者GuiCustomControl的類,然後類的構造函數會去創建你的子控制項,設置好你的數據綁定,最終創建一個GuiWindow*的對象給你用。所以GacUI用到了C++的什麼功能,Workflow就必須能夠使用C++的什麼功能。
為了做到這一點,我做了一個C++的反射。這個反射唯一的作用就是為了讓Workflow存在。反射的內容有很多,你可以註冊你自己的類、成員函數、屬性、事件和介面,每一個類型最終變成一個ITypeDescriptor的實例。因此你就可以使用這個對象來調用函數,甚至是創建一個介面的實現,還有動態生成一個從C++的類繼承下來的新類型等等。GacUI的代碼本來就很多,所以反射需要的代碼就更多,實際上release模式下那個16M的exe的其中15M就是在做這些事情的。
但是我相信絕大多數GacUI的程序都不需要動態載入UI的能力,所以實際上這個反射就完全沒有用。但是沒有反射Workflow又跑不了。所以我就想到了一個最簡單的解決方法:只要能把Workflow編譯成C++,那你直接把這些代碼文件鏈接進去就可以了!
於是到了今天為止,我就完成了Workflow到C++翻譯的基本工作。有單元測試就是好啊,只要我把所有單元測試裡面的Workflow代碼都翻譯成C++,然後也能運行通過,最後檢查一下code coverage沒問題,那我對我的轉換程序就有足夠的信心了。大家可以在 vczh-libraries/Workflow 看到我所有的測試用例,以及在 vczh-libraries/Workflow 看到所有生成的C++代碼。
當然這只是第一階段的工作,為了方便C++代碼的生成,因此就產生了很多多餘的字元,把代碼搞得很難看。不過反正生成出來的代碼是不應該被閱讀的,所以如何美化他就變成一個平行的、不緊急的、低優先順序的工作了。為什麼要去管那些不需要閱讀的代碼是不是好看呢?哈哈哈哈哈哈。
當然僅僅是這樣的翻譯還是不夠的。接下來我還會繼續開發GacGen.exe,讓它生成的代碼可以自動merge用戶修改的代碼(主要指的是用戶插入事件處理函數的能力),最終讓XML開發的UI擺脫15M的反射,輕鬆愉快地跑起來。這樣用戶就有兩個選擇,不需要動態特性的就全部生成C++鏈接進程序里,需要動態特性的就留下Workflow的byte code在資源文件裡面,不生成C++代碼。
說實話,最近這幾個星期再做這個事情的時候,我感覺十分的無聊。這種完全沒有挑戰性的苦力業務代碼寫起來就是很不爽的,但是又不得不寫。我覺得這就可以回答之前在知乎上提到的一個問題。什麼是純業務邏輯的代碼?這(vczh-libraries/Workflow)就是純業務邏輯的代碼。這種代碼只要你心情好,手的乳酸不要積累太多,一天要寫多少行都可以,完全不需要經過大腦思考。做這個東西也是我最近不怎麼刷知乎的主要原因,白天工作回來,晚上寫這個都累死了,根本不想動。
推薦閱讀:
※《C++ Primer》讀書筆記-第七章 06 類的靜態成員
※Roman To Integer
※【源碼眾讀】之問題解答,Part_3
※《C++ Primer》讀書筆記-第十二章 02 動態數組
