Defer plugin discovery until actually needed (significant startup time improvement...
authorDavid Robillard <d@drobilla.net>
Thu, 22 Oct 2009 17:17:34 +0000 (17:17 +0000)
committerDavid Robillard <d@drobilla.net>
Thu, 22 Oct 2009 17:17:34 +0000 (17:17 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@5859 d708f5d6-7413-0410-9779-e7cbd77b26cf

14 files changed:
gtk2_ardour/mixer_strip.cc
gtk2_ardour/mixer_strip.h
gtk2_ardour/mixer_ui.cc
gtk2_ardour/mixer_ui.h
gtk2_ardour/processor_box.cc
gtk2_ardour/processor_box.h
gtk2_ardour/route_params_ui.cc
gtk2_ardour/route_params_ui.h
libs/ardour/ardour/audio_unit.h
libs/ardour/ardour/lv2_plugin.h
libs/ardour/ardour/plugin_manager.h
libs/ardour/audio_unit.cc
libs/ardour/lv2_plugin.cc
libs/ardour/plugin_manager.cc

index c2e38a1d34eabf09e9d8e56866a825e521160998..c82a621d36c1df969d5bc95ac62d8e71a86110c6 100644 (file)
@@ -74,20 +74,19 @@ sigc::signal<void,boost::shared_ptr<Route> > MixerStrip::SwitchIO;
 int MixerStrip::scrollbar_height = 0;
 
 MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, bool in_mixer)
-       : AxisView(sess)
+       : AxisView(sess)
        , RouteUI (sess)
        ,_mixer(mx)
        , _mixer_owned (in_mixer)
-       , processor_box (sess, mx.plugin_selector(), mx.selection(), this, in_mixer)
+       , processor_box (sess, sigc::mem_fun(*this, &MixerStrip::plugin_selector), mx.selection(), this, in_mixer)
        , gpm (sess)
        , panners (sess)
        , _mono_button (_("Mono"))
        , button_table (3, 2)
        , middle_button_table (1, 2)
-       , bottom_button_table (1, 2)
+       , bottom_button_table (1, 2)
        , meter_point_label (_("pre"))
-       , comment_button (_("Comments"))
-
+       , comment_button (_("Comments"))
 {
        init ();
 
@@ -101,19 +100,18 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, bool in_mixer)
 }
 
 MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr<Route> rt, bool in_mixer)
-       : AxisView(sess)
+       : AxisView(sess)
        , RouteUI (sess)
        ,_mixer(mx)
        , _mixer_owned (in_mixer)
-       , processor_box (sess, mx.plugin_selector(), mx.selection(), this, in_mixer)
+       , processor_box (sess, sigc::mem_fun(*this, &MixerStrip::plugin_selector), mx.selection(), this, in_mixer)
        , gpm (sess)
        , panners (sess)
        , button_table (3, 2)
        , middle_button_table (1, 2)
-       , bottom_button_table (1, 2)
+       , bottom_button_table (1, 2)
        , meter_point_label (_("pre"))
