I'm using modules with my addon which works really well for predefined modules (i.e., for modules being loaded during the addon-loading process). Now, I want to create user-defined modules after regular login (i.e., after the main addon is already loaded and enabled) and basically use the same procedure with NewModule().
The problem, however, is that those modules are not initialized and enabled immediately. Initialization and enabling only happens upon a ADDON_LOADED event caused by a Load-on-Demand addon (thus, quite randomly).
My current workaround for this is to extract the OnEvent() function with AceAddon.frame:GetScript() and to call it manually. This, however, is certainly not the way to go.
Is there an accepted way to initialize new modules manually if they are created after the main addon has been enabled?
A) Scenerio A, the module is part of your main addon and is not standalone.
Just call YourAddon:GetModule("modulename"):Enable() from when you want it enabled. The module's OnInitializ() will always be called since its loaded at addon load time right after the main addon's one.
In this scenerio, the module's file would be loaded before ADDON_LOADED fired for the main addon and the main addon's TOC file will have its filename listed.
B) Scenerio B, the module is load on demand, which also means its a standalone addon with its own folder.
In this case, the module will have its own ADDON_LOADED event after PLAYER_LOGIN, which when fired, will cause both OnInitialize() and OnEnable() to be called for the module.
I think nyyr means the modules are dynamically created on demand *after* the loading process ended. Am I right ?
As he said, AceAddon requires at least one ADDON_LOADED event to initialize and eventually enable the addon and its modules. That won't happen with dynamically created modules. Anyway, I think it isn't intended to work that way.
Maybe could you explain us why you've chosen this approach and what you are trying to do ?
Yes, Adirelle, its as you explained. The module is created dynamically on behalf of the main addon after everything is loaded.
The reason I want to create modules dynamically is as follows:
The addon (a HUD, ArcHUD3) provides a framework which is used by its modules to create rings for various purposes (e.g., to display a health bar, power bar etc.). Every single ring is realised by a single module with the ability to enable/disable them as required. Most rings are already predefined and thus can be loaded under the condition which Xinhuan described as scenario A (so no problem with those).
Now, I want to add custom rings that show the durations or stack sizes of user-defined buffs or debuffs. For each ring, a new module is created manually by the user the first time he or she defines it. After each login then, the definitions of the custom modules are extracted from the config DB and instantiated by the main addon. This also has to happen after the ADDON_LOADED event, i.e. in the OnInitialize() routine of the main addon.
That was the easiest way to go in the first place, since I didn't need to change much for the module prototype and still have the possibility to enable/disable user-defined rings separately without implementing a special case for those user-defined modules.
Perhaps I missed something and this behaviour is not supposed to be realised as modules?
Yep, that would be an option. The only problem with calling it manually is, that AceAddon:InitializeAddon() and AceAddon:EnableAddon() will be then called *twice* since the module is added to the AceAddon.initializequeue and there is no way to prevent NewModule (or rather NewAddon) to do so.
Calling AceAddon:EnableAddon() twice is no problem, since it does a check.
Calling AceAddon:InitializeAddon() does no check and will call OnInitialize() of the module/addon twice. In my OnInitialize() methods, I can set a flag to avoid double-initialization. However, there might be a potential problem with OnEmbedInitialize() of embedded libraries since this is also called twice for the same module. I will browse through the libs in question and check if there might be problems there.
However, it would be nice to have some control over this auto-initialization for dynamically created modules to ensure this is only done once. Maybe a new parameter to NewModule()?
The first time I delved into the whole module thing it was immediately clear that understand exactly how things load and when would have been very useful for a beginner. I ended up simply running some experiments and finding what I could on the forums to make sure I understood the behavior correctly.