• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In
You are now the owner of this repo.

mobalazs / rotor-framework / 27651430343

16 Jun 2026 10:09PM UTC coverage: 91.166% (+1.1%) from 90.071%
27651430343

Pull #26

github

web-flow
Merge 0c0f331b9 into eb93c3e64
Pull Request #26: Feat/combine reducers

74 of 80 new or added lines in 8 files covered. (92.5%)

33 existing lines in 2 files now uncovered.

2229 of 2445 relevant lines covered (91.17%)

1.26 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.44
/src/source/engine/builder/PluginAdapter.bs
1
namespace Rotor.ViewBuilder
2

3
    ' =====================================================================
4
    ' PluginHookClass - Container for plugin hook metadata and handler function
5
    ' =====================================================================
6
    class PluginHookClass
7

8
        pluginKey as string
9
        handlerFn as function
10

11
        ' ---------------------------------------------------------------------
12
        ' new - Initializes the instance
13
        '
14
        ' @description Initializes plugin hook with key and handler
15
        ' @param {object} config - Configuration with pluginKey and handlerFn
16
        ' ---------------------------------------------------------------------
17
        sub new(config)
18
            m.pluginKey = config.pluginKey
1✔
19
            m.handlerFn = config.handlerFn
1✔
20
        end sub
21

22
    end class
23

24
    ' =====================================================================
25
    ' pluginAdapter - Manages plugin registration and lifecycle hook integration. Maintains plugin instances and maps lifecycle hooks to plugin handlers.
26
    ' =====================================================================
27
    class pluginAdapter
28

29
        plugins as object
30

31
        ' ---------------------------------------------------------------------
32
        ' new - Initializes the instance
33
        '
34
        ' @description Initializes plugin hook storage for all lifecycle types
35
        ' ---------------------------------------------------------------------
36
        sub new()
37

38
            ' dedicated plugin lifecycle hooks
39
            for each hookType in [
1✔
40
                    Rotor.Const.LifeCycleHookType.BEFORE_MOUNT,
41
                    Rotor.Const.LifeCycleHookType.AFTER_MOUNTED,
42
                    Rotor.Const.LifeCycleHookType.BEFORE_UPDATE,
43
                    Rotor.Const.LifeCycleHookType.AFTER_UPDATED,
44
                    Rotor.Const.LifeCycleHookType.BEFORE_DESTROY
45
                ]
46
                m.pluginHooks[hookType] = {}
1✔
47
            end for
48

49
        end sub
50

51
        ' Plugins has limited type of hooks to lifecycle (check the list below)
52
        pluginHooks = {}
53
        pluginKeyList = CreateObject("roList")
54
        pluginInstanceHash = {} ' Maps plugin keys to plugin instances (supports multiple keys per plugin)
55

56
        frameworkInstance as Rotor.Framework
57

58
        ' ---------------------------------------------------------------------
59
        ' registerPlugins - Registers plugins and their lifecycle hooks with the framework
60
        '
61

62
        ' @param {object} pluginConfig - Plugin configuration object or array
63
        ' ---------------------------------------------------------------------
64
        sub registerPlugins (pluginConfig as object)
65

66
            plugins = Rotor.Utils.ensureArray(pluginConfig)
1✔
67

68
            for each plugin in plugins
1✔
69

70
                ' Plugin key
71
                pluginKey = plugin.pluginKey
1✔
72

73
                ' Setup hooks
74
                hooks = plugin.hooks
1✔
75
                if Rotor.Utils.isValid(hooks) and hooks.Count() > 0
3✔
76

77
                    ' Register hooks for primary plugin key
78
                    for each hook in hooks
1✔
79
                        pluginHook = new PluginHookClass({
1✔
80
                            pluginKey: pluginKey,
81
                            handlerFn: hooks[hook]
82
                        })
83
                        m.pluginHooks[hook][pluginKey] = pluginHook
1✔
84
                    end for
85

86
                    ' Register hooks for alias key too (single alias only)
87
                    if Rotor.Utils.isString(plugin.aliasPluginKey) and plugin.aliasPluginKey <> ""
2✔
88
                        aliasKey = plugin.aliasPluginKey
1✔
89
                        for each hook in hooks
1✔
90
                            pluginHook = new PluginHookClass({
1✔
91
                                pluginKey: pluginKey,
92
                                handlerFn: hooks[hook]
93
                            })
