remove virtual inheritance of sigc::trackable by Receiver and AbstractUI<T>, done by changing Gtkmm2ext::UI to use composition (HAS-A) rather than inheritance (IS-A) for Receiver; use correct synchronization when starting up a BseUI event loop thread so that tests that start/stop quickly do not encounter a race condition
git-svn-id: svn://localhost/ardour2/branches/3.0@12264 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
69a242ba64
commit
37969d837e
@ -45,7 +45,7 @@ MidiControlUI* MidiControlUI::_instance = 0;
|
||||
#include "pbd/abstract_ui.cc" /* instantiate the template */
|
||||
|
||||
MidiControlUI::MidiControlUI (Session& s)
|
||||
: AbstractUI<MidiUIRequest> (_("midiui"))
|
||||
: AbstractUI<MidiUIRequest> (X_("midiui"))
|
||||
, _session (s)
|
||||
{
|
||||
MIDI::Manager::instance()->PortsChanged.connect_same_thread (rebind_connection, boost::bind (&MidiControlUI::change_midi_ports, this));
|
||||
|
@ -64,6 +64,8 @@ BaseUI::RequestType Gtkmm2ext::AddTimeout = BaseUI::new_request_type();
|
||||
|
||||
UI::UI (string namestr, int *argc, char ***argv)
|
||||
: AbstractUI<UIRequest> (namestr)
|
||||
, _receiver (*this)
|
||||
|
||||
{
|
||||
theMain = new Main (argc, argv);
|
||||
|
||||
@ -252,10 +254,10 @@ UI::load_rcfile (string path, bool themechange)
|
||||
void
|
||||
UI::run (Receiver &old_receiver)
|
||||
{
|
||||
listen_to (error);
|
||||
listen_to (info);
|
||||
listen_to (warning);
|
||||
listen_to (fatal);
|
||||
_receiver.listen_to (error);
|
||||
_receiver.listen_to (info);
|
||||
_receiver.listen_to (warning);
|
||||
_receiver.listen_to (fatal);
|
||||
|
||||
/* stop the old receiver (text/console) once we hit the first idle */
|
||||
|
||||
@ -266,7 +268,7 @@ UI::run (Receiver &old_receiver)
|
||||
theMain->run ();
|
||||
_active = false;
|
||||
stopping ();
|
||||
hangup ();
|
||||
_receiver.hangup ();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -88,8 +88,21 @@ struct UIRequest : public BaseUI::BaseRequestObject {
|
||||
}
|
||||
};
|
||||
|
||||
class UI : public Receiver, public AbstractUI<UIRequest>
|
||||
class UI : public AbstractUI<UIRequest>
|
||||
{
|
||||
private:
|
||||
class MyReceiver : public Receiver {
|
||||
public:
|
||||
MyReceiver (UI& ui) : _ui (ui) {}
|
||||
void receive (Transmitter::Channel chn, const char *msg) {
|
||||
_ui.receive (chn, msg);
|
||||
}
|
||||
private:
|
||||
UI& _ui;
|
||||
};
|
||||
|
||||
MyReceiver _receiver;
|
||||
|
||||
public:
|
||||
UI (std::string name, int *argc, char **argv[]);
|
||||
virtual ~UI ();
|
||||
@ -183,6 +196,7 @@ class UI : public Receiver, public AbstractUI<UIRequest>
|
||||
bool color_picked;
|
||||
|
||||
void do_request (UIRequest*);
|
||||
|
||||
};
|
||||
|
||||
} /* namespace */
|
||||
|
@ -74,11 +74,22 @@ void
|
||||
BaseUI::main_thread ()
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::EventLoop, string_compose ("%1: event loop running in thread %2\n", name(), pthread_self()));
|
||||
std::cerr << string_compose ("%1: event loop running in thread %2\n", name(), pthread_self());
|
||||
set_event_loop_for_thread (this);
|
||||
thread_init ();
|
||||
_main_loop->get_context()->signal_idle().connect (sigc::mem_fun (*this, &BaseUI::signal_running));
|
||||
_main_loop->run ();
|
||||
}
|
||||
|
||||
bool
|
||||
BaseUI::signal_running ()
|
||||
{
|
||||
Glib::Mutex::Lock lm (_run_lock);
|
||||
_running.signal ();
|
||||
|
||||
return false; // don't call it again
|
||||
}
|
||||
|
||||
void
|
||||
BaseUI::run ()
|
||||
{
|
||||
@ -91,7 +102,11 @@ BaseUI::run ()
|
||||
/* glibmm hack - drop the refptr to the IOSource now before it can hurt */
|
||||
request_channel.drop_ios ();
|
||||
|
||||
Glib::Mutex::Lock lm (_run_lock);
|
||||
run_loop_thread = Thread::create (mem_fun (*this, &BaseUI::main_thread), true);
|
||||
std::cerr << "wait for " << name() << " thread to start\n";
|
||||
_running.wait (_run_lock);
|
||||
std::cerr << "\tthread now running\n";
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -41,7 +41,7 @@
|
||||
*/
|
||||
|
||||
|
||||
class BaseUI : virtual public sigc::trackable, public PBD::EventLoop
|
||||
class BaseUI : public sigc::trackable, public PBD::EventLoop
|
||||
{
|
||||
public:
|
||||
BaseUI (const std::string& name);
|
||||
@ -76,6 +76,14 @@ class BaseUI : virtual public sigc::trackable, public PBD::EventLoop
|
||||
|
||||
Glib::RefPtr<Glib::MainLoop> _main_loop;
|
||||
Glib::Thread* run_loop_thread;
|
||||
Glib::Mutex _run_lock;
|
||||
Glib::Cond _running;
|
||||
|
||||
/* this signals _running from within the event loop,
|
||||
from an idle callback
|
||||
*/
|
||||
|
||||
bool signal_running ();
|
||||
|
||||
/** Derived UI objects can implement thread_init()
|
||||
* which will be called by the event loop thread
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
class strstream;
|
||||
|
||||
class Receiver : virtual public sigc::trackable
|
||||
class Receiver : public sigc::trackable
|
||||
{
|
||||
public:
|
||||
Receiver ();
|
||||
|
@ -142,6 +142,7 @@ def build(bld):
|
||||
testobj.includes = obj.includes + ['test', '../pbd']
|
||||
testobj.uselib = 'CPPUNIT XML SNDFILE'
|
||||
testobj.use = 'libpbd'
|
||||
testobj.name = 'libpbd-tests'
|
||||
if sys.platform != 'darwin':
|
||||
testobj.linkflags = ['-lrt']
|
||||
|
||||
|
@ -39,7 +39,8 @@ class Route;
|
||||
class Session;
|
||||
class Bundle;
|
||||
|
||||
class ControlProtocol : public PBD::Stateful, public PBD::ScopedConnectionList, public BasicUI {
|
||||
class ControlProtocol : public PBD::Stateful, public PBD::ScopedConnectionList, public BasicUI
|
||||
{
|
||||
public:
|
||||
ControlProtocol (Session&, std::string name);
|
||||
virtual ~ControlProtocol();
|
||||
|
Loading…
Reference in New Issue
Block a user