/[svn]/gigedit/trunk/src/plugin/linuxsamplerplugin.cpp
ViewVC logotype

Diff of /gigedit/trunk/src/plugin/linuxsamplerplugin.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3176 by schoenebeck, Mon Jan 2 22:13:01 2017 UTC revision 3177 by schoenebeck, Thu May 11 20:59:46 2017 UTC
# Line 35  Line 35 
35  #include <iostream>  #include <iostream>
36  #include <sigc++/bind.h>  #include <sigc++/bind.h>
37  #include <glibmm/main.h>  #include <glibmm/main.h>
38    #include <set>
39    
40  REGISTER_INSTRUMENT_EDITOR(LinuxSamplerPlugin)  REGISTER_INSTRUMENT_EDITOR(LinuxSamplerPlugin)
41    
42    struct LSPluginPrivate {
43        std::set<gig::Region*> debounceRegionChange;
44        bool debounceRegionChangedScheduled;
45    
46        LSPluginPrivate() {
47            debounceRegionChangedScheduled = false;
48        }
49    };
50    
51  LinuxSamplerPlugin::LinuxSamplerPlugin() {  LinuxSamplerPlugin::LinuxSamplerPlugin() {
52      pApp = new GigEdit;      pApp = new GigEdit;
53        priv = new LSPluginPrivate;
54  }  }
55    
56  LinuxSamplerPlugin::~LinuxSamplerPlugin() {  LinuxSamplerPlugin::~LinuxSamplerPlugin() {
57      if (pApp) delete static_cast<GigEdit*>(pApp);      if (pApp) delete static_cast<GigEdit*>(pApp);
58        if (priv) delete priv;
59  }  }
60    
61  int LinuxSamplerPlugin::Main(void* pInstrument, String sTypeName, String sTypeVersion, void* /*pUserData*/) {  int LinuxSamplerPlugin::Main(void* pInstrument, String sTypeName, String sTypeVersion, void* /*pUserData*/) {
# Line 95  int LinuxSamplerPlugin::Main(void* pInst Line 107  int LinuxSamplerPlugin::Main(void* pInst
107          )          )
108      );      );
109      app->signal_dimreg_to_be_changed().connect(      app->signal_dimreg_to_be_changed().connect(
110          sigc::bind(          // not connected directly anymore ...
111            /*sigc::bind(
112              sigc::mem_fun(              sigc::mem_fun(
113                  *this, &LinuxSamplerPlugin::NotifyDataStructureToBeChanged                  *this, &LinuxSamplerPlugin::NotifyDataStructureToBeChanged
114              ),              ),
115              "gig::DimensionRegion"              "gig::DimensionRegion"
116          )          )*/
117            // ... because we are doing some event debouncing here :
118            sigc::mem_fun(*this, &LinuxSamplerPlugin::__onDimRegionToBeChanged)
119      );      );
120      app->signal_dimreg_changed().connect(      app->signal_dimreg_changed().connect(
121          sigc::bind(          // not connected directly anymore ...
122            /*sigc::bind(
123              sigc::mem_fun(              sigc::mem_fun(
124                  *this, &LinuxSamplerPlugin::NotifyDataStructureChanged                  *this, &LinuxSamplerPlugin::NotifyDataStructureChanged
125              ),              ),
126              "gig::DimensionRegion"              "gig::DimensionRegion"
127          )          )*/
128            // ... because we are doing some event debouncing here :
129            sigc::mem_fun(*this, &LinuxSamplerPlugin::__onDimRegionChanged)
130      );      );
131      app->signal_sample_changed().connect(      app->signal_sample_changed().connect(
132          sigc::bind(          sigc::bind(
# Line 163  int LinuxSamplerPlugin::Main(void* pInst Line 181  int LinuxSamplerPlugin::Main(void* pInst
181      return app->run(pGigInstr);      return app->run(pGigInstr);
182  }  }
183    
184    void LinuxSamplerPlugin::__onDimRegionToBeChanged(gig::DimensionRegion* pDimRgn) {
185        // instead of sending this signal per dimregion ...
186        //NotifyDataStructureToBeChanged(pDimRgn, "gig::DimensionRegion");
187    
188        // ... we are rather debouncing those dimregion to be changed events, and
189        // instead only send a region to be changed event, which is much faster when
190        // changing a very large amount of dimregions.
191        if (!pDimRgn) return;
192        gig::Region* pRegion = (gig::Region*) pDimRgn->GetParent();
193        const bool bIdle = priv->debounceRegionChange.empty();
194        bool bRegionLocked = priv->debounceRegionChange.count(pRegion);
195        if (!bRegionLocked) {
196            if (bIdle)
197                printf("DimRgn change event debounce BEGIN (%p)\n", pRegion);
198            priv->debounceRegionChange.insert(pRegion);
199            NotifyDataStructureToBeChanged(pRegion, "gig::Region");
200        }
201    }
202    
203    void LinuxSamplerPlugin::__onDimRegionChanged(gig::DimensionRegion* pDimRgn) {
204        // like above, not sending this ...
205        //NotifyDataStructureChanged(pDimRgn, "gig::DimensionRegion");
206    
207        // ... but rather aggressively debounce those dim region changed events and
208        // sending a debounced region changed event instead.
209        if (!pDimRgn) return;
210        if (!priv->debounceRegionChangedScheduled) {
211            priv->debounceRegionChangedScheduled = true;
212            Glib::signal_idle().connect_once(
213                sigc::mem_fun(*this, &LinuxSamplerPlugin::__onDimRegionChangedDebounced),
214                Glib::PRIORITY_HIGH_IDLE
215            );
216        }
217    }
218    
219    void LinuxSamplerPlugin::__onDimRegionChangedDebounced() {
220        // Note that we are really aggressively unlocking the region here: we are
221        // not even bothering whether the amount "changed" events match with the
222        // previously sent amount of "to be changed" events, because this handler
223        // here is only called when the app's event loop is already idle for a
224        // while, which is not the case if the app is still changing instrument
225        // parameters (except if the app is i.e. currently showing an error dialog
226        // to the user).
227        priv->debounceRegionChangedScheduled = false;
228        for (std::set<gig::Region*>::const_iterator it = priv->debounceRegionChange.begin();
229             it != priv->debounceRegionChange.end(); ++it)
230        {
231            gig::Region* pRegion = *it;
232            NotifyDataStructureChanged(pRegion, "gig::Region");
233        }
234        priv->debounceRegionChange.clear();
235        printf("DimRgn change event debounce END\n");
236    }
237    
238  bool LinuxSamplerPlugin::__onPollPeriod() {  bool LinuxSamplerPlugin::__onPollPeriod() {
239      #if HAVE_LINUXSAMPLER_VIRTUAL_MIDI_DEVICE      #if HAVE_LINUXSAMPLER_VIRTUAL_MIDI_DEVICE
240      GigEdit* app = static_cast<GigEdit*>(pApp);      GigEdit* app = static_cast<GigEdit*>(pApp);

Legend:
Removed from v.3176  
changed lines
  Added in v.3177

  ViewVC Help
Powered by ViewVC