94
                            m.pluginHooks[hook][aliasKey] = pluginHook
1✔
95
                        end for
96
                    end if
97

98
                end if
99

100
                ' Register primary plugin key
101
                m.pluginKeyList.AddTail(pluginKey)
1✔
102

103
                ' Map all registry keys to the primary plugin key
104
                m.pluginInstanceHash[pluginKey] = pluginKey
1✔
105

106
                ' Add alias key to pluginKeyList for widget detection (single alias only)
107
                if Rotor.Utils.isString(plugin.aliasPluginKey) and plugin.aliasPluginKey <> ""
2✔
108
                    aliasKey = plugin.aliasPluginKey
1✔
109
                    m.pluginKeyList.AddTail(aliasKey)
1✔
110
                    m.pluginInstanceHash[aliasKey] = pluginKey
1✔
111
                end if
112

113
                ' Store plugin instance in framework plugins map
114
                m.frameworkInstance.plugins[pluginKey] = plugin
1✔
115

116
                ' Set framework instance reference
117
                plugin.frameworkInstance = m.frameworkInstance
1✔
118

119
                ' Initialize plugin if init method exists
120
                if Rotor.Utils.isFunction(plugin.init)
3✔
121
                    ' Initialize plugin
122
                    plugin.init()
1✔
123
                end if
124

125
            end for
126

127
        end sub
128

129
        ' ---------------------------------------------------------------------
130
        ' getPlugin - Retrieves plugin instance by key
131
        ' @param {string} pluginKey - Plugin registry key
132
        ' @returns {object} Plugin instance
133
        ' ---------------------------------------------------------------------
134
        public function getPlugin(pluginKey) as Rotor.BasePlugin
135
            primaryPluginKey = m.pluginInstanceHash[pluginKey]
1✔
136
            return m.frameworkInstance.plugins[primaryPluginKey]
1✔
137
        end function
138

139
        ' ---------------------------------------------------------------------
140
        ' destroyPlugins - Destroys all registered plugins
141
        '
142
        ' Iterates the registered plugin instances (stored on the framework,
143
        ' keyed by primary plugin key), invokes each plugin's destroy() so it can
144
        ' release its own resources, then clears its framework reference.
145
        ' ---------------------------------------------------------------------
146
        sub destroyPlugins()
147
            if m.frameworkInstance = invalid then return
2✔
148

149
            registeredPlugins = m.frameworkInstance.plugins
1✔
150
            for each pluginKey in registeredPlugins.Keys()
1✔
151
                plugin = registeredPlugins[pluginKey]
1✔
152
                ' Only act on actual plugin instances (the map may contain stray
153
                ' non-plugin values written by callers); accessing .destroy on a
154
                ' primitive would crash.
155
                if Rotor.Utils.isAssociativeArray(plugin) and Rotor.Utils.isFunction(plugin.destroy)
3✔
156
                    ' Call directly on the instance so `m` is the plugin. Guard each
157
                    ' plugin so one failing teardown can't abort the rest.
158
                    ' NOTE: we do NOT null plugin.frameworkInstance here -- later
159
                    ' teardown steps (e.g. widgetTree.destroy firing beforeDestroy
160
                    ' hooks) still need it; the plugin is discarded with the framework.
161
                    try
162
                        plugin.destroy()
1✔
163
                    catch e
NEW
164
                        print "[ROTOR][PLUGIN_ADAPTER][WARNING] plugin '" ; pluginKey ; "' destroy failed: " ; e.message
×
165
                    end try
166
                end if
167
            end for
168
        end sub
169

170
        ' ---------------------------------------------------------------------
171
        '
172

173
        ' init - Initializes the adapter with framework instance reference
174
        '
175
        ' @param {object} frameworkInstance - Framework instance reference
176
        ' ---------------------------------------------------------------------
177
        sub init(frameworkInstance as object)
178
            m.frameworkInstance = frameworkInstance
1✔
179
        end sub
180

181
        ' ---------------------------------------------------------------------
182
        ' destroy - Destroys all plugins, then cleans up framework reference
183
        '
184
        ' ---------------------------------------------------------------------
185
        sub destroy()
186
            m.destroyPlugins()
1✔
187
            m.frameworkInstance = invalid
1✔
188
        end sub
189

190
    end class
191

192
end namespace
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc