12-07-2015, 04:54 PM
So I'm trying to make a plugin acts as a soft dependency, meaning that other plugins can utilize it if it is there, but do not require it. I tried coming up with a way that will make the system function if not all the plugins are loaded on startup, which means that HOOK_PLUGINS_LOADED won't work. My current method works, but is significantly less than ideal, because it spams the console with errors that don't matter (among other things). Here's the code outline:
[spoiler]
Options I considered but thought were meh:
An inbuilt list of plugins that this is a soft dependency for. It would then loop through the list (this would happen at the same time as "SpreadTheWord" happens in the above code) and execute for every plugin it found in the list that is loaded. However, this could require a lot of maintenance if I manage to write this well enough to be widely used (the concept is great, my execution might not be).
A config file with a list of all plugins installed that can utilize the API that the end user has to modify. I personally don't like that one much, as I hate trusting the end user. I've seen some... interesting end users, as I'm sure many of you have as well.
Every plugin that wants to use the API checking if it is loaded. If there were a plugin loaded (note the singular) hook that was called any time ANY plugin was loaded, this would be simple. Just have them check if the API is loaded on every plugin load. However, I know that hook would be awkward. I did some testing and the server doesn't tick (at least world ticks don't) while plugins are loading. Meaning a HOOK_PLUGIN_LOADED would probably either only be called once during load (at the same time as HOOK_PLUGINS_LOADED) or would be called multiple times within a single world tick, which could make for a sticky situation? Not really sure there. So the perfect solution form my standpoint is possibly terrible from a Cuberite dev's.
Every plugin that wants to use the API checking if it is loaded on a clock. So just have a function that calls itself using cWorld:ScheduleTask() after some delay so long as the API isn't found. It would initially be called using the HOOK_PLUGINS_LOADED of 5 ticks after loading method displayed above, and then call itself if the API wasn't found. I just don't like the idea of having a lot of long term loops, no matter how little energy they may or may not use.
All "disabling" signals could be handled by the API simply by recording what plugins were talking to it and looping through that list on disable (similarly other plugins could call a "remove me from the API" function on their disable if the API was active at that time).
So any methods besides the above? And which would you choose?
[spoiler]
g_Announced = nil function Initialize(a_Plugin) a_Plugin:SetName("SoftDepend") a_Plugin:SetVersion(.1) cRoot:Get():GetDefaultWorld():ScheduleTask(5,spreadTheWord) cPluginManager.AddHook(cPluginManager.HOOK_PLUGINS_LOADED,spreadTheWord) return true end function spreadTheWord() if not g_Announced then announceLoad() end end function announceLoad() cPluginManager:Get():ForEachPlugin( function(a_Plugin) cPluginManager:CallPlugin(a_Plugin:GetName(),"MySpecialFunction") end ) return true end[/spoiler]
Options I considered but thought were meh:
An inbuilt list of plugins that this is a soft dependency for. It would then loop through the list (this would happen at the same time as "SpreadTheWord" happens in the above code) and execute for every plugin it found in the list that is loaded. However, this could require a lot of maintenance if I manage to write this well enough to be widely used (the concept is great, my execution might not be).
A config file with a list of all plugins installed that can utilize the API that the end user has to modify. I personally don't like that one much, as I hate trusting the end user. I've seen some... interesting end users, as I'm sure many of you have as well.
Every plugin that wants to use the API checking if it is loaded. If there were a plugin loaded (note the singular) hook that was called any time ANY plugin was loaded, this would be simple. Just have them check if the API is loaded on every plugin load. However, I know that hook would be awkward. I did some testing and the server doesn't tick (at least world ticks don't) while plugins are loading. Meaning a HOOK_PLUGIN_LOADED would probably either only be called once during load (at the same time as HOOK_PLUGINS_LOADED) or would be called multiple times within a single world tick, which could make for a sticky situation? Not really sure there. So the perfect solution form my standpoint is possibly terrible from a Cuberite dev's.
Every plugin that wants to use the API checking if it is loaded on a clock. So just have a function that calls itself using cWorld:ScheduleTask() after some delay so long as the API isn't found. It would initially be called using the HOOK_PLUGINS_LOADED of 5 ticks after loading method displayed above, and then call itself if the API wasn't found. I just don't like the idea of having a lot of long term loops, no matter how little energy they may or may not use.
All "disabling" signals could be handled by the API simply by recording what plugins were talking to it and looping through that list on disable (similarly other plugins could call a "remove me from the API" function on their disable if the API was active at that time).
So any methods besides the above? And which would you choose?