Skip to content

Commit 92f5472

Browse files
committed
impl plugin manager
1 parent fdddbf8 commit 92f5472

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

src/bricklib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export * as forms from './forms.js';
1616
export * as glyphs from './glyphs.js';
1717
export * as locale from './locale.js';
1818
export * as logger from './logger.js';
19+
export * as plugin from './plugin.js';
1920
export * as rawtext from './rawtext.js';
2021
export * as server from './server.js';
2122
export * as thread from './thread.js';

src/bricklib/plugin.ts

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/**
2+
* Plugin manager for bricklib.
3+
*/
4+
5+
const registry: Map<string, Plugin> = new Map();
6+
7+
/**
8+
* @class
9+
* Plugin instance class.
10+
*/
11+
export class Plugin
12+
{
13+
/**
14+
* @constructor
15+
* Make a new Plugin instance.
16+
* @param fn The setup function.
17+
*/
18+
constructor(fn: PluginFunc)
19+
{
20+
this.setup = fn;
21+
}
22+
23+
/**
24+
* The identifier of the plugin (if registered).
25+
*/
26+
public id: string = null;
27+
28+
/**
29+
* The function to execute when loading the plugin.
30+
*/
31+
public setup: PluginFunc = null;
32+
33+
/**
34+
* The function to execute when unloading the plugin.
35+
*/
36+
public teardown: PluginFunc = null;
37+
38+
/**
39+
* Whether the plugin is already loaded (don't modify).
40+
*/
41+
public loaded: boolean = false;
42+
43+
/**
44+
* Add this plugin to the registry.
45+
* @returns Itself.
46+
* @throws This function can throw errors.
47+
*/
48+
public register(id: string): this
49+
{
50+
if (this.id != null)
51+
throw new Error('Plugin already registered!');
52+
if (doesExist(id))
53+
throw new Error('Plugin already exists: ' + id);
54+
registry.set(id, this);
55+
this.id = id;
56+
return this;
57+
}
58+
59+
/**
60+
* Remove this plugin from the registry.
61+
* @returns Itself.
62+
*/
63+
public deregister(): this
64+
{
65+
if (this.id != null && getPlugin(this.id) === this)
66+
registry.delete(this.id);
67+
return this;
68+
}
69+
}
70+
71+
/**
72+
* Loads a plugin. You may use this if your plugin depends on another plugin,
73+
* to make sure everything is properly initialized.
74+
* @param id The plugin's identifier.
75+
* @throws This function can throw errors.
76+
*/
77+
export function loadPlugin(id: string): void
78+
{
79+
const plg = registry.get(id);
80+
if (!plg) throw new ReferenceError('No such plugin: ' + id);
81+
if (plg.loaded) return;
82+
plg.loaded = true;
83+
plg.setup(plg);
84+
}
85+
86+
/**
87+
* Unloads a plugin by calling its teardown function.
88+
* @param id The plugin's identifier.
89+
* @throws This function can throw errrors.
90+
*/
91+
export function unloadPlugin(id: string): void
92+
{
93+
const plg = registry.get(id);
94+
if (!plg) throw new ReferenceError('No such plugin: ' + id);
95+
if (!plg.loaded) return;
96+
plg.teardown?.(plg);
97+
plg.loaded = false;
98+
}
99+
100+
/**
101+
* Checks if a plugin exists on the registry.
102+
* @param id The plugin identifier to lookup.
103+
* @returns True if the plugin exists, false otherwise.
104+
*/
105+
export function doesExist(id: string): boolean
106+
{
107+
return registry.has(id);
108+
}
109+
110+
/**
111+
* Get the plugin instance of a plugin with identifier `id`.
112+
* @param id The plugin's identifier.
113+
* @returns The Plugin instance or null.
114+
*/
115+
export function getPlugin(id: string): Plugin | null
116+
{
117+
return registry.get(id) ?? null; /* null, not undefined */
118+
}
119+
120+
/**
121+
* Make and register new plugin.
122+
* @param id The identifier of the plugin.
123+
* @param fn The setup function.
124+
* @returns The plugin instance.
125+
* @throws This function can throw errors.
126+
*/
127+
export function newPlugin(id: string, fn: PluginFunc): Plugin
128+
{
129+
return new Plugin(fn).register(id);
130+
}
131+
132+
/**
133+
* A plugin function.
134+
*/
135+
export type PluginFunc = (self: Plugin) => void;

0 commit comments

Comments
 (0)