summaryrefslogtreecommitdiffstats
path: root/src/libs/engine
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2006-09-18 06:24:53 +0000
committerDavid Robillard <d@drobilla.net>2006-09-18 06:24:53 +0000
commit6f93b3d7c80f9dee2d95fac1bbc4f781a6f45979 (patch)
tree82b27a4802198215546558c006f7ac4228ab0599 /src/libs/engine
parentd520692eb49ff9e5aded38061a204713571b095b (diff)
downloadingen-6f93b3d7c80f9dee2d95fac1bbc4f781a6f45979.tar.gz
ingen-6f93b3d7c80f9dee2d95fac1bbc4f781a6f45979.tar.bz2
ingen-6f93b3d7c80f9dee2d95fac1bbc4f781a6f45979.zip
Work on loading old (deprecated) patches.
More error tolerance in Store, related bugfixes. Patch port adding (threading) bug fixed (made event blocking). Better PatchView cacheing. Moved generic things from engine to util (shared) Bug fixes, features, etc. git-svn-id: http://svn.drobilla.net/lad/ingen@142 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/libs/engine')
-rw-r--r--src/libs/engine/ClientBroadcaster.cpp10
-rw-r--r--src/libs/engine/ClientBroadcaster.h5
-rw-r--r--src/libs/engine/Engine.h2
-rw-r--r--src/libs/engine/Makefile.am7
-rw-r--r--src/libs/engine/NodeFactory.cpp19
-rw-r--r--src/libs/engine/NodeFactory.h1
-rw-r--r--src/libs/engine/OSCClientSender.cpp16
-rw-r--r--src/libs/engine/OSCClientSender.h6
-rw-r--r--src/libs/engine/OSCEngineReceiver.cpp57
-rw-r--r--src/libs/engine/OSCEngineReceiver.h5
-rw-r--r--src/libs/engine/ObjectSender.cpp90
-rw-r--r--src/libs/engine/ObjectSender.h4
-rw-r--r--src/libs/engine/Plugin.h9
-rw-r--r--src/libs/engine/PostProcessor.h2
-rw-r--r--src/libs/engine/QueuedEngineInterface.cpp33
-rw-r--r--src/libs/engine/QueuedEngineInterface.h4
-rw-r--r--src/libs/engine/QueuedEventSource.h2
-rw-r--r--src/libs/engine/Thread.cpp104
-rw-r--r--src/libs/engine/events.h2
-rw-r--r--src/libs/engine/events/AddNodeEvent.cpp31
-rw-r--r--src/libs/engine/events/AddNodeEvent.h18
-rw-r--r--src/libs/engine/events/AddPortEvent.cpp31
-rw-r--r--src/libs/engine/events/AddPortEvent.h2
-rw-r--r--src/libs/engine/events/CreatePatchEvent.cpp8
-rw-r--r--src/libs/engine/events/Makefile.am4
-rw-r--r--src/libs/engine/events/RequestAllObjectsEvent.cpp2
-rw-r--r--src/libs/engine/events/RequestObjectEvent.cpp97
-rw-r--r--src/libs/engine/events/RequestObjectEvent.h (renamed from src/libs/engine/Slave.h)48
-rw-r--r--src/libs/engine/events/RequestPluginEvent.cpp78
-rw-r--r--src/libs/engine/events/RequestPluginEvent.h (renamed from src/libs/engine/Thread.h)48
30 files changed, 458 insertions, 287 deletions
diff --git a/src/libs/engine/ClientBroadcaster.cpp b/src/libs/engine/ClientBroadcaster.cpp
index 7a21c38b..a214131a 100644
--- a/src/libs/engine/ClientBroadcaster.cpp
+++ b/src/libs/engine/ClientBroadcaster.cpp
@@ -175,7 +175,7 @@ ClientBroadcaster::send_plugins_to(CountedPtr<ClientInterface> client, const lis
for (list<Plugin*>::const_iterator i = plugin_list.begin(); i != plugin_list.end(); ++i) {
const Plugin* const plugin = *i;
- client->new_plugin(plugin->type_string(), plugin->uri(), plugin->name());
+ client->new_plugin(plugin->uri(), plugin->name());
}
client->transfer_end();
@@ -191,10 +191,10 @@ ClientBroadcaster::send_plugins(const list<Plugin*>& plugin_list)
void
-ClientBroadcaster::send_node(const Node* node)
+ClientBroadcaster::send_node(const Node* node, bool recursive)
{
for (ClientList::const_iterator i = _clients.begin(); i != _clients.end(); ++i)
- ObjectSender::send_node((*i).second.get(), node);
+ ObjectSender::send_node((*i).second.get(), node, recursive);
}
@@ -300,10 +300,10 @@ ClientBroadcaster::send_program_remove(const string& node_path, int bank, int pr
* Sends all objects underneath Patch - contained Nodes, etc.
*/
void
-ClientBroadcaster::send_patch(const Patch* const p)
+ClientBroadcaster::send_patch(const Patch* const p, bool recursive)
{
for (ClientList::const_iterator i = _clients.begin(); i != _clients.end(); ++i)
- ObjectSender::send_patch((*i).second.get(), p);
+ ObjectSender::send_patch((*i).second.get(), p, recursive);
}
diff --git a/src/libs/engine/ClientBroadcaster.h b/src/libs/engine/ClientBroadcaster.h
index 47ad75b4..97f2abf2 100644
--- a/src/libs/engine/ClientBroadcaster.h
+++ b/src/libs/engine/ClientBroadcaster.h
@@ -41,6 +41,7 @@ namespace Shared { class ClientKey; }
using Shared::ClientKey;
using Shared::ClientInterface;
+
/** Broadcaster for all clients.
*
* This sends messages to all client simultaneously through the opaque
@@ -71,8 +72,8 @@ public:
//void send_node_creation_messages(const Node* const node);
void send_plugins(const list<Plugin*>& plugin_list);
- void send_patch(const Patch* const p);
- void send_node(const Node* const node);
+ void send_patch(const Patch* const p, bool recursive);
+ void send_node(const Node* const node, bool recursive);
void send_port(const Port* port);
void send_destroyed(const string& path);
void send_patch_cleared(const string& patch_path);
diff --git a/src/libs/engine/Engine.h b/src/libs/engine/Engine.h
index 1f84d867..a8d110ca 100644
--- a/src/libs/engine/Engine.h
+++ b/src/libs/engine/Engine.h
@@ -72,7 +72,7 @@ public:
MidiDriver* midi_driver() const { return m_midi_driver; }
Maid* maid() const { return m_maid; }
PostProcessor* post_processor() const { return m_post_processor; }
- ClientBroadcaster* broadcaster() const { return m_broadcaster; }
+ ClientBroadcaster* broadcaster() const { return m_broadcaster; }
ObjectStore* object_store() const { return m_object_store; }
NodeFactory* node_factory() const { return m_node_factory; }
LashDriver* lash_driver() const { return m_lash_driver; }
diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am
index 99679932..3747515b 100644
--- a/src/libs/engine/Makefile.am
+++ b/src/libs/engine/Makefile.am
@@ -72,9 +72,6 @@ libingen_la_SOURCES = \
Plugin.cpp \
Array.h \
List.h \
- Slave.h \
- Thread.h \
- Thread.cpp \
PostProcessor.h \
PostProcessor.cpp \
Connection.h \
@@ -133,6 +130,10 @@ libingen_la_SOURCES = \
events/SetMetadataEvent.cpp \
events/RequestMetadataEvent.h \
events/RequestMetadataEvent.cpp \
+ events/RequestPluginEvent.h \
+ events/RequestPluginEvent.cpp \
+ events/RequestObjectEvent.h \
+ events/RequestObjectEvent.cpp \
events/RequestPortValueEvent.h \
events/RequestPortValueEvent.cpp \
events/RequestAllObjectsEvent.h \
diff --git a/src/libs/engine/NodeFactory.cpp b/src/libs/engine/NodeFactory.cpp
index ca762678..1cbabaeb 100644
--- a/src/libs/engine/NodeFactory.cpp
+++ b/src/libs/engine/NodeFactory.cpp
@@ -95,7 +95,6 @@ NodeFactory::~NodeFactory()
const Plugin*
NodeFactory::plugin(const string& uri)
{
- // FIXME: this needs.. well, fixing
for (list<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i)
if ((*i)->uri() == uri)
return (*i);
@@ -104,6 +103,24 @@ NodeFactory::plugin(const string& uri)
}
+/** DEPRECATED: Find a plugin by type, lib, label.
+ *
+ * Do not use.
+ */
+const Plugin*
+NodeFactory::plugin(const string& type, const string& lib, const string& label)
+{
+ if (type == "" || lib == "" || label == "")
+ return NULL;
+
+ for (list<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i)
+ if ((*i)->type_string() == type && (*i)->lib_name() == lib && (*i)->plug_label() == label)
+ return (*i);
+
+ return NULL;
+}
+
+
void
NodeFactory::load_plugins()
{
diff --git a/src/libs/engine/NodeFactory.h b/src/libs/engine/NodeFactory.h
index 1fd6c2d4..573c6808 100644
--- a/src/libs/engine/NodeFactory.h
+++ b/src/libs/engine/NodeFactory.h
@@ -57,6 +57,7 @@ public:
const list<Plugin*>& plugins() { return _plugins; }
const Plugin* plugin(const string& uri);
+ const Plugin* plugin(const string& type, const string& lib, const string& label); // DEPRECATED
private:
#ifdef HAVE_LADSPA
diff --git a/src/libs/engine/OSCClientSender.cpp b/src/libs/engine/OSCClientSender.cpp
index 538630c0..17b730fb 100644
--- a/src/libs/engine/OSCClientSender.cpp
+++ b/src/libs/engine/OSCClientSender.cpp
@@ -217,13 +217,14 @@ OSCClientSender::plugins()
* this one (/om/new_node), followed by a series of /om/new_port commands,
* followed by /om/new_node_end. </p> \n \n
*/
-void OSCClientSender::new_node(string plugin_type,
- string plugin_uri,
- string node_path,
- bool is_polyphonic,
- uint32_t num_ports)
+void OSCClientSender::new_node(string plugin_uri,
+ string node_path,
+ bool is_polyphonic,
+ uint32_t num_ports)
{
- lo_send(_address, "/om/new_node", "sssii", plugin_type.c_str(), plugin_uri.c_str(),
+ //cerr << "Sending node " << node_path << endl;
+
+ lo_send(_address, "/om/new_node", "ssii", plugin_uri.c_str(),
node_path.c_str(), is_polyphonic ? 1 : 0, num_ports);
#if 0
/*
@@ -453,10 +454,9 @@ OSCClientSender::control_change(string port_path, float value)
* \arg \b name (string) - Descriptive human-readable name of plugin (ie "ADSR Envelope")
*/
void
-OSCClientSender::new_plugin(string type, string uri, string name)
+OSCClientSender::new_plugin(string uri, string name)
{
lo_message m = lo_message_new();
- lo_message_add_string(m, type.c_str());
lo_message_add_string(m, uri.c_str());
lo_message_add_string(m, name.c_str());
diff --git a/src/libs/engine/OSCClientSender.h b/src/libs/engine/OSCClientSender.h
index 260dba63..a2ee9e26 100644
--- a/src/libs/engine/OSCClientSender.h
+++ b/src/libs/engine/OSCClientSender.h
@@ -72,14 +72,12 @@ public:
void error(string msg);
- virtual void new_plugin(string type,
- string uri,
+ virtual void new_plugin(string uri,
string name);
virtual void new_patch(string path, uint32_t poly);
- virtual void new_node(string plugin_type,
- string plugin_uri,
+ virtual void new_node(string plugin_uri,
string node_path,
bool is_polyphonic,
uint32_t num_ports);
diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp
index 92ab08f0..50876850 100644
--- a/src/libs/engine/OSCEngineReceiver.cpp
+++ b/src/libs/engine/OSCEngineReceiver.cpp
@@ -88,7 +88,7 @@ OSCEngineReceiver::OSCEngineReceiver(CountedPtr<Engine> engine, size_t queue_siz
lo_server_add_method(_server, "/om/synth/disable_patch", "is", disable_patch_cb, this);
lo_server_add_method(_server, "/om/synth/clear_patch", "is", clear_patch_cb, this);
lo_server_add_method(_server, "/om/synth/create_port", "issi", create_port_cb, this);
- lo_server_add_method(_server, "/om/synth/create_node", "isssi", create_node_cb, this);
+ lo_server_add_method(_server, "/om/synth/create_node", "issssi", create_node_cb, this);
lo_server_add_method(_server, "/om/synth/create_node", "issi", create_node_by_uri_cb, this);
lo_server_add_method(_server, "/om/synth/destroy", "is", destroy_cb, this);
lo_server_add_method(_server, "/om/synth/rename", "iss", rename_cb, this);
@@ -110,9 +110,12 @@ OSCEngineReceiver::OSCEngineReceiver(CountedPtr<Engine> engine, size_t queue_siz
lo_server_add_method(_server, "/om/metadata/set", NULL, metadata_set_cb, this);
// Queries
+ lo_server_add_method(_server, "/om/request/plugin", "is", request_plugin_cb, this);
+ lo_server_add_method(_server, "/om/request/object", "is", request_object_cb, this);
+ lo_server_add_method(_server, "/om/request/port_value", "is", request_port_value_cb, this);
lo_server_add_method(_server, "/om/request/plugins", "i", request_plugins_cb, this);
lo_server_add_method(_server, "/om/request/all_objects", "i", request_all_objects_cb, this);
- lo_server_add_method(_server, "/om/request/port_value", "is", request_port_value_cb, this);
+
// DSSI support
#ifdef HAVE_DSSI
@@ -799,29 +802,37 @@ OSCEngineReceiver::m_metadata_get_cb(const char* path, const char* types, lo_arg
/** \page engine_osc_namespace
- * <p> \b /om/responder/plugins - Requests the engine send a list of all known plugins.
+ * <p> \b /om/responder/plugin - Requests the engine send the value of a port.
* \arg \b response-id (integer)
+ * \arg \b port-path (string) - Full path of port to send the value of </p> \n \n
*
* \li Reply will be sent to client registered with the source address of this message.</p> \n \n
*/
int
-OSCEngineReceiver::m_request_plugins_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg)
+OSCEngineReceiver::m_request_plugin_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg)
{
- request_plugins();
+ const char* uri = &argv[1]->s;
+
+ request_plugin(uri);
+
return 0;
}
/** \page engine_osc_namespace
- * <p> \b /om/responder/all_objects - Requests the engine send information about \em all objects (patches, nodes, etc)
+ * <p> \b /om/responder/object - Requests the engine send the value of a port.
* \arg \b response-id (integer)
- *
+ * \arg \b port-path (string) - Full path of port to send the value of </p> \n \n
+ *
* \li Reply will be sent to client registered with the source address of this message.</p> \n \n
*/
int
-OSCEngineReceiver::m_request_all_objects_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg)
+OSCEngineReceiver::m_request_object_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg)
{
- request_all_objects();
+ const char* object_path = &argv[1]->s;
+
+ request_object(object_path);
+
return 0;
}
@@ -843,6 +854,34 @@ OSCEngineReceiver::m_request_port_value_cb(const char* path, const char* types,
}
+/** \page engine_osc_namespace
+ * <p> \b /om/responder/plugins - Requests the engine send a list of all known plugins.
+ * \arg \b response-id (integer)
+ *
+ * \li Reply will be sent to client registered with the source address of this message.</p> \n \n
+ */
+int
+OSCEngineReceiver::m_request_plugins_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg)
+{
+ request_plugins();
+ return 0;
+}
+
+
+/** \page engine_osc_namespace
+ * <p> \b /om/responder/all_objects - Requests the engine send information about \em all objects (patches, nodes, etc)
+ * \arg \b response-id (integer)
+ *
+ * \li Reply will be sent to client registered with the source address of this message.</p> \n \n
+ */
+int
+OSCEngineReceiver::m_request_all_objects_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg)
+{
+ request_all_objects();
+ return 0;
+}
+
+
#ifdef HAVE_DSSI
int
OSCEngineReceiver::m_dssi_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg)
diff --git a/src/libs/engine/OSCEngineReceiver.h b/src/libs/engine/OSCEngineReceiver.h
index 793286d4..c31587e6 100644
--- a/src/libs/engine/OSCEngineReceiver.h
+++ b/src/libs/engine/OSCEngineReceiver.h
@@ -107,9 +107,12 @@ private:
LO_HANDLER(midi_learn);
LO_HANDLER(metadata_get);
LO_HANDLER(metadata_set);
+ LO_HANDLER(request_plugin);
+ LO_HANDLER(request_object);
+ LO_HANDLER(request_port_value);
LO_HANDLER(request_plugins);
LO_HANDLER(request_all_objects);
- LO_HANDLER(request_port_value);
+
#ifdef HAVE_DSSI
LO_HANDLER(dssi);
#endif
diff --git a/src/libs/engine/ObjectSender.cpp b/src/libs/engine/ObjectSender.cpp
index 1e6b93c5..f7b4790f 100644
--- a/src/libs/engine/ObjectSender.cpp
+++ b/src/libs/engine/ObjectSender.cpp
@@ -28,41 +28,35 @@ namespace Ingen {
void
-ObjectSender::send_patch(ClientInterface* client, const Patch* patch)
+ObjectSender::send_patch(ClientInterface* client, const Patch* patch, bool recursive)
{
client->new_patch(patch->path(), patch->internal_poly());
- for (List<Node*>::const_iterator j = patch->nodes().begin();
- j != patch->nodes().end(); ++j) {
- const Node* const node = (*j);
+ if (recursive) {
- send_node(client, node);
- }
-
- // Send port information
- for (size_t i=0; i < patch->num_ports(); ++i) {
- Port* const port = patch->ports().at(i);
- send_port(client, port);
-/*
- // Send metadata
- const GraphObject::MetadataMap& data = port->metadata();
- for (GraphObject::MetadataMap::const_iterator i = data.begin(); i != data.end(); ++i)
- client->metadata_update(port->path(), (*i).first, (*i).second);
-
- // Control port, send value
- if (port->type() == DataType::FLOAT && port->buffer_size() == 1)
- client->control_change(port->path(),
- dynamic_cast<TypedPort<Sample>*>(port)->buffer(0)->value_at(0));
-*/
- }
+ // Send nodes
+ for (List<Node*>::const_iterator j = patch->nodes().begin();
+ j != patch->nodes().end(); ++j) {
+
+ const Node* const node = (*j);
+ send_node(client, node, true);
+ }
+ // Send ports
+ for (size_t i=0; i < patch->num_ports(); ++i) {
+
+ Port* const port = patch->ports().at(i);
+ send_port(client, port);
+
+ }
+
+ // Send connections
+ for (List<Connection*>::const_iterator j = patch->connections().begin();
+ j != patch->connections().end(); ++j)
+ client->connection((*j)->src_port()->path(), (*j)->dst_port()->path());
+
+ }
- // Send connections
- for (List<Connection*>::const_iterator j = patch->connections().begin();
- j != patch->connections().end(); ++j)
- client->connection((*j)->src_port()->path(), (*j)->dst_port()->path());
-
-
// Send metadata
const GraphObject::MetadataMap& data = patch->metadata();
for (GraphObject::MetadataMap::const_iterator j = data.begin(); j != data.end(); ++j)
@@ -75,7 +69,7 @@ ObjectSender::send_patch(ClientInterface* client, const Patch* patch)
/** Sends a node or a patch */
void
-ObjectSender::send_node(ClientInterface* client, const Node* node)
+ObjectSender::send_node(ClientInterface* client, const Node* node, bool recursive)
{
const Plugin* const plugin = node->plugin();
@@ -87,7 +81,7 @@ ObjectSender::send_node(ClientInterface* client, const Node* node)
assert(node->path().length() > 0);
if (plugin->type() == Plugin::Patch) {
- send_patch(client, (Patch*)node);
+ send_patch(client, (Patch*)node, recursive);
return;
}
@@ -95,32 +89,30 @@ ObjectSender::send_node(ClientInterface* client, const Node* node)
cerr << "Node " << node->path() << " plugin has no URI! Not sending." << endl;
return;
}
-
- client->bundle_begin();
-
// FIXME: bundleify
+ //client->bundle_begin();
const Array<Port*>& ports = node->ports();
- client->new_node(node->plugin()->type_string(), node->plugin()->uri(),
- node->path(), polyphonic, ports.size());
+ client->new_node(node->plugin()->uri(), node->path(), polyphonic, ports.size());
- // Send ports
- for (size_t j=0; j < ports.size(); ++j) {
- Port* const port = ports.at(j);
- assert(port);
-
- send_port(client, port);
- //client->new_port(port->path(), port->type().uri(), port->is_output());
+ if (recursive) {
+ // Send ports
+ for (size_t j=0; j < ports.size(); ++j) {
+ Port* const port = ports.at(j);
+ assert(port);
+
+ send_port(client, port);
+ }
}
- client->bundle_end();
-
// Send metadata
const GraphObject::MetadataMap& data = node->metadata();
for (GraphObject::MetadataMap::const_iterator j = data.begin(); j != data.end(); ++j)
client->metadata_update(node->path(), (*j).first, (*j).second);
+
+ //client->bundle_end();
}
@@ -128,6 +120,8 @@ void
ObjectSender::send_port(ClientInterface* client, const Port* port)
{
assert(port);
+
+ //cerr << "Sending port " << port->path();
// FIXME: temporary compatibility hack
string type = port->type().uri();
@@ -137,7 +131,9 @@ ObjectSender::send_port(ClientInterface* client, const Port* port)
else
type = "AUDIO";
}
-
+
+ //cerr << ", type = " << type << endl;
+
client->new_port(port->path(), type, port->is_output());
// Send control value
@@ -171,7 +167,7 @@ ObjectSender::send_plugins(ClientInterface* client, const list<Plugin*>& plugs)
*/
for (list<Plugin*>::const_iterator j = plugs.begin(); j != plugs.end(); ++j) {
const Plugin* const p = *j;
- client->new_plugin(p->type_string(), p->uri(), p->name());
+ client->new_plugin(p->uri(), p->name());
}
/*
plugin = (*j);
diff --git a/src/libs/engine/ObjectSender.h b/src/libs/engine/ObjectSender.h
index 38b1577f..ddd72dd7 100644
--- a/src/libs/engine/ObjectSender.h
+++ b/src/libs/engine/ObjectSender.h
@@ -45,8 +45,8 @@ public:
// FIXME: Make all object parameters const
- static void send_patch(ClientInterface* client, const Patch* patch);
- static void send_node(ClientInterface* client, const Node* node);
+ static void send_patch(ClientInterface* client, const Patch* patch, bool recursive);
+ static void send_node(ClientInterface* client, const Node* node, bool recursive);
static void send_port(ClientInterface* client, const Port* port);
static void send_plugins(ClientInterface* client, const std::list<Plugin*>& plugs);
};
diff --git a/src/libs/engine/Plugin.h b/src/libs/engine/Plugin.h
index bdb5a748..a841d6ee 100644
--- a/src/libs/engine/Plugin.h
+++ b/src/libs/engine/Plugin.h
@@ -53,6 +53,11 @@ public:
Plugin(Type type, const string& uri)
: _type(type)
, _uri(uri)
+ , _id(0)
+ , _library(NULL)
+#ifdef HAVE_SLV2
+ , _slv2_plugin(NULL)
+#endif
{}
// FIXME: remove
@@ -71,10 +76,12 @@ public:
if (copy->_type != Internal)
exit(EXIT_FAILURE);
_type = copy->_type;
- _lib_path = copy->_lib_path;
_uri = copy->_uri;
+ _lib_path = copy->_lib_path;
+ _lib_name = copy->_lib_name;
_plug_label = copy->_plug_label;
_name = copy->_name;
+ _id = _id;
_library = copy->_library;
}
diff --git a/src/libs/engine/PostProcessor.h b/src/libs/engine/PostProcessor.h
index e29175ee..212e3797 100644
--- a/src/libs/engine/PostProcessor.h
+++ b/src/libs/engine/PostProcessor.h
@@ -20,7 +20,7 @@
#include <pthread.h>
#include "types.h"
#include "util/Queue.h"
-#include "Slave.h"
+#include "util/Slave.h"
class Maid;
diff --git a/src/libs/engine/QueuedEngineInterface.cpp b/src/libs/engine/QueuedEngineInterface.cpp
index f8fc4827..53c5668c 100644
--- a/src/libs/engine/QueuedEngineInterface.cpp
+++ b/src/libs/engine/QueuedEngineInterface.cpp
@@ -135,7 +135,7 @@ void QueuedEngineInterface::create_port(const string& path,
const string& data_type,
bool direction)
{
- push_queued(new AddPortEvent(*_engine.get(), _responder, now(), path, data_type, direction));
+ push_queued(new AddPortEvent(*_engine.get(), _responder, now(), path, data_type, direction, this));
}
@@ -144,7 +144,8 @@ QueuedEngineInterface::create_node(const string& path,
const string& plugin_uri,
bool polyphonic)
{
- push_queued(new AddNodeEvent(*_engine.get(), _responder, now(), path, plugin_uri, polyphonic));
+ push_queued(new AddNodeEvent(*_engine.get(), _responder, now(),
+ path, plugin_uri, polyphonic));
}
@@ -155,18 +156,8 @@ QueuedEngineInterface::create_node(const string& path,
const string& plugin_label,
bool polyphonic)
{
- cerr << "FIXME: deprecated create_node\n";
- throw;
-#if 0
- // FIXME: ew
-
- Plugin* plugin = new Plugin();
- plugin->set_type(plugin_type);
- plugin->lib_name(plugin_lib);
- plugin->plug_label(plugin_label);
-
- push_queued(new AddNodeEvent(*_engine.get(), _responder, now(), path, plugin, polyphonic));
-#endif
+ push_queued(new AddNodeEvent(*_engine.get(), _responder, now(),
+ path, plugin_type, plugin_lib, plugin_label, polyphonic));
}
void
@@ -295,6 +286,20 @@ QueuedEngineInterface::ping()
void
+QueuedEngineInterface::request_plugin(const string& uri)
+{
+ push_queued(new RequestPluginEvent(*_engine.get(), _responder, now(), uri));
+}
+
+
+void
+QueuedEngineInterface::request_object(const string& path)
+{
+ push_queued(new RequestObjectEvent(*_engine.get(), _responder, now(), path));
+}
+
+
+void
QueuedEngineInterface::request_port_value(const string& port_path)
{
push_queued(new RequestPortValueEvent(*_engine.get(), _responder, now(), port_path));
diff --git a/src/libs/engine/QueuedEngineInterface.h b/src/libs/engine/QueuedEngineInterface.h
index 10b120e8..2a922acd 100644
--- a/src/libs/engine/QueuedEngineInterface.h
+++ b/src/libs/engine/QueuedEngineInterface.h
@@ -142,6 +142,10 @@ public:
virtual void ping();
+ virtual void request_plugin(const string& uri);
+
+ virtual void request_object(const string& path);
+
virtual void request_port_value(const string& port_path);
virtual void request_plugins();
diff --git a/src/libs/engine/QueuedEventSource.h b/src/libs/engine/QueuedEventSource.h
index f6be92d7..fddb61ab 100644
--- a/src/libs/engine/QueuedEventSource.h
+++ b/src/libs/engine/QueuedEventSource.h
@@ -22,7 +22,7 @@
#include "types.h"
#include "util/Semaphore.h"
#include "util/Queue.h"
-#include "Slave.h"
+#include "util/Slave.h"
#include "Event.h"
#include "EventSource.h"
diff --git a/src/libs/engine/Thread.cpp b/src/libs/engine/Thread.cpp
deleted file mode 100644
index 45c27ec4..00000000
--- a/src/libs/engine/Thread.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "Thread.h"
-#include <cassert>
-#include <iostream>
-#include <pthread.h>
-
-using std::cerr; using std::cout; using std::endl;
-
-namespace Ingen {
-
-
-Thread::Thread()
-: _pthread_exists(false)
-{
-}
-
-
-Thread::~Thread()
-{
- stop();
-}
-
-
-/** Start the process thread.
- */
-void
-Thread::start()
-{
- cout << "[" << _name << " Thread] Starting." << endl;
-
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setstacksize(&attr, 1500000);
-
- pthread_create(&_pthread, &attr, _static_run, this);
- _pthread_exists = true;
-}
-
-
-/** Stop the process thread.
- */
-void
-Thread::stop()
-{
- if (_pthread_exists) {
- pthread_cancel(_pthread);
- pthread_join(_pthread, NULL);
- _pthread_exists = false;
- }
-}
-
-
-/** Set the scheduling policy for this thread.
- *
- * @param must be one of SCHED_FIFO, SCHED_RR, or SCHED_OTHER.
- */
-void
-Thread::set_scheduling(int policy, unsigned int priority)
-{
- sched_param sp;
- sp.sched_priority = priority;
- int result = pthread_setschedparam(_pthread, SCHED_FIFO, &sp);
- if (!result) {
- cout << "[" << _name << " Thread] Set scheduling policy to ";
- switch (policy) {
- case SCHED_FIFO: cout << "SCHED_FIFO"; break;
- case SCHED_RR: cout << "SCHED_RR"; break;
- case SCHED_OTHER: cout << "SCHED_OTHER"; break;
- default: cout << "UNKNOWN"; break;
- }
- cout << ", priority " << sp.sched_priority << endl;
- } else {
- cout << "[" << _name << " Thread] Unable to set scheduling policy ("
- << strerror(result) << ")" << endl;
- }
-}
-
-
-void*
-Thread::_static_run(void* me)
-{
- Thread* myself = (Thread*)me;
- myself->_run();
- // and I
- return NULL;
-}
-
-} // namespace Ingen
-
diff --git a/src/libs/engine/events.h b/src/libs/engine/events.h
index 9db13bc7..056c302d 100644
--- a/src/libs/engine/events.h
+++ b/src/libs/engine/events.h
@@ -34,6 +34,8 @@
#include "DestroyEvent.h"
#include "SetMetadataEvent.h"
#include "RequestMetadataEvent.h"
+#include "RequestObjectEvent.h"
+#include "RequestPluginEvent.h"
#include "RequestPortValueEvent.h"
#include "RequestAllObjectsEvent.h"
#include "RequestPluginsEvent.h"
diff --git a/src/libs/engine/events/AddNodeEvent.cpp b/src/libs/engine/events/AddNodeEvent.cpp
index 6e42ef82..1a317e39 100644
--- a/src/libs/engine/events/AddNodeEvent.cpp
+++ b/src/libs/engine/events/AddNodeEvent.cpp
@@ -33,23 +33,31 @@
namespace Ingen {
-/*AddNodeEvent::AddNodeEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, Plugin* plugin, bool poly)
+AddNodeEvent::AddNodeEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path,
+ const string& plugin_uri, bool poly)
: QueuedEvent(engine, responder, timestamp),
m_path(path),
- m_plugin(plugin),
+ m_plugin_uri(plugin_uri),
m_poly(poly),
m_patch(NULL),
m_node(NULL),
m_process_order(NULL),
m_node_already_exists(false)
{
-}*/
+}
+
+/** DEPRECATED: Construct from type, library name, and plugin label.
+ *
+ * Do not use.
+ */
AddNodeEvent::AddNodeEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path,
- const string& plugin_uri, bool poly)
+ const string& plugin_type, const string& plugin_lib, const string& plugin_label, bool poly)
: QueuedEvent(engine, responder, timestamp),
m_path(path),
- m_plugin_uri(plugin_uri),
+ m_plugin_type(plugin_type),
+ m_plugin_lib(plugin_lib),
+ m_plugin_label(plugin_label),
m_poly(poly),
m_patch(NULL),
m_node(NULL),
@@ -59,11 +67,6 @@ AddNodeEvent::AddNodeEvent(Engine& engine, CountedPtr<Responder> responder, Samp
}
-AddNodeEvent::~AddNodeEvent()
-{
-}
-
-
void
AddNodeEvent::pre_process()
{
@@ -74,7 +77,10 @@ AddNodeEvent::pre_process()
}
m_patch = _engine.object_store()->find_patch(m_path.parent());
- const Plugin* plugin = _engine.node_factory()->plugin(m_plugin_uri);
+
+ const Plugin* plugin = (m_plugin_uri != "")
+ ? _engine.node_factory()->plugin(m_plugin_uri)
+ : _engine.node_factory()->plugin(m_plugin_type, m_plugin_lib, m_plugin_label);
if (m_patch && plugin) {
if (m_poly)
@@ -130,8 +136,7 @@ AddNodeEvent::post_process()
_responder->respond_error(msg);
} else {
_responder->respond_ok();
- //_engine.broadcaster()->send_node_creation_messages(m_node);
- _engine.broadcaster()->send_node(m_node);
+ _engine.broadcaster()->send_node(m_node, true); // yes, send ports
}
}
diff --git a/src/libs/engine/events/AddNodeEvent.h b/src/libs/engine/events/AddNodeEvent.h
index b4345f90..22e164ea 100644
--- a/src/libs/engine/events/AddNodeEvent.h
+++ b/src/libs/engine/events/AddNodeEvent.h
@@ -39,15 +39,22 @@ class Plugin;
class AddNodeEvent : public QueuedEvent
{
public:
- //AddNodeEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, Plugin* plugin, bool poly);
AddNodeEvent(Engine& engine,
CountedPtr<Responder> responder,
SampleCount timestamp,
const string& node_path,
const string& plugin_uri,
bool poly);
-
- ~AddNodeEvent();
+
+ // DEPRECATED
+ AddNodeEvent(Engine& engine,
+ CountedPtr<Responder> responder,
+ SampleCount timestamp,
+ const string& node_path,
+ const string& plugin_type,
+ const string& lib_name,
+ const string& plugin_label,
+ bool poly);
void pre_process();
void execute(SampleCount nframes, FrameTime start, FrameTime end);
@@ -56,7 +63,10 @@ public:
private:
string m_patch_name;
Path m_path;
- string m_plugin_uri;
+ string m_plugin_uri; ///< If nonempty then type, library, label, are ignored
+ string m_plugin_type;
+ string m_plugin_lib;
+ string m_plugin_label;
bool m_poly;
Patch* m_patch;
Node* m_node;
diff --git a/src/libs/engine/events/AddPortEvent.cpp b/src/libs/engine/events/AddPortEvent.cpp
index 06ddae94..ae692b1b 100644
--- a/src/libs/engine/events/AddPortEvent.cpp
+++ b/src/libs/engine/events/AddPortEvent.cpp
@@ -23,6 +23,7 @@
#include "Patch.h"
#include "Maid.h"
#include "util/Path.h"
+#include "QueuedEventSource.h"
#include "ObjectStore.h"
#include "ClientBroadcaster.h"
#include "util/Path.h"
@@ -32,12 +33,13 @@
#include "List.h"
#include "Driver.h"
#include "DuplexPort.h"
+#include "Array.h"
namespace Ingen {
-AddPortEvent::AddPortEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output)
-: QueuedEvent(engine, responder, timestamp),
+AddPortEvent::AddPortEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output, QueuedEventSource* source)
+: QueuedEvent(engine, responder, timestamp, true, source),
_path(path),
_type(type),
_is_output(is_output),
@@ -46,6 +48,14 @@ AddPortEvent::AddPortEvent(Engine& engine, CountedPtr<Responder> responder, Samp
_patch_port(NULL),
_driver_port(NULL)
{
+ /* This is blocking because of the two different sets of Patch ports, the array used in the
+ * audio thread (inherited from NodeBase), and the arrays used in the pre processor thread.
+ * If two add port events arrive in the same cycle and the second pre processes before the
+ * first executes, bad things happen (ports are lost).
+ *
+ * FIXME: fix this using RCU
+ */
+
string type_str;
if (type == "CONTROL" || type == "AUDIO")
_data_type = DataType::FLOAT;
@@ -73,17 +83,22 @@ AddPortEvent::pre_process()
if (_type == "AUDIO" || _type == "MIDI")
buffer_size = _engine.audio_driver()->buffer_size();
+ const size_t old_num_ports = _patch->num_ports();
+
_patch_port = _patch->create_port(_path.name(), _data_type, buffer_size, _is_output);
+
if (_patch_port) {
+
if (_is_output)
_patch->add_output(new ListNode<Port*>(_patch_port));
else
_patch->add_input(new ListNode<Port*>(_patch_port));
if (_patch->external_ports())
- _ports_array = new Array<Port*>(_patch->num_ports() + 1, *_patch->external_ports());
+ _ports_array = new Array<Port*>(old_num_ports + 1, *_patch->external_ports());
else
- _ports_array = new Array<Port*>(_patch->num_ports() + 1, NULL);
+ _ports_array = new Array<Port*>(old_num_ports + 1, NULL);
+
_ports_array->at(_patch->num_ports()) = _patch_port;
_engine.object_store()->add(_patch_port);
@@ -96,6 +111,9 @@ AddPortEvent::pre_process()
_driver_port = _engine.midi_driver()->create_port(
dynamic_cast<DuplexPort<MidiMessage>*>(_patch_port));
}
+
+ assert(_patch->num_ports() == old_num_ports);
+ assert(_ports_array->size() == _patch->num_ports() + 1);
}
}
QueuedEvent::pre_process();
@@ -108,8 +126,10 @@ AddPortEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
QueuedEvent::execute(nframes, start, end);
if (_patch_port) {
+
_engine.maid()->push(_patch->external_ports());
//_patch->add_port(_port);
+
_patch->external_ports(_ports_array);
}
@@ -121,6 +141,9 @@ AddPortEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
void
AddPortEvent::post_process()
{
+ if (_source)
+ _source->unblock();
+
if (!_patch_port) {
const string msg = string("Could not create port - ").append(_path);
_responder->respond_error(msg);
diff --git a/src/libs/engine/events/AddPortEvent.h b/src/libs/engine/events/AddPortEvent.h
index 070d07df..0ef33515 100644
--- a/src/libs/engine/events/AddPortEvent.h
+++ b/src/libs/engine/events/AddPortEvent.h
@@ -41,7 +41,7 @@ class DriverPort;
class AddPortEvent : public QueuedEvent
{
public:
- AddPortEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output);
+ AddPortEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output, QueuedEventSource* source);
void pre_process();
void execute(SampleCount nframes, FrameTime start, FrameTime end);
diff --git a/src/libs/engine/events/CreatePatchEvent.cpp b/src/libs/engine/events/CreatePatchEvent.cpp
index 7532291b..97be5557 100644
--- a/src/libs/engine/events/CreatePatchEvent.cpp
+++ b/src/libs/engine/events/CreatePatchEvent.cpp
@@ -120,11 +120,9 @@ CreatePatchEvent::post_process()
_responder->respond_ok();
- // Don't want to send nodes that have been added since prepare()
- //_engine.broadcaster()->send_node_creation_messages(m_patch);
-
- // Patches are always empty on creation, so this is fine
- _engine.broadcaster()->send_patch(m_patch);
+ // Don't send ports/nodes that have been added since prepare()
+ // (otherwise they would be sent twice)
+ _engine.broadcaster()->send_patch(m_patch, false);
} else if (m_error == OBJECT_EXISTS) {
string msg = "Unable to create patch: ";
diff --git a/src/libs/engine/events/Makefile.am b/src/libs/engine/events/Makefile.am
index 5b29e12b..a1760738 100644
--- a/src/libs/engine/events/Makefile.am
+++ b/src/libs/engine/events/Makefile.am
@@ -36,6 +36,10 @@ EXTRA_DIST = \
events/SetMetadataEvent.cpp \
events/RequestMetadataEvent.h \
events/RequestMetadataEvent.cpp \
+ events/RequestPluginEvent.h \
+ events/RequestPluginEvent.cpp \
+ events/RequestObjectEvent.h \
+ events/RequestObjectEvent.cpp \
events/RequestPortValueEvent.h \
events/RequestPortValueEvent.cpp \
events/RequestAllObjectsEvent.h \
diff --git a/src/libs/engine/events/RequestAllObjectsEvent.cpp b/src/libs/engine/events/RequestAllObjectsEvent.cpp
index f51a514e..893aa5df 100644
--- a/src/libs/engine/events/RequestAllObjectsEvent.cpp
+++ b/src/libs/engine/events/RequestAllObjectsEvent.cpp
@@ -48,7 +48,7 @@ RequestAllObjectsEvent::post_process()
// Everything is a child of the root patch, so this sends it all
Patch* root = _engine.object_store()->find_patch("/");
if (root)
- ObjectSender::send_patch(m_client.get(), root);
+ ObjectSender::send_patch(m_client.get(), root, true);
} else {
_responder->respond_error("Unable to find client to send all objects");
diff --git a/src/libs/engine/events/RequestObjectEvent.cpp b/src/libs/engine/events/RequestObjectEvent.cpp
new file mode 100644
index 00000000..3b0dc6fd
--- /dev/null
+++ b/src/libs/engine/events/RequestObjectEvent.cpp
@@ -0,0 +1,97 @@
+/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
+ *
+ * Ingen is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "RequestObjectEvent.h"
+#include <string>
+#include "Responder.h"
+#include "Engine.h"
+#include "interface/ClientInterface.h"
+#include "TypedPort.h"
+#include "ObjectStore.h"
+#include "ClientBroadcaster.h"
+#include "Patch.h"
+#include "Node.h"
+#include "ObjectSender.h"
+
+using std::string;
+
+namespace Ingen {
+
+
+RequestObjectEvent::RequestObjectEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path)
+: QueuedEvent(engine, responder, timestamp),
+ m_path(path),
+ m_object(NULL)
+{
+}
+
+
+void
+RequestObjectEvent::pre_process()
+{
+ m_client = _engine.broadcaster()->client(_responder->client_key());
+ m_object = _engine.object_store()->find(m_path);
+
+ QueuedEvent::pre_process();
+}
+
+
+void
+RequestObjectEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
+{
+ QueuedEvent::execute(nframes, start, end);
+ assert(_time >= start && _time <= end);
+}
+
+
+void
+RequestObjectEvent::post_process()
+{
+ if (!m_object) {
+ _responder->respond_error("Unable to find object requested.");
+
+ } else if (m_client) {
+ Patch* const patch = dynamic_cast<Patch*>(m_object);
+ if (patch) {
+ _responder->respond_ok();
+ ObjectSender::send_patch(m_client.get(), patch, true);
+ return;
+ }
+
+ Node* const node = dynamic_cast<Node*>(m_object);
+ if (node) {
+ _responder->respond_ok();
+ ObjectSender::send_node(m_client.get(), node, true);
+ return;
+ }
+
+ Port* const port = dynamic_cast<Port*>(m_object);
+ if (port) {
+ _responder->respond_ok();
+ ObjectSender::send_port(m_client.get(), port);
+ return;
+ }
+
+ _responder->respond_error("Object of unknown type requested.");
+
+ } else {
+ _responder->respond_error("Unable to find client to send object.");
+ }
+}
+
+
+} // namespace Ingen
+
diff --git a/src/libs/engine/Slave.h b/src/libs/engine/events/RequestObjectEvent.h
index b48a3ab7..276b60fa 100644
--- a/src/libs/engine/Slave.h
+++ b/src/libs/engine/events/RequestObjectEvent.h
@@ -14,48 +14,42 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef SLAVE_H
-#define SLAVE_H
+#ifndef REQUESTOBJECTEVENT_H
+#define REQUESTOBJECTEVENT_H
-#include <pthread.h>
-#include "util/Semaphore.h"
-#include "Thread.h"
+#include <string>
+#include "QueuedEvent.h"
+#include "types.h"
+
+using std::string;
namespace Ingen {
+
+class GraphObject;
+namespace Shared { class ClientInterface; }
+using Shared::ClientInterface;
-/** Thread driven by (realtime safe) signals.
+/** A request from a client to send the value of a port.
*
* \ingroup engine
*/
-class Slave : public Thread
+class RequestObjectEvent : public QueuedEvent
{
public:
- Slave() : _whip(0) {}
-
- /** Tell the slave to do whatever work it does. Realtime safe. */
- inline void whip() { _whip.post(); }
-
-protected:
- virtual void _whipped() = 0;
+ RequestObjectEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path);
- Semaphore _whip;
+ void pre_process();
+ void execute(SampleCount nframes, FrameTime start, FrameTime end);
+ void post_process();
private:
- // Prevent copies
- Slave(const Slave&);
- Slave& operator=(const Slave&);
-
- inline void _run()
- {
- while (true) {
- _whip.wait();
- _whipped();
- }
- }
+ string m_path;
+ GraphObject* m_object;
+ CountedPtr<ClientInterface> m_client;
};
} // namespace Ingen
-#endif // SLAVE_H
+#endif // REQUESTOBJECTEVENT_H
diff --git a/src/libs/engine/events/RequestPluginEvent.cpp b/src/libs/engine/events/RequestPluginEvent.cpp
new file mode 100644
index 00000000..95141226
--- /dev/null
+++ b/src/libs/engine/events/RequestPluginEvent.cpp
@@ -0,0 +1,78 @@
+/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
+ *
+ * Ingen is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "RequestPluginEvent.h"
+#include <string>
+#include "Responder.h"
+#include "Engine.h"
+#include "interface/ClientInterface.h"
+#include "TypedPort.h"
+#include "ObjectStore.h"
+#include "ClientBroadcaster.h"
+#include "NodeFactory.h"
+#include "Plugin.h"
+
+using std::string;
+
+namespace Ingen {
+
+
+RequestPluginEvent::RequestPluginEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& uri)
+: QueuedEvent(engine, responder, timestamp),
+ m_uri(uri),
+ m_plugin(NULL)
+{
+}
+
+
+void
+RequestPluginEvent::pre_process()
+{
+ m_client = _engine.broadcaster()->client(_responder->client_key());
+ m_plugin = _engine.node_factory()->plugin(m_uri);
+
+ QueuedEvent::pre_process();
+}
+
+
+void
+RequestPluginEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
+{
+ QueuedEvent::execute(nframes, start, end);
+ assert(_time >= start && _time <= end);
+}
+
+
+void
+RequestPluginEvent::post_process()
+{
+ if (!m_plugin) {
+ _responder->respond_error("Unable to find plugin requested.");
+
+ } else if (m_client) {
+
+ _responder->respond_ok();
+ assert(m_plugin->uri() == m_uri);
+ m_client->new_plugin(m_uri, m_plugin->name());
+
+ } else {
+ _responder->respond_error("Unable to find client to send plugin.");
+ }
+}
+
+
+} // namespace Ingen
+
diff --git a/src/libs/engine/Thread.h b/src/libs/engine/events/RequestPluginEvent.h
index 52423844..1c12c78e 100644
--- a/src/libs/engine/Thread.h
+++ b/src/libs/engine/events/RequestPluginEvent.h
@@ -14,50 +14,42 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef THREAD_H
-#define THREAD_H
+#ifndef REQUESTPLUGINEVENT_H
+#define REQUESTPLUGINEVENT_H
#include <string>
-#include <pthread.h>
-
-namespace Ingen {
+#include "QueuedEvent.h"
+#include "types.h"
+using std::string;
-/* FIXME: This isn't Ingen specific at all. Move it to util. */
+namespace Ingen {
+
+class Plugin;
+namespace Shared { class ClientInterface; }
+using Shared::ClientInterface;
-/** Abstract base class for all threads.
+/** A request from a client to send the value of a port.
*
* \ingroup engine
*/
-class Thread
+class RequestPluginEvent : public QueuedEvent
{
public:
- Thread();
- virtual ~Thread();
-
- virtual void start();
- virtual void stop();
+ RequestPluginEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& uri);
- void set_name(const std::string& name) { _name = name; }
- void set_scheduling(int policy, unsigned int priority);
-
-protected:
- virtual void _run() = 0;
-
- std::string _name;
- pthread_t _pthread;
- bool _pthread_exists;
+ void pre_process();
+ void execute(SampleCount nframes, FrameTime start, FrameTime end);
+ void post_process();
private:
- // Prevent copies
- Thread(const Thread&);
- Thread& operator=(const Thread&);
-
- static void* _static_run(void* me);
+ string m_uri;
+ const Plugin* m_plugin;
+ CountedPtr<ClientInterface> m_client;
};
} // namespace Ingen
-#endif // THREAD_H
+#endif // REQUESTPLUGINEVENT_H