-       , comment_button (_("Comments"))
-
+       , comment_button (_("Comments"))
 {
        init ();
        set_button_names ();
@@ -1795,3 +1793,9 @@ MixerStrip::mono_button_clicked ()
 {
        panners.set_mono (_mono_button.get_active ());
 }
+
+PluginSelector&
+MixerStrip::plugin_selector()
+{
+       return _mixer.plugin_selector();
+}
index c83c260845cf3ee7889402c2875d7ec31e4306d6..891d3a4d8dbdfe335a4421ab09186d584714a771 100644 (file)
@@ -87,8 +87,9 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
        Width get_width_enum () const { return _width; }
        void* width_owner () const { return _width_owner; }
 
-       GainMeter& gain_meter() { return gpm; }
-       PannerUI&  panner_ui()  { return panners; }
+       GainMeter&      gain_meter()      { return gpm; }
+       PannerUI&       panner_ui()       { return panners; }
+       PluginSelector& plugin_selector();
 
        void fast_update ();
        void set_embedded (bool);
index 51578ad2b4ab6b7640bfaaf9a4b8ba7e150e3f0c..9931d51ff0dbfd6778a58f9164dd160eab1b97b1 100644 (file)
@@ -62,6 +62,7 @@ using PBD::atoi;
 
 Mixer_UI::Mixer_UI ()
        : Window (Gtk::WINDOW_TOPLEVEL)
+       , _plugin_selector (0)
 {
        session = 0;
        _strip_width = Config->get_default_narrow_ms() ? Narrow : Wide;
@@ -76,9 +77,9 @@ Mixer_UI::Mixer_UI ()
 
        Route::SyncOrderKeys.connect (mem_fun (*this, &Mixer_UI::sync_order_keys));
 
-       scroller_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
-       scroller_base.set_name ("MixerWindow");
-       scroller_base.signal_button_release_event().connect (mem_fun(*this, &Mixer_UI::strip_scroller_button_release));
+       scroller_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
+       scroller_base.set_name ("MixerWindow");
+       scroller_base.signal_button_release_event().connect (mem_fun(*this, &Mixer_UI::strip_scroller_button_release));
        // add as last item of strip packer
        strip_packer.pack_end (scroller_base, true, true);
 
@@ -220,8 +221,6 @@ Mixer_UI::Mixer_UI ()
        signal_delete_event().connect (mem_fun (*this, &Mixer_UI::hide_window));
        add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK);
 
-       _plugin_selector = new PluginSelector (PluginManager::the_manager());
-
        signal_configure_event().connect (mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::configure_handler));
 
        _selection.RoutesChanged.connect (mem_fun(*this, &Mixer_UI::follow_strip_selection));
@@ -466,7 +465,8 @@ Mixer_UI::connect_to_session (Session* sess)
 
        route_groups_changed ();
 
-       _plugin_selector->set_session (session);
+       if (_plugin_selector)
+               _plugin_selector->set_session (session);
 
        if (_visible) {
               show_window();
@@ -1487,3 +1487,12 @@ Mixer_UI::set_route_group_activation (RouteGroup* g, bool a)
        g->set_active (a, this);
 }
 
+PluginSelector&
+Mixer_UI::plugin_selector()
+{
+       if (!_plugin_selector) {
+               _plugin_selector = new PluginSelector (PluginManager::the_manager());
+               _plugin_selector->set_session (session);
+       }
+       return *_plugin_selector;
+}
index c7378404efac34c8c923869e85e4bf1d129759e6..e96178160af9298fe26e8d20cdaacb5c12026068 100644 (file)
@@ -58,7 +58,7 @@ class Mixer_UI : public Gtk::Window
 
        void connect_to_session (ARDOUR::Session *);
 
-       PluginSelector&  plugin_selector() { return *_plugin_selector; }
+       PluginSelector& plugin_selector();
 
        void  set_strip_width (Width);
        Width get_strip_width () const { return _strip_width; }
index aba5abe2941cb952617b7f006c15b61ca1c1ac41..b21ce633da3ff9135ed014a431f79062eb6b022d 100644 (file)
@@ -93,13 +93,13 @@ bool ProcessorBox::get_colors = true;
 Gdk::Color* ProcessorBox::active_processor_color;
 Gdk::Color* ProcessorBox::inactive_processor_color;
 
-ProcessorBox::ProcessorBox (Session& sess, PluginSelector &plugsel,
-                           RouteRedirectSelection & rsel, MixerStrip* parent, bool owner_is_mixer)
+ProcessorBox::ProcessorBox (ARDOUR::Session& sess, sigc::slot<PluginSelector&> get_plugin_selector,
+                       RouteRedirectSelection& rsel, MixerStrip* parent, bool owner_is_mixer)
        : _session(sess)
        , _parent_strip (parent)
        , _owner_is_mixer (owner_is_mixer)
+       , _get_plugin_selector (get_plugin_selector)
        , _placement(PreFader)
