{"push_id":767269911,"size":10,"distinct_size":10,"ref":"refs/heads/new_hooks2","head":"74905b365fcb21b1fc5d20123a08c4a6229fa81a","before":"ecd893dbd5888e546e51855b1ba50cb25e18fa04","commits":[{"sha":"721009e262e9bc279122566a60e14af0048d9094","author":{"email":"38b59099dea6e36c9c0d1bba897883252c87bb46@rockbox.org","name":"Thomas Martitz"},"message":"plugins: plugin loader redesign\n\nThe old plugin loader has a number of deficiencies:\n\n- plugins need to export a couple of callback functions into the global namespace\n- plugins need to export data pointers, that are written by Geany\n- the exported functions have no user_data param, so there is no way to\n  pass context/state back to the plugin (it needs global storage for that)\n- plugin registration is implicit, plugins have no way to not register themselves\n  (it may want that due to missing runtime dependencies)\n- plugins perform the ABI/API verification, and even though we provide a\n  convinience wrapper, it may get that wrong\n\nAs a result, I designed a new loader with the following design principles\n- semantics of callbacks should not change, but they they shouldn't be mess\n  with the global namespace\n- each callback receives a self-identifying param (the GeanyPlugin instance) and\n  a plugin-defined data pointer for their own use\n- explicit registration through a new API function\n- in-core API/ABI checks\n\nThe following principles shall be left unchanged:\n- The scan is done on startup and when the PM dialog is opened\n- Geany allocates GeanyPluginPrivate for each plugin, and GeanyPlugin is\n  a member of it\n- Geany initially probes for the validity of the plugin, including file type\n  and API/ABI check, thus Geany has the last word in determining what a\n  plugin is\n- the PM dialog is updated with the proper, translated plugin information\n- the PM dialog GUI and user interaction in general is unchanged\n\nWith the redesign, plugins export a single function: geany_load_module().\nThis is called when the GModule is loaded. The main purpose of this function\nis to call geany_plugin_register() (new API function) to register the plugin.\nThis is the only function that is learned about through g_module_symbol().\nWithin this call the plugin should\na) set the localized info fields of GeanyPlugin::info\nb) pass compiled-against and minimum API version as well as compiled-against\n   ABI version, to allow Geany to verify compatibility\nc) pass a pointer to an instance of GeanyPluginFuncs\n   which holds pointers to enhanced versions of the known callbacks (except\n   configure_single which is dropped).\nd) optionally pass a plugin-private data pointer for later callbacks\n\nEnhanced means that all callbacks receive the GeanyPlugin pointer as the first\nand a pdata pointer as the last. pdata is private to the plugin and is set\nby geany_plugin_register().\n\nThe callbacks need (should) not be globally defined anymore, and the global\nGeanyData, GeanyPlugin and GeanyFunctions pointers are ignored and not set\nanymore. GeanyData is available through GeanyPlugin::geany_data.","distinct":true,"url":"https://api.github.com/repos/kugel-/geany/commits/721009e262e9bc279122566a60e14af0048d9094"},{"sha":"babf0083353b1d3501fee439b6228c2fbe84cc82","author":{"email":"38b59099dea6e36c9c0d1bba897883252c87bb46@rockbox.org","name":"Thomas Martitz"},"message":"plugins: Let plugins fill GeanyPlugin::callbacks instead of passing their own pointer\n\nThis is easier to handle if we decide to add callbacks. Since we can\nzero-initialize callbacks before passing it to the plugin we can be certain as\nto which callbacks the plugin knew about when it was compiled. This is exactly\nthe same method used for GeanyPlugin::info already and easier than inspecting\nthe API version.","distinct":true,"url":"https://api.github.com/repos/kugel-/geany/commits/babf0083353b1d3501fee439b6228c2fbe84cc82"},{"sha":"f2579141bb4188d4fc97eee494ba36e809661ddf","author":{"email":"38b59099dea6e36c9c0d1bba897883252c87bb46@rockbox.org","name":"Thomas Martitz"},"message":"plugins: Replace geany_plugin_register() pdata with a separate API function\n\nThe API function adds a free_func parameter, and can also be called\nafter geany_plugin_register(), i.e. in the plugin's init() callback. This\nfixes a by-design memory leak and gives greater flexibility.","distinct":true,"url":"https://api.github.com/repos/kugel-/geany/commits/f2579141bb4188d4fc97eee494ba36e809661ddf"},{"sha":"dc1e9a800b4df633d0f94718f12a806564db5ce8","author":{"email":"38b59099dea6e36c9c0d1bba897883252c87bb46@rockbox.org","name":"Thomas Martitz"},"message":"plugins: Refactor legacy plugin support\n\nWith geany_plugin_set_data() the legacy plugin support can be made\nmore transparent by using wrapper functions that call the actual plugin_*\nfunctions. This allows to remove the differentiation in code that's not\ndirectly concerned with actually loading plugins.\n\nThis commit doesn't change anything except for one thing: legacy plugins now\ncannot call geany_plugin_set_data(). But it is meant for new-style plugins\nanyway.","distinct":true,"url":"https://api.github.com/repos/kugel-/geany/commits/dc1e9a800b4df633d0f94718f12a806564db5ce8"},{"sha":"64beaaff63f5182c5f969369e3d708c9464c76f7","author":{"email":"38b59099dea6e36c9c0d1bba897883252c87bb46@rockbox.org","name":"Thomas Martitz"},"message":"demoplugin: Adapt demoplugin to the new loader\n\nDemoplugin, while not installed by default, is a nice starting point\nand mini-howto. Therefore it should advertise the new loader from the\nbeginning.","distinct":true,"url":"https://api.github.com/repos/kugel-/geany/commits/64beaaff63f5182c5f969369e3d708c9464c76f7"},{"sha":"afd495cfad02d25ac541a0543b241058651f8a5e","author":{"email":"38b59099dea6e36c9c0d1bba897883252c87bb46@rockbox.org","name":"Thomas Martitz"},"message":"plugins: change return codes of geany_load_module() and GeanyPluginFuncs::init\n\n- The return value from geany_load_module is removed (void). It was ignored\n  anyway and we have to check separately whether the plugin loaded OK or not\n  anyway. If the plugin specific code fails it should simply not call\n  geany_plugin_register() (which it should only call iff all other conditions\n  are good).\n\n- GeanyPluginFuncs::init() now returns a bool to allow failing initialization.\n  Some plugins might want to defer work to their init() (i.e. only do\n  it when the plugin was activated by the user), and some of that work can\n  possibly fail (e.g. GtkBuilder fails to load .xml).\n\nNote that the GUI integration of the latter is less than ideal but this kind\nof GUI/policy work is out of scope for this patch set. Therefore a plugin\nfailing to init is simply removed from the PM dialog as if it became\nincompatible. However, as the code that generates the list does not call init\nthey will show up again if the PM dialog is re-opened.","distinct":true,"url":"https://api.github.com/repos/kugel-/geany/commits/afd495cfad02d25ac541a0543b241058651f8a5e"},{"sha":"e772435204527f3f3df77a3a3fd115106de3530b","author":{"email":"38b59099dea6e36c9c0d1bba897883252c87bb46@rockbox.org","name":"Thomas Martitz"},"message":"plugins: Pass pdata to PluginCallback function by default\n\nIf the plugin did not set its own user_data we set it to whatever it set\nwith geany_plugin_register_full() or geany_plugin_set_data().\nThis is particularly convinient because PluginCallback is usually statically\nallocated, at which point dynamically allocated plugin data doesn't exists yet.","distinct":true,"url":"https://api.github.com/repos/kugel-/geany/commits/e772435204527f3f3df77a3a3fd115106de3530b"},{"sha":"50eca349f33373d5cd0f5df73095a9a056fd2ced","author":{"email":"38b59099dea6e36c9c0d1bba897883252c87bb46@rockbox.org","name":"Thomas Martitz"},"message":"plugins: Updated doxygen for the new plugin loader\n\nThe documentation provides a quite detailed description of the new loader\nIn addition it adds a \"how to transition\" that briefly describes the old\nloader (for curious newcomers) and lots of hints for porting legacy\nplugins to the new loader.","distinct":true,"url":"https://api.github.com/repos/kugel-/geany/commits/50eca349f33373d5cd0f5df73095a9a056fd2ced"},{"sha":"a652fb79781a9f17900fe9af05cc288eee7c6f73","author":{"email":"38b59099dea6e36c9c0d1bba897883252c87bb46@rockbox.org","name":"Thomas Martitz"},"message":"plugins: separate geany_plugin_set_data() dual-use\n\nIt was found that because geany_plugin_set_data() could be used by both\nplugin's init() and geany_load_module(), that it introduced some uncertainty\nas to when to call the free_func. init() callers might expect the call\naround the same time as cleanup() is called, while geany_load_module()\ncallers expected the call at module unload time.\n\nIt was indeed called at module unload time. But that means that init() callers\ncannot call it again reliably after in a init()->cleanup()->init() flow (when\ntoggling the plugin) without fully unloading the plugin (which is what we do\ncurrently but that's we would want to change).\n\nWith the separation we can actually destroy the data depending on where\nit was set and do everything unambigiously.","distinct":true,"url":"https://api.github.com/repos/kugel-/geany/commits/a652fb79781a9f17900fe9af05cc288eee7c6f73"},{"sha":"74905b365fcb21b1fc5d20123a08c4a6229fa81a","author":{"email":"38b59099dea6e36c9c0d1bba897883252c87bb46@rockbox.org","name":"Thomas Martitz"},"message":"plugins: Clarify which API functions may be called within geany_load_module()\n\nSince geany_load_module() is called for non-enabled plugins you may not\nuse the plugin API here yet. The only exceptions to this rule are API functions\nrequired for plugin registration.\n\nThis rule is hard to enforce (would need to g_return_if_val(PLUGIN_LOADED_OK(p))\nfor all API functions (well, those taking a plugin pointer anyway), so this\nrule is only documented for now.","distinct":true,"url":"https://api.github.com/repos/kugel-/geany/commits/74905b365fcb21b1fc5d20123a08c4a6229fa81a"}]}