mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 23:35:03 +01:00
major design changes: use glib event loop for MIDI thread/UI; rework design of BaseUI and AbstractUI; solo & mute are both temporarily broken; OSC control up next; may segfault during exit
git-svn-id: svn://localhost/ardour2/branches/3.0@6328 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
90f95df207
commit
c38e02285f
50 changed files with 753 additions and 908 deletions
|
|
@ -33,36 +33,24 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
using namespace Glib;
|
||||
|
||||
uint32_t BaseUI::rt_bit = 1;
|
||||
uint64_t BaseUI::rt_bit = 1;
|
||||
BaseUI::RequestType BaseUI::CallSlot = BaseUI::new_request_type();
|
||||
|
||||
BaseUI::BaseUI (string str, bool with_signal_pipe)
|
||||
: _name (str)
|
||||
BaseUI::BaseUI (const string& str)
|
||||
: run_loop_thread (0)
|
||||
, _name (str)
|
||||
{
|
||||
/* odd pseudo-singleton semantics */
|
||||
|
||||
base_ui_instance = this;
|
||||
|
||||
signal_pipe[0] = -1;
|
||||
signal_pipe[1] = -1;
|
||||
request_channel.ios()->connect (sigc::mem_fun (*this, &BaseUI::request_handler));
|
||||
|
||||
if (with_signal_pipe) {
|
||||
if (setup_signal_pipe ()) {
|
||||
throw failed_constructor ();
|
||||
}
|
||||
}
|
||||
/* derived class must set _ok */
|
||||
}
|
||||
|
||||
BaseUI::~BaseUI()
|
||||
{
|
||||
if (signal_pipe[0] >= 0) {
|
||||
close (signal_pipe[0]);
|
||||
}
|
||||
|
||||
if (signal_pipe[1] >= 0) {
|
||||
close (signal_pipe[1]);
|
||||
}
|
||||
}
|
||||
|
||||
BaseUI::RequestType
|
||||
|
|
@ -78,32 +66,53 @@ BaseUI::new_request_type ()
|
|||
return rt;
|
||||
}
|
||||
|
||||
int
|
||||
BaseUI::setup_signal_pipe ()
|
||||
void
|
||||
BaseUI::main_thread ()
|
||||
{
|
||||
/* setup the pipe that other threads send us notifications/requests
|
||||
through.
|
||||
*/
|
||||
|
||||
if (pipe (signal_pipe)) {
|
||||
error << string_compose (_("%1-UI: cannot create error signal pipe (%2)"), _name, ::strerror (errno))
|
||||
<< endmsg;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fcntl (signal_pipe[0], F_SETFL, O_NONBLOCK)) {
|
||||
error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal read pipe (%2)"), _name, ::strerror (errno))
|
||||
<< endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fcntl (signal_pipe[1], F_SETFL, O_NONBLOCK)) {
|
||||
error << string_compose (_("%1-UI: cannot set O_NONBLOCK on signal write pipe (%2)"), _name, ::strerror (errno))
|
||||
<< endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
thread_init ();
|
||||
_main_loop->run ();
|
||||
}
|
||||
|
||||
void
|
||||
BaseUI::run ()
|
||||
{
|
||||
/* to be called by UI's that need/want their own distinct, self-created event loop thread.
|
||||
Derived classes should have set up a handler for IO on request_channel.ios()
|
||||
*/
|
||||
|
||||
_main_loop = MainLoop::create (MainContext::create());
|
||||
request_channel.ios()->attach (_main_loop->get_context());
|
||||
run_loop_thread = Thread::create (mem_fun (*this, &BaseUI::main_thread), true);
|
||||
}
|
||||
|
||||
void
|
||||
BaseUI::quit ()
|
||||
{
|
||||
_main_loop->quit ();
|
||||
run_loop_thread->join ();
|
||||
}
|
||||
|
||||
bool
|
||||
BaseUI::request_handler (Glib::IOCondition ioc)
|
||||
{
|
||||
/* check the transport request pipe */
|
||||
|
||||
if (ioc & ~IO_IN) {
|
||||
_main_loop->quit ();
|
||||
}
|
||||
|
||||
if (ioc & IO_IN) {
|
||||
request_channel.drain ();
|
||||
|
||||
/* there may been an error. we'd rather handle requests first,
|
||||
and then get IO_HUP or IO_ERR on the next loop.
|
||||
*/
|
||||
|
||||
/* handle requests */
|
||||
|
||||
handle_ui_requests ();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue