摘要:系統(tǒng)在初始化時,會加載所有,然后分別在和生成對應(yīng)的。那么在中,又是如何將上述的生成為開發(fā)者直接使用的接口的呢下面就為大家介紹我們引入的。它接受一個對象,然后會遍歷原型鏈中的對象,并且分別按照和去生成一個叫的對象,最后將這個對象返回給開發(fā)者。
在 Node.js 社區(qū)中,其實不乏通過 Markdown 生成 RESTful API 的框架,按照一定的格式約定好 API 所需要的數(shù)據(jù),然后再通過解析 Markdown 文檔,將這些關(guān)鍵數(shù)據(jù)提取出來,最后生成數(shù)據(jù)庫模型和 HTTPS 服務(wù)。
YodaOS 作為一個前端操作系統(tǒng),同樣使用了類似的技術(shù)。YodaOS 中的應(yīng)用分為:lightapp 和 extapp,前者是集成在語音交互運行時(Vui-daemon)進程內(nèi)部的輕應(yīng)用,它主要是用于一個交互簡單,需要快速響應(yīng)的場景,比如音量控制、系統(tǒng)控制等。后者作為一個獨立的進程,通過 Child Process 與主進程通訊,使用場景主要是音樂、游戲、電話等需要長時期使用的應(yīng)用。
為什么要有輕應(yīng)用?輕應(yīng)用更像是一個腳本,每當(dāng)用戶一次進行一次交互,只需要從預(yù)先加載的腳本中調(diào)用定義在對應(yīng)腳本的函數(shù)即可完成一次響應(yīng),往往這類應(yīng)用交互比較簡單,如果為此要創(chuàng)建在每次交互的過程中進行一次
ipc 甚至 fork 時,無論對性能還是內(nèi)存來說,都是比較浪費的。
在設(shè)計之初,我們期望對于開發(fā)者來說,并不需要針對不同類型的應(yīng)用,只需要在 package.json 中修改類型即可,YodaOS API 應(yīng)當(dāng)保持完全一致。這樣的話,我們則面對一個問題,即使是能做到高度抽象,也需要在每次新增一個接口時,修改兩處代碼,這其實是有違我們的設(shè)計初衷的。
**
API Descriptor**
為此,我們引入了 API Descriptor 的概念:https://github.com/yodaos-pro...??梢园阉醋魇怯?JavaScript 寫的 DSL,它用于描述每個 YodaOS API,包括命名空間、事件、方法等定義。系統(tǒng)在初始化時,會加載所有 API Descriptor,然后分別在 lightapp 和 extapp 生成對應(yīng)的 API。
Object.assign(ActivityDescriptor.prototype,
{
/** * When the app is active. * @event yodaRT.activity.Activity#active */ active: { type: "event" }, /** * When the Activity API is ready. * @event yodaRT.activity.Activity#ready */ ready: { type: "event" }, /** * When an activity is created. * @event yodaRT.activity.Activity#create */ created: { type: "event" }
}
)
上面的代碼分別定義了 Activity 中的幾個事件:active、ready 和 create。因此,在任何應(yīng)用中都可以這樣寫:
module.exports = activity => {
activity.on("active", () => console.log("app activated"))
activity.on("ready", () => console.log("app is ready"))
activity.on("created", () => console.log("app is created"))
}
接下來我們再看看“方法”是如何定義:
Object.assign(ActivityDescriptor.prototype,
{
/** * Get all properties, it contains the following fields: * - `deviceId` the device id. * - `deviceTypeId` the device type id. * - `key` the cloud key. * - `secret` the cloud secret. * - `masterId` the userId or masterId. * * @memberof yodaRT.activity.Activity * @instance * @function get * @returns {Promise
}
)
可以看到,與定義事件的方式一樣,只需要在 Descriptor 的原型鏈中,增加對應(yīng)的對象,然后設(shè)置類型(type)為 method 即可,然后在 fn 中實現(xiàn)函數(shù)。
module.exports = activity => {
activity.get().then(
(data) => console.log("credentialse is", data), (err) => console.error("something went wrong", err))
}
這樣除了 API 定義可以統(tǒng)一起來了,也能比較方便地基于 JSDoc 生成統(tǒng)一的 API Reference 給開發(fā)者,使得整個 API 的修改能做到簡單易讀、門檻低和修改成本低等。
**
API Translator**
那么在 YodaOS 中,又是如何將上述的 Descriptor 生成為開發(fā)者直接使用的接口的呢?下面就為大家介紹我們引入的 Translator。
Translator 是按照我們支持的應(yīng)用類型對應(yīng)的,因此對于 lightapp 和 extapp 來說,我們也分為兩個 translator:
進程內(nèi)的 https://github.com/yodaos-pro...
進程間的 https://github.com/yodaos-pro...
本文并不具體展開每個 translator 的工作原理,但會做一些簡單的流程介紹。以 translator-ipc 為例:
module.exports.translate = translate
function translate (descriptor) {
if (typeof process.send !== "function") {
throw new Error("IpcTranslator must work in child process.")
}
var activity = PropertyDescriptions.namespace(null, descriptor, null, null)
listenIpc()
return activity
}
每個 translator 提供一個函數(shù),即 translate(descriptor)。它接受一個 descriptor 對象,然后會遍歷原型鏈中的對象,并且分別按照 namespace、event 和 method 去生成一個叫 activity 的對象,最后將這個對象返回給開發(fā)者。
當(dāng)開發(fā)者在使用某個 API 時,activity 對象會按照 translator 預(yù)先生成(約定)好的邏輯調(diào)用到服務(wù)端(Vui-daemon),最后再通過 Promise 返回調(diào)用后的結(jié)果,從而完成一次接口調(diào)用。
**
后記**
本文簡單介紹了 YodaOS 在 API 設(shè)計過程中,如何利用 DSL,解決 YodaOS API 在多種應(yīng)用形態(tài)保持一致性。以此,我們希望拋磚引玉:
幫助讀者更好地了解 YodaOS API 的生成過程
幫助讀者了解到 DSL,也能將這種思路應(yīng)用在自己的項目中
如有更多問題,歡迎評論,或者直接在 GitHub 上給我們提問題:Build software better, together
**
參考**
D-Bus introspection:Introspection - Using of D-Bus
YodaOS:YODAOS Project
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/102911.html
摘要:接下來,由會通過上傳音頻數(shù)據(jù),云端通過一系列算法最終將語音數(shù)據(jù)轉(zhuǎn)換為兩部分結(jié)果純文本,表示這段音頻數(shù)據(jù)中用戶所說的話,比如若琪今天的天氣。 本文是面向 Web 開發(fā)者所寫,介紹關(guān)于語音交互的一篇科普性質(zhì)的文章,希望借助這篇文章,讓開發(fā)者了解到什么是語音交互,以及在 YodaOS 中的技術(shù)實現(xiàn)。不了解YodaOS是什么?點擊這里回顧。 作為 Web 開發(fā)者,相信在面試時常會被問到瀏覽器輸...
摘要:的架構(gòu)跟類似,從下至上,由系統(tǒng)服務(wù)和應(yīng)用框架組成。依托于提供的運行時,從到現(xiàn)在的和,在構(gòu)建工具領(lǐng)域,社區(qū)也不斷涌現(xiàn)出非常卓越的開源項目來。 大家好,很開心在這里宣布 YodaOS 開源了。他將承載 Rokid 4年以來對于人工智能和語音交互領(lǐng)域的沉淀,并選擇 Node.js 作為操作系統(tǒng)的一等開發(fā)公民,全部開放給社區(qū)。 showImg(https://segmentfault.com/...
摘要:月號,杭州和聯(lián)合主辦的第八期技術(shù)分享會,在公司如期舉行。張偉林,宋小菜資深前端開發(fā)工程師,年,霹靂迷,已手殘的紙牌魔術(shù)師,喜歡神奇的東西,技術(shù)棧從上向下不斷橫向縱向貫穿,目前在尋找前后端大一統(tǒng)思想的路上越走越偏。 showImg(https://segmentfault.com/img/bVbkWN4?w=3000&h=1686); 12 月 9 號,杭州 NodeParty 和 Ro...
摘要:為了能讓感興趣的開發(fā)者小伙伴第一時間體驗到,聯(lián)合社區(qū)趕在春節(jié)前發(fā)起開發(fā)套件試用征集活動,該套件是基于自研語音解決方案平臺打造而成。與此同時,我們也同樣提供高度定制化模塊化的整體架構(gòu),開發(fā)者亦可方便地選擇想要集成的模塊對整個操作系統(tǒng)重新組裝。 1月28日,Rokid為人機交互設(shè)備開發(fā)的開源人工智能操作系統(tǒng)——YodaOS正式上線,可用于智能音箱、智能家居、智能穿戴和車載等多種設(shè)備和場景。...
摘要:為了能讓感興趣的開發(fā)者小伙伴第一時間體驗到,聯(lián)合社區(qū)趕在春節(jié)前發(fā)起開發(fā)套件試用征集活動,該套件是基于自研語音解決方案平臺打造而成。與此同時,我們也同樣提供高度定制化模塊化的整體架構(gòu),開發(fā)者亦可方便地選擇想要集成的模塊對整個操作系統(tǒng)重新組裝。 1月28日,Rokid為人機交互設(shè)備開發(fā)的開源人工智能操作系統(tǒng)——YodaOS正式上線,可用于智能音箱、智能家居、智能穿戴和車載等多種設(shè)備和場景。...
閱讀 3242·2021-10-13 09:40
閱讀 3725·2019-08-30 15:54
閱讀 1322·2019-08-30 13:20
閱讀 3003·2019-08-30 11:26
閱讀 487·2019-08-29 11:33
閱讀 1113·2019-08-26 14:00
閱讀 2370·2019-08-26 13:58
閱讀 3381·2019-08-26 10:39