@realsee/five
Version:
Realsee Renderer SDK
106 lines (99 loc) • 31.1 kB
HTML
<html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>features/plugin | 如视 Five SDK</title><meta name="description" content="Documentation for 如视 Five SDK"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">如视 Five SDK</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">features/plugin</a></li></ul></div><div class="tsd-panel tsd-typography"><h1 id="插件系统-plugin-system" class="tsd-anchor-link">插件系统 (Plugin System)<a href="#插件系统-plugin-system" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1>
<ul>
<li><strong>Summary</strong>: Five 插件系统基于 <code>BasePlugin</code> 命名空间构建,提供了一套标准化的状态管理、生命周期控制和事件通信机制。</li>
<li><strong>Schema</strong>: 核心类型定义位于 <code>BasePlugin</code> 命名空间。</li>
<li><strong>Concepts</strong>: BasePlugin, State, Lifecycle, Controller.</li>
<li><strong>Configuration</strong>: 插件特定的参数配置。</li>
<li><strong>Examples</strong>: 标准插件开发示例。</li>
</ul>
<h2 id="schema" class="tsd-anchor-link">Schema<a href="#schema" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<blockquote>
<p><strong>Definition</strong>: <a href="../../plugins/BasePlugin/index.d.ts">BasePlugin</a></p>
</blockquote>
<p><code>BasePlugin</code> 是一个命名空间,包含 <code>Controller</code> (抽象基类), <code>State</code> (状态接口), <code>EventMap</code> (事件映射) 等核心定义。</p>
<pre><code class="typescript"><span class="hl-10">export</span><span class="hl-1"> </span><span class="hl-3">namespace</span><span class="hl-1"> </span><span class="hl-7">BasePlugin</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-10">export</span><span class="hl-1"> </span><span class="hl-3">interface</span><span class="hl-1"> </span><span class="hl-7">State</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">enabled</span><span class="hl-1">: </span><span class="hl-7">boolean</span><br/><span class="hl-1"> </span><span class="hl-6">visible</span><span class="hl-1">?: </span><span class="hl-7">boolean</span><br/><span class="hl-1"> </span><span class="hl-6">config</span><span class="hl-1">?: </span><span class="hl-7">unknown</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> </span><span class="hl-10">export</span><span class="hl-1"> </span><span class="hl-3">abstract</span><span class="hl-1"> </span><span class="hl-3">class</span><span class="hl-1"> </span><span class="hl-7">Controller</span><span class="hl-1"><</span><span class="hl-7">PluginState</span><span class="hl-1">, </span><span class="hl-7">PluginEventMap</span><span class="hl-1">, </span><span class="hl-7">PluginServerData</span><span class="hl-1">, </span><span class="hl-7">PluginData</span><span class="hl-1">> {</span><br/><span class="hl-1"> </span><span class="hl-3">public</span><span class="hl-1"> </span><span class="hl-6">five</span><span class="hl-1">: </span><span class="hl-7">Five</span><br/><span class="hl-1"> </span><span class="hl-3">public</span><span class="hl-1"> </span><span class="hl-3">abstract</span><span class="hl-1"> </span><span class="hl-6">state</span><span class="hl-1">: </span><span class="hl-7">PluginState</span><br/><span class="hl-1"> </span><span class="hl-3">public</span><span class="hl-1"> </span><span class="hl-6">hooks</span><span class="hl-1">: </span><span class="hl-7">Subscribe</span><span class="hl-1"><</span><span class="hl-7">PluginEventMap</span><span class="hl-1">></span><br/><span class="hl-1"> </span><span class="hl-8">// ...</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<h2 id="concepts" class="tsd-anchor-link">Concepts<a href="#concepts" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<h3 id="directory-structure-目录结构" class="tsd-anchor-link">Directory Structure (目录结构)<a href="#directory-structure-目录结构" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>一个标准的插件通常包含以下文件:</p>
<pre><code class="text">PluginName/
├── index.ts # 插件入口,导出工厂函数和类型
├── Controller.ts # 插件控制器,核心逻辑实现
└── typing.ts # 类型定义
</code><button type="button">Copy</button></pre>
<h3 id="baseplugin" class="tsd-anchor-link">BasePlugin<a href="#baseplugin" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>所有插件推荐继承 <code>BasePlugin.Controller</code>。它定义了规范的泛型接口:</p>
<ul>
<li><code>PluginState</code>: 插件状态类型,继承自 <code>BasePlugin.State</code>。</li>
<li><code>PluginEventMap</code>: 插件事件类型,继承自 <code>BasePlugin.EventMap</code>。</li>
<li><code>PluginServerData</code>: 服务端原始数据类型。</li>
<li><code>PluginData</code>: 解析后的插件数据类型。</li>
</ul>
<h3 id="state-状态" class="tsd-anchor-link">State (状态)<a href="#state-状态" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>插件的状态驱动其行为。<code>BasePlugin.State</code> 定义了最基本的状态:</p>
<ul>
<li><code>enabled</code>: 是否启用。</li>
<li><code>visible</code>: UI 是否可见。</li>
<li><code>config</code>: 配置项。</li>
</ul>
<h3 id="lifecycle-生命周期" class="tsd-anchor-link">Lifecycle (生命周期)<a href="#lifecycle-生命周期" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>插件的主要生命周期方法:</p>
<ul>
<li><strong>constructor</strong>: 初始化配置和初始状态。</li>
<li><strong>load</strong>: 加载和解析数据。</li>
<li><strong>enable</strong>: 启用插件,注册事件监听,添加副作用。</li>
<li><strong>disable</strong>: 禁用插件,移除事件监听,清理副作用。</li>
<li><strong>dispose</strong>: 销毁插件,彻底清理资源。</li>
</ul>
<h2 id="configuration" class="tsd-anchor-link">Configuration<a href="#configuration" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<h3 id="baseplugin-configuration" class="tsd-anchor-link">BasePlugin Configuration<a href="#baseplugin-configuration" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p><code>BasePlugin</code> 控制器构造函数接受可选的配置对象:</p>
<table>
<thead>
<tr>
<th style="text-align:left">Parameter</th>
<th style="text-align:left">Type</th>
<th style="text-align:left">Default</th>
<th style="text-align:left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left"><code>staticPrefix</code></td>
<td style="text-align:left"><code>string</code></td>
<td style="text-align:left"><code>'//vr-image-4.realsee-cdn.cn'</code></td>
<td style="text-align:left">静态资源前缀。</td>
</tr>
<tr>
<td style="text-align:left"><code>i18n</code></td>
<td style="text-align:left"><code>(key: string) => string</code></td>
<td style="text-align:left"><code>undefined</code></td>
<td style="text-align:left">国际化转换函数。</td>
</tr>
</tbody>
</table>
<h2 id="examples" class="tsd-anchor-link">Examples<a href="#examples" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<h3 id="plugin-development-walkthrough-插件开发指南" class="tsd-anchor-link">Plugin Development Walkthrough (插件开发指南)<a href="#plugin-development-walkthrough-插件开发指南" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3>
<p>以创建一个 <code>MyPlugin</code> 为例。</p>
<h4 id="1-定义类型-typingts" class="tsd-anchor-link">1. 定义类型 (typing.ts)<a href="#1-定义类型-typingts" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4>
<p>定义插件所需的参数、状态、数据和事件类型。</p>
<pre><code class="typescript"><span class="hl-10">import</span><span class="hl-1"> { </span><span class="hl-6">BasePlugin</span><span class="hl-1"> } </span><span class="hl-10">from</span><span class="hl-1"> </span><span class="hl-9">'../BasePlugin'</span><br/><br/><span class="hl-8">// 1. 定义参数</span><br/><span class="hl-10">export</span><span class="hl-1"> </span><span class="hl-3">interface</span><span class="hl-1"> </span><span class="hl-7">Params</span><span class="hl-1"> </span><span class="hl-3">extends</span><span class="hl-1"> </span><span class="hl-7">BasePlugin</span><span class="hl-1">.</span><span class="hl-7">Config</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">initialState</span><span class="hl-1">?: </span><span class="hl-7">Partial</span><span class="hl-1"><</span><span class="hl-7">State</span><span class="hl-1">></span><br/><span class="hl-1"> </span><span class="hl-6">config</span><span class="hl-1">?: </span><span class="hl-7">Config</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-8">// 2. 定义配置</span><br/><span class="hl-10">export</span><span class="hl-1"> </span><span class="hl-3">interface</span><span class="hl-1"> </span><span class="hl-7">Config</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">color</span><span class="hl-1">?: </span><span class="hl-7">string</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-8">// 3. 定义状态 (继承 BasePlugin.State)</span><br/><span class="hl-10">export</span><span class="hl-1"> </span><span class="hl-3">interface</span><span class="hl-1"> </span><span class="hl-7">State</span><span class="hl-1"> </span><span class="hl-3">extends</span><span class="hl-1"> </span><span class="hl-7">BasePlugin</span><span class="hl-1">.</span><span class="hl-7">State</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">activeId</span><span class="hl-1">?: </span><span class="hl-7">string</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-8">// 4. 定义数据类型</span><br/><span class="hl-10">export</span><span class="hl-1"> </span><span class="hl-3">interface</span><span class="hl-1"> </span><span class="hl-7">ServerData</span><span class="hl-1"> { </span><span class="hl-8">/* 服务端数据结构 */</span><span class="hl-1"> }</span><br/><span class="hl-10">export</span><span class="hl-1"> </span><span class="hl-3">interface</span><span class="hl-1"> </span><span class="hl-7">PluginData</span><span class="hl-1"> { </span><span class="hl-8">/* 解析后的数据结构 */</span><span class="hl-1"> }</span><br/><br/><span class="hl-8">// 5. 定义事件 (继承 BasePlugin.EventMap)</span><br/><span class="hl-10">export</span><span class="hl-1"> </span><span class="hl-3">interface</span><span class="hl-1"> </span><span class="hl-7">EventMap</span><span class="hl-1"> </span><span class="hl-3">extends</span><span class="hl-1"> </span><span class="hl-7">BasePlugin</span><span class="hl-1">.</span><span class="hl-7">EventMap</span><span class="hl-1"><</span><span class="hl-7">State</span><span class="hl-1">, </span><span class="hl-7">PluginData</span><span class="hl-1">> {</span><br/><span class="hl-1"> </span><span class="hl-5">click</span><span class="hl-1">: (</span><span class="hl-6">id</span><span class="hl-1">: </span><span class="hl-7">string</span><span class="hl-1">) </span><span class="hl-3">=></span><span class="hl-1"> </span><span class="hl-7">void</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<h4 id="2-实现控制器-controllerts" class="tsd-anchor-link">2. 实现控制器 (Controller.ts)<a href="#2-实现控制器-controllerts" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4>
<p>继承 <code>BasePlugin.Controller</code> 并实现核心逻辑。</p>
<pre><code class="typescript"><span class="hl-10">import</span><span class="hl-1"> { </span><span class="hl-6">Five</span><span class="hl-1"> } </span><span class="hl-10">from</span><span class="hl-1"> </span><span class="hl-9">'@realsee/five'</span><br/><span class="hl-10">import</span><span class="hl-1"> { </span><span class="hl-6">BasePlugin</span><span class="hl-1"> } </span><span class="hl-10">from</span><span class="hl-1"> </span><span class="hl-9">'../BasePlugin'</span><br/><span class="hl-10">import</span><span class="hl-1"> </span><span class="hl-3">*</span><span class="hl-1"> </span><span class="hl-10">as</span><span class="hl-1"> </span><span class="hl-6">MyPluginType</span><span class="hl-1"> </span><span class="hl-10">from</span><span class="hl-1"> </span><span class="hl-9">'./typing'</span><br/><br/><span class="hl-10">export</span><span class="hl-1"> </span><span class="hl-3">class</span><span class="hl-1"> </span><span class="hl-7">Controller</span><span class="hl-1"> </span><span class="hl-3">extends</span><span class="hl-1"> </span><span class="hl-7">BasePlugin</span><span class="hl-1">.</span><span class="hl-7">Controller</span><span class="hl-1"><</span><br/><span class="hl-1"> </span><span class="hl-7">MyPluginType</span><span class="hl-1">.</span><span class="hl-7">State</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-7">MyPluginType</span><span class="hl-1">.</span><span class="hl-7">EventMap</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-7">MyPluginType</span><span class="hl-1">.</span><span class="hl-7">ServerData</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-7">MyPluginType</span><span class="hl-1">.</span><span class="hl-7">PluginData</span><br/><span class="hl-1">> {</span><br/><span class="hl-1"> </span><span class="hl-3">public</span><span class="hl-1"> </span><span class="hl-6">state</span><span class="hl-1">: </span><span class="hl-7">MyPluginType</span><span class="hl-1">.</span><span class="hl-7">State</span><br/><br/><span class="hl-1"> </span><span class="hl-3">constructor</span><span class="hl-1">(</span><span class="hl-6">five</span><span class="hl-1">: </span><span class="hl-7">Five</span><span class="hl-1">, </span><span class="hl-6">params</span><span class="hl-1">?: </span><span class="hl-7">MyPluginType</span><span class="hl-1">.</span><span class="hl-7">Params</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-3">super</span><span class="hl-1">(</span><span class="hl-6">five</span><span class="hl-1">)</span><br/><span class="hl-1"> </span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-6">state</span><span class="hl-1"> = {</span><br/><span class="hl-1"> </span><span class="hl-6">enabled:</span><span class="hl-1"> </span><span class="hl-3">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-6">visible:</span><span class="hl-1"> </span><span class="hl-3">true</span><span class="hl-1">,</span><br/><span class="hl-1"> ...</span><span class="hl-6">params</span><span class="hl-1">?.</span><span class="hl-6">initialState</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> </span><span class="hl-10">if</span><span class="hl-1"> (</span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-6">state</span><span class="hl-1">.</span><span class="hl-6">enabled</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-5">_enable</span><span class="hl-1">()</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-3">public</span><span class="hl-1"> </span><span class="hl-3">async</span><span class="hl-1"> </span><span class="hl-5">load</span><span class="hl-1">(</span><span class="hl-6">serverData</span><span class="hl-1">: </span><span class="hl-7">MyPluginType</span><span class="hl-1">.</span><span class="hl-7">ServerData</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-8">// 解析数据</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-3">public</span><span class="hl-1"> </span><span class="hl-5">enable</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-10">if</span><span class="hl-1"> (</span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-6">state</span><span class="hl-1">.</span><span class="hl-6">enabled</span><span class="hl-1">) </span><span class="hl-10">return</span><br/><span class="hl-1"> </span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-6">state</span><span class="hl-1">.</span><span class="hl-6">enabled</span><span class="hl-1"> = </span><span class="hl-3">true</span><br/><span class="hl-1"> </span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-5">_enable</span><span class="hl-1">()</span><br/><span class="hl-1"> </span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-6">hooks</span><span class="hl-1">.</span><span class="hl-5">emit</span><span class="hl-1">(</span><span class="hl-9">'stateChange'</span><span class="hl-1">, { </span><span class="hl-6">state:</span><span class="hl-1"> </span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-6">state</span><span class="hl-1">, </span><span class="hl-6">userAction:</span><span class="hl-1"> </span><span class="hl-3">true</span><span class="hl-1"> })</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-3">public</span><span class="hl-1"> </span><span class="hl-5">disable</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-10">if</span><span class="hl-1"> (!</span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-6">state</span><span class="hl-1">.</span><span class="hl-6">enabled</span><span class="hl-1">) </span><span class="hl-10">return</span><br/><span class="hl-1"> </span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-6">state</span><span class="hl-1">.</span><span class="hl-6">enabled</span><span class="hl-1"> = </span><span class="hl-3">false</span><br/><span class="hl-1"> </span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-5">_disable</span><span class="hl-1">()</span><br/><span class="hl-1"> </span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-6">hooks</span><span class="hl-1">.</span><span class="hl-5">emit</span><span class="hl-1">(</span><span class="hl-9">'stateChange'</span><span class="hl-1">, { </span><span class="hl-6">state:</span><span class="hl-1"> </span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-6">state</span><span class="hl-1">, </span><span class="hl-6">userAction:</span><span class="hl-1"> </span><span class="hl-3">true</span><span class="hl-1"> })</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-3">public</span><span class="hl-1"> </span><span class="hl-5">dispose</span><span class="hl-1"> = () </span><span class="hl-3">=></span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-5">disable</span><span class="hl-1">()</span><br/><span class="hl-1"> </span><span class="hl-3">this</span><span class="hl-1">.</span><span class="hl-6">hooks</span><span class="hl-1">.</span><span class="hl-5">emit</span><span class="hl-1">(</span><span class="hl-9">'dispose'</span><span class="hl-1">)</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-3">private</span><span class="hl-1"> </span><span class="hl-5">_enable</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-8">// five.scene.add(...)</span><br/><span class="hl-1"> </span><span class="hl-8">// five.on('tap', this.onTap)</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-3">private</span><span class="hl-1"> </span><span class="hl-5">_disable</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-8">// five.scene.remove(...)</span><br/><span class="hl-1"> </span><span class="hl-8">// five.off('tap', this.onTap)</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
</code><button type="button">Copy</button></pre>
<h4 id="3-导出插件-indexts" class="tsd-anchor-link">3. 导出插件 (index.ts)<a href="#3-导出插件-indexts" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4>
<p>提供一个工厂函数。</p>
<pre><code class="typescript"><span class="hl-10">import</span><span class="hl-1"> { </span><span class="hl-6">Five</span><span class="hl-1"> } </span><span class="hl-10">from</span><span class="hl-1"> </span><span class="hl-9">'@realsee/five'</span><br/><span class="hl-10">import</span><span class="hl-1"> { </span><span class="hl-6">Controller</span><span class="hl-1"> } </span><span class="hl-10">from</span><span class="hl-1"> </span><span class="hl-9">'./Controller'</span><br/><span class="hl-10">import</span><span class="hl-1"> </span><span class="hl-3">*</span><span class="hl-1"> </span><span class="hl-10">as</span><span class="hl-1"> </span><span class="hl-6">MyPluginType</span><span class="hl-1"> </span><span class="hl-10">from</span><span class="hl-1"> </span><span class="hl-9">'./typing'</span><br/><br/><span class="hl-10">export</span><span class="hl-1"> </span><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-5">MyPlugin</span><span class="hl-1"> = (</span><span class="hl-6">five</span><span class="hl-1">: </span><span class="hl-7">Five</span><span class="hl-1">, </span><span class="hl-6">params</span><span class="hl-1">?: </span><span class="hl-7">MyPluginType</span><span class="hl-1">.</span><span class="hl-7">Params</span><span class="hl-1">) </span><span class="hl-3">=></span><br/><span class="hl-1"> </span><span class="hl-3">new</span><span class="hl-1"> </span><span class="hl-5">Controller</span><span class="hl-1">(</span><span class="hl-6">five</span><span class="hl-1">, </span><span class="hl-6">params</span><span class="hl-1">)</span><br/><br/><span class="hl-10">export</span><span class="hl-1"> </span><span class="hl-10">type</span><span class="hl-1"> { </span><span class="hl-6">MyPluginType</span><span class="hl-1">, </span><span class="hl-6">Controller</span><span class="hl-1"> </span><span class="hl-10">as</span><span class="hl-1"> </span><span class="hl-6">MyPluginController</span><span class="hl-1"> }</span>
</code><button type="button">Copy</button></pre>
<h2 id="common-pitfalls-最佳实践" class="tsd-anchor-link">Common Pitfalls (最佳实践)<a href="#common-pitfalls-最佳实践" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2>
<ol>
<li><strong>状态驱动</strong>: 始终通过修改 <code>state</code> 来驱动插件行为,而不是直接操作 DOM 或 3D 对象。</li>
<li><strong>清理资源</strong>: 在 <code>disable</code> 和 <code>dispose</code> 中务必清理所有事件监听和副作用,防止内存泄漏。</li>
<li><strong>类型安全</strong>: 充分利用 TypeScript 泛型,确保事件和状态的类型安全。</li>
</ol>
<hr>
<pre><code class="yaml"><span class="hl-0">tags</span><span class="hl-1">: [</span><span class="hl-2">插件</span><span class="hl-1">, </span><span class="hl-2">插件开发</span><span class="hl-1">, </span><span class="hl-2">扩展</span><span class="hl-1">, </span><span class="hl-2">自定义功能</span><span class="hl-1">, </span><span class="hl-2">状态管理</span><span class="hl-1">, </span><span class="hl-2">plugin</span><span class="hl-1">, </span><span class="hl-2">baseplugin</span><span class="hl-1">, </span><span class="hl-2">development</span><span class="hl-1">, </span><span class="hl-2">guide</span><span class="hl-1">, </span><span class="hl-2">extension</span><span class="hl-1">, </span><span class="hl-2">lifecycle</span><span class="hl-1">]</span>
</code><button type="button">Copy</button></pre>
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#插件系统-plugin-system"><span>插件系统 (<wbr/>Plugin <wbr/>System)</span></a><ul><li><a href="#schema"><span>Schema</span></a></li><li><a href="#concepts"><span>Concepts</span></a></li><li><ul><li><a href="#directory-structure-目录结构"><span>Directory <wbr/>Structure (目录结构)</span></a></li><li><a href="#baseplugin"><span>Base<wbr/>Plugin</span></a></li><li><a href="#state-状态"><span>State (状态)</span></a></li><li><a href="#lifecycle-生命周期"><span>Lifecycle (生命周期)</span></a></li></ul></li><li><a href="#configuration"><span>Configuration</span></a></li><li><ul><li><a href="#baseplugin-configuration"><span>Base<wbr/>Plugin <wbr/>Configuration</span></a></li></ul></li><li><a href="#examples"><span>Examples</span></a></li><li><ul><li><a href="#plugin-development-walkthrough-插件开发指南"><span>Plugin <wbr/>Development <wbr/>Walkthrough (插件开发指南)</span></a></li><li><ul><li><a href="#1-定义类型-typingts"><span>1. 定义类型 (typing.ts)</span></a></li><li><a href="#2-实现控制器-controllerts"><span>2. 实现控制器 (<wbr/>Controller.ts)</span></a></li><li><a href="#3-导出插件-indexts"><span>3. 导出插件 (index.ts)</span></a></li></ul></li></ul></li><li><a href="#common-pitfalls-最佳实践"><span>Common <wbr/>Pitfalls (最佳实践)</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">如视 Five SDK</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>