Module: Esp::Plugins
- Defined in:
- lib/esp/plugins.rb
Overview
The game-plugin registry. Each plugin (Esp::Mw today; future Esp::Ob, Esp::Sr) registers itself here at load time with a short ‘id` (the value that lands in a project’s ‘.espresso/project.json` `game:` field) and the modules the frontends need to reach into — its Operations façade today.
The shell composes its routes/tools against this registry, so the only thing tying the shell to a specific game is the project the user opens. Add a plugin: drop ‘lib/esp/<id>/`, call `Esp::Plugins.register` from its entry file, and add it to the load manifest.
Lookups are by id string; ‘default_id` names the plugin used when no project is open (today: the first registered, which is `mw` because the load manifest loads it first). Slice 2 wires Esp::Operations.dispatch through `Esp::Plugins.active_for(input)` so an op like `build` reaches the plugin matching the active project’s ‘game:` field rather than always Esp::Mw::Operations.
Defined Under Namespace
Classes: Entry
Class Method Summary collapse
-
.active_for(input = {}) ⇒ Object
The plugin handling the current request.
- .default_id ⇒ Object
- .fetch(id) ⇒ Object
- .ids ⇒ Object
-
.known?(id) ⇒ Boolean
True when ‘id` names a registered plugin.
-
.register(id, label:, operations:) ⇒ Object
A plugin announces itself.
-
.registry ⇒ Object
The id → Entry map, lazily initialized and populated by plugins at load time.
Class Method Details
.active_for(input = {}) ⇒ Object
The plugin handling the current request. Order of precedence:
1. explicit `game:` in the input hash (lets the diff panel etc.
target a specific plugin even when a project is open),
2. the active project's game (Esp::ActiveProject.game),
3. the default plugin (the only one for now; the fallback for
ops invoked before any project is open — version, providers).
Unknown id raises so frontends surface a clear error.
48 49 50 51 |
# File 'lib/esp/plugins.rb', line 48 def active_for(input = {}) id = (input.is_a?(Hash) && input['game']) || Esp::ActiveProject.game || default_id fetch(id) end |
.default_id ⇒ Object
64 65 66 |
# File 'lib/esp/plugins.rb', line 64 def default_id registry.keys.first end |
.fetch(id) ⇒ Object
53 54 55 56 57 58 |
# File 'lib/esp/plugins.rb', line 53 def fetch(id) registry.fetch(id.to_s) do raise Esp::Operations::InputError, Esp.t('errors.plugins.unknown_game', game: id, known: ids.join(', ')) end end |
.ids ⇒ Object
60 61 62 |
# File 'lib/esp/plugins.rb', line 60 def ids registry.keys end |
.known?(id) ⇒ Boolean
True when ‘id` names a registered plugin. Cheap predicate for open_project to validate before storing on ActiveProject.
70 71 72 |
# File 'lib/esp/plugins.rb', line 70 def known?(id) registry.key?(id.to_s) end |
.register(id, label:, operations:) ⇒ Object
A plugin announces itself. ‘operations` is its Esp::*::Operations module (the game half of the service layer); `label` is the human-friendly name shown in error messages. Idempotent — a re-load in tests just rebinds the same entry.
35 36 37 38 39 |
# File 'lib/esp/plugins.rb', line 35 def register(id, label:, operations:) @mutex.synchronize do registry[id.to_s] = Entry.new(id: id.to_s, label: label, operations: operations) end end |
.registry ⇒ Object
The id → Entry map, lazily initialized and populated by plugins at load time. Mutable hash (like Esp::Providers.registry) because the plugin set isn’t known until every require finishes.
27 28 29 |
# File 'lib/esp/plugins.rb', line 27 def registry @registry ||= {} end |