@virid/renderer
v0.3.3
Published
Electron renderer process adapter for virid, responsible for forwarding and receiving messages from the main process
Downloads
836
Readme
@virid/renderer
@virid/renderer 是electron应用的渲染进程适配器,提供ToMainMessage和FromMainMessage的自动路由功能与主进程报道功能。
🌟 核心设计理念
在 @virid/renderer 中,渲染进程朝主进程发送消息被抽象为ToMainMessage,该消息可以直接通过调度器分发,消息将会通过IPC直接传送到主进程或其他渲染进程并触发对应的System。主进程朝渲染进程发送的消息被抽象为FromMainMessage,一旦主进程发送了对应的消息,FromMainMessage将会自动被投递到调度器触发相应的渲染进程System。
- 路由自动注册:渲染进程窗口开启后,自动向主进程注册自身,以后所有的消息都将携带自身的窗口信息。
- 类型恢复:消息在通过IPC通道后,恢复成真正的Message类重新进入
@virid/core并被调度器识别并分发。实现不同进程的位置无关性。 - 消息定向与广播:可以通过其他渲染进程的ID来实现定向通信,或者使用*来广播消息。
🔌启用插件
import { createVirid } from "@virid/core";
import { RenderPlugin } from "@virid/renderer";
const app = createVirid();
//需要给每个窗口指定一个唯一的windowId来向主进程报道
app.use(RenderPlugin, {
windowId: "renderer",
});🛠️ @virid/renderer 核心 API 概览
ToMainMessage
- 功能:一个特殊的消息基类,可被继承。所有继承自
ToMainMessage的Message将被发往其他进程 - 逻辑:该消息类型需要两个特殊标记,
__virid_target标记了目的地,__virid_message_type标记了在目的地应该被还原为的Message类型 - 示例:
//在渲染进程
import { ToMainMessage } from "@virid/renderer";
// __virid_target=‘main’,说明消息需要发往主进程
// 当指定__virid_target=‘*’时,消息将会对所有渲染进程广播
// __virid_message_type: string = 'close-window',描述了在主进程,该消息将会重新变为的类型
export class CloseWindowMessage extends ToMainMessage {
__virid_target = "main";
__virid_message_type: string = "close-window";
}
export class MinimizeWindowMessage extends ToMainMessage {
__virid_target = "main";
__virid_message_type: string = "minimize-window";
}
export class MaximizeWindowMessage extends ToMainMessage {
__virid_target = "main";
__virid_message_type: string = "maximize-window";
}在主进程,可以通过@FromRender结合FromRenderMessage来实现对应的转换。详情见@virid/main 。
//在主进程
import { FromRenderMessage, FromRenderer, ToRenderMessage } from "@virid/main";
//这里的每个id都和渲染进程的消息对应
@FromRenderer("close-window")
export class CloseWindowMessage extends FromRendererMessage {}
@FromRenderer("minimize-window")
export class MinimizeWindowMessage extends FromRendererMessage {}
@FromRenderer("maximize-window")
export class MaximizeWindowMessage extends FromRendererMessage {}
// 通过这三个System,可以实现所有窗口的最小化、最大化、关闭功能
// senderWindow为发送消息的窗口本身
export class WindowSystem {
@System()
closeWindow(@Message(CloseWindowMessage) message: CloseWindowMessage) {
message.senderWindow.close();
}
@System()
minimizeWindow(
@Message(MinimizeWindowMessage) message: MinimizeWindowMessage,
) {
message.senderWindow.minimize();
}
@System()
maximizeWindow(
@Message(MaximizeWindowMessage) message: MaximizeWindowMessage,
) {
if (message.senderWindow.isMaximized()) {
message.senderWindow.unmaximize();
} else {
message.senderWindow.maximize();
}
}
}FromMainMessage/@FromIpc()
- 功能:一个特殊的消息基类,可被继承。所有继承自
FromMainMessage的Message将在主进程发送消息时自动转换并投递到当前进程的virid调度中心 - 逻辑:
@FromIpc()接受一个字符串类型的ID,该ID与主进程中发送的ToRendererMessage的ID应该相同。 - 示例:
//在渲染进程
import { FromIpc, FromMainMessage, ToMainMessage } from "@virid/renderer";
@FromIpc("file-dialog")
class ChooseBgImageMessage extends FromMainMessage {
constructor(public path: string) {
super();
}
}
class OpenDialogMessage extends ToMainMessage {
__virid_target: string = "main";
__virid_message_type: string = "open-dialog";
constructor(
public options: {
title?: string;
filters?: Array<{ name: string; extensions: string[] }>;
properties?: Array<
"openFile" | "openDirectory" | "multiSelections" | "showHiddenFiles"
>;
},
) {
super();
}
}在主进程,可以通过@FromRender结合FromRenderMessage来实现对应的转换。详情见@virid/main 。
//在主进程
import {
FromRendererMessage,
FromRenderer,
ToRenderMessage,
} from "@virid/main";
// @FromRender('open-dialog')表明,当上面的渲染进程调用OpenDialogMessage.send(options)时
// 主进程的OpenDialogMessage将被自动投递,因此下面的openDialog System将被virid自动调用
// 当openDialog执行完毕,将返回一个RenderDialogMessage,该RenderDialogMessage标记了目的地与类型
// 其会转换为渲染进程的OpenDialogMessage并触发渲染进程的System或者Listener执行
@FromRenderer("open-dialog")
export class OpenDialogMessage extends FromRendererMessage {
constructor(
public options: {
title?: string;
filters?: Array<{ name: string; extensions: string[] }>;
properties?: Array<
"openFile" | "openDirectory" | "multiSelections" | "showHiddenFiles"
>;
},
) {
super();
}
}
export class RenderDialogMessage extends ToRendererMessage {
__virid_target: string = "renderer";
__virid_message_type: string = "file-dialog";
constructor(public path: string) {
super();
}
}
export class WindowSystem {
@System()
async openDialog(@Message(OpenDialogMessage) message: OpenDialogMessage) {
// 调用原生对话框
const result = await dialog.showOpenDialog(
message.senderWindow,
message.options,
);
// 如果用户没有取消,并且确实选择了文件
if (!result.canceled && result.filePaths.length > 0) {
const selectedPath = result.filePaths[0];
return new RenderDialogMessage(selectedPath);
}
return;
}
}