-       , _plugin_selector(plugsel)
        , _rr_selection(rsel)
 {
        if (get_colors) {
@@ -309,7 +309,7 @@ ProcessorBox::show_processor_menu (gint arg)
        Gtk::MenuItem* plugin_menu_item = dynamic_cast<Gtk::MenuItem*>(ActionManager::get_widget("/processormenu/newplugin"));
 
        if (plugin_menu_item) {
-               plugin_menu_item->set_submenu (_plugin_selector.plugin_menu());
+               plugin_menu_item->set_submenu (_get_plugin_selector().plugin_menu());
        }
 
        paste_action->set_sensitive (!_rr_selection.processors.empty());
@@ -469,7 +469,7 @@ ProcessorBox::processor_button_press_event (GdkEventButton *ev)
        } else if (!processor && ev->button == 1 && ev->type == GDK_2BUTTON_PRESS) {
 
                choose_plugin ();
-               _plugin_selector.show_manager ();
+               _get_plugin_selector().show_manager ();
        }
 
 
@@ -572,7 +572,7 @@ ProcessorBox::deselect_all_processors ()
 void
 ProcessorBox::choose_plugin ()
 {
-       _plugin_selector.set_interested_object (*this);
+       _get_plugin_selector().set_interested_object (*this);
 }
 
 void
index 6a80549132ab46ba3663f2f0a4f3c8593a2f9c32..075e176903ce90e09784eed9b9958d2e62f7fb98 100644 (file)
@@ -69,7 +69,8 @@ namespace ARDOUR {
 class ProcessorBox : public Gtk::HBox, public PluginInterestedObject
 {
   public:
-       ProcessorBox (ARDOUR::Session&, PluginSelector &, RouteRedirectSelection &, MixerStrip* parent, bool owner_is_mixer = false);
+       ProcessorBox (ARDOUR::Session&, sigc::slot<PluginSelector&> get_plugin_selector,
+                       RouteRedirectSelection&, MixerStrip* parent, bool owner_is_mixer = false);
        ~ProcessorBox ();
 
        void set_route (boost::shared_ptr<ARDOUR::Route>);
@@ -96,12 +97,13 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject
        bool                 ab_direction;
        std::vector<sigc::connection> connections;
 
+       sigc::slot<PluginSelector&> _get_plugin_selector;
+
        boost::shared_ptr<ARDOUR::Processor> _processor_being_created;
 
-       ARDOUR::Placement   _placement;
+       ARDOUR::Placement _placement;
 
-       PluginSelector     & _plugin_selector;
-       RouteRedirectSelection  & _rr_selection;
+       RouteRedirectSelection& _rr_selection;
 
        void route_going_away ();
 
index 80849bebe4b3e971387b5e97326defb366857b7c..888e28aab0a8261655711d5b15a8b68b8fba8b05 100644 (file)
@@ -64,7 +64,6 @@ RouteParams_UI::RouteParams_UI ()
        : ArdourDialog ("track/bus inspector"),
          latency_apply_button (Stock::APPLY),
          track_menu(0)
-
 {
        insert_box = 0;
        _input_iosel = 0;
@@ -224,10 +223,11 @@ RouteParams_UI::setup_processor_boxes()
                cleanup_processor_boxes();
 
                // construct new redirect boxes
-               insert_box = new ProcessorBox(*session, *_plugin_selector, _rr_selection, 0);
-               insert_box->set_route (_route);
+               insert_box = new ProcessorBox(*session,
+                               sigc::mem_fun(*this, &RouteParams_UI::plugin_selector), _rr_selection, 0);
+               insert_box->set_route (_route);
 
-               redir_hpane.pack1 (*insert_box);
+               redir_hpane.pack1 (*insert_box);
 
                insert_box->ProcessorSelected.connect (mem_fun(*this, &RouteParams_UI::redirect_selected));
                insert_box->ProcessorUnselected.connect (mem_fun(*this, &RouteParams_UI::redirect_selected));
index 75c0ef731dbd2dc1ad5de94e95ed1d21ed870379..ca582dadd3cf1f7492627941cde074b7f781ee5f 100644 (file)
@@ -78,11 +78,11 @@ class RouteParams_UI : public ArdourDialog
        Gtk::ScrolledWindow      route_select_scroller;
 
        Gtk::Notebook            notebook;
-       Gtk::Frame               input_frame;
-       Gtk::Frame               output_frame;
+       Gtk::Frame               input_frame;
+       Gtk::Frame               output_frame;
        Gtk::HPaned              redir_hpane;
 
-       Gtk::Frame               route_select_frame;
+       Gtk::Frame               route_select_frame;
 
        Gtk::HBox                route_hpacker;
        Gtk::VBox                route_vpacker;
@@ -93,9 +93,9 @@ class RouteParams_UI : public ArdourDialog
 
        Gtk::HPaned              right_hpane;
 
-       Gtk::Frame               route_choice_frame;
+       Gtk::Frame               route_choice_frame;
 
-       Gtk::Frame               route_param_frame;
+       Gtk::Frame               route_param_frame;
 
        Gtk::VBox                choice_vpacker;
 
@@ -145,7 +145,7 @@ class RouteParams_UI : public ArdourDialog
 
 
        /* treeview */
-       struct RouteDisplayModelColumns : public Gtk::TreeModel::ColumnRecord {
+       struct RouteDisplayModelColumns : public Gtk::TreeModel::ColumnRecord {
                RouteDisplayModelColumns() {
                        add(text);
                        add(route);
index a1f22a88df8b9e030262cab31e8c97695125207e..d1dd92dd3d140cd1025f7405d270535703273752 100644 (file)
@@ -166,7 +166,7 @@ class AUPluginInfo : public PluginInfo {
 
        AUPluginCachedInfo cache;
 
-       static PluginInfoList discover ();
+       static PluginInfoList* discover ();
        static void get_names (CAComponentDescription&, std::string& name, Glib::ustring& maker);
         static std::string stringify_descriptor (const CAComponentDescription&);
 
index f2773a3d6c0f7372d3b3777a6ec909906c4a3a28..9705459ee1dc7e9f53168470bf482e993e1e7fc3 100644 (file)
@@ -176,7 +176,7 @@ struct LV2World {
        SLV2Value srate;
        SLV2Value gtk_gui;
        SLV2Value external_gui;
-        SLV2Value logarithmic;
+       SLV2Value logarithmic;
 };
 
 
@@ -184,7 +184,7 @@ class LV2PluginInfo : public PluginInfo {
 public:
        LV2PluginInfo (void* slv2_world, void* slv2_plugin);;
        ~LV2PluginInfo ();;
-       static PluginInfoList discover (void* slv2_world);
+       static PluginInfoList* discover (void* slv2_world);
 
        PluginPtr load (Session& session);
 
index c792b539a797f0c585ffe715cc2d1399996bfead..d564d62a877e339d239588b62b30ad468411b4fa 100644 (file)
@@ -46,12 +46,10 @@ class PluginManager : public boost::noncopyable {
        PluginManager ();
        ~PluginManager ();
 
-       /* realtime plugin APIs */
-
-       ARDOUR::PluginInfoList &vst_plugin_info ()    { return _vst_plugin_info; }
-       ARDOUR::PluginInfoList &ladspa_plugin_info () { return _ladspa_plugin_info; }
-       ARDOUR::PluginInfoList &lv2_plugin_info ()    { return _lv2_plugin_info; }
-       ARDOUR::PluginInfoList &au_plugin_info ()     { return _au_plugin_info; }
+       ARDOUR::PluginInfoList &vst_plugin_info ();
+       ARDOUR::PluginInfoList &ladspa_plugin_info ();
+       ARDOUR::PluginInfoList &lv2_plugin_info ();
+       ARDOUR::PluginInfoList &au_plugin_info ();
 
        void refresh ();
 
@@ -85,10 +83,11 @@ class PluginManager : public boost::noncopyable {
        typedef std::set<FavoritePlugin> FavoritePluginList;
        FavoritePluginList favorites;
 
-       ARDOUR::PluginInfoList _vst_plugin_info;
-       ARDOUR::PluginInfoList _ladspa_plugin_info;
-       ARDOUR::PluginInfoList _lv2_plugin_info;
-       ARDOUR::PluginInfoList _au_plugin_info;
+       ARDOUR::PluginInfoList  _empty_plugin_info;
+       ARDOUR::PluginInfoList* _vst_plugin_info;
+       ARDOUR::PluginInfoList* _ladspa_plugin_info;
+       ARDOUR::PluginInfoList* _lv2_plugin_info;
+       ARDOUR::PluginInfoList* _au_plugin_info;
 
 #ifdef HAVE_SLV2
        LV2World* _lv2_world;
@@ -107,10 +106,8 @@ class PluginManager : public boost::noncopyable {
        void add_vst_presets ();
        void add_presets (std::string domain);
 
-       int au_discover ();
        void au_refresh ();
 
-       int lv2_discover ();
        void lv2_refresh ();
 
        int vst_discover_from_path (std::string path);
index b0ced9bdfbe2b57eeac0f4db3df6adb12d60c6cc..cb91b34cf5e89c95c076967d31af60acfc29b56c 100644 (file)
@@ -1444,7 +1444,7 @@ AUPluginInfo::au_cache_path ()
        return Glib::build_filename (ARDOUR::get_user_ardour_path(), "au_cache");
 }
 
-PluginInfoList
+PluginInfoList*
 AUPluginInfo::discover ()
 {
        XMLTree tree;
@@ -1453,7 +1453,7 @@ AUPluginInfo::discover ()
                ARDOUR::BootMessage (_("Discovering AudioUnit plugins (could take some time ...)"));
        }
 
-       PluginInfoList plugs;
+       PluginInfoList* plugs = new PluginInfoList ();
 
        discover_fx (plugs);
        discover_music (plugs);
index 678dfd47159e354bc6c0aedad6d132e5f9d8a8fc..2090d18e96d212d83c88abb5d9e270fb3c8e41b5 100644 (file)
@@ -703,15 +703,15 @@ LV2PluginInfo::load (Session& session)
        return PluginPtr();
 }
 
-PluginInfoList
+PluginInfoList*
 LV2PluginInfo::discover (void* lv2_world)
 {
-       PluginInfoList plugs;
+       PluginInfoList* plugs = new PluginInfoList;
 
        LV2World* world = (LV2World*)lv2_world;
        SLV2Plugins plugins = slv2_world_get_all_plugins(world->world);
 
-       cerr << "LV2: Discovered " << slv2_plugins_size (plugins) << " plugins\n";
+       cerr << "LV2: Discovering " << slv2_plugins_size (plugins) << " plugins" << endl;
 
        for (unsigned i=0; i < slv2_plugins_size(plugins); ++i) {
                SLV2Plugin p = slv2_plugins_get_at(plugins, i);
@@ -750,9 +750,11 @@ LV2PluginInfo::discover (void* lv2_world)
                info->unique_id = slv2_value_as_uri(slv2_plugin_get_uri(p));
                info->index = 0; // Meaningless for LV2
 
-               plugs.push_back (info);
+               plugs->push_back (info);
        }
 
+       cerr << "Done LV2 discovery" << endl;
+
        return plugs;
 }
 
index 6ac57400c482ea06c991d9576e1e50df8fd17c3f..8315397fe85bbaa30f0243175b8c21b9e0d404a2 100644 (file)
@@ -74,6 +74,10 @@ using namespace std;
 PluginManager* PluginManager::_manager = 0;
 
 PluginManager::PluginManager ()
+       : _vst_plugin_info(0)
+       , _ladspa_plugin_info(0)
+       , _lv2_plugin_info(0)
+       , _au_plugin_info(0)
 {
        char* s;
        string lrdf_path;
@@ -135,8 +139,6 @@ PluginManager::PluginManager ()
 #endif
 
        BootMessage (_("Discovering Plugins"));
-
-       refresh ();
 }
 
 void
@@ -159,7 +161,10 @@ PluginManager::refresh ()
 void
 PluginManager::ladspa_refresh ()
 {
-       _ladspa_plugin_info.clear ();
+       if (_ladspa_plugin_info)
+               _ladspa_plugin_info->clear ();
+       else
+               _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
 
        static const char *standard_paths[] = {
                "/usr/local/lib64/ladspa",
@@ -240,12 +245,13 @@ PluginManager::ladspa_discover_from_path (string /*path*/)
        return ret;
 }
 
-static bool rdf_filter (const string &str, void */*arg*/)
+static bool rdf_filter (const string &str, void/*arg*/)
 {
        return str[0] != '.' &&
                   ((str.find(".rdf")  == (str.length() - 4)) ||
             (str.find(".rdfs") == (str.length() - 5)) ||
-                   (str.find(".n3")   == (str.length() - 3)));
+                   (str.find(".n3")   == (str.length() - 3)) ||
+                   (str.find(".ttl")  == (str.length() - 4)));
 }
 
 void
@@ -368,22 +374,22 @@ PluginManager::ladspa_discover (string path)
                        }
                }
 
-               if(_ladspa_plugin_info.empty()){
-                       _ladspa_plugin_info.push_back (info);
+               if(_ladspa_plugin_info->empty()){
+                       _ladspa_plugin_info->push_back (info);
                }
 
                //Ensure that the plugin is not already in the plugin list.
 
                bool found = false;
 
-               for (PluginInfoList::const_iterator i = _ladspa_plugin_info.begin(); i != _ladspa_plugin_info.end(); ++i) {
+               for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
                        if(0 == info->unique_id.compare((*i)->unique_id)){
                              found = true;
                        }
                }
 
                if(!found){
-                   _ladspa_plugin_info.push_back (info);
+                   _ladspa_plugin_info->push_back (info);
                }
        }
 
@@ -433,14 +439,8 @@ PluginManager::get_ladspa_category (uint32_t plugin_id)
 void
 PluginManager::lv2_refresh ()
 {
-       lv2_discover();
-}
-
-int
-PluginManager::lv2_discover ()
-{
+       delete _lv2_plugin_info;
        _lv2_plugin_info = LV2PluginInfo::discover(_lv2_world);
-       return 0;
 }
 #endif
 
@@ -448,14 +448,8 @@ PluginManager::lv2_discover ()
 void
 PluginManager::au_refresh ()
 {
-       au_discover();
-}
-
-int
-PluginManager::au_discover ()
-{
+       delete _au_plugin_info;
        _au_plugin_info = AUPluginInfo::discover();
-       return 0;
 }
 
 #endif
@@ -465,7 +459,10 @@ PluginManager::au_discover ()
 void
 PluginManager::vst_refresh ()
 {
-       _vst_plugin_info.clear ();
+       if (_vst_plugin_info)
+               _vst_plugin_info->clear ();
+       else
+               _vst_plugin_info = new ARDOUR::PluginInfoList();
 
        if (vst_path.length() == 0) {
                vst_path = "/usr/local/lib/vst:/usr/lib/vst";
@@ -552,7 +549,7 @@ PluginManager::vst_discover (string path)
        info->n_outputs.set_audio (finfo->numOutputs);
        info->type = ARDOUR::VST;
 
-       _vst_plugin_info.push_back (info);
+       _vst_plugin_info->push_back (info);
        fst_free_info (finfo);
 
        return 0;
@@ -663,3 +660,47 @@ PluginManager::remove_favorite (PluginType t, string id)
        FavoritePlugin fp (t, id);
        favorites.erase (fp);
 }
+
+ARDOUR::PluginInfoList&
+PluginManager::vst_plugin_info ()
+{
+#ifdef VST_SUPPORT
+       if (!_vst_plugin_info)
+               vst_refresh();
+       return *_vst_plugin_info;
+#else
+       return _empty_plugin_info;
+#endif
+}
+
+ARDOUR::PluginInfoList&
+PluginManager::ladspa_plugin_info ()
+{
+       if (!_ladspa_plugin_info)
+               ladspa_refresh();
+       return *_ladspa_plugin_info;
+}
+
+ARDOUR::PluginInfoList&
+PluginManager::lv2_plugin_info ()
+{
+#ifdef HAVE_SLV2
+       if (!_lv2_plugin_info)
+               lv2_refresh();
+       return *_lv2_plugin_info;
+#else
+       return _empty_plugin_info;
+#endif
+}
+
+ARDOUR::PluginInfoList&
+PluginManager::au_plugin_info ()
+{
+#ifdef HAVE_AUDIOUNITS
+       if (!_au_plugin_info)
+               au_refresh();
+       return *_au_plugin_info;
+#else
+       return _empty_plugin_info;
+#endif
+}