summaryrefslogtreecommitdiffstats
path: root/src/libs/engine/events
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/engine/events')
-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.h55
-rw-r--r--src/libs/engine/events/RequestPluginEvent.cpp78
-rw-r--r--src/libs/engine/events/RequestPluginEvent.h55
11 files changed, 353 insertions, 28 deletions
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/events/RequestObjectEvent.h b/src/libs/engine/events/RequestObjectEvent.h
new file mode 100644
index 00000000..276b60fa
--- /dev/null
+++ b/src/libs/engine/events/RequestObjectEvent.h
@@ -0,0 +1,55 @@
+/* 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
+ */
+
+#ifndef REQUESTOBJECTEVENT_H
+#define REQUESTOBJECTEVENT_H
+
+#include <string>
+#include "QueuedEvent.h"
+#include "types.h"
+
+using std::string;
+
+namespace Ingen {
+
+class GraphObject;
+namespace Shared { class ClientInterface; }
+using Shared::ClientInterface;
+
+
+/** A request from a client to send the value of a port.
+ *
+ * \ingroup engine
+ */
+class RequestObjectEvent : public QueuedEvent
+{
+public:
+ RequestObjectEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path);
+
+ void pre_process();
+ void execute(SampleCount nframes, FrameTime start, FrameTime end);
+ void post_process();
+
+private:
+ string m_path;
+ GraphObject* m_object;
+ CountedPtr<ClientInterface> m_client;
+};
+
+
+} // namespace Ingen
+
+#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/events/RequestPluginEvent.h b/src/libs/engine/events/RequestPluginEvent.h
new file mode 100644
index 00000000..1c12c78e
--- /dev/null
+++ b/src/libs/engine/events/RequestPluginEvent.h
@@ -0,0 +1,55 @@
+/* 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
+ */
+
+#ifndef REQUESTPLUGINEVENT_H
+#define REQUESTPLUGINEVENT_H
+
+#include <string>
+#include "QueuedEvent.h"
+#include "types.h"
+
+using std::string;
+
+namespace Ingen {
+
+class Plugin;
+namespace Shared { class ClientInterface; }
+using Shared::ClientInterface;
+
+
+/** A request from a client to send the value of a port.
+ *
+ * \ingroup engine
+ */
+class RequestPluginEvent : public QueuedEvent
+{
+public:
+ RequestPluginEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& uri);
+
+ void pre_process();
+ void execute(SampleCount nframes, FrameTime start, FrameTime end);
+ void post_process();
+
+private:
+ string m_uri;
+ const Plugin* m_plugin;
+ CountedPtr<ClientInterface> m_client;
+};
+
+
+} // namespace Ingen
+
+#endif // REQUESTPLUGINEVENT_H