@realsee/five
Version:
Realsee Renderer SDK
211 lines (157 loc) • 5.71 kB
Markdown
- **Summary**: Five 插件系统基于 `BasePlugin` 命名空间构建,提供了一套标准化的状态管理、生命周期控制和事件通信机制。
- **Schema**: 核心类型定义位于 `BasePlugin` 命名空间。
- **Concepts**: BasePlugin, State, Lifecycle, Controller.
- **Configuration**: 插件特定的参数配置。
- **Examples**: 标准插件开发示例。
> **Definition**: [BasePlugin](../../plugins/BasePlugin/index.d.ts)
`BasePlugin` 是一个命名空间,包含 `Controller` (抽象基类), `State` (状态接口), `EventMap` (事件映射) 等核心定义。
```typescript
export namespace BasePlugin {
export interface State {
enabled: boolean
visible?: boolean
config?: unknown
}
export abstract class Controller<PluginState, PluginEventMap, PluginServerData, PluginData> {
public five: Five
public abstract state: PluginState
public hooks: Subscribe<PluginEventMap>
// ...
}
}
```
一个标准的插件通常包含以下文件:
```text
PluginName/
├── index.ts
├── Controller.ts
└── typing.ts
```
所有插件推荐继承 `BasePlugin.Controller`。它定义了规范的泛型接口:
- `PluginState`: 插件状态类型,继承自 `BasePlugin.State`。
- `PluginEventMap`: 插件事件类型,继承自 `BasePlugin.EventMap`。
- `PluginServerData`: 服务端原始数据类型。
- `PluginData`: 解析后的插件数据类型。
插件的状态驱动其行为。`BasePlugin.State` 定义了最基本的状态:
- `enabled`: 是否启用。
- `visible`: UI 是否可见。
- `config`: 配置项。
插件的主要生命周期方法:
- **constructor**: 初始化配置和初始状态。
- **load**: 加载和解析数据。
- **enable**: 启用插件,注册事件监听,添加副作用。
- **disable**: 禁用插件,移除事件监听,清理副作用。
- **dispose**: 销毁插件,彻底清理资源。
`BasePlugin` 控制器构造函数接受可选的配置对象:
| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `staticPrefix` | `string` | `'//vr-image-4.realsee-cdn.cn'` | 静态资源前缀。 |
| `i18n` | `(key: string) => string` | `undefined` | 国际化转换函数。 |
以创建一个 `MyPlugin` 为例。
定义插件所需的参数、状态、数据和事件类型。
```typescript
import { BasePlugin } from '../BasePlugin'
// 1. 定义参数
export interface Params extends BasePlugin.Config {
initialState?: Partial<State>
config?: Config
}
// 2. 定义配置
export interface Config {
color?: string
}
// 3. 定义状态 (继承 BasePlugin.State)
export interface State extends BasePlugin.State {
activeId?: string
}
// 4. 定义数据类型
export interface ServerData { /* 服务端数据结构 */ }
export interface PluginData { /* 解析后的数据结构 */ }
// 5. 定义事件 (继承 BasePlugin.EventMap)
export interface EventMap extends BasePlugin.EventMap<State, PluginData> {
click: (id: string) => void
}
```
继承 `BasePlugin.Controller` 并实现核心逻辑。
```typescript
import { Five } from '@realsee/five'
import { BasePlugin } from '../BasePlugin'
import * as MyPluginType from './typing'
export class Controller extends BasePlugin.Controller<
MyPluginType.State,
MyPluginType.EventMap,
MyPluginType.ServerData,
MyPluginType.PluginData
> {
public state: MyPluginType.State
constructor(five: Five, params?: MyPluginType.Params) {
super(five)
this.state = {
enabled: true,
visible: true,
...params?.initialState
}
if (this.state.enabled) {
this._enable()
}
}
public async load(serverData: MyPluginType.ServerData) {
// 解析数据
}
public enable() {
if (this.state.enabled) return
this.state.enabled = true
this._enable()
this.hooks.emit('stateChange', { state: this.state, userAction: true })
}
public disable() {
if (!this.state.enabled) return
this.state.enabled = false
this._disable()
this.hooks.emit('stateChange', { state: this.state, userAction: true })
}
public dispose = () => {
this.disable()
this.hooks.emit('dispose')
}
private _enable() {
// five.scene.add(...)
// five.on('tap', this.onTap)
}
private _disable() {
// five.scene.remove(...)
// five.off('tap', this.onTap)
}
}
```
提供一个工厂函数。
```typescript
import { Five } from '@realsee/five'
import { Controller } from './Controller'
import * as MyPluginType from './typing'
export const MyPlugin = (five: Five, params?: MyPluginType.Params) =>
new Controller(five, params)
export type { MyPluginType, Controller as MyPluginController }
```
1. **状态驱动**: 始终通过修改 `state` 来驱动插件行为,而不是直接操作 DOM 或 3D 对象。
2. **清理资源**: 在 `disable` 和 `dispose` 中务必清理所有事件监听和副作用,防止内存泄漏。
3. **类型安全**: 充分利用 TypeScript 泛型,确保事件和状态的类型安全。
---
```yaml
tags: [插件, 插件开发, 扩展, 自定义功能, 状态管理, plugin, baseplugin, development, guide, extension, lifecycle]
```