commit e429ffb45d85dcbe8a6c8a3d6dffcbd383e1e408
parent 87cc5f927e9187bec928ab73b3ece644e1c9c578
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Mon, 2 Mar 2015 20:57:02 -0500
DSSI: Get Plugin To Compile/Link Properly
Diffstat:
7 files changed, 269 insertions(+), 245 deletions(-)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
@@ -377,8 +377,9 @@ target_link_libraries(zynaddsubfx
${AUDIO_LIBRARIES}
)
-if (DssiEnable AND FALSE)
+if (DssiEnable)
add_library(zynaddsubfx_dssi SHARED
+ UI/ConnectionDummy.cpp
Output/DSSIaudiooutput.cpp
)
diff --git a/src/Misc/MiddleWare.cpp b/src/Misc/MiddleWare.cpp
@@ -15,9 +15,6 @@
#include "../UI/Connection.h"
#include "../UI/Fl_Osc_Interface.h"
-#ifndef NO_UI
-#include "../UI/Fl_Osc_Widget.H"
-#endif
#include <map>
@@ -431,8 +428,6 @@ struct ParamStore
PADnoteParameters *pad[NUM_MIDI_PARTS][NUM_KIT_ITEMS];
};
-static Fl_Osc_Interface *genOscInterface(class MiddleWareImpl*);
-
/* Implementation */
class MiddleWareImpl
{
@@ -544,7 +539,7 @@ class MiddleWareImpl
}
public:
- MiddleWareImpl(void);
+ MiddleWareImpl(MiddleWare *mw);
~MiddleWareImpl(void);
void warnMemoryLeaks(void);
@@ -760,7 +755,7 @@ public:
std::atomic_int actual_load[NUM_MIDI_PARTS];
};
-MiddleWareImpl::MiddleWareImpl(void)
+MiddleWareImpl::MiddleWareImpl(MiddleWare *mw)
{
server = lo_server_new_with_proto(NULL, LO_UDP, liblo_error_cb);
lo_server_add_method(server, NULL, NULL, handler_function, NULL);
@@ -774,7 +769,7 @@ MiddleWareImpl::MiddleWareImpl(void)
idle = 0;
master = new Master();
- osc = genOscInterface(this);
+ osc = GUI::genOscInterface(mw);
//Grab objects of interest from master
obj_store.extractMaster(master);
@@ -1122,226 +1117,14 @@ void MiddleWareImpl::write(const char *path, const char *args, va_list va)
warnx("Failed to write message to '%s'", path);
}
-/******************************************************************************
- * OSC Interface For User Interface *
- * *
- * This is a largely out of date section of code *
- * Most type specific write methods are no longer used *
- * See UI/Fl_Osc_* to see what is actually used in this interface *
- ******************************************************************************/
-class UI_Interface:public Fl_Osc_Interface
-{
- public:
- UI_Interface(MiddleWareImpl *impl_)
- :impl(impl_)
- {}
-
- void requestValue(string s) override
- {
- //Fl_Osc_Interface::requestValue(s);
- if(last_url != "GUI") {
- impl->write("/echo", "ss", "OSC_URL", "GUI");
- last_url = "GUI";
- }
-
- impl->write(s.c_str(),"");
- }
-
- void write(string s, const char *args, ...) override
- {
- va_list va;
- va_start(va, args);
- //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 4 + 30, 0 + 40);
- ////fprintf(stderr, ".");
- //fprintf(stderr, "write(%s:%s)\n", s.c_str(), args);
- //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
- impl->write(s.c_str(), args, va);
- va_end(va);
- }
-
- void writeRaw(const char *msg) override
- {
- //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 4 + 30, 0 + 40);
- ////fprintf(stderr, ".");
- //fprintf(stderr, "rawWrite(%s:%s)\n", msg, rtosc_argument_string(msg));
- //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
- impl->handleMsg(msg);
- }
-
- void writeValue(string s, string ss) override
- {
- //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 4 + 30, 0 + 40);
- //fprintf(stderr, "writevalue<string>(%s,%s)\n", s.c_str(),ss.c_str());
- //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
- impl->write(s.c_str(), "s", ss.c_str());
- }
-
- void writeValue(string s, char c) override
- {
- //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 4 + 30, 0 + 40);
- //fprintf(stderr, "writevalue<char>(%s,%d)\n", s.c_str(),c);
- //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
- impl->write(s.c_str(), "c", c);
- }
-
- void writeValue(string s, float f) override
- {
- //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 4 + 30, 0 + 40);
- //fprintf(stderr, "writevalue<float>(%s,%f)\n", s.c_str(),f);
- //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
- impl->write(s.c_str(), "f", f);
- }
-
- void createLink(string s, class Fl_Osc_Widget*w) override
- {
- assert(s.length() != 0);
- Fl_Osc_Interface::createLink(s,w);
- assert(!strstr(s.c_str(), "/part0/kit-1"));
- map.insert(std::pair<string,Fl_Osc_Widget*>(s,w));
- }
-
- void renameLink(string old, string newer, Fl_Osc_Widget *w) override
- {
- //fprintf(stdout, "renameLink('%s','%s',%p)\n",
- // old.c_str(), newer.c_str(), w);
- removeLink(old, w);
- createLink(newer, w);
- }
-
- void removeLink(string s, class Fl_Osc_Widget*w) override
- {
- for(auto i = map.begin(); i != map.end(); ++i) {
- if(i->first == s && i->second == w) {
- map.erase(i);
- break;
- }
- }
- //printf("[%d] removing '%s' (%p)...\n", map.size(), s.c_str(), w);
- }
-
- virtual void removeLink(class Fl_Osc_Widget *w)
- {
- bool processing = true;
- while(processing)
- {
- //Verify Iterator invalidation sillyness
- processing = false;//Exit if no new elements are found
- for(auto i = map.begin(); i != map.end(); ++i) {
- if(i->second == w) {
- //printf("[%d] removing '%s' (%p)...\n", map.size()-1,
- // i->first.c_str(), w);
- map.erase(i);
- processing = true;
- break;
- }
- }
- }
- }
-
- //A very simplistic implementation of a UI agnostic refresh method
- virtual void damage(const char *path)
- {
-#ifndef NO_UI
- //printf("\n\nDamage(\"%s\")\n", path);
- for(auto pair:map) {
- if(strstr(pair.first.c_str(), path)) {
- auto *tmp = dynamic_cast<Fl_Widget*>(pair.second);
- //if(tmp)
- // printf("%x, %d %d [%s]\n", (int)pair.second, tmp->visible_r(), tmp->visible(), pair.first.c_str());
- //else
- // printf("%x, (NULL)[%s]\n", (int)pair.second,pair.first.c_str());
- if(!tmp || tmp->visible_r())
- pair.second->update();
- }
- }
-#endif
- }
-
- void tryLink(const char *msg) override
- {
-
- //DEBUG
- //if(strcmp(msg, "/vu-meter"))//Ignore repeated message
- // printf("trying the link for a '%s'<%s>\n", msg, rtosc_argument_string(msg));
- const char *handle = rindex(msg,'/');
- if(handle)
- ++handle;
-
- int found_count = 0;
-
- auto range = map.equal_range(msg);
- for(auto itr = range.first; itr != range.second; ++itr) {
- auto widget = itr->second;
- found_count++;
- const char *arg_str = rtosc_argument_string(msg);
-
- //Always provide the raw message
- widget->OSC_raw(msg);
-
- if(!strcmp(arg_str, "b")) {
- widget->OSC_value(rtosc_argument(msg,0).b.len,
- rtosc_argument(msg,0).b.data,
- handle);
- } else if(!strcmp(arg_str, "c")) {
- widget->OSC_value((char)rtosc_argument(msg,0).i,
- handle);
- } else if(!strcmp(arg_str, "s")) {
- widget->OSC_value((const char*)rtosc_argument(msg,0).s,
- handle);
- } else if(!strcmp(arg_str, "i")) {
- widget->OSC_value((int)rtosc_argument(msg,0).i,
- handle);
- } else if(!strcmp(arg_str, "f")) {
- widget->OSC_value((float)rtosc_argument(msg,0).f,
- handle);
- } else if(!strcmp(arg_str, "T") || !strcmp(arg_str, "F")) {
- widget->OSC_value((bool)rtosc_argument(msg,0).T, handle);
- }
- }
-
- if(found_count == 0
- && strcmp(msg, "/vu-meter")
- && strcmp(msg, "undo_change")
- && !strstr(msg, "parameter")
- && !strstr(msg, "Prespoint")) {
- //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 1, 7 + 30, 0 + 40);
- //fprintf(stderr, "Unknown widget '%s'\n", msg);
- //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
- }
- };
-
- void dumpLookupTable(void)
- {
- if(!map.empty()) {
- printf("Leaked controls:\n");
- for(auto i = map.begin(); i != map.end(); ++i) {
- printf("Known control '%s' (%p)...\n", i->first.c_str(), i->second);
- }
- }
- }
-
-
- private:
- std::multimap<string,Fl_Osc_Widget*> map;
- MiddleWareImpl *impl;
-};
-
void MiddleWareImpl::warnMemoryLeaks(void)
-{
- UI_Interface *o = (UI_Interface*)osc;
- o->dumpLookupTable();
-}
-
-Fl_Osc_Interface *genOscInterface(class MiddleWareImpl *impl)
-{
- return new UI_Interface(impl);
-}
+{}
/******************************************************************************
* MidleWare Forwarding Stubs *
******************************************************************************/
MiddleWare::MiddleWare(void)
-:impl(new MiddleWareImpl())
+:impl(new MiddleWareImpl(this))
{}
MiddleWare::~MiddleWare(void)
{
@@ -1380,8 +1163,35 @@ void MiddleWare::transmitMsg(const char *msg)
{
impl->handleMsg(msg);
}
+
+void MiddleWare::transmitMsg(const char *path, const char *args, ...)
+{
+ char buffer[1024];
+ va_list va;
+ va_start(va,args);
+ if(rtosc_vmessage(buffer,1024,path,args,va))
+ transmitMsg(buffer);
+ va_end(va);
+}
+
+void MiddleWare::transmitMsg(const char *path, const char *args, va_list va)
+{
+ char buffer[1024];
+ if(rtosc_vmessage(buffer, 1024, path, args, va))
+ transmitMsg(buffer);
+}
void MiddleWare::pendingSetProgram(int part)
{
impl->pending_load[part]++;
}
+
+std::string MiddleWare::activeUrl(void)
+{
+ return last_url;
+}
+
+void MiddleWare::activeUrl(std::string u)
+{
+ last_url = u;
+}
diff --git a/src/Misc/MiddleWare.h b/src/Misc/MiddleWare.h
@@ -19,10 +19,17 @@ class MiddleWare
void tick(void);
//Do A Readonly Operation (For Parameter Copy)
void doReadOnlyOp(std::function<void()>);
- //Handle a rtosc Message
+ //Handle a rtosc Message uToB
void transmitMsg(const char *);
+ //Handle a rtosc Message uToB
+ void transmitMsg(const char *, const char *args, ...);
+ //Handle a rtosc Message uToB
+ void transmitMsg(const char *, const char *args, va_list va);
//Indicate that a program will be loaded on a known part
void pendingSetProgram(int part);
+ //Get/Set the active bToU url
+ std::string activeUrl(void);
+ void activeUrl(std::string u);
private:
class MiddleWareImpl *impl;
};
diff --git a/src/Output/DSSIaudiooutput.cpp b/src/Output/DSSIaudiooutput.cpp
@@ -43,6 +43,7 @@ class WavFile;
namespace Nio {
bool start(void){return 1;};
void stop(void){};
+ void masterSwap(Master *){};
void waveNew(WavFile *){}
void waveStart(void){}
void waveStop(void){}
@@ -365,24 +366,11 @@ void DSSIaudiooutput::selectProgram(unsigned long bank, unsigned long program)
if((bank < master->bank.banks.size()) && (program < BANK_SIZE)) {
const std::string bankdir = master->bank.banks[bank].dir;
if(!bankdir.empty()) {
- pthread_mutex_lock(&master->mutex);
-
- /* We have to turn off the CheckPADsynth functionality, else
- * the program change takes way too long and we get timeouts
- * and hence zombies (!) */
- int save = config.cfg.CheckPADsynth;
- config.cfg.CheckPADsynth = 0;
-
/* Load the bank... */
master->bank.loadbank(bankdir);
- /* restore the CheckPADsynth flag */
- config.cfg.CheckPADsynth = save;
-
/* Now load the instrument... */
master->bank.loadfromslot((unsigned int)program, master->part[0]);
-
- pthread_mutex_unlock(&master->mutex);
}
}
}
@@ -441,7 +429,6 @@ void DSSIaudiooutput::runSynth(unsigned long sample_count,
unsigned long event_index = 0;
unsigned long next_event_frame = 0;
unsigned long to_frame = 0;
- pthread_mutex_lock(&master->mutex);
do {
/* Find the time of the next event, if any */
@@ -491,7 +478,6 @@ void DSSIaudiooutput::runSynth(unsigned long sample_count,
// Keep going until we have the desired total length of sample...
} while(to_frame < sample_count);
- pthread_mutex_unlock(&master->mutex);
}
/**
@@ -547,7 +533,7 @@ DSSI_Descriptor *DSSIaudiooutput::initDssiDescriptor()
newLadspaDescriptor->Name = "ZynAddSubFX";
newLadspaDescriptor->Maker =
"Nasca Octavian Paul <zynaddsubfx@yahoo.com>";
- newLadspaDescriptor->Copyright = "GNU General Public License v.2";
+ newLadspaDescriptor->Copyright = "GNU General Public License v2";
newLadspaDescriptor->PortCount = 2;
newPortNames = new const char *[newLadspaDescriptor->PortCount];
@@ -646,10 +632,8 @@ DSSIaudiooutput::~DSSIaudiooutput()
void DSSIaudiooutput::initBanks(void)
{
if(!banksInited) {
- pthread_mutex_lock(&master->mutex);
master->bank.rescanforbanks();
banksInited = true;
- pthread_mutex_unlock(&master->mutex);
}
}
@@ -687,7 +671,6 @@ long DSSIaudiooutput::bankNoToMap = 1;
*/
bool DSSIaudiooutput::mapNextBank()
{
- pthread_mutex_lock(&master->mutex);
Bank &bank = master->bank;
bool retval;
if((bankNoToMap >= (int)bank.banks.size())
@@ -706,6 +689,5 @@ bool DSSIaudiooutput::mapNextBank()
bankNoToMap++;
retval = true;
}
- pthread_mutex_unlock(&master->mutex);
return retval;
}
diff --git a/src/UI/Connection.cpp b/src/UI/Connection.cpp
@@ -1,6 +1,8 @@
#include "Connection.h"
#include "Fl_Osc_Interface.h"
#include "../globals.h"
+#include <map>
+#include <cassert>
#include <rtosc/rtosc.h>
#include <rtosc/ports.h>
@@ -10,6 +12,7 @@
#include "Fl_Osc_Tree.H"
#include "common.H"
#include "MasterUI.h"
+#include "../Misc/MiddleWare.h"
#ifdef NTK_GUI
#include <FL/Fl_Shared_Image.H>
@@ -18,6 +21,10 @@
#include <err.h>
#endif // NTK_GUI
+#ifndef NO_UI
+#include "Fl_Osc_Widget.H"
+#endif
+
using namespace GUI;
class MasterUI *ui;
extern rtosc::UndoHistory undo;
@@ -112,7 +119,7 @@ void GUI::destroyUi(ui_handle_t ui)
delete static_cast<MasterUI*>(ui);
}
-#define BEGIN(x) {x,"",NULL,[](const char *m, rtosc::RtData d){ \
+#define BEGIN(x) {x,":non-realtime\0",NULL,[](const char *m, rtosc::RtData d){ \
MasterUI *ui = static_cast<MasterUI*>(d.obj); \
rtosc_arg_t a0 = {0}, a1 = {0}; \
if(rtosc_narguments(m) > 0) \
@@ -191,3 +198,213 @@ void GUI::tickUi(ui_handle_t)
{
Fl::wait(0.02f);
}
+
+/******************************************************************************
+ * OSC Interface For User Interface *
+ * *
+ * This is a largely out of date section of code *
+ * Most type specific write methods are no longer used *
+ * See UI/Fl_Osc_* to see what is actually used in this interface *
+ ******************************************************************************/
+class UI_Interface:public Fl_Osc_Interface
+{
+ public:
+ UI_Interface(MiddleWare *impl_)
+ :impl(impl_)
+ {}
+
+ void requestValue(string s) override
+ {
+ //Fl_Osc_Interface::requestValue(s);
+ if(impl->activeUrl() != "GUI") {
+ impl->transmitMsg("/echo", "ss", "OSC_URL", "GUI");
+ impl->activeUrl("GUI");
+ }
+
+ impl->transmitMsg(s.c_str(),"");
+ }
+
+ void write(string s, const char *args, ...) override
+ {
+ va_list va;
+ va_start(va, args);
+ //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 4 + 30, 0 + 40);
+ ////fprintf(stderr, ".");
+ //fprintf(stderr, "write(%s:%s)\n", s.c_str(), args);
+ //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
+ impl->transmitMsg(s.c_str(), args, va);
+ va_end(va);
+ }
+
+ void writeRaw(const char *msg) override
+ {
+ fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 4 + 30, 0 + 40);
+ //fprintf(stderr, ".");
+ fprintf(stderr, "rawWrite(%s:%s)\n", msg, rtosc_argument_string(msg));
+ fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
+ impl->transmitMsg(msg);
+ }
+
+ void writeValue(string s, string ss) override
+ {
+ fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 4 + 30, 0 + 40);
+ fprintf(stderr, "writevalue<string>(%s,%s)\n", s.c_str(),ss.c_str());
+ fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
+ impl->transmitMsg(s.c_str(), "s", ss.c_str());
+ }
+
+ void writeValue(string s, char c) override
+ {
+ fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 4 + 30, 0 + 40);
+ fprintf(stderr, "writevalue<char>(%s,%d)\n", s.c_str(),c);
+ fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
+ impl->transmitMsg(s.c_str(), "c", c);
+ }
+
+ void writeValue(string s, float f) override
+ {
+ fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 4 + 30, 0 + 40);
+ fprintf(stderr, "writevalue<float>(%s,%f)\n", s.c_str(),f);
+ fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
+ impl->transmitMsg(s.c_str(), "f", f);
+ }
+
+ void createLink(string s, class Fl_Osc_Widget*w) override
+ {
+ assert(s.length() != 0);
+ Fl_Osc_Interface::createLink(s,w);
+ assert(!strstr(s.c_str(), "/part0/kit-1"));
+ map.insert(std::pair<string,Fl_Osc_Widget*>(s,w));
+ }
+
+ void renameLink(string old, string newer, Fl_Osc_Widget *w) override
+ {
+ fprintf(stdout, "renameLink('%s','%s',%p)\n",
+ old.c_str(), newer.c_str(), w);
+ removeLink(old, w);
+ createLink(newer, w);
+ }
+
+ void removeLink(string s, class Fl_Osc_Widget*w) override
+ {
+ for(auto i = map.begin(); i != map.end(); ++i) {
+ if(i->first == s && i->second == w) {
+ map.erase(i);
+ break;
+ }
+ }
+ //printf("[%d] removing '%s' (%p)...\n", map.size(), s.c_str(), w);
+ }
+
+ virtual void removeLink(class Fl_Osc_Widget *w) override
+ {
+ bool processing = true;
+ while(processing)
+ {
+ //Verify Iterator invalidation sillyness
+ processing = false;//Exit if no new elements are found
+ for(auto i = map.begin(); i != map.end(); ++i) {
+ if(i->second == w) {
+ //printf("[%d] removing '%s' (%p)...\n", map.size()-1,
+ // i->first.c_str(), w);
+ map.erase(i);
+ processing = true;
+ break;
+ }
+ }
+ }
+ }
+
+ //A very simplistic implementation of a UI agnostic refresh method
+ virtual void damage(const char *path) override
+ {
+#ifndef NO_UI
+ //printf("\n\nDamage(\"%s\")\n", path);
+ for(auto pair:map) {
+ if(strstr(pair.first.c_str(), path)) {
+ auto *tmp = dynamic_cast<Fl_Widget*>(pair.second);
+ //if(tmp)
+ // printf("%x, %d %d [%s]\n", (int)pair.second, tmp->visible_r(), tmp->visible(), pair.first.c_str());
+ //else
+ // printf("%x, (NULL)[%s]\n", (int)pair.second,pair.first.c_str());
+ if(!tmp || tmp->visible_r())
+ pair.second->update();
+ }
+ }
+#endif
+ }
+
+ void tryLink(const char *msg) override
+ {
+
+ //DEBUG
+ //if(strcmp(msg, "/vu-meter"))//Ignore repeated message
+ // printf("trying the link for a '%s'<%s>\n", msg, rtosc_argument_string(msg));
+ const char *handle = rindex(msg,'/');
+ if(handle)
+ ++handle;
+
+ int found_count = 0;
+
+ auto range = map.equal_range(msg);
+ for(auto itr = range.first; itr != range.second; ++itr) {
+ auto widget = itr->second;
+ found_count++;
+ const char *arg_str = rtosc_argument_string(msg);
+
+ //Always provide the raw message
+ widget->OSC_raw(msg);
+
+ if(!strcmp(arg_str, "b")) {
+ widget->OSC_value(rtosc_argument(msg,0).b.len,
+ rtosc_argument(msg,0).b.data,
+ handle);
+ } else if(!strcmp(arg_str, "c")) {
+ widget->OSC_value((char)rtosc_argument(msg,0).i,
+ handle);
+ } else if(!strcmp(arg_str, "s")) {
+ widget->OSC_value((const char*)rtosc_argument(msg,0).s,
+ handle);
+ } else if(!strcmp(arg_str, "i")) {
+ widget->OSC_value((int)rtosc_argument(msg,0).i,
+ handle);
+ } else if(!strcmp(arg_str, "f")) {
+ widget->OSC_value((float)rtosc_argument(msg,0).f,
+ handle);
+ } else if(!strcmp(arg_str, "T") || !strcmp(arg_str, "F")) {
+ widget->OSC_value((bool)rtosc_argument(msg,0).T, handle);
+ }
+ }
+
+ if(found_count == 0
+ && strcmp(msg, "/vu-meter")
+ && strcmp(msg, "undo_change")
+ && !strstr(msg, "parameter")
+ && !strstr(msg, "Prespoint")) {
+ //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 1, 7 + 30, 0 + 40);
+ //fprintf(stderr, "Unknown widget '%s'\n", msg);
+ //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
+ }
+ };
+
+ void dumpLookupTable(void)
+ {
+ if(!map.empty()) {
+ printf("Leaked controls:\n");
+ for(auto i = map.begin(); i != map.end(); ++i) {
+ printf("Known control '%s' (%p)...\n", i->first.c_str(), i->second);
+ }
+ }
+ }
+
+
+ private:
+ std::multimap<string,Fl_Osc_Widget*> map;
+ MiddleWare *impl;
+};
+
+Fl_Osc_Interface *GUI::genOscInterface(MiddleWare *mw)
+{
+ return new UI_Interface(mw);
+}
+
diff --git a/src/UI/Connection.h b/src/UI/Connection.h
@@ -3,6 +3,7 @@
//remove the tendrils of the UI from the RT code
class Fl_Osc_Interface;
+class MiddleWare;
namespace GUI
{
typedef void *ui_handle_t;
@@ -12,4 +13,6 @@ void destroyUi(ui_handle_t);
void raiseUi(ui_handle_t, const char *);
void raiseUi(ui_handle_t, const char *, const char *, ...);
void tickUi(ui_handle_t);
+
+Fl_Osc_Interface *genOscInterface(MiddleWare*);
};
diff --git a/src/UI/ConnectionDummy.cpp b/src/UI/ConnectionDummy.cpp
@@ -18,4 +18,8 @@ void tickUi(ui_handle_t)
{
usleep(100000);
}
+Fl_Osc_Interface *genOscInterface(MiddleWare*)
+{
+ return NULL;
+}
};