如视 Five SDK
    Preparing search index...

    插件系统 (Plugin System)

    • Summary: Five 插件系统基于 BasePlugin 命名空间构建,提供了一套标准化的状态管理、生命周期控制和事件通信机制。
    • Schema: 核心类型定义位于 BasePlugin 命名空间。
    • Concepts: BasePlugin, State, Lifecycle, Controller.
    • Configuration: 插件特定的参数配置。
    • Examples: 标准插件开发示例。

    Definition: BasePlugin

    BasePlugin 是一个命名空间,包含 Controller (抽象基类), State (状态接口), EventMap (事件映射) 等核心定义。

    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>
    // ...
    }
    }

    一个标准的插件通常包含以下文件:

    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 为例。

    定义插件所需的参数、状态、数据和事件类型。

    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 并实现核心逻辑。

    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)
    }
    }

    提供一个工厂函数。

    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. 清理资源: 在 disabledispose 中务必清理所有事件监听和副作用,防止内存泄漏。
    3. 类型安全: 充分利用 TypeScript 泛型,确保事件和状态的类型安全。

    tags: [插件, 插件开发, 扩展, 自定义功能, 状态管理, plugin, baseplugin, development, guide, extension, lifecycle]