七牛实训营记录
七牛实训营记录
Overview
- 有时候懒得切输入法可能文章部分会是英语
总的来说,写这篇文章一方面是为了记录一下自己的整体在几个月内做出的内容,一方面也是想分享写具体的技术内容。
这次在七牛做的是一个在线的代码编辑器,其实是goplus builder
这个东东。我们从产品设计开始然后架构然后再是写代码,从头到尾经历了一个“干净”的编程流程,最后我们做出了一个完整的带有许多LSP(Language Server Protocol)功能的在线编辑器。
Goplus builder
What is gop builder?
Go+ Builder is a tool for building games. We create it to help children to learn abilities to build.
Go+ Builder is developed based on spx, which is a game engine built on Go+.
技术总览
我们的前端的架构是Vuejs,同时前端中的编辑器是Monaco,也就是Vscode用的那个。
我们通过使用WASM来给Builder来提供具体的类似于 LSP
的能力,用Go
来写的WASM。
在后端部分我们还结合了AI,Gop
是有一个Web服务协议的,因此后端部分我们用的是Gop
。
一些架构
在架构设计阶段的设计
来自于Markdown
EditorUI
EditorUI 的目标是帮助用户把自身的逻辑快速而完整地通过代码表达出来。 通过在 UI 层面实现并调用不同的功能模块,如文档快速预览、代码高亮分析、AI 答疑解惑以及更便捷的代码补全菜单,来降低初学者的编程门槛,并提高了编码效率。
详见 EditorUI 。
Coordinator
Coordinator 负责协调各个模块之间的交互。管理各个模块的交互以及数据流程,确保整个可扩展性与保证各模块内部只关心内部实现。
- 例子
import { EditorUI as ui } from 'ui'
import { DocAbility as doc } from 'ui'
import { Compiler as compiler } from 'ui'
function documentImplement() {
ui.registerHoverProvider({
async providerHover(model, ctx) {
const word = model.getValueInRange(ctx.position)
const id = compiler.getDefinition()
const content = await doc.getNormalDoc(id)
const moreActions: Action[] = []
const detailContent = await doc.getDetailDoc(id)
if (detailContent != null) {
moreActions.push({
icon: IconEnum.Document,
label: "xxx",
onClick: () => {
ui.invokeDocumentDetail("markdown")
}
})
}
const c: LayerContent = {
content: content.content,
moreActions: [
...moreActions
]
}
return c
},
})
}
Compiler
Compiler模块具体利用编译器能力、代码检查等能力负责对代码、proj部分进行解析并生成AST树,并根据AST进行生成类型,实现基于wasm提供。
目前Complier 负责向UI模块提供其所需要的四种功能,分别是:
- 获取行内提示
- 获取错误提示
- 获取补全列表
- 获取Token类型
- 对外接口
interface Compiler {
// List
getInlayHints(codes: Code[]): InlayHint[]
getDiagnostics(codes: Code[]): Diagnostic[]
getCompletionItems(codes: Code[], position: Position): CompletionItem[]
// Single identifier
getDefinition(codes: Code[], position: Position): Identifier | null
}
Runtime
Runtime模块负责在debug模式下负责捕获运行时错误并提供内容让UI组件获取。
- 对外接口
interface Runtime {
OnRuntimeErrors(cb: (errors: RuntimeError) => void): Dispose;
}
Doc
文档是指以Markdown格式提供的,对spx与gop关键字等代码Token的解释型文档,通过维护文档可以向用户展示功能与代码的解释。文档内容分层为简略文档和详细文档,以满足不同界面形式对不同信息量的对应。
-
目前 目前文档直接维护在前端代码中,内部实现仅为一个文档获取的函数。
-
未来
考虑到未来社区支持,社区作者对其文档的可配置性需求,未来考虑增加后端数据存储支持。
- 对外接口
interface DocAbility{
getNormalDoc(token: Token): Doc | null
getDetailDoc(token: Token): Doc | null
}
Project
用到所有Project的地方都可以由项目中原有的Project类实现。因此目前只需要复用即可。
- 对外接口(已有)
interface Project {
// 获取项目中的精灵代码、背景代码
getProjectCode(): Code[] //现有:exportGameFiles
// project file hash
getFileHash(): string // 现有 filesHash
// project context
getContext(): ProjectContext // 现有 Project.name, Sprite.name[]
// rename
Sprite: {
setName(name: string): void
},
// ...otherAssetsName(Sound, Stage)
}
Chatbot
用于负责与AI交流的部分,提供开启一个会话与继续发送消息的能力。提供了 解释、添加注释、修复代码 这三个对话功能。
export interface ChatBot {
startExplainChat(input: Input): Chat
startCommentChat(input: Input): Chat
startFixCodeChat(input: Input): Chat
}
Suggest
建议模块负责提供一个利用LLM来生成代码建议的功能,内部通过传入代码与光标位置对代码进行补全式生成。
export interface Suggest {
startSuggestTask(input: Input): SuggestItem[]
}
收货
总的来说,我们小组通过这次实训营,不仅仅是锻炼到我们的代码能力,同时也是锻炼到我们的综合的架构思维,逻辑思维等等,我们的带教导师寒星也是非常非常好的,非常耐心并且给出的思路能起到让我们点拨开云雾般的感觉,属于是能力非常非常厉害。
并且我们不仅仅在前端的部分得到锻炼,还在Gop的部分,甚至于亲自通过使用Compiler相关的一些能力,让我们的编码能力也在多维得到了很好的锻炼。
#七牛云#