Class: Avo::PluginManager
- Inherits:
-
Object
- Object
- Avo::PluginManager
- Defined in:
- lib/avo/plugin_manager.rb
Instance Attribute Summary collapse
-
#engines ⇒ Object
readonly
Returns the value of attribute engines.
-
#plugins ⇒ Object
(also: #all)
readonly
Returns the value of attribute plugins.
Instance Method Summary collapse
- #as_json(*arg) ⇒ Object
-
#begin_reload ⇒ Object
Starts a re-registration cycle without touching the currently published @plugins/@engines, so concurrent readers (e.g. mount_avo's route-drawing loop) keep seeing the complete pre-reload list until #commit_reload publishes the new one.
-
#commit_reload ⇒ Object
Publishes the registrations collected since #begin_reload.
-
#initialize ⇒ PluginManager
constructor
A new instance of PluginManager.
- #installed?(name) ⇒ Boolean
- #mount_engine(klass, **options) ⇒ Object
- #register(name, priority: 10) ⇒ Object
- #register_field(method_name, klass) ⇒ Object
-
#register_menu_item(name, &block) ⇒ Object
Register a custom menu DSL method (e.g.
form) contributed by a plugin, so it can be used insideconfig.main_menuand friends. - #register_resource_tool ⇒ Object
- #register_tool ⇒ Object
- #register_view_type(name, component:, icon:, active_icon:, translation_key: nil) ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize ⇒ PluginManager
Returns a new instance of PluginManager.
8 9 10 11 12 13 |
# File 'lib/avo/plugin_manager.rb', line 8 def initialize @plugins = [] @engines = [] @building_plugins = [] @building_engines = [] end |
Instance Attribute Details
#engines ⇒ Object (readonly)
Returns the value of attribute engines.
4 5 6 |
# File 'lib/avo/plugin_manager.rb', line 4 def engines @engines end |
#plugins ⇒ Object (readonly) Also known as: all
Returns the value of attribute plugins.
3 4 5 |
# File 'lib/avo/plugin_manager.rb', line 3 def plugins @plugins end |
Instance Method Details
#as_json(*arg) ⇒ Object
88 89 90 91 92 93 94 95 |
# File 'lib/avo/plugin_manager.rb', line 88 def as_json(*arg) plugins.map do |plugin| { klass: plugin.to_s, priority: plugin.priority, } end end |
#begin_reload ⇒ Object
Starts a re-registration cycle without touching the currently published @plugins/@engines, so concurrent readers (e.g. mount_avo's route-drawing loop) keep seeing the complete pre-reload list until #commit_reload publishes the new one. Called by Avo.boot inside its Mutex, so only one reload is ever building at a time.
20 21 22 23 |
# File 'lib/avo/plugin_manager.rb', line 20 def begin_reload @building_plugins = [] @building_engines = [] end |
#commit_reload ⇒ Object
Publishes the registrations collected since #begin_reload. Each of the two reassignments below is individually an atomic pointer swap, so a reader of .engines alone (or .plugins alone) always sees the complete old list or the complete new one, never a partially rebuilt one. The two fields are not published jointly -- a reader combining both in one operation could observe them from different reload generations. No current reader does that (mount_avo reads only .engines; installed? reads only .plugins).
33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/avo/plugin_manager.rb', line 33 def commit_reload @plugins = @building_plugins @engines = @building_engines # Reset to fresh arrays rather than nil: register/mount_engine must # stay callable even outside a begin_reload/commit_reload window -- # e.g. avo-permissions calls Avo.plugin_manager.register at Rails # initializer time, before Avo.boot ever runs. Such a call is simply # discarded by the next #begin_reload rather than raising, matching # the pre-atomic-publish behavior where register/mount_engine never # crashed regardless of timing. @building_plugins = [] @building_engines = [] end |
#installed?(name) ⇒ Boolean
105 106 107 108 109 |
# File 'lib/avo/plugin_manager.rb', line 105 def installed?(name) plugins.any? do |plugin| plugin.name.to_s == name.to_s end end |
#mount_engine(klass, **options) ⇒ Object
111 112 113 114 115 116 117 |
# File 'lib/avo/plugin_manager.rb', line 111 def mount_engine(klass, **) # Dedup by class so a plugin hook that (by bug) calls mount_engine # twice for the same engine within one boot can't leave a duplicate # entry for #commit_reload to publish. @building_engines.delete_if { |engine| engine[:klass] == klass } @building_engines << {klass:, options:} end |
#register(name, priority: 10) ⇒ Object
47 48 49 50 51 52 53 54 |
# File 'lib/avo/plugin_manager.rb', line 47 def register(name, priority: 10) # Capture the file that called `register` so the plugin can later resolve # the gem it actually ships in. Plugins register under nicknames # (e.g. `:rhino` for `avo-rhino_field`), so the name alone isn't enough. registered_from = caller_locations(1, 1)&.first&.path @building_plugins << Plugin.new(name:, priority: priority, registered_from: registered_from) end |
#register_field(method_name, klass) ⇒ Object
60 61 62 63 64 65 66 67 68 |
# File 'lib/avo/plugin_manager.rb', line 60 def register_field(method_name, klass) # Avo.boot method is executed multiple times. # During the first run, it correctly loads descendants of Avo::Fields::Base. # Plugins are then loaded, introducing additional descendants to Avo::Fields::Base. # On subsequent runs, Avo::Fields::Base descendants now include these plugin fields. # This field_name_attribute assign forces the field name to retain the registered name instead of being computed dynamically from the field class. klass.field_name_attribute = method_name Avo.field_manager.load_field method_name, klass end |
#register_menu_item(name, &block) ⇒ Object
Register a custom menu DSL method (e.g. form) contributed by a plugin,
so it can be used inside config.main_menu and friends. Delegates to
avo-menu's builder when it's installed; a no-op otherwise, so plugins can
register unconditionally. The block is evaluated in the menu builder's
context, so it can call link, resource, etc. See
Avo::Menu::Builder.register_item.
76 77 78 79 80 |
# File 'lib/avo/plugin_manager.rb', line 76 def (name, &block) return unless defined?(Avo::Menu::Builder) Avo::Menu::Builder.register_item(name, &block) end |
#register_resource_tool ⇒ Object
82 83 |
# File 'lib/avo/plugin_manager.rb', line 82 def register_resource_tool end |
#register_tool ⇒ Object
85 86 |
# File 'lib/avo/plugin_manager.rb', line 85 def register_tool end |
#register_view_type(name, component:, icon:, active_icon:, translation_key: nil) ⇒ Object
56 57 58 |
# File 'lib/avo/plugin_manager.rb', line 56 def register_view_type(name, component:, icon:, active_icon:, translation_key: nil) Avo.view_type_manager.register(name, component:, icon:, active_icon:, translation_key:) end |
#to_s ⇒ Object
97 98 99 100 101 102 103 |
# File 'lib/avo/plugin_manager.rb', line 97 def to_s plugins.map do |plugin| plugin.to_s end.join(",") rescue "Failed to fetch plugins." end |