From 952d0c985dd511050ba17f4e293faf01d7885dad Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 3 Jun 2009 00:56:34 +0000 Subject: Chop "Event" from event source file names. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2066 a436a847-0d15-0410-975c-d299462d15a1 --- src/engine/events/AllNotesOff.cpp | 73 ++++++++ src/engine/events/AllNotesOff.hpp | 49 ++++++ src/engine/events/AllNotesOffEvent.cpp | 73 -------- src/engine/events/AllNotesOffEvent.hpp | 49 ------ src/engine/events/ClearPatch.cpp | 179 ++++++++++++++++++++ src/engine/events/ClearPatch.hpp | 64 +++++++ src/engine/events/ClearPatchEvent.cpp | 179 -------------------- src/engine/events/ClearPatchEvent.hpp | 64 ------- src/engine/events/Connection.cpp | 204 ++++++++++++++++++++++ src/engine/events/Connection.hpp | 90 ++++++++++ src/engine/events/ConnectionEvent.cpp | 204 ---------------------- src/engine/events/ConnectionEvent.hpp | 90 ---------- src/engine/events/CreateNode.cpp | 148 ++++++++++++++++ src/engine/events/CreateNode.hpp | 70 ++++++++ src/engine/events/CreateNodeEvent.cpp | 148 ---------------- src/engine/events/CreateNodeEvent.hpp | 70 -------- src/engine/events/CreatePatch.cpp | 164 ++++++++++++++++++ src/engine/events/CreatePatch.hpp | 66 ++++++++ src/engine/events/CreatePatchEvent.cpp | 164 ------------------ src/engine/events/CreatePatchEvent.hpp | 66 -------- src/engine/events/CreatePort.cpp | 181 ++++++++++++++++++++ src/engine/events/CreatePort.hpp | 80 +++++++++ src/engine/events/CreatePortEvent.cpp | 181 -------------------- src/engine/events/CreatePortEvent.hpp | 80 --------- src/engine/events/Deactivate.hpp | 47 ++++++ src/engine/events/DeactivateEvent.hpp | 47 ------ src/engine/events/Delete.cpp | 213 +++++++++++++++++++++++ src/engine/events/Delete.hpp | 87 ++++++++++ src/engine/events/DeleteEvent.cpp | 213 ----------------------- src/engine/events/DeleteEvent.hpp | 87 ---------- src/engine/events/DisconnectAll.cpp | 186 ++++++++++++++++++++ src/engine/events/DisconnectAll.hpp | 76 +++++++++ src/engine/events/DisconnectAllEvent.cpp | 186 -------------------- src/engine/events/DisconnectAllEvent.hpp | 76 --------- src/engine/events/Disconnection.cpp | 212 +++++++++++++++++++++++ src/engine/events/Disconnection.hpp | 88 ++++++++++ src/engine/events/DisconnectionEvent.cpp | 212 ----------------------- src/engine/events/DisconnectionEvent.hpp | 88 ---------- src/engine/events/Get.cpp | 86 ++++++++++ src/engine/events/Get.hpp | 56 ++++++ src/engine/events/GetEvent.cpp | 86 ---------- src/engine/events/GetEvent.hpp | 56 ------ src/engine/events/LoadPlugins.cpp | 53 ++++++ src/engine/events/LoadPlugins.hpp | 45 +++++ src/engine/events/LoadPluginsEvent.cpp | 53 ------ src/engine/events/LoadPluginsEvent.hpp | 45 ----- src/engine/events/MidiLearn.cpp | 83 +++++++++ src/engine/events/MidiLearn.hpp | 58 +++++++ src/engine/events/MidiLearnEvent.cpp | 83 --------- src/engine/events/MidiLearnEvent.hpp | 58 ------- src/engine/events/Move.cpp | 142 ++++++++++++++++ src/engine/events/Move.hpp | 76 +++++++++ src/engine/events/MoveEvent.cpp | 142 ---------------- src/engine/events/MoveEvent.hpp | 76 --------- src/engine/events/Note.cpp | 104 ++++++++++++ src/engine/events/Note.hpp | 66 ++++++++ src/engine/events/NoteEvent.cpp | 104 ------------ src/engine/events/NoteEvent.hpp | 66 -------- src/engine/events/PingQueued.hpp | 48 ++++++ src/engine/events/PingQueuedEvent.hpp | 48 ------ src/engine/events/RegisterClient.cpp | 57 +++++++ src/engine/events/RegisterClient.hpp | 52 ++++++ src/engine/events/RegisterClientEvent.cpp | 57 ------- src/engine/events/RegisterClientEvent.hpp | 52 ------ src/engine/events/RequestAllObjects.cpp | 60 +++++++ src/engine/events/RequestAllObjects.hpp | 42 +++++ src/engine/events/RequestAllObjectsEvent.cpp | 60 ------- src/engine/events/RequestAllObjectsEvent.hpp | 42 ----- src/engine/events/RequestMetadata.cpp | 128 ++++++++++++++ src/engine/events/RequestMetadata.hpp | 73 ++++++++ src/engine/events/RequestMetadataEvent.cpp | 128 -------------- src/engine/events/RequestMetadataEvent.hpp | 73 -------- src/engine/events/RequestPlugins.cpp | 57 +++++++ src/engine/events/RequestPlugins.hpp | 47 ++++++ src/engine/events/RequestPluginsEvent.cpp | 57 ------- src/engine/events/RequestPluginsEvent.hpp | 47 ------ src/engine/events/SendPortActivity.cpp | 34 ++++ src/engine/events/SendPortActivity.hpp | 65 +++++++ src/engine/events/SendPortActivityEvent.cpp | 34 ---- src/engine/events/SendPortActivityEvent.hpp | 65 ------- src/engine/events/SendPortValue.cpp | 43 +++++ src/engine/events/SendPortValue.hpp | 76 +++++++++ src/engine/events/SendPortValueEvent.cpp | 43 ----- src/engine/events/SendPortValueEvent.hpp | 76 --------- src/engine/events/SetMetadata.cpp | 242 ++++++++++++++++++++++++++ src/engine/events/SetMetadata.hpp | 100 +++++++++++ src/engine/events/SetMetadataEvent.cpp | 243 --------------------------- src/engine/events/SetMetadataEvent.hpp | 100 ----------- src/engine/events/SetPortValue.cpp | 230 +++++++++++++++++++++++++ src/engine/events/SetPortValue.hpp | 86 ++++++++++ src/engine/events/SetPortValueEvent.cpp | 230 ------------------------- src/engine/events/SetPortValueEvent.hpp | 86 ---------- src/engine/events/UnregisterClient.cpp | 47 ++++++ src/engine/events/UnregisterClient.hpp | 48 ++++++ src/engine/events/UnregisterClientEvent.cpp | 47 ------ src/engine/events/UnregisterClientEvent.hpp | 48 ------ 96 files changed, 4581 insertions(+), 4582 deletions(-) create mode 100644 src/engine/events/AllNotesOff.cpp create mode 100644 src/engine/events/AllNotesOff.hpp delete mode 100644 src/engine/events/AllNotesOffEvent.cpp delete mode 100644 src/engine/events/AllNotesOffEvent.hpp create mode 100644 src/engine/events/ClearPatch.cpp create mode 100644 src/engine/events/ClearPatch.hpp delete mode 100644 src/engine/events/ClearPatchEvent.cpp delete mode 100644 src/engine/events/ClearPatchEvent.hpp create mode 100644 src/engine/events/Connection.cpp create mode 100644 src/engine/events/Connection.hpp delete mode 100644 src/engine/events/ConnectionEvent.cpp delete mode 100644 src/engine/events/ConnectionEvent.hpp create mode 100644 src/engine/events/CreateNode.cpp create mode 100644 src/engine/events/CreateNode.hpp delete mode 100644 src/engine/events/CreateNodeEvent.cpp delete mode 100644 src/engine/events/CreateNodeEvent.hpp create mode 100644 src/engine/events/CreatePatch.cpp create mode 100644 src/engine/events/CreatePatch.hpp delete mode 100644 src/engine/events/CreatePatchEvent.cpp delete mode 100644 src/engine/events/CreatePatchEvent.hpp create mode 100644 src/engine/events/CreatePort.cpp create mode 100644 src/engine/events/CreatePort.hpp delete mode 100644 src/engine/events/CreatePortEvent.cpp delete mode 100644 src/engine/events/CreatePortEvent.hpp create mode 100644 src/engine/events/Deactivate.hpp delete mode 100644 src/engine/events/DeactivateEvent.hpp create mode 100644 src/engine/events/Delete.cpp create mode 100644 src/engine/events/Delete.hpp delete mode 100644 src/engine/events/DeleteEvent.cpp delete mode 100644 src/engine/events/DeleteEvent.hpp create mode 100644 src/engine/events/DisconnectAll.cpp create mode 100644 src/engine/events/DisconnectAll.hpp delete mode 100644 src/engine/events/DisconnectAllEvent.cpp delete mode 100644 src/engine/events/DisconnectAllEvent.hpp create mode 100644 src/engine/events/Disconnection.cpp create mode 100644 src/engine/events/Disconnection.hpp delete mode 100644 src/engine/events/DisconnectionEvent.cpp delete mode 100644 src/engine/events/DisconnectionEvent.hpp create mode 100644 src/engine/events/Get.cpp create mode 100644 src/engine/events/Get.hpp delete mode 100644 src/engine/events/GetEvent.cpp delete mode 100644 src/engine/events/GetEvent.hpp create mode 100644 src/engine/events/LoadPlugins.cpp create mode 100644 src/engine/events/LoadPlugins.hpp delete mode 100644 src/engine/events/LoadPluginsEvent.cpp delete mode 100644 src/engine/events/LoadPluginsEvent.hpp create mode 100644 src/engine/events/MidiLearn.cpp create mode 100644 src/engine/events/MidiLearn.hpp delete mode 100644 src/engine/events/MidiLearnEvent.cpp delete mode 100644 src/engine/events/MidiLearnEvent.hpp create mode 100644 src/engine/events/Move.cpp create mode 100644 src/engine/events/Move.hpp delete mode 100644 src/engine/events/MoveEvent.cpp delete mode 100644 src/engine/events/MoveEvent.hpp create mode 100644 src/engine/events/Note.cpp create mode 100644 src/engine/events/Note.hpp delete mode 100644 src/engine/events/NoteEvent.cpp delete mode 100644 src/engine/events/NoteEvent.hpp create mode 100644 src/engine/events/PingQueued.hpp delete mode 100644 src/engine/events/PingQueuedEvent.hpp create mode 100644 src/engine/events/RegisterClient.cpp create mode 100644 src/engine/events/RegisterClient.hpp delete mode 100644 src/engine/events/RegisterClientEvent.cpp delete mode 100644 src/engine/events/RegisterClientEvent.hpp create mode 100644 src/engine/events/RequestAllObjects.cpp create mode 100644 src/engine/events/RequestAllObjects.hpp delete mode 100644 src/engine/events/RequestAllObjectsEvent.cpp delete mode 100644 src/engine/events/RequestAllObjectsEvent.hpp create mode 100644 src/engine/events/RequestMetadata.cpp create mode 100644 src/engine/events/RequestMetadata.hpp delete mode 100644 src/engine/events/RequestMetadataEvent.cpp delete mode 100644 src/engine/events/RequestMetadataEvent.hpp create mode 100644 src/engine/events/RequestPlugins.cpp create mode 100644 src/engine/events/RequestPlugins.hpp delete mode 100644 src/engine/events/RequestPluginsEvent.cpp delete mode 100644 src/engine/events/RequestPluginsEvent.hpp create mode 100644 src/engine/events/SendPortActivity.cpp create mode 100644 src/engine/events/SendPortActivity.hpp delete mode 100644 src/engine/events/SendPortActivityEvent.cpp delete mode 100644 src/engine/events/SendPortActivityEvent.hpp create mode 100644 src/engine/events/SendPortValue.cpp create mode 100644 src/engine/events/SendPortValue.hpp delete mode 100644 src/engine/events/SendPortValueEvent.cpp delete mode 100644 src/engine/events/SendPortValueEvent.hpp create mode 100644 src/engine/events/SetMetadata.cpp create mode 100644 src/engine/events/SetMetadata.hpp delete mode 100644 src/engine/events/SetMetadataEvent.cpp delete mode 100644 src/engine/events/SetMetadataEvent.hpp create mode 100644 src/engine/events/SetPortValue.cpp create mode 100644 src/engine/events/SetPortValue.hpp delete mode 100644 src/engine/events/SetPortValueEvent.cpp delete mode 100644 src/engine/events/SetPortValueEvent.hpp create mode 100644 src/engine/events/UnregisterClient.cpp create mode 100644 src/engine/events/UnregisterClient.hpp delete mode 100644 src/engine/events/UnregisterClientEvent.cpp delete mode 100644 src/engine/events/UnregisterClientEvent.hpp (limited to 'src/engine/events') diff --git a/src/engine/events/AllNotesOff.cpp b/src/engine/events/AllNotesOff.cpp new file mode 100644 index 00000000..415e1a95 --- /dev/null +++ b/src/engine/events/AllNotesOff.cpp @@ -0,0 +1,73 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "AllNotesOff.hpp" +#include "Responder.hpp" +#include "Engine.hpp" +#include "EngineStore.hpp" +#include "module/World.hpp" +#include "shared/Store.hpp" + +using namespace Raul; + +namespace Ingen { + + +/** Note off with patch explicitly passed - triggered by MIDI. + */ +AllNotesOffEvent::AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, PatchImpl* patch) +: Event(engine, responder, timestamp), + _patch(patch) +{ +} + + +/** Note off event with lookup - triggered by OSC. + */ +AllNotesOffEvent::AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Path& patch_path) +: Event(engine, responder, timestamp), + _patch_path(patch_path), + _patch(NULL) +{ +} + + +void +AllNotesOffEvent::execute(ProcessContext& context) +{ + Event::execute(context); + + if (!_patch) + _patch = _engine.engine_store()->find_patch(_patch_path); + + //if (_patch != NULL) + // for (Raul::List::iterator j = _patch->midi_in_nodes().begin(); j != _patch->midi_in_nodes().end(); ++j) + // (*j)->all_notes_off(offset); +} + + +void +AllNotesOffEvent::post_process() +{ + if (_patch != NULL) + _responder->respond_ok(); +} + + +} // namespace Ingen + + diff --git a/src/engine/events/AllNotesOff.hpp b/src/engine/events/AllNotesOff.hpp new file mode 100644 index 00000000..a7c5d58b --- /dev/null +++ b/src/engine/events/AllNotesOff.hpp @@ -0,0 +1,49 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 ALLNOTESOFFEVENT_H +#define ALLNOTESOFFEVENT_H + +#include "Event.hpp" + +namespace Ingen { + +class PatchImpl; + + +/** A note off event for all active voices. + * + * \ingroup engine + */ +class AllNotesOffEvent : public Event +{ +public: + AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, PatchImpl* patch); + AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& patch_path); + + void execute(ProcessContext& context); + void post_process(); + +private: + const Raul::Path _patch_path; + PatchImpl* _patch; +}; + + +} // namespace Ingen + +#endif // ALLNOTESOFFEVENT_H diff --git a/src/engine/events/AllNotesOffEvent.cpp b/src/engine/events/AllNotesOffEvent.cpp deleted file mode 100644 index cb4f9294..00000000 --- a/src/engine/events/AllNotesOffEvent.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "AllNotesOffEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "module/World.hpp" -#include "shared/Store.hpp" - -using namespace Raul; - -namespace Ingen { - - -/** Note off with patch explicitly passed - triggered by MIDI. - */ -AllNotesOffEvent::AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, PatchImpl* patch) -: Event(engine, responder, timestamp), - _patch(patch) -{ -} - - -/** Note off event with lookup - triggered by OSC. - */ -AllNotesOffEvent::AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Path& patch_path) -: Event(engine, responder, timestamp), - _patch_path(patch_path), - _patch(NULL) -{ -} - - -void -AllNotesOffEvent::execute(ProcessContext& context) -{ - Event::execute(context); - - if (!_patch) - _patch = _engine.engine_store()->find_patch(_patch_path); - - //if (_patch != NULL) - // for (Raul::List::iterator j = _patch->midi_in_nodes().begin(); j != _patch->midi_in_nodes().end(); ++j) - // (*j)->all_notes_off(offset); -} - - -void -AllNotesOffEvent::post_process() -{ - if (_patch != NULL) - _responder->respond_ok(); -} - - -} // namespace Ingen - - diff --git a/src/engine/events/AllNotesOffEvent.hpp b/src/engine/events/AllNotesOffEvent.hpp deleted file mode 100644 index a7c5d58b..00000000 --- a/src/engine/events/AllNotesOffEvent.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 ALLNOTESOFFEVENT_H -#define ALLNOTESOFFEVENT_H - -#include "Event.hpp" - -namespace Ingen { - -class PatchImpl; - - -/** A note off event for all active voices. - * - * \ingroup engine - */ -class AllNotesOffEvent : public Event -{ -public: - AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, PatchImpl* patch); - AllNotesOffEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& patch_path); - - void execute(ProcessContext& context); - void post_process(); - -private: - const Raul::Path _patch_path; - PatchImpl* _patch; -}; - - -} // namespace Ingen - -#endif // ALLNOTESOFFEVENT_H diff --git a/src/engine/events/ClearPatch.cpp b/src/engine/events/ClearPatch.cpp new file mode 100644 index 00000000..434360a7 --- /dev/null +++ b/src/engine/events/ClearPatch.cpp @@ -0,0 +1,179 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "raul/Maid.hpp" +#include "ClearPatch.hpp" +#include "Responder.hpp" +#include "Engine.hpp" +#include "PatchImpl.hpp" +#include "ClientBroadcaster.hpp" +#include "util.hpp" +#include "EngineStore.hpp" +#include "PortImpl.hpp" +#include "NodeImpl.hpp" +#include "ConnectionImpl.hpp" +#include "QueuedEventSource.hpp" +#include "AudioDriver.hpp" +#include "MidiDriver.hpp" + +using namespace std; +using namespace Raul; + +namespace Ingen { + +using namespace Shared; + + +ClearPatchEvent::ClearPatchEvent(Engine& engine, SharedPtr responder, FrameTime time, QueuedEventSource* source, const Path& patch_path) + : QueuedEvent(engine, responder, time, true, source) + , _patch_path(patch_path) + , _process(false) + , _ports_array(NULL) + , _compiled_patch(NULL) + , _driver_ports(NULL) +{ +} + + +void +ClearPatchEvent::pre_process() +{ + EngineStore::Objects::iterator patch_iterator = _engine.engine_store()->find(_patch_path); + + if (patch_iterator != _engine.engine_store()->end()) { + _patch = PtrCast(patch_iterator->second); + if (_patch) { + _process = _patch->enabled(); + _removed_table = _engine.engine_store()->remove_children(patch_iterator); + _patch->nodes().clear(); + _patch->connections().clear(); + _patch->clear_ports(); + _ports_array = _patch->build_ports_array(); + if (_patch->enabled()) + _compiled_patch = _patch->compile(); + + // Remove driver ports + if (_patch->parent() == NULL) { + size_t port_count = 0; + for (EngineStore::Objects::iterator i = _removed_table->begin(); + i != _removed_table->end(); ++i) { + SharedPtr port = PtrCast(i->second); + if (port) + ++port_count; + + SharedPtr node = PtrCast(i->second); + if (node) + node->deactivate(); + } + + _driver_ports = new DriverPorts(port_count, NULL); + } + } + } + + QueuedEvent::pre_process(); +} + + +void +ClearPatchEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + + if (_patch && _removed_table) { + _patch->disable(); + + if (_patch->compiled_patch() != NULL) { + _engine.maid()->push(_patch->compiled_patch()); + _patch->compiled_patch(NULL); + } + + _patch->connections().clear(); + _patch->compiled_patch(_compiled_patch); + Raul::Array* old_ports = _patch->external_ports(); + _patch->external_ports(_ports_array); + _ports_array = old_ports; + + // Remove driver ports + if (_patch->parent() == NULL) { + for (EngineStore::Objects::iterator i = _removed_table->begin(); + i != _removed_table->end(); ++i) { + SharedPtr port = PtrCast(i->second); + if (port && port->type() == DataType::AUDIO) { + _driver_ports->push_back( + _engine.audio_driver()->remove_port(port->path())); + } else if (port && port->type() == DataType::EVENT) { + _driver_ports->push_back( + _engine.midi_driver()->remove_port(port->path())); + } + } + } + } +} + + +void +ClearPatchEvent::post_process() +{ + if (_patch != NULL) { + delete _ports_array; + + // Restore patch's run state + if (_process) + _patch->enable(); + else + _patch->disable(); + + // Make sure everything's sane + assert(_patch->nodes().size() == 0); + assert(_patch->num_ports() == 0); + assert(_patch->connections().size() == 0); + + // Deactivate nodes + for (EngineStore::Objects::iterator i = _removed_table->begin(); + i != _removed_table->end(); ++i) { + SharedPtr node = PtrCast(i->second); + if (node) + node->deactivate(); + } + + // Unregister and destroy driver ports + if (_driver_ports) { + for (size_t i = 0; i < _driver_ports->size(); ++i) { + Raul::List::Node* ln = _driver_ports->at(i); + if (ln) { + ln->elem()->destroy(); + _engine.maid()->push(ln); + } + } + delete _driver_ports; + } + + // Reply + _responder->respond_ok(); + _engine.broadcaster()->send_clear_patch(_patch_path); + + } else { + _responder->respond_error(string("Patch ") + _patch_path.str() + " not found"); + } + + _source->unblock(); // FIXME: can be done earlier in execute? +} + + +} // namespace Ingen + diff --git a/src/engine/events/ClearPatch.hpp b/src/engine/events/ClearPatch.hpp new file mode 100644 index 00000000..4dc7dddb --- /dev/null +++ b/src/engine/events/ClearPatch.hpp @@ -0,0 +1,64 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 CLEARPATCHEVENT_H +#define CLEARPATCHEVENT_H + +#include "raul/Array.hpp" +#include "raul/Table.hpp" +#include "raul/Path.hpp" +#include "QueuedEvent.hpp" +#include "EngineStore.hpp" +#include "PatchImpl.hpp" + +namespace Ingen { + +class PatchImpl; +class DriverPort; + + +/** Delete all nodes from a patch. + * + * \ingroup engine + */ +class ClearPatchEvent : public QueuedEvent +{ +public: + ClearPatchEvent(Engine& engine, SharedPtr responder, FrameTime time, QueuedEventSource* source, const Raul::Path& patch_path); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + const Raul::Path _patch_path; + SharedPtr _patch; + bool _process; + Raul::Array* _ports_array; ///< New (external) ports for Patch + CompiledPatch* _compiled_patch; ///< Patch's new process order + + typedef Raul::Array::Node*> DriverPorts; + DriverPorts* _driver_ports; + + SharedPtr _removed_table; +}; + + +} // namespace Ingen + + +#endif // CLEARPATCHEVENT_H diff --git a/src/engine/events/ClearPatchEvent.cpp b/src/engine/events/ClearPatchEvent.cpp deleted file mode 100644 index 3a016a66..00000000 --- a/src/engine/events/ClearPatchEvent.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "raul/Maid.hpp" -#include "ClearPatchEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "util.hpp" -#include "EngineStore.hpp" -#include "PortImpl.hpp" -#include "NodeImpl.hpp" -#include "ConnectionImpl.hpp" -#include "QueuedEventSource.hpp" -#include "AudioDriver.hpp" -#include "MidiDriver.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { - -using namespace Shared; - - -ClearPatchEvent::ClearPatchEvent(Engine& engine, SharedPtr responder, FrameTime time, QueuedEventSource* source, const Path& patch_path) - : QueuedEvent(engine, responder, time, true, source) - , _patch_path(patch_path) - , _process(false) - , _ports_array(NULL) - , _compiled_patch(NULL) - , _driver_ports(NULL) -{ -} - - -void -ClearPatchEvent::pre_process() -{ - EngineStore::Objects::iterator patch_iterator = _engine.engine_store()->find(_patch_path); - - if (patch_iterator != _engine.engine_store()->end()) { - _patch = PtrCast(patch_iterator->second); - if (_patch) { - _process = _patch->enabled(); - _removed_table = _engine.engine_store()->remove_children(patch_iterator); - _patch->nodes().clear(); - _patch->connections().clear(); - _patch->clear_ports(); - _ports_array = _patch->build_ports_array(); - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - - // Remove driver ports - if (_patch->parent() == NULL) { - size_t port_count = 0; - for (EngineStore::Objects::iterator i = _removed_table->begin(); - i != _removed_table->end(); ++i) { - SharedPtr port = PtrCast(i->second); - if (port) - ++port_count; - - SharedPtr node = PtrCast(i->second); - if (node) - node->deactivate(); - } - - _driver_ports = new DriverPorts(port_count, NULL); - } - } - } - - QueuedEvent::pre_process(); -} - - -void -ClearPatchEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch && _removed_table) { - _patch->disable(); - - if (_patch->compiled_patch() != NULL) { - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(NULL); - } - - _patch->connections().clear(); - _patch->compiled_patch(_compiled_patch); - Raul::Array* old_ports = _patch->external_ports(); - _patch->external_ports(_ports_array); - _ports_array = old_ports; - - // Remove driver ports - if (_patch->parent() == NULL) { - for (EngineStore::Objects::iterator i = _removed_table->begin(); - i != _removed_table->end(); ++i) { - SharedPtr port = PtrCast(i->second); - if (port && port->type() == DataType::AUDIO) { - _driver_ports->push_back( - _engine.audio_driver()->remove_port(port->path())); - } else if (port && port->type() == DataType::EVENT) { - _driver_ports->push_back( - _engine.midi_driver()->remove_port(port->path())); - } - } - } - } -} - - -void -ClearPatchEvent::post_process() -{ - if (_patch != NULL) { - delete _ports_array; - - // Restore patch's run state - if (_process) - _patch->enable(); - else - _patch->disable(); - - // Make sure everything's sane - assert(_patch->nodes().size() == 0); - assert(_patch->num_ports() == 0); - assert(_patch->connections().size() == 0); - - // Deactivate nodes - for (EngineStore::Objects::iterator i = _removed_table->begin(); - i != _removed_table->end(); ++i) { - SharedPtr node = PtrCast(i->second); - if (node) - node->deactivate(); - } - - // Unregister and destroy driver ports - if (_driver_ports) { - for (size_t i = 0; i < _driver_ports->size(); ++i) { - Raul::List::Node* ln = _driver_ports->at(i); - if (ln) { - ln->elem()->destroy(); - _engine.maid()->push(ln); - } - } - delete _driver_ports; - } - - // Reply - _responder->respond_ok(); - _engine.broadcaster()->send_clear_patch(_patch_path); - - } else { - _responder->respond_error(string("Patch ") + _patch_path.str() + " not found"); - } - - _source->unblock(); // FIXME: can be done earlier in execute? -} - - -} // namespace Ingen - diff --git a/src/engine/events/ClearPatchEvent.hpp b/src/engine/events/ClearPatchEvent.hpp deleted file mode 100644 index 4dc7dddb..00000000 --- a/src/engine/events/ClearPatchEvent.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 CLEARPATCHEVENT_H -#define CLEARPATCHEVENT_H - -#include "raul/Array.hpp" -#include "raul/Table.hpp" -#include "raul/Path.hpp" -#include "QueuedEvent.hpp" -#include "EngineStore.hpp" -#include "PatchImpl.hpp" - -namespace Ingen { - -class PatchImpl; -class DriverPort; - - -/** Delete all nodes from a patch. - * - * \ingroup engine - */ -class ClearPatchEvent : public QueuedEvent -{ -public: - ClearPatchEvent(Engine& engine, SharedPtr responder, FrameTime time, QueuedEventSource* source, const Raul::Path& patch_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const Raul::Path _patch_path; - SharedPtr _patch; - bool _process; - Raul::Array* _ports_array; ///< New (external) ports for Patch - CompiledPatch* _compiled_patch; ///< Patch's new process order - - typedef Raul::Array::Node*> DriverPorts; - DriverPorts* _driver_ports; - - SharedPtr _removed_table; -}; - - -} // namespace Ingen - - -#endif // CLEARPATCHEVENT_H diff --git a/src/engine/events/Connection.cpp b/src/engine/events/Connection.cpp new file mode 100644 index 00000000..08ba49d5 --- /dev/null +++ b/src/engine/events/Connection.cpp @@ -0,0 +1,204 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 +#include +#include "raul/Maid.hpp" +#include "raul/Path.hpp" +#include "ClientBroadcaster.hpp" +#include "Connection.hpp" +#include "ConnectionImpl.hpp" +#include "Engine.hpp" +#include "InputPort.hpp" +#include "EngineStore.hpp" +#include "OutputPort.hpp" +#include "PatchImpl.hpp" +#include "PortImpl.hpp" +#include "Responder.hpp" +#include "types.hpp" + +using namespace std; +using namespace Raul; + +namespace Ingen { + +using namespace Shared; + + +ConnectionEvent::ConnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Path& src_port_path, const Path& dst_port_path) + : QueuedEvent(engine, responder, timestamp) + , _src_port_path(src_port_path) + , _dst_port_path(dst_port_path) + , _patch(NULL) + , _src_port(NULL) + , _dst_port(NULL) + , _compiled_patch(NULL) + , _patch_listnode(NULL) + , _port_listnode(NULL) + , _error(NO_ERROR) +{ +} + + +void +ConnectionEvent::pre_process() +{ + if (_src_port_path.parent().parent() != _dst_port_path.parent().parent() + && _src_port_path.parent() != _dst_port_path.parent().parent() + && _src_port_path.parent().parent() != _dst_port_path.parent()) { + _error = PARENT_PATCH_DIFFERENT; + QueuedEvent::pre_process(); + return; + } + + _src_port = _engine.engine_store()->find_port(_src_port_path); + _dst_port = _engine.engine_store()->find_port(_dst_port_path); + + if (_src_port == NULL || _dst_port == NULL) { + _error = PORT_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + if ( ! (_src_port->type() == _dst_port->type() + || ( (_src_port->type() == DataType::CONTROL || _src_port->type() == DataType::AUDIO) + && (_dst_port->type() == DataType::CONTROL || _dst_port->type() == DataType::AUDIO) ))) { + _error = TYPE_MISMATCH; + QueuedEvent::pre_process(); + return; + } + + _dst_input_port = dynamic_cast(_dst_port); + _src_output_port = dynamic_cast(_src_port); + + if (!_dst_input_port || !_src_output_port) { + _error = DIRECTION_MISMATCH; + QueuedEvent::pre_process(); + return; + } + + NodeImpl* const src_node = _src_port->parent_node(); + NodeImpl* const dst_node = _dst_port->parent_node(); + + // Connection to a patch port from inside the patch + if (src_node->parent_patch() != dst_node->parent_patch()) { + + assert(src_node->parent() == dst_node || dst_node->parent() == src_node); + if (src_node->parent() == dst_node) + _patch = dynamic_cast(dst_node); + else + _patch = dynamic_cast(src_node); + + // Connection from a patch input to a patch output (pass through) + } else if (src_node == dst_node && dynamic_cast(src_node)) { + _patch = dynamic_cast(src_node); + + // Normal connection between nodes with the same parent + } else { + _patch = src_node->parent_patch(); + } + + assert(_patch); + + if (_patch->has_connection(_src_output_port, _dst_input_port)) { + _error = ALREADY_CONNECTED; + QueuedEvent::pre_process(); + return; + } + + if (src_node == NULL || dst_node == NULL) { + _error = PARENTS_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + if (_patch != src_node && src_node->parent() != _patch && dst_node->parent() != _patch) { + _error = PARENTS_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + _connection = SharedPtr(new ConnectionImpl(_src_port, _dst_port)); + _patch_listnode = new PatchImpl::Connections::Node(_connection); + _port_listnode = new InputPort::Connections::Node(_connection); + + // Need to be careful about patch port connections here and adding a node's + // parent as a dependant/provider, or adding a patch as it's own provider... + if (src_node != dst_node && src_node->parent() == dst_node->parent()) { + dst_node->providers()->push_back(new Raul::List::Node(src_node)); + src_node->dependants()->push_back(new Raul::List::Node(dst_node)); + } + + _patch->add_connection(_patch_listnode); + + if (_patch->enabled()) + _compiled_patch = _patch->compile(); + + QueuedEvent::pre_process(); +} + + +void +ConnectionEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + + if (_error == NO_ERROR) { + // This must be inserted here, since they're actually used by the audio thread + _dst_input_port->add_connection(_port_listnode); + if (_patch->compiled_patch() != NULL) + _engine.maid()->push(_patch->compiled_patch()); + _patch->compiled_patch(_compiled_patch); + } +} + + +void +ConnectionEvent::post_process() +{ + std::ostringstream ss; + if (_error == NO_ERROR) { + _responder->respond_ok(); + _engine.broadcaster()->send_connection(_connection); + return; + } + + ss << boost::format("Unable to make connection %1% -> %2% (") % _src_port_path % _dst_port_path; + + switch (_error) { + case PARENT_PATCH_DIFFERENT: + ss << "Ports have mismatched parents"; break; + case PORT_NOT_FOUND: + ss << "Port not found"; break; + case TYPE_MISMATCH: + ss << "Type mismatch"; break; + case DIRECTION_MISMATCH: + ss << "Direction mismatch"; break; + case ALREADY_CONNECTED: + ss << "Already connected"; break; + case PARENTS_NOT_FOUND: + ss << "Parents not found"; break; + default: + ss << "Unknown error"; + } + ss << ")"; + _responder->respond_error(ss.str()); +} + + +} // namespace Ingen + diff --git a/src/engine/events/Connection.hpp b/src/engine/events/Connection.hpp new file mode 100644 index 00000000..b1f4bf6c --- /dev/null +++ b/src/engine/events/Connection.hpp @@ -0,0 +1,90 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 CONNECTIONEVENT_H +#define CONNECTIONEVENT_H + +#include "raul/Path.hpp" +#include "QueuedEvent.hpp" +#include "PatchImpl.hpp" +#include "InputPort.hpp" +#include "types.hpp" + +namespace Raul { + template class ListNode; + template class Array; +} + +namespace Ingen { + +class PatchImpl; +class NodeImpl; +class ConnectionImpl; +class MidiMessage; +class PortImpl; +class InputPort; +class OutputPort; +class CompiledPatch; + + +/** Make a Connection between two Ports. + * + * \ingroup engine + */ +class ConnectionEvent : public QueuedEvent +{ +public: + ConnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& src_port_path, const Raul::Path& dst_port_path); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + + enum ErrorType { + NO_ERROR, + PARENT_PATCH_DIFFERENT, + PORT_NOT_FOUND, + TYPE_MISMATCH, + DIRECTION_MISMATCH, + ALREADY_CONNECTED, + PARENTS_NOT_FOUND + }; + + Raul::Path _src_port_path; + Raul::Path _dst_port_path; + + PatchImpl* _patch; + PortImpl* _src_port; + PortImpl* _dst_port; + OutputPort* _src_output_port; + InputPort* _dst_input_port; + + CompiledPatch* _compiled_patch; ///< New process order for Patch + + SharedPtr _connection; + PatchImpl::Connections::Node* _patch_listnode; + InputPort::Connections::Node* _port_listnode; + + ErrorType _error; +}; + + +} // namespace Ingen + +#endif // CONNECTIONEVENT_H diff --git a/src/engine/events/ConnectionEvent.cpp b/src/engine/events/ConnectionEvent.cpp deleted file mode 100644 index 34c6a027..00000000 --- a/src/engine/events/ConnectionEvent.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 -#include -#include "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "ClientBroadcaster.hpp" -#include "ConnectionEvent.hpp" -#include "ConnectionImpl.hpp" -#include "Engine.hpp" -#include "InputPort.hpp" -#include "EngineStore.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "PortImpl.hpp" -#include "Responder.hpp" -#include "types.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { - -using namespace Shared; - - -ConnectionEvent::ConnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Path& src_port_path, const Path& dst_port_path) - : QueuedEvent(engine, responder, timestamp) - , _src_port_path(src_port_path) - , _dst_port_path(dst_port_path) - , _patch(NULL) - , _src_port(NULL) - , _dst_port(NULL) - , _compiled_patch(NULL) - , _patch_listnode(NULL) - , _port_listnode(NULL) - , _error(NO_ERROR) -{ -} - - -void -ConnectionEvent::pre_process() -{ - if (_src_port_path.parent().parent() != _dst_port_path.parent().parent() - && _src_port_path.parent() != _dst_port_path.parent().parent() - && _src_port_path.parent().parent() != _dst_port_path.parent()) { - _error = PARENT_PATCH_DIFFERENT; - QueuedEvent::pre_process(); - return; - } - - _src_port = _engine.engine_store()->find_port(_src_port_path); - _dst_port = _engine.engine_store()->find_port(_dst_port_path); - - if (_src_port == NULL || _dst_port == NULL) { - _error = PORT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if ( ! (_src_port->type() == _dst_port->type() - || ( (_src_port->type() == DataType::CONTROL || _src_port->type() == DataType::AUDIO) - && (_dst_port->type() == DataType::CONTROL || _dst_port->type() == DataType::AUDIO) ))) { - _error = TYPE_MISMATCH; - QueuedEvent::pre_process(); - return; - } - - _dst_input_port = dynamic_cast(_dst_port); - _src_output_port = dynamic_cast(_src_port); - - if (!_dst_input_port || !_src_output_port) { - _error = DIRECTION_MISMATCH; - QueuedEvent::pre_process(); - return; - } - - NodeImpl* const src_node = _src_port->parent_node(); - NodeImpl* const dst_node = _dst_port->parent_node(); - - // Connection to a patch port from inside the patch - if (src_node->parent_patch() != dst_node->parent_patch()) { - - assert(src_node->parent() == dst_node || dst_node->parent() == src_node); - if (src_node->parent() == dst_node) - _patch = dynamic_cast(dst_node); - else - _patch = dynamic_cast(src_node); - - // Connection from a patch input to a patch output (pass through) - } else if (src_node == dst_node && dynamic_cast(src_node)) { - _patch = dynamic_cast(src_node); - - // Normal connection between nodes with the same parent - } else { - _patch = src_node->parent_patch(); - } - - assert(_patch); - - if (_patch->has_connection(_src_output_port, _dst_input_port)) { - _error = ALREADY_CONNECTED; - QueuedEvent::pre_process(); - return; - } - - if (src_node == NULL || dst_node == NULL) { - _error = PARENTS_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if (_patch != src_node && src_node->parent() != _patch && dst_node->parent() != _patch) { - _error = PARENTS_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - _connection = SharedPtr(new ConnectionImpl(_src_port, _dst_port)); - _patch_listnode = new PatchImpl::Connections::Node(_connection); - _port_listnode = new InputPort::Connections::Node(_connection); - - // Need to be careful about patch port connections here and adding a node's - // parent as a dependant/provider, or adding a patch as it's own provider... - if (src_node != dst_node && src_node->parent() == dst_node->parent()) { - dst_node->providers()->push_back(new Raul::List::Node(src_node)); - src_node->dependants()->push_back(new Raul::List::Node(dst_node)); - } - - _patch->add_connection(_patch_listnode); - - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - - QueuedEvent::pre_process(); -} - - -void -ConnectionEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_error == NO_ERROR) { - // This must be inserted here, since they're actually used by the audio thread - _dst_input_port->add_connection(_port_listnode); - if (_patch->compiled_patch() != NULL) - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(_compiled_patch); - } -} - - -void -ConnectionEvent::post_process() -{ - std::ostringstream ss; - if (_error == NO_ERROR) { - _responder->respond_ok(); - _engine.broadcaster()->send_connection(_connection); - return; - } - - ss << boost::format("Unable to make connection %1% -> %2% (") % _src_port_path % _dst_port_path; - - switch (_error) { - case PARENT_PATCH_DIFFERENT: - ss << "Ports have mismatched parents"; break; - case PORT_NOT_FOUND: - ss << "Port not found"; break; - case TYPE_MISMATCH: - ss << "Type mismatch"; break; - case DIRECTION_MISMATCH: - ss << "Direction mismatch"; break; - case ALREADY_CONNECTED: - ss << "Already connected"; break; - case PARENTS_NOT_FOUND: - ss << "Parents not found"; break; - default: - ss << "Unknown error"; - } - ss << ")"; - _responder->respond_error(ss.str()); -} - - -} // namespace Ingen - diff --git a/src/engine/events/ConnectionEvent.hpp b/src/engine/events/ConnectionEvent.hpp deleted file mode 100644 index b1f4bf6c..00000000 --- a/src/engine/events/ConnectionEvent.hpp +++ /dev/null @@ -1,90 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 CONNECTIONEVENT_H -#define CONNECTIONEVENT_H - -#include "raul/Path.hpp" -#include "QueuedEvent.hpp" -#include "PatchImpl.hpp" -#include "InputPort.hpp" -#include "types.hpp" - -namespace Raul { - template class ListNode; - template class Array; -} - -namespace Ingen { - -class PatchImpl; -class NodeImpl; -class ConnectionImpl; -class MidiMessage; -class PortImpl; -class InputPort; -class OutputPort; -class CompiledPatch; - - -/** Make a Connection between two Ports. - * - * \ingroup engine - */ -class ConnectionEvent : public QueuedEvent -{ -public: - ConnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& src_port_path, const Raul::Path& dst_port_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - - enum ErrorType { - NO_ERROR, - PARENT_PATCH_DIFFERENT, - PORT_NOT_FOUND, - TYPE_MISMATCH, - DIRECTION_MISMATCH, - ALREADY_CONNECTED, - PARENTS_NOT_FOUND - }; - - Raul::Path _src_port_path; - Raul::Path _dst_port_path; - - PatchImpl* _patch; - PortImpl* _src_port; - PortImpl* _dst_port; - OutputPort* _src_output_port; - InputPort* _dst_input_port; - - CompiledPatch* _compiled_patch; ///< New process order for Patch - - SharedPtr _connection; - PatchImpl::Connections::Node* _patch_listnode; - InputPort::Connections::Node* _port_listnode; - - ErrorType _error; -}; - - -} // namespace Ingen - -#endif // CONNECTIONEVENT_H diff --git a/src/engine/events/CreateNode.cpp b/src/engine/events/CreateNode.cpp new file mode 100644 index 00000000..28b50258 --- /dev/null +++ b/src/engine/events/CreateNode.cpp @@ -0,0 +1,148 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "raul/Maid.hpp" +#include "raul/Path.hpp" +#include "raul/Path.hpp" +#include "redlandmm/World.hpp" +#include "module/World.hpp" +#include "CreateNode.hpp" +#include "Responder.hpp" +#include "PatchImpl.hpp" +#include "NodeImpl.hpp" +#include "PluginImpl.hpp" +#include "Engine.hpp" +#include "PatchImpl.hpp" +#include "NodeFactory.hpp" +#include "ClientBroadcaster.hpp" +#include "EngineStore.hpp" +#include "PortImpl.hpp" +#include "AudioDriver.hpp" + +using namespace std; +using namespace Raul; + +namespace Ingen { + +using namespace Shared; + +CreateNodeEvent::CreateNodeEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Path& path, + const URI& plugin_uri, + bool polyphonic, + const Resource::Properties& properties) + : QueuedEvent(engine, responder, timestamp) + , _path(path) + , _plugin_uri(plugin_uri) + , _polyphonic(polyphonic) + , _patch(NULL) + , _node(NULL) + , _compiled_patch(NULL) + , _node_already_exists(false) + , _properties(properties) +{ + string uri = _plugin_uri.str(); + if (uri.substr(0, 3) == "om:") { + size_t colon = 2; + uri = uri.substr(colon + 1); + if ((colon = uri.find(":")) == string::npos) + return; + _plugin_type = uri.substr(0, colon + 1); + _plugin_label = uri.substr(colon + 1); + uri = ""; + } +} + + +void +CreateNodeEvent::pre_process() +{ + if (_engine.engine_store()->find_object(_path) != NULL) { + _node_already_exists = true; + QueuedEvent::pre_process(); + return; + } + + _patch = _engine.engine_store()->find_patch(_path.parent()); + + PluginImpl* const plugin = (_plugin_label == "") + ? _engine.node_factory()->plugin(_plugin_uri.str()) + : _engine.node_factory()->plugin(_plugin_type, _plugin_lib, _plugin_label); + + if (_patch && plugin) { + + _node = plugin->instantiate(_path.name(), _polyphonic, _patch, _engine); + _node->properties().insert(_properties.begin(), _properties.end()); + + if (_node != NULL) { + _node->activate(); + + // This can be done here because the audio thread doesn't touch the + // node tree - just the process order array + _patch->add_node(new PatchImpl::Nodes::Node(_node)); + //_node->add_to_store(_engine.engine_store()); + _engine.engine_store()->add(_node); + + // FIXME: not really necessary to build process order since it's not connected, + // just append to the list + if (_patch->enabled()) + _compiled_patch = _patch->compile(); + } + } + QueuedEvent::pre_process(); +} + + +void +CreateNodeEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + + if (_node != NULL) { + if (_patch->compiled_patch() != NULL) + _engine.maid()->push(_patch->compiled_patch()); + _patch->compiled_patch(_compiled_patch); + } +} + + +void +CreateNodeEvent::post_process() +{ + string msg; + if (_node_already_exists) { + msg = string("Could not create node - ").append(_path.str());// + " already exists."; + _responder->respond_error(msg); + } else if (_patch == NULL) { + msg = "Could not find patch '" + _path.parent().str() +"' to add node."; + _responder->respond_error(msg); + } else if (_node == NULL) { + msg = "Unable to load node "; + msg += _path.str() + " (you're missing the plugin " + _plugin_uri.str() + ")"; + _responder->respond_error(msg); + } else { + _responder->respond_ok(); + _engine.broadcaster()->send_object(_node, true); // yes, send ports + } +} + + +} // namespace Ingen + diff --git a/src/engine/events/CreateNode.hpp b/src/engine/events/CreateNode.hpp new file mode 100644 index 00000000..b8dbf082 --- /dev/null +++ b/src/engine/events/CreateNode.hpp @@ -0,0 +1,70 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 CREATENODEEVENT_H +#define CREATENODEEVENT_H + +#include +#include "QueuedEvent.hpp" +#include "interface/Resource.hpp" + +namespace Ingen { + +class PatchImpl; +class NodeImpl; +class CompiledPatch; + + +/** An event to load a Node and insert it into a Patch. + * + * \ingroup engine + */ +class CreateNodeEvent : public QueuedEvent +{ +public: + CreateNodeEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::Path& node_path, + const Raul::URI& plugin_uri, + bool poly, + const Shared::Resource::Properties& properties); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + Raul::Path _path; + Raul::URI _plugin_uri; ///< If nonempty then type, library, label, are ignored + std::string _plugin_type; + std::string _plugin_lib; + std::string _plugin_label; + bool _polyphonic; + PatchImpl* _patch; + NodeImpl* _node; + CompiledPatch* _compiled_patch; ///< Patch's new process order + bool _node_already_exists; + + Shared::Resource::Properties _properties; +}; + + +} // namespace Ingen + +#endif // CREATENODEEVENT_H diff --git a/src/engine/events/CreateNodeEvent.cpp b/src/engine/events/CreateNodeEvent.cpp deleted file mode 100644 index 718a94a3..00000000 --- a/src/engine/events/CreateNodeEvent.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "raul/Path.hpp" -#include "redlandmm/World.hpp" -#include "module/World.hpp" -#include "CreateNodeEvent.hpp" -#include "Responder.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PluginImpl.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "NodeFactory.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" -#include "PortImpl.hpp" -#include "AudioDriver.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { - -using namespace Shared; - -CreateNodeEvent::CreateNodeEvent( - Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const Path& path, - const URI& plugin_uri, - bool polyphonic, - const Resource::Properties& properties) - : QueuedEvent(engine, responder, timestamp) - , _path(path) - , _plugin_uri(plugin_uri) - , _polyphonic(polyphonic) - , _patch(NULL) - , _node(NULL) - , _compiled_patch(NULL) - , _node_already_exists(false) - , _properties(properties) -{ - string uri = _plugin_uri.str(); - if (uri.substr(0, 3) == "om:") { - size_t colon = 2; - uri = uri.substr(colon + 1); - if ((colon = uri.find(":")) == string::npos) - return; - _plugin_type = uri.substr(0, colon + 1); - _plugin_label = uri.substr(colon + 1); - uri = ""; - } -} - - -void -CreateNodeEvent::pre_process() -{ - if (_engine.engine_store()->find_object(_path) != NULL) { - _node_already_exists = true; - QueuedEvent::pre_process(); - return; - } - - _patch = _engine.engine_store()->find_patch(_path.parent()); - - PluginImpl* const plugin = (_plugin_label == "") - ? _engine.node_factory()->plugin(_plugin_uri.str()) - : _engine.node_factory()->plugin(_plugin_type, _plugin_lib, _plugin_label); - - if (_patch && plugin) { - - _node = plugin->instantiate(_path.name(), _polyphonic, _patch, _engine); - _node->properties().insert(_properties.begin(), _properties.end()); - - if (_node != NULL) { - _node->activate(); - - // This can be done here because the audio thread doesn't touch the - // node tree - just the process order array - _patch->add_node(new PatchImpl::Nodes::Node(_node)); - //_node->add_to_store(_engine.engine_store()); - _engine.engine_store()->add(_node); - - // FIXME: not really necessary to build process order since it's not connected, - // just append to the list - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - } - } - QueuedEvent::pre_process(); -} - - -void -CreateNodeEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_node != NULL) { - if (_patch->compiled_patch() != NULL) - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(_compiled_patch); - } -} - - -void -CreateNodeEvent::post_process() -{ - string msg; - if (_node_already_exists) { - msg = string("Could not create node - ").append(_path.str());// + " already exists."; - _responder->respond_error(msg); - } else if (_patch == NULL) { - msg = "Could not find patch '" + _path.parent().str() +"' to add node."; - _responder->respond_error(msg); - } else if (_node == NULL) { - msg = "Unable to load node "; - msg += _path.str() + " (you're missing the plugin " + _plugin_uri.str() + ")"; - _responder->respond_error(msg); - } else { - _responder->respond_ok(); - _engine.broadcaster()->send_object(_node, true); // yes, send ports - } -} - - -} // namespace Ingen - diff --git a/src/engine/events/CreateNodeEvent.hpp b/src/engine/events/CreateNodeEvent.hpp deleted file mode 100644 index b8dbf082..00000000 --- a/src/engine/events/CreateNodeEvent.hpp +++ /dev/null @@ -1,70 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 CREATENODEEVENT_H -#define CREATENODEEVENT_H - -#include -#include "QueuedEvent.hpp" -#include "interface/Resource.hpp" - -namespace Ingen { - -class PatchImpl; -class NodeImpl; -class CompiledPatch; - - -/** An event to load a Node and insert it into a Patch. - * - * \ingroup engine - */ -class CreateNodeEvent : public QueuedEvent -{ -public: - CreateNodeEvent( - Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const Raul::Path& node_path, - const Raul::URI& plugin_uri, - bool poly, - const Shared::Resource::Properties& properties); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - Raul::Path _path; - Raul::URI _plugin_uri; ///< If nonempty then type, library, label, are ignored - std::string _plugin_type; - std::string _plugin_lib; - std::string _plugin_label; - bool _polyphonic; - PatchImpl* _patch; - NodeImpl* _node; - CompiledPatch* _compiled_patch; ///< Patch's new process order - bool _node_already_exists; - - Shared::Resource::Properties _properties; -}; - - -} // namespace Ingen - -#endif // CREATENODEEVENT_H diff --git a/src/engine/events/CreatePatch.cpp b/src/engine/events/CreatePatch.cpp new file mode 100644 index 00000000..de7cefd3 --- /dev/null +++ b/src/engine/events/CreatePatch.cpp @@ -0,0 +1,164 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "raul/Maid.hpp" +#include "raul/Path.hpp" +#include "events/CreatePatch.hpp" +#include "Responder.hpp" +#include "PatchImpl.hpp" +#include "NodeImpl.hpp" +#include "PluginImpl.hpp" +#include "Engine.hpp" +#include "ClientBroadcaster.hpp" +#include "AudioDriver.hpp" +#include "EngineStore.hpp" + +using namespace std; +using namespace Raul; + +namespace Ingen { + +using namespace Shared; + + +CreatePatchEvent::CreatePatchEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::Path& path, + int poly, + const Resource::Properties& properties) + : QueuedEvent(engine, responder, timestamp) + , _path(path) + , _patch(NULL) + , _parent(NULL) + , _compiled_patch(NULL) + , _poly(poly) + , _error(NO_ERROR) + , _properties(properties) +{ +} + + +void +CreatePatchEvent::pre_process() +{ + if (_path.is_root() || _engine.engine_store()->find_object(_path) != NULL) { + _error = OBJECT_EXISTS; + QueuedEvent::pre_process(); + return; + } + + if (_poly < 1) { + _error = INVALID_POLY; + QueuedEvent::pre_process(); + return; + } + + const Path& path = (const Path&)_path; + + _parent = _engine.engine_store()->find_patch(path.parent()); + if (_parent == NULL) { + _error = PARENT_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + uint32_t poly = 1; + if (_parent != NULL && _poly > 1 && _poly == static_cast(_parent->internal_polyphony())) + poly = _poly; + + _patch = new PatchImpl(_engine, path.name(), poly, _parent, _engine.audio_driver()->sample_rate(), _engine.audio_driver()->buffer_size(), _poly); + _patch->meta().properties().insert(_properties.begin(), _properties.end()); + _patch->meta().set_property("rdf:type", Atom(Atom::URI, "ingen:Patch")); + _patch->set_property("rdf:type", Atom(Atom::URI, "ingen:Node")); + + if (_parent != NULL) { + _parent->add_node(new PatchImpl::Nodes::Node(_patch)); + + if (_parent->enabled()) + _compiled_patch = _parent->compile(); + } + + _patch->activate(); + + // Insert into EngineStore + //_patch->add_to_store(_engine.engine_store()); + _engine.engine_store()->add(_patch); + + QueuedEvent::pre_process(); +} + + +void +CreatePatchEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + + if (_patch != NULL) { + if (_parent == NULL) { + assert(_path.is_root()); + assert(_patch->parent_patch() == NULL); + _engine.audio_driver()->set_root_patch(_patch); + } else { + assert(_parent != NULL); + assert(!_path.is_root()); + if (_parent->compiled_patch() != NULL) + _engine.maid()->push(_parent->compiled_patch()); + _parent->compiled_patch(_compiled_patch); + } + } +} + + +void +CreatePatchEvent::post_process() +{ + string msg; + if (_responder) { + switch (_error) { + case NO_ERROR: + _responder->respond_ok(); + // Don't send ports/nodes that have been added since prepare() + // (otherwise they would be sent twice) + _engine.broadcaster()->send_object(_patch, false); + break; + case OBJECT_EXISTS: + _responder->respond_ok(); + /*string msg = "Unable to create patch: "; + msg.append(_path).append(" already exists."); + _responder->respond_error(msg);*/ + break; + case PARENT_NOT_FOUND: + msg = "Unable to create patch: Parent "; + msg.append(Path(_path).parent().str()).append(" not found."); + _responder->respond_error(msg); + break; + case INVALID_POLY: + msg = "Unable to create patch "; + msg.append(_path.str()).append(": ").append("Invalid polyphony respondered."); + _responder->respond_error(msg); + break; + default: + _responder->respond_error("Unable to load patch."); + } + } +} + + +} // namespace Ingen + diff --git a/src/engine/events/CreatePatch.hpp b/src/engine/events/CreatePatch.hpp new file mode 100644 index 00000000..44b47d8c --- /dev/null +++ b/src/engine/events/CreatePatch.hpp @@ -0,0 +1,66 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 CREATEPATCHEVENT_H +#define CREATEPATCHEVENT_H + +#include "QueuedEvent.hpp" +#include "interface/Resource.hpp" + +namespace Ingen { + +class PatchImpl; +class CompiledPatch; + + +/** Creates a new Patch. + * + * \ingroup engine + */ +class CreatePatchEvent : public QueuedEvent +{ +public: + CreatePatchEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::Path& path, + int poly, + const Shared::Resource::Properties& properties); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + enum ErrorType { NO_ERROR, OBJECT_EXISTS, PARENT_NOT_FOUND, INVALID_POLY }; + + const Raul::Path _path; + PatchImpl* _patch; + PatchImpl* _parent; + CompiledPatch* _compiled_patch; + int _poly; + ErrorType _error; + + Shared::Resource::Properties _properties; +}; + + +} // namespace Ingen + + +#endif // CREATEPATCHEVENT_H diff --git a/src/engine/events/CreatePatchEvent.cpp b/src/engine/events/CreatePatchEvent.cpp deleted file mode 100644 index ccb4f887..00000000 --- a/src/engine/events/CreatePatchEvent.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "CreatePatchEvent.hpp" -#include "Responder.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PluginImpl.hpp" -#include "Engine.hpp" -#include "ClientBroadcaster.hpp" -#include "AudioDriver.hpp" -#include "EngineStore.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { - -using namespace Shared; - - -CreatePatchEvent::CreatePatchEvent( - Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const Raul::Path& path, - int poly, - const Resource::Properties& properties) - : QueuedEvent(engine, responder, timestamp) - , _path(path) - , _patch(NULL) - , _parent(NULL) - , _compiled_patch(NULL) - , _poly(poly) - , _error(NO_ERROR) - , _properties(properties) -{ -} - - -void -CreatePatchEvent::pre_process() -{ - if (_path.is_root() || _engine.engine_store()->find_object(_path) != NULL) { - _error = OBJECT_EXISTS; - QueuedEvent::pre_process(); - return; - } - - if (_poly < 1) { - _error = INVALID_POLY; - QueuedEvent::pre_process(); - return; - } - - const Path& path = (const Path&)_path; - - _parent = _engine.engine_store()->find_patch(path.parent()); - if (_parent == NULL) { - _error = PARENT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - uint32_t poly = 1; - if (_parent != NULL && _poly > 1 && _poly == static_cast(_parent->internal_polyphony())) - poly = _poly; - - _patch = new PatchImpl(_engine, path.name(), poly, _parent, _engine.audio_driver()->sample_rate(), _engine.audio_driver()->buffer_size(), _poly); - _patch->meta().properties().insert(_properties.begin(), _properties.end()); - _patch->meta().set_property("rdf:type", Atom(Atom::URI, "ingen:Patch")); - _patch->set_property("rdf:type", Atom(Atom::URI, "ingen:Node")); - - if (_parent != NULL) { - _parent->add_node(new PatchImpl::Nodes::Node(_patch)); - - if (_parent->enabled()) - _compiled_patch = _parent->compile(); - } - - _patch->activate(); - - // Insert into EngineStore - //_patch->add_to_store(_engine.engine_store()); - _engine.engine_store()->add(_patch); - - QueuedEvent::pre_process(); -} - - -void -CreatePatchEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch != NULL) { - if (_parent == NULL) { - assert(_path.is_root()); - assert(_patch->parent_patch() == NULL); - _engine.audio_driver()->set_root_patch(_patch); - } else { - assert(_parent != NULL); - assert(!_path.is_root()); - if (_parent->compiled_patch() != NULL) - _engine.maid()->push(_parent->compiled_patch()); - _parent->compiled_patch(_compiled_patch); - } - } -} - - -void -CreatePatchEvent::post_process() -{ - string msg; - if (_responder) { - switch (_error) { - case NO_ERROR: - _responder->respond_ok(); - // Don't send ports/nodes that have been added since prepare() - // (otherwise they would be sent twice) - _engine.broadcaster()->send_object(_patch, false); - break; - case OBJECT_EXISTS: - _responder->respond_ok(); - /*string msg = "Unable to create patch: "; - msg.append(_path).append(" already exists."); - _responder->respond_error(msg);*/ - break; - case PARENT_NOT_FOUND: - msg = "Unable to create patch: Parent "; - msg.append(Path(_path).parent().str()).append(" not found."); - _responder->respond_error(msg); - break; - case INVALID_POLY: - msg = "Unable to create patch "; - msg.append(_path.str()).append(": ").append("Invalid polyphony respondered."); - _responder->respond_error(msg); - break; - default: - _responder->respond_error("Unable to load patch."); - } - } -} - - -} // namespace Ingen - diff --git a/src/engine/events/CreatePatchEvent.hpp b/src/engine/events/CreatePatchEvent.hpp deleted file mode 100644 index 44b47d8c..00000000 --- a/src/engine/events/CreatePatchEvent.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 CREATEPATCHEVENT_H -#define CREATEPATCHEVENT_H - -#include "QueuedEvent.hpp" -#include "interface/Resource.hpp" - -namespace Ingen { - -class PatchImpl; -class CompiledPatch; - - -/** Creates a new Patch. - * - * \ingroup engine - */ -class CreatePatchEvent : public QueuedEvent -{ -public: - CreatePatchEvent( - Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const Raul::Path& path, - int poly, - const Shared::Resource::Properties& properties); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum ErrorType { NO_ERROR, OBJECT_EXISTS, PARENT_NOT_FOUND, INVALID_POLY }; - - const Raul::Path _path; - PatchImpl* _patch; - PatchImpl* _parent; - CompiledPatch* _compiled_patch; - int _poly; - ErrorType _error; - - Shared::Resource::Properties _properties; -}; - - -} // namespace Ingen - - -#endif // CREATEPATCHEVENT_H diff --git a/src/engine/events/CreatePort.cpp b/src/engine/events/CreatePort.cpp new file mode 100644 index 00000000..e12cdea2 --- /dev/null +++ b/src/engine/events/CreatePort.cpp @@ -0,0 +1,181 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "raul/Array.hpp" +#include "raul/Atom.hpp" +#include "raul/List.hpp" +#include "raul/Maid.hpp" +#include "raul/Path.hpp" +#include "Responder.hpp" +#include "CreatePort.hpp" +#include "PatchImpl.hpp" +#include "PluginImpl.hpp" +#include "Engine.hpp" +#include "PatchImpl.hpp" +#include "QueuedEventSource.hpp" +#include "EngineStore.hpp" +#include "ClientBroadcaster.hpp" +#include "PortImpl.hpp" +#include "AudioDriver.hpp" +#include "MidiDriver.hpp" +#include "OSCDriver.hpp" +#include "DuplexPort.hpp" + +using namespace std; +using namespace Raul; + +namespace Ingen { + +using namespace Shared; + + +CreatePortEvent::CreatePortEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::Path& path, + const Raul::URI& type, + bool is_output, + QueuedEventSource* source, + const Resource::Properties& properties) + : QueuedEvent(engine, responder, timestamp, true, source) + , _error(NO_ERROR) + , _path(path) + , _type(type) + , _is_output(is_output) + , _data_type(type) + , _patch(NULL) + , _patch_port(NULL) + , _driver_port(NULL) + , _properties(properties) +{ + /* 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). + * + * TODO: fix this using RCU? + */ + + if (_data_type == DataType::UNKNOWN) { + cerr << "[CreatePortEvent] Unknown port type " << type << endl; + _error = UNKNOWN_TYPE; + } +} + + +void +CreatePortEvent::pre_process() +{ + if (_error == UNKNOWN_TYPE || _engine.engine_store()->find_object(_path)) { + QueuedEvent::pre_process(); + return; + } + + _patch = _engine.engine_store()->find_patch(_path.parent()); + + if (_patch != NULL) { + assert(_patch->path() == _path.parent()); + + size_t buffer_size = 1; + if (_type.str() != "ingen:Float") + buffer_size = _engine.audio_driver()->buffer_size(); + + const uint32_t old_num_ports = _patch->num_ports(); + + _patch_port = _patch->create_port(_path.name(), _data_type, buffer_size, _is_output); + _patch_port->set_property("rdf:instanceOf", Atom(Atom::URI, _patch_port->meta_uri().str())); + _patch_port->meta().properties().insert(_properties.begin(), _properties.end()); + + if (_patch_port) { + + if (_is_output) + _patch->add_output(new Raul::List::Node(_patch_port)); + else + _patch->add_input(new Raul::List::Node(_patch_port)); + + if (_patch->external_ports()) + _ports_array = new Raul::Array(old_num_ports + 1, *_patch->external_ports()); + else + _ports_array = new Raul::Array(old_num_ports + 1, NULL); + + _ports_array->at(_patch->num_ports()-1) = _patch_port; + _engine.engine_store()->add(_patch_port); + + if (!_patch->parent()) { + if (_type.str() == "lv2:AudioPort") { + _driver_port = _engine.audio_driver()->create_port( + dynamic_cast(_patch_port)); + } else if (_type.str() == "lv2ev:EventPort") { + _driver_port = _engine.midi_driver()->create_port( + dynamic_cast(_patch_port)); + } + } + + assert(_ports_array->size() == _patch->num_ports()); + + } else { + _error = CREATION_FAILED; + } + } + QueuedEvent::pre_process(); +} + + +void +CreatePortEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + + if (_patch_port) { + _engine.maid()->push(_patch->external_ports()); + _patch->external_ports(_ports_array); + } + + if (_driver_port) { + if (_type.str() == "lv2:AudioPort") { + _engine.audio_driver()->add_port(_driver_port); + } else if (_type.str() == "lv2ev:EventPort") { + _engine.midi_driver()->add_port(_driver_port); + } + } +} + + +void +CreatePortEvent::post_process() +{ + string msg; + switch (_error) { + case NO_ERROR: + _responder->respond_ok(); + _engine.broadcaster()->send_object(_patch_port, true); + break; + case UNKNOWN_TYPE: + msg = string("Could not create port ") + _path.str() + " (Unknown type)"; + _responder->respond_error(msg); + break; + case CREATION_FAILED: + msg = string("Could not create port ") + _path.str() + " (Creation failed)"; + _responder->respond_error(msg); + break; + } +} + + +} // namespace Ingen + diff --git a/src/engine/events/CreatePort.hpp b/src/engine/events/CreatePort.hpp new file mode 100644 index 00000000..ab65eabd --- /dev/null +++ b/src/engine/events/CreatePort.hpp @@ -0,0 +1,80 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 CREATEPORTEVENT_H +#define CREATEPORTEVENT_H + +#include "QueuedEvent.hpp" +#include "raul/Path.hpp" +#include "raul/Array.hpp" +#include "interface/DataType.hpp" +#include "interface/Resource.hpp" + +namespace Ingen { + +class PatchImpl; +class PortImpl; +class DriverPort; + + +/** An event to add a Port to a Patch. + * + * \ingroup engine + */ +class CreatePortEvent : public QueuedEvent +{ +public: + CreatePortEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::Path& path, + const Raul::URI& type, + bool is_output, + QueuedEventSource* source, + const Shared::Resource::Properties& properties); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + + enum ErrorType { + NO_ERROR, + UNKNOWN_TYPE, + CREATION_FAILED + }; + + ErrorType _error; + Raul::Path _path; + Raul::URI _type; + bool _is_output; + Shared::DataType _data_type; + PatchImpl* _patch; + PortImpl* _patch_port; + Raul::Array* _ports_array; ///< New (external) ports array for Patch + DriverPort* _driver_port; ///< Driver (eg Jack) port if this is a toplevel port + bool _succeeded; + + Shared::Resource::Properties _properties; +}; + + +} // namespace Ingen + +#endif // CREATEPORTEVENT_H diff --git a/src/engine/events/CreatePortEvent.cpp b/src/engine/events/CreatePortEvent.cpp deleted file mode 100644 index 8136e3ae..00000000 --- a/src/engine/events/CreatePortEvent.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "raul/Array.hpp" -#include "raul/Atom.hpp" -#include "raul/List.hpp" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "Responder.hpp" -#include "CreatePortEvent.hpp" -#include "PatchImpl.hpp" -#include "PluginImpl.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "QueuedEventSource.hpp" -#include "EngineStore.hpp" -#include "ClientBroadcaster.hpp" -#include "PortImpl.hpp" -#include "AudioDriver.hpp" -#include "MidiDriver.hpp" -#include "OSCDriver.hpp" -#include "DuplexPort.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { - -using namespace Shared; - - -CreatePortEvent::CreatePortEvent( - Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const Raul::Path& path, - const Raul::URI& type, - bool is_output, - QueuedEventSource* source, - const Resource::Properties& properties) - : QueuedEvent(engine, responder, timestamp, true, source) - , _error(NO_ERROR) - , _path(path) - , _type(type) - , _is_output(is_output) - , _data_type(type) - , _patch(NULL) - , _patch_port(NULL) - , _driver_port(NULL) - , _properties(properties) -{ - /* 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). - * - * TODO: fix this using RCU? - */ - - if (_data_type == DataType::UNKNOWN) { - cerr << "[CreatePortEvent] Unknown port type " << type << endl; - _error = UNKNOWN_TYPE; - } -} - - -void -CreatePortEvent::pre_process() -{ - if (_error == UNKNOWN_TYPE || _engine.engine_store()->find_object(_path)) { - QueuedEvent::pre_process(); - return; - } - - _patch = _engine.engine_store()->find_patch(_path.parent()); - - if (_patch != NULL) { - assert(_patch->path() == _path.parent()); - - size_t buffer_size = 1; - if (_type.str() != "ingen:Float") - buffer_size = _engine.audio_driver()->buffer_size(); - - const uint32_t old_num_ports = _patch->num_ports(); - - _patch_port = _patch->create_port(_path.name(), _data_type, buffer_size, _is_output); - _patch_port->set_property("rdf:instanceOf", Atom(Atom::URI, _patch_port->meta_uri().str())); - _patch_port->meta().properties().insert(_properties.begin(), _properties.end()); - - if (_patch_port) { - - if (_is_output) - _patch->add_output(new Raul::List::Node(_patch_port)); - else - _patch->add_input(new Raul::List::Node(_patch_port)); - - if (_patch->external_ports()) - _ports_array = new Raul::Array(old_num_ports + 1, *_patch->external_ports()); - else - _ports_array = new Raul::Array(old_num_ports + 1, NULL); - - _ports_array->at(_patch->num_ports()-1) = _patch_port; - _engine.engine_store()->add(_patch_port); - - if (!_patch->parent()) { - if (_type.str() == "lv2:AudioPort") { - _driver_port = _engine.audio_driver()->create_port( - dynamic_cast(_patch_port)); - } else if (_type.str() == "lv2ev:EventPort") { - _driver_port = _engine.midi_driver()->create_port( - dynamic_cast(_patch_port)); - } - } - - assert(_ports_array->size() == _patch->num_ports()); - - } else { - _error = CREATION_FAILED; - } - } - QueuedEvent::pre_process(); -} - - -void -CreatePortEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch_port) { - _engine.maid()->push(_patch->external_ports()); - _patch->external_ports(_ports_array); - } - - if (_driver_port) { - if (_type.str() == "lv2:AudioPort") { - _engine.audio_driver()->add_port(_driver_port); - } else if (_type.str() == "lv2ev:EventPort") { - _engine.midi_driver()->add_port(_driver_port); - } - } -} - - -void -CreatePortEvent::post_process() -{ - string msg; - switch (_error) { - case NO_ERROR: - _responder->respond_ok(); - _engine.broadcaster()->send_object(_patch_port, true); - break; - case UNKNOWN_TYPE: - msg = string("Could not create port ") + _path.str() + " (Unknown type)"; - _responder->respond_error(msg); - break; - case CREATION_FAILED: - msg = string("Could not create port ") + _path.str() + " (Creation failed)"; - _responder->respond_error(msg); - break; - } -} - - -} // namespace Ingen - diff --git a/src/engine/events/CreatePortEvent.hpp b/src/engine/events/CreatePortEvent.hpp deleted file mode 100644 index ab65eabd..00000000 --- a/src/engine/events/CreatePortEvent.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 CREATEPORTEVENT_H -#define CREATEPORTEVENT_H - -#include "QueuedEvent.hpp" -#include "raul/Path.hpp" -#include "raul/Array.hpp" -#include "interface/DataType.hpp" -#include "interface/Resource.hpp" - -namespace Ingen { - -class PatchImpl; -class PortImpl; -class DriverPort; - - -/** An event to add a Port to a Patch. - * - * \ingroup engine - */ -class CreatePortEvent : public QueuedEvent -{ -public: - CreatePortEvent( - Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const Raul::Path& path, - const Raul::URI& type, - bool is_output, - QueuedEventSource* source, - const Shared::Resource::Properties& properties); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - - enum ErrorType { - NO_ERROR, - UNKNOWN_TYPE, - CREATION_FAILED - }; - - ErrorType _error; - Raul::Path _path; - Raul::URI _type; - bool _is_output; - Shared::DataType _data_type; - PatchImpl* _patch; - PortImpl* _patch_port; - Raul::Array* _ports_array; ///< New (external) ports array for Patch - DriverPort* _driver_port; ///< Driver (eg Jack) port if this is a toplevel port - bool _succeeded; - - Shared::Resource::Properties _properties; -}; - - -} // namespace Ingen - -#endif // CREATEPORTEVENT_H diff --git a/src/engine/events/Deactivate.hpp b/src/engine/events/Deactivate.hpp new file mode 100644 index 00000000..57f09b28 --- /dev/null +++ b/src/engine/events/Deactivate.hpp @@ -0,0 +1,47 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 DEACTIVATEEVENT_H +#define DEACTIVATEEVENT_H + +#include "QueuedEvent.hpp" +#include "Engine.hpp" + +namespace Ingen { + + +/** Deactivates the engine. + * + * \ingroup engine + */ +class DeactivateEvent : public QueuedEvent +{ +public: + DeactivateEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) + : QueuedEvent(engine, responder, timestamp) + {} + + void post_process() { + _responder->respond_ok(); + _engine.deactivate(); + } +}; + + +} // namespace Ingen + +#endif // DEACTIVATEEVENT_H diff --git a/src/engine/events/DeactivateEvent.hpp b/src/engine/events/DeactivateEvent.hpp deleted file mode 100644 index 57f09b28..00000000 --- a/src/engine/events/DeactivateEvent.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 DEACTIVATEEVENT_H -#define DEACTIVATEEVENT_H - -#include "QueuedEvent.hpp" -#include "Engine.hpp" - -namespace Ingen { - - -/** Deactivates the engine. - * - * \ingroup engine - */ -class DeactivateEvent : public QueuedEvent -{ -public: - DeactivateEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) - : QueuedEvent(engine, responder, timestamp) - {} - - void post_process() { - _responder->respond_ok(); - _engine.deactivate(); - } -}; - - -} // namespace Ingen - -#endif // DEACTIVATEEVENT_H diff --git a/src/engine/events/Delete.cpp b/src/engine/events/Delete.cpp new file mode 100644 index 00000000..54e5626e --- /dev/null +++ b/src/engine/events/Delete.cpp @@ -0,0 +1,213 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "raul/Maid.hpp" +#include "raul/Path.hpp" +#include "Delete.hpp" +#include "Responder.hpp" +#include "Engine.hpp" +#include "PatchImpl.hpp" +#include "NodeBase.hpp" +#include "PluginImpl.hpp" +#include "AudioDriver.hpp" +#include "MidiDriver.hpp" +#include "DisconnectAll.hpp" +#include "ClientBroadcaster.hpp" +#include "EngineStore.hpp" +#include "QueuedEventSource.hpp" +#include "PortImpl.hpp" + +using namespace std; + +namespace Ingen { + +using namespace Shared; + + +DeleteEvent::DeleteEvent(Engine& engine, SharedPtr responder, FrameTime time, QueuedEventSource* source, const Raul::Path& path) + : QueuedEvent(engine, responder, time, true, source) + , _path(path) + , _store_iterator(engine.engine_store()->end()) + , _driver_port(NULL) + , _patch_node_listnode(NULL) + , _patch_port_listnode(NULL) + , _ports_array(NULL) + , _compiled_patch(NULL) + , _disconnect_event(NULL) +{ + assert(_source); +} + + +DeleteEvent::~DeleteEvent() +{ + delete _disconnect_event; +} + + +void +DeleteEvent::pre_process() +{ + _store_iterator = _engine.engine_store()->find(_path); + + if (_store_iterator != _engine.engine_store()->end()) { + _node = PtrCast(_store_iterator->second); + + if (!_node) + _port = PtrCast(_store_iterator->second); + } + + if (_store_iterator != _engine.engine_store()->end()) { + _removed_table = _engine.engine_store()->remove(_store_iterator); + } + + if (_node != NULL && !_path.is_root()) { + assert(_node->parent_patch()); + _patch_node_listnode = _node->parent_patch()->remove_node(_path.name()); + if (_patch_node_listnode) { + assert(_patch_node_listnode->elem() == _node.get()); + + _disconnect_event = new DisconnectAllEvent(_engine, _node->parent_patch(), _node.get()); + _disconnect_event->pre_process(); + + if (_node->parent_patch()->enabled()) { + // FIXME: is this called multiple times? + _compiled_patch = _node->parent_patch()->compile(); +#ifndef NDEBUG + // Be sure node is removed from process order, so it can be deleted + for (size_t i=0; i < _compiled_patch->size(); ++i) { + assert(_compiled_patch->at(i).node() != _node.get()); + // FIXME: check providers/dependants too + } +#endif + } + } + } else if (_port) { + assert(_port->parent_patch()); + _patch_port_listnode = _port->parent_patch()->remove_port(_path.name()); + if (_patch_port_listnode) { + assert(_patch_port_listnode->elem() == _port.get()); + + _disconnect_event = new DisconnectAllEvent(_engine, _port->parent_patch(), _port.get()); + _disconnect_event->pre_process(); + + if (_port->parent_patch()->enabled()) { + // FIXME: is this called multiple times? + _compiled_patch = _port->parent_patch()->compile(); + _ports_array = _port->parent_patch()->build_ports_array(); + assert(_ports_array->size() == _port->parent_patch()->num_ports()); + } + } + + } + + QueuedEvent::pre_process(); +} + + +void +DeleteEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + + if (_patch_node_listnode) { + assert(_node); + + if (_disconnect_event) + _disconnect_event->execute(context); + + if (_node->parent_patch()->compiled_patch()) + _engine.maid()->push(_node->parent_patch()->compiled_patch()); + + _node->parent_patch()->compiled_patch(_compiled_patch); + + } else if (_patch_port_listnode) { + assert(_port); + + if (_disconnect_event) + _disconnect_event->execute(context); + + if (_port->parent_patch()->compiled_patch()) + _engine.maid()->push(_port->parent_patch()->compiled_patch()); + + _port->parent_patch()->compiled_patch(_compiled_patch); + + if (_port->parent_patch()->external_ports()) + _engine.maid()->push(_port->parent_patch()->external_ports()); + + _port->parent_patch()->external_ports(_ports_array); + + if ( ! _port->parent_patch()->parent()) { + if (_port->type() == DataType::AUDIO) + _driver_port = _engine.audio_driver()->remove_port(_port->path()); + else if (_port->type() == DataType::EVENT) + _driver_port = _engine.midi_driver()->remove_port(_port->path()); + + // Apparently this needs to be called in post_process?? + //if (_driver_port) + // _driver_port->elem()->unregister(); + } + } + + if (_source) + _source->unblock(); +} + + +void +DeleteEvent::post_process() +{ + if (!_node && !_port) { + if (_path.is_root()) { + _responder->respond_error("You can not destroy the root patch (/)"); + } else { + string msg = string("Could not find object ") + _path.str() + " to destroy"; + _responder->respond_error(msg); + } + } + + if (_patch_node_listnode) { + assert(_node); + _node->deactivate(); + _responder->respond_ok(); + _engine.broadcaster()->bundle_begin(); + if (_disconnect_event) + _disconnect_event->post_process(); + _engine.broadcaster()->send_deleted(_path); + _engine.broadcaster()->bundle_end(); + _engine.maid()->push(_patch_node_listnode); + } else if (_patch_port_listnode) { + assert(_port); + _responder->respond_ok(); + _engine.broadcaster()->bundle_begin(); + if (_disconnect_event) + _disconnect_event->post_process(); + _engine.broadcaster()->send_deleted(_path); + _engine.broadcaster()->bundle_end(); + _engine.maid()->push(_patch_port_listnode); + } else { + _responder->respond_error("Unable to destroy object"); + } + + if (_driver_port) { + _driver_port->elem()->destroy(); + _engine.maid()->push(_driver_port); + } +} + + +} // namespace Ingen diff --git a/src/engine/events/Delete.hpp b/src/engine/events/Delete.hpp new file mode 100644 index 00000000..abaf9cdd --- /dev/null +++ b/src/engine/events/Delete.hpp @@ -0,0 +1,87 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 DESTROYEVENT_H +#define DESTROYEVENT_H + +#include "QueuedEvent.hpp" +#include "EngineStore.hpp" +#include "PatchImpl.hpp" + +namespace Raul { + template class Array; + template class ListNode; +} + +namespace Ingen { + +class GraphObjectImpl; +class NodeImpl; +class PortImpl; +class DriverPort; +class DisconnectAllEvent; +class CompiledPatch; + +/** \page methods + *

DELETE

+ * As per WebDAV (RFC4918 S9.6). + * + * Remove an object from the engine and destroy it. + * + * \li All properties of the object are lost + * \li All references to the object are lost (e.g. the parent's reference to + * this child is lost, any connections to the object are removed, etc.) + */ + +/** DELETE a graph object (see \ref methods). + * \ingroup engine + */ +class DeleteEvent : public QueuedEvent +{ +public: + DeleteEvent( + Engine& engine, + SharedPtr responder, + FrameTime timestamp, + QueuedEventSource* source, + const Raul::Path& path); + + ~DeleteEvent(); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + Raul::Path _path; + EngineStore::iterator _store_iterator; + SharedPtr _node; ///< Non-NULL iff a node + SharedPtr _port; ///< Non-NULL iff a port + Raul::List::Node* _driver_port; + PatchImpl::Nodes::Node* _patch_node_listnode; + Raul::List::Node* _patch_port_listnode; + Raul::Array* _ports_array; ///< New (external) ports for Patch + CompiledPatch* _compiled_patch; ///< Patch's new process order + DisconnectAllEvent* _disconnect_event; + + SharedPtr< Raul::Table > > _removed_table; +}; + + +} // namespace Ingen + +#endif // DESTROYEVENT_H diff --git a/src/engine/events/DeleteEvent.cpp b/src/engine/events/DeleteEvent.cpp deleted file mode 100644 index 958a8d42..00000000 --- a/src/engine/events/DeleteEvent.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "DeleteEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "NodeBase.hpp" -#include "PluginImpl.hpp" -#include "AudioDriver.hpp" -#include "MidiDriver.hpp" -#include "DisconnectAllEvent.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" -#include "QueuedEventSource.hpp" -#include "PortImpl.hpp" - -using namespace std; - -namespace Ingen { - -using namespace Shared; - - -DeleteEvent::DeleteEvent(Engine& engine, SharedPtr responder, FrameTime time, QueuedEventSource* source, const Raul::Path& path) - : QueuedEvent(engine, responder, time, true, source) - , _path(path) - , _store_iterator(engine.engine_store()->end()) - , _driver_port(NULL) - , _patch_node_listnode(NULL) - , _patch_port_listnode(NULL) - , _ports_array(NULL) - , _compiled_patch(NULL) - , _disconnect_event(NULL) -{ - assert(_source); -} - - -DeleteEvent::~DeleteEvent() -{ - delete _disconnect_event; -} - - -void -DeleteEvent::pre_process() -{ - _store_iterator = _engine.engine_store()->find(_path); - - if (_store_iterator != _engine.engine_store()->end()) { - _node = PtrCast(_store_iterator->second); - - if (!_node) - _port = PtrCast(_store_iterator->second); - } - - if (_store_iterator != _engine.engine_store()->end()) { - _removed_table = _engine.engine_store()->remove(_store_iterator); - } - - if (_node != NULL && !_path.is_root()) { - assert(_node->parent_patch()); - _patch_node_listnode = _node->parent_patch()->remove_node(_path.name()); - if (_patch_node_listnode) { - assert(_patch_node_listnode->elem() == _node.get()); - - _disconnect_event = new DisconnectAllEvent(_engine, _node->parent_patch(), _node.get()); - _disconnect_event->pre_process(); - - if (_node->parent_patch()->enabled()) { - // FIXME: is this called multiple times? - _compiled_patch = _node->parent_patch()->compile(); -#ifndef NDEBUG - // Be sure node is removed from process order, so it can be deleted - for (size_t i=0; i < _compiled_patch->size(); ++i) { - assert(_compiled_patch->at(i).node() != _node.get()); - // FIXME: check providers/dependants too - } -#endif - } - } - } else if (_port) { - assert(_port->parent_patch()); - _patch_port_listnode = _port->parent_patch()->remove_port(_path.name()); - if (_patch_port_listnode) { - assert(_patch_port_listnode->elem() == _port.get()); - - _disconnect_event = new DisconnectAllEvent(_engine, _port->parent_patch(), _port.get()); - _disconnect_event->pre_process(); - - if (_port->parent_patch()->enabled()) { - // FIXME: is this called multiple times? - _compiled_patch = _port->parent_patch()->compile(); - _ports_array = _port->parent_patch()->build_ports_array(); - assert(_ports_array->size() == _port->parent_patch()->num_ports()); - } - } - - } - - QueuedEvent::pre_process(); -} - - -void -DeleteEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch_node_listnode) { - assert(_node); - - if (_disconnect_event) - _disconnect_event->execute(context); - - if (_node->parent_patch()->compiled_patch()) - _engine.maid()->push(_node->parent_patch()->compiled_patch()); - - _node->parent_patch()->compiled_patch(_compiled_patch); - - } else if (_patch_port_listnode) { - assert(_port); - - if (_disconnect_event) - _disconnect_event->execute(context); - - if (_port->parent_patch()->compiled_patch()) - _engine.maid()->push(_port->parent_patch()->compiled_patch()); - - _port->parent_patch()->compiled_patch(_compiled_patch); - - if (_port->parent_patch()->external_ports()) - _engine.maid()->push(_port->parent_patch()->external_ports()); - - _port->parent_patch()->external_ports(_ports_array); - - if ( ! _port->parent_patch()->parent()) { - if (_port->type() == DataType::AUDIO) - _driver_port = _engine.audio_driver()->remove_port(_port->path()); - else if (_port->type() == DataType::EVENT) - _driver_port = _engine.midi_driver()->remove_port(_port->path()); - - // Apparently this needs to be called in post_process?? - //if (_driver_port) - // _driver_port->elem()->unregister(); - } - } - - if (_source) - _source->unblock(); -} - - -void -DeleteEvent::post_process() -{ - if (!_node && !_port) { - if (_path.is_root()) { - _responder->respond_error("You can not destroy the root patch (/)"); - } else { - string msg = string("Could not find object ") + _path.str() + " to destroy"; - _responder->respond_error(msg); - } - } - - if (_patch_node_listnode) { - assert(_node); - _node->deactivate(); - _responder->respond_ok(); - _engine.broadcaster()->bundle_begin(); - if (_disconnect_event) - _disconnect_event->post_process(); - _engine.broadcaster()->send_deleted(_path); - _engine.broadcaster()->bundle_end(); - _engine.maid()->push(_patch_node_listnode); - } else if (_patch_port_listnode) { - assert(_port); - _responder->respond_ok(); - _engine.broadcaster()->bundle_begin(); - if (_disconnect_event) - _disconnect_event->post_process(); - _engine.broadcaster()->send_deleted(_path); - _engine.broadcaster()->bundle_end(); - _engine.maid()->push(_patch_port_listnode); - } else { - _responder->respond_error("Unable to destroy object"); - } - - if (_driver_port) { - _driver_port->elem()->destroy(); - _engine.maid()->push(_driver_port); - } -} - - -} // namespace Ingen diff --git a/src/engine/events/DeleteEvent.hpp b/src/engine/events/DeleteEvent.hpp deleted file mode 100644 index abaf9cdd..00000000 --- a/src/engine/events/DeleteEvent.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 DESTROYEVENT_H -#define DESTROYEVENT_H - -#include "QueuedEvent.hpp" -#include "EngineStore.hpp" -#include "PatchImpl.hpp" - -namespace Raul { - template class Array; - template class ListNode; -} - -namespace Ingen { - -class GraphObjectImpl; -class NodeImpl; -class PortImpl; -class DriverPort; -class DisconnectAllEvent; -class CompiledPatch; - -/** \page methods - *

DELETE

- * As per WebDAV (RFC4918 S9.6). - * - * Remove an object from the engine and destroy it. - * - * \li All properties of the object are lost - * \li All references to the object are lost (e.g. the parent's reference to - * this child is lost, any connections to the object are removed, etc.) - */ - -/** DELETE a graph object (see \ref methods). - * \ingroup engine - */ -class DeleteEvent : public QueuedEvent -{ -public: - DeleteEvent( - Engine& engine, - SharedPtr responder, - FrameTime timestamp, - QueuedEventSource* source, - const Raul::Path& path); - - ~DeleteEvent(); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - Raul::Path _path; - EngineStore::iterator _store_iterator; - SharedPtr _node; ///< Non-NULL iff a node - SharedPtr _port; ///< Non-NULL iff a port - Raul::List::Node* _driver_port; - PatchImpl::Nodes::Node* _patch_node_listnode; - Raul::List::Node* _patch_port_listnode; - Raul::Array* _ports_array; ///< New (external) ports for Patch - CompiledPatch* _compiled_patch; ///< Patch's new process order - DisconnectAllEvent* _disconnect_event; - - SharedPtr< Raul::Table > > _removed_table; -}; - - -} // namespace Ingen - -#endif // DESTROYEVENT_H diff --git a/src/engine/events/DisconnectAll.cpp b/src/engine/events/DisconnectAll.cpp new file mode 100644 index 00000000..4fa643ea --- /dev/null +++ b/src/engine/events/DisconnectAll.cpp @@ -0,0 +1,186 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 +#include "raul/Array.hpp" +#include "raul/List.hpp" +#include "raul/Maid.hpp" +#include "raul/Path.hpp" +#include "ClientBroadcaster.hpp" +#include "ConnectionImpl.hpp" +#include "events/DisconnectAll.hpp" +#include "events/Disconnection.hpp" +#include "Engine.hpp" +#include "InputPort.hpp" +#include "NodeImpl.hpp" +#include "EngineStore.hpp" +#include "OutputPort.hpp" +#include "PatchImpl.hpp" +#include "PortImpl.hpp" +#include "Responder.hpp" +#include "util.hpp" + +using namespace std; +using namespace Raul; + +namespace Ingen { + + +DisconnectAllEvent::DisconnectAllEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Path& parent_path, const Path& node_path) + : QueuedEvent(engine, responder, timestamp) + , _parent_path(parent_path) + , _path(node_path) + , _parent(NULL) + , _node(NULL) + , _port(NULL) + , _lookup(true) + , _error(NO_ERROR) +{ +} + + +/** Internal version for use by other events. + */ +DisconnectAllEvent::DisconnectAllEvent(Engine& engine, PatchImpl* parent, GraphObjectImpl* object) + : QueuedEvent(engine) + , _parent_path(parent->path()) + , _path(object->path()) + , _parent(parent) + , _node(dynamic_cast(object)) + , _port(dynamic_cast(object)) + , _lookup(false) + , _error(NO_ERROR) +{ +} + + +DisconnectAllEvent::~DisconnectAllEvent() +{ + for (Raul::List::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) + delete (*i); +} + + +void +DisconnectAllEvent::pre_process() +{ + if (_lookup) { + _parent = _engine.engine_store()->find_patch(_parent_path); + + if (_parent == NULL) { + _error = PARENT_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + GraphObjectImpl* object = _engine.engine_store()->find_object(_path); + + if (object == NULL) { + _error = OBJECT_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + if (object->parent_patch() != _parent && object->parent()->parent_patch() != _parent) { + _error = INVALID_PARENT_PATH; + QueuedEvent::pre_process(); + return; + } + + // Only one of these will succeed + _node = dynamic_cast(object); + _port = dynamic_cast(object); + + assert((_node || _port) && !(_node && _port)); + } + + if (_node) { + for (PatchImpl::Connections::const_iterator i = _parent->connections().begin(); + i != _parent->connections().end(); ++i) { + ConnectionImpl* c = (ConnectionImpl*)i->get(); + if ((c->src_port()->parent_node() == _node || c->dst_port()->parent_node() == _node) + && !c->pending_disconnection()) { + DisconnectionEvent* ev = new DisconnectionEvent(_engine, + SharedPtr(new Responder()), _time, c->src_port(), c->dst_port()); + ev->pre_process(); + _disconnection_events.push_back(new Raul::List::Node(ev)); + c->pending_disconnection(true); + } + } + } else { // _port + for (PatchImpl::Connections::const_iterator i = _parent->connections().begin(); + i != _parent->connections().end(); ++i) { + ConnectionImpl* c = (ConnectionImpl*)i->get(); + if ((c->src_port() == _port || c->dst_port() == _port) && !c->pending_disconnection()) { + DisconnectionEvent* ev = new DisconnectionEvent(_engine, + SharedPtr(new Responder()), _time, c->src_port(), c->dst_port()); + ev->pre_process(); + _disconnection_events.push_back(new Raul::List::Node(ev)); + c->pending_disconnection(true); + } + } + } + + QueuedEvent::pre_process(); +} + + +void +DisconnectAllEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + + if (_error == NO_ERROR) { + for (Raul::List::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) + (*i)->execute(context); + } +} + + +void +DisconnectAllEvent::post_process() +{ + if (_error == NO_ERROR) { + if (_responder) + _responder->respond_ok(); + for (Raul::List::iterator i = _disconnection_events.begin(); + i != _disconnection_events.end(); ++i) + (*i)->post_process(); + } else { + if (_responder) { + boost::format fmt("Unable to disconnect %1% (%2%)"); + fmt % _path; + switch (_error) { + case INVALID_PARENT_PATH: + fmt % string("Invalid parent path: ").append(_parent_path.str()); + break; + case PARENT_NOT_FOUND: + fmt % string("Unable to find parent: ").append(_parent_path.str()); + break; + case OBJECT_NOT_FOUND: + fmt % string("Unable to find object"); + default: + break; + } + _responder->respond_error(fmt.str()); + } + } +} + + +} // namespace Ingen + diff --git a/src/engine/events/DisconnectAll.hpp b/src/engine/events/DisconnectAll.hpp new file mode 100644 index 00000000..66c639f1 --- /dev/null +++ b/src/engine/events/DisconnectAll.hpp @@ -0,0 +1,76 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 DISCONNECTNODEEVENT_H +#define DISCONNECTNODEEVENT_H + +#include "raul/List.hpp" +#include "raul/Path.hpp" +#include "QueuedEvent.hpp" + +namespace Ingen { + +class DisconnectionEvent; +class PatchImpl; +class NodeImpl; +class Connection; +class PortImpl; +class InputPort; +class OutputPort; + + +/** An event to disconnect all connections to a Node. + * + * \ingroup engine + */ +class DisconnectAllEvent : public QueuedEvent +{ +public: + DisconnectAllEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& parent_path, const Raul::Path& node_path); + DisconnectAllEvent(Engine& engine, PatchImpl* parent, GraphObjectImpl* object); + ~DisconnectAllEvent(); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + enum ErrorType { + NO_ERROR, + INVALID_PARENT_PATH, + PARENT_NOT_FOUND, + OBJECT_NOT_FOUND, + }; + + Raul::Path _parent_path; + Raul::Path _path; + PatchImpl* _parent; + NodeImpl* _node; + PortImpl* _port; + Raul::List _disconnection_events; + + bool _lookup; + bool _disconnect_parent; + + ErrorType _error; +}; + + +} // namespace Ingen + + +#endif // DISCONNECTNODEEVENT_H diff --git a/src/engine/events/DisconnectAllEvent.cpp b/src/engine/events/DisconnectAllEvent.cpp deleted file mode 100644 index 11c4c668..00000000 --- a/src/engine/events/DisconnectAllEvent.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 -#include "raul/Array.hpp" -#include "raul/List.hpp" -#include "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "ClientBroadcaster.hpp" -#include "ConnectionImpl.hpp" -#include "DisconnectAllEvent.hpp" -#include "DisconnectionEvent.hpp" -#include "Engine.hpp" -#include "InputPort.hpp" -#include "NodeImpl.hpp" -#include "EngineStore.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "PortImpl.hpp" -#include "Responder.hpp" -#include "util.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { - - -DisconnectAllEvent::DisconnectAllEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Path& parent_path, const Path& node_path) - : QueuedEvent(engine, responder, timestamp) - , _parent_path(parent_path) - , _path(node_path) - , _parent(NULL) - , _node(NULL) - , _port(NULL) - , _lookup(true) - , _error(NO_ERROR) -{ -} - - -/** Internal version for use by other events. - */ -DisconnectAllEvent::DisconnectAllEvent(Engine& engine, PatchImpl* parent, GraphObjectImpl* object) - : QueuedEvent(engine) - , _parent_path(parent->path()) - , _path(object->path()) - , _parent(parent) - , _node(dynamic_cast(object)) - , _port(dynamic_cast(object)) - , _lookup(false) - , _error(NO_ERROR) -{ -} - - -DisconnectAllEvent::~DisconnectAllEvent() -{ - for (Raul::List::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) - delete (*i); -} - - -void -DisconnectAllEvent::pre_process() -{ - if (_lookup) { - _parent = _engine.engine_store()->find_patch(_parent_path); - - if (_parent == NULL) { - _error = PARENT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - GraphObjectImpl* object = _engine.engine_store()->find_object(_path); - - if (object == NULL) { - _error = OBJECT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if (object->parent_patch() != _parent && object->parent()->parent_patch() != _parent) { - _error = INVALID_PARENT_PATH; - QueuedEvent::pre_process(); - return; - } - - // Only one of these will succeed - _node = dynamic_cast(object); - _port = dynamic_cast(object); - - assert((_node || _port) && !(_node && _port)); - } - - if (_node) { - for (PatchImpl::Connections::const_iterator i = _parent->connections().begin(); - i != _parent->connections().end(); ++i) { - ConnectionImpl* c = (ConnectionImpl*)i->get(); - if ((c->src_port()->parent_node() == _node || c->dst_port()->parent_node() == _node) - && !c->pending_disconnection()) { - DisconnectionEvent* ev = new DisconnectionEvent(_engine, - SharedPtr(new Responder()), _time, c->src_port(), c->dst_port()); - ev->pre_process(); - _disconnection_events.push_back(new Raul::List::Node(ev)); - c->pending_disconnection(true); - } - } - } else { // _port - for (PatchImpl::Connections::const_iterator i = _parent->connections().begin(); - i != _parent->connections().end(); ++i) { - ConnectionImpl* c = (ConnectionImpl*)i->get(); - if ((c->src_port() == _port || c->dst_port() == _port) && !c->pending_disconnection()) { - DisconnectionEvent* ev = new DisconnectionEvent(_engine, - SharedPtr(new Responder()), _time, c->src_port(), c->dst_port()); - ev->pre_process(); - _disconnection_events.push_back(new Raul::List::Node(ev)); - c->pending_disconnection(true); - } - } - } - - QueuedEvent::pre_process(); -} - - -void -DisconnectAllEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_error == NO_ERROR) { - for (Raul::List::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) - (*i)->execute(context); - } -} - - -void -DisconnectAllEvent::post_process() -{ - if (_error == NO_ERROR) { - if (_responder) - _responder->respond_ok(); - for (Raul::List::iterator i = _disconnection_events.begin(); - i != _disconnection_events.end(); ++i) - (*i)->post_process(); - } else { - if (_responder) { - boost::format fmt("Unable to disconnect %1% (%2%)"); - fmt % _path; - switch (_error) { - case INVALID_PARENT_PATH: - fmt % string("Invalid parent path: ").append(_parent_path.str()); - break; - case PARENT_NOT_FOUND: - fmt % string("Unable to find parent: ").append(_parent_path.str()); - break; - case OBJECT_NOT_FOUND: - fmt % string("Unable to find object"); - default: - break; - } - _responder->respond_error(fmt.str()); - } - } -} - - -} // namespace Ingen - diff --git a/src/engine/events/DisconnectAllEvent.hpp b/src/engine/events/DisconnectAllEvent.hpp deleted file mode 100644 index 66c639f1..00000000 --- a/src/engine/events/DisconnectAllEvent.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 DISCONNECTNODEEVENT_H -#define DISCONNECTNODEEVENT_H - -#include "raul/List.hpp" -#include "raul/Path.hpp" -#include "QueuedEvent.hpp" - -namespace Ingen { - -class DisconnectionEvent; -class PatchImpl; -class NodeImpl; -class Connection; -class PortImpl; -class InputPort; -class OutputPort; - - -/** An event to disconnect all connections to a Node. - * - * \ingroup engine - */ -class DisconnectAllEvent : public QueuedEvent -{ -public: - DisconnectAllEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& parent_path, const Raul::Path& node_path); - DisconnectAllEvent(Engine& engine, PatchImpl* parent, GraphObjectImpl* object); - ~DisconnectAllEvent(); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum ErrorType { - NO_ERROR, - INVALID_PARENT_PATH, - PARENT_NOT_FOUND, - OBJECT_NOT_FOUND, - }; - - Raul::Path _parent_path; - Raul::Path _path; - PatchImpl* _parent; - NodeImpl* _node; - PortImpl* _port; - Raul::List _disconnection_events; - - bool _lookup; - bool _disconnect_parent; - - ErrorType _error; -}; - - -} // namespace Ingen - - -#endif // DISCONNECTNODEEVENT_H diff --git a/src/engine/events/Disconnection.cpp b/src/engine/events/Disconnection.cpp new file mode 100644 index 00000000..fcbd643b --- /dev/null +++ b/src/engine/events/Disconnection.cpp @@ -0,0 +1,212 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "raul/Maid.hpp" +#include "raul/Path.hpp" +#include "events/Disconnection.hpp" +#include "Responder.hpp" +#include "Engine.hpp" +#include "ConnectionImpl.hpp" +#include "InputPort.hpp" +#include "OutputPort.hpp" +#include "PatchImpl.hpp" +#include "ClientBroadcaster.hpp" +#include "PortImpl.hpp" +#include "EngineStore.hpp" + +using namespace std; + +namespace Ingen { + + +//// DisconnectionEvent //// + + +DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& src_port_path, const Raul::Path& dst_port_path) + : QueuedEvent(engine, responder, timestamp) + , _src_port_path(src_port_path) + , _dst_port_path(dst_port_path) + , _patch(NULL) + , _src_port(NULL) + , _dst_port(NULL) + , _lookup(true) + , _patch_connection(NULL) + , _compiled_patch(NULL) + , _error(NO_ERROR) +{ +} + + +DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, PortImpl* const src_port, PortImpl* const dst_port) +: QueuedEvent(engine, responder, timestamp), + _src_port_path(src_port->path()), + _dst_port_path(dst_port->path()), + _patch(src_port->parent_node()->parent_patch()), + _src_port(src_port), + _dst_port(dst_port), + _lookup(false), + _compiled_patch(NULL), + _error(NO_ERROR) +{ + // FIXME: These break for patch ports.. is that ok? + /*assert(src_port->is_output()); + assert(dst_port->is_input()); + assert(src_port->type() == dst_port->type()); + assert(src_port->parent_node()->parent_patch() + == dst_port->parent_node()->parent_patch()); */ +} + + +void +DisconnectionEvent::pre_process() +{ + if (_lookup) { + if (_src_port_path.parent().parent() != _dst_port_path.parent().parent() + && _src_port_path.parent() != _dst_port_path.parent().parent() + && _src_port_path.parent().parent() != _dst_port_path.parent()) { + _error = PARENT_PATCH_DIFFERENT; + QueuedEvent::pre_process(); + return; + } + + _src_port = _engine.engine_store()->find_port(_src_port_path); + _dst_port = _engine.engine_store()->find_port(_dst_port_path); + } + + if (_src_port == NULL || _dst_port == NULL) { + _error = PORT_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + _dst_input_port = dynamic_cast(_dst_port); + _src_output_port = dynamic_cast(_src_port); + assert(_src_output_port); + assert(_dst_input_port); + + NodeImpl* const src_node = _src_port->parent_node(); + NodeImpl* const dst_node = _dst_port->parent_node(); + + // Connection to a patch port from inside the patch + if (src_node->parent_patch() != dst_node->parent_patch()) { + + assert(src_node->parent() == dst_node || dst_node->parent() == src_node); + if (src_node->parent() == dst_node) + _patch = dynamic_cast(dst_node); + else + _patch = dynamic_cast(src_node); + + // Connection from a patch input to a patch output (pass through) + } else if (src_node == dst_node && dynamic_cast(src_node)) { + _patch = dynamic_cast(src_node); + + // Normal connection between nodes with the same parent + } else { + _patch = src_node->parent_patch(); + } + + assert(_patch); + + if (!_patch->has_connection(_src_output_port, _dst_input_port)) { + _error = NOT_CONNECTED; + QueuedEvent::pre_process(); + return; + } + + if (src_node == NULL || dst_node == NULL) { + _error = PARENTS_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + for (Raul::List::iterator i = dst_node->providers()->begin(); i != dst_node->providers()->end(); ++i) + if ((*i) == src_node) { + delete dst_node->providers()->erase(i); + break; + } + + for (Raul::List::iterator i = src_node->dependants()->begin(); i != src_node->dependants()->end(); ++i) + if ((*i) == dst_node) { + delete src_node->dependants()->erase(i); + break; + } + + _patch_connection = _patch->remove_connection(_src_port, _dst_port); + + if (_patch->enabled()) + _compiled_patch = _patch->compile(); + + QueuedEvent::pre_process(); +} + + +void +DisconnectionEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + + if (_error == NO_ERROR) { + InputPort::Connections::Node* const port_connection + = _dst_input_port->remove_connection(_src_output_port); + + if (port_connection != NULL) { + assert(_patch_connection); + + if (port_connection->elem() != _patch_connection->elem()) { + cerr << "ERROR: Corrupt connections:" << endl; + cerr << "\t" << port_connection->elem() << ": " + << port_connection->elem()->src_port_path() + << " -> " << port_connection->elem()->dst_port_path() << endl + << "!=" << endl + << "\t" << _patch_connection->elem() << ": " + << _patch_connection->elem()->src_port_path() + << " -> " << _patch_connection->elem()->dst_port_path() << endl; + } + assert(port_connection->elem() == _patch_connection->elem()); + + // Destroy list node, which will drop reference to connection itself + _engine.maid()->push(port_connection); + _engine.maid()->push(_patch_connection); + + if (_patch->compiled_patch() != NULL) + _engine.maid()->push(_patch->compiled_patch()); + _patch->compiled_patch(_compiled_patch); + } else { + _error = CONNECTION_NOT_FOUND; + } + } +} + + +void +DisconnectionEvent::post_process() +{ + if (_error == NO_ERROR) { + _responder->respond_ok(); + _engine.broadcaster()->send_disconnection(_src_port->path(), _dst_port->path()); + } else { + // FIXME: better error messages + string msg = "Unable to disconnect "; + msg.append(_src_port_path.str() + " -> " + _dst_port_path.str()); + cerr << "DISCONNECTION ERROR " << (unsigned)_error << endl; + _responder->respond_error(msg); + } +} + + +} // namespace Ingen + diff --git a/src/engine/events/Disconnection.hpp b/src/engine/events/Disconnection.hpp new file mode 100644 index 00000000..24766462 --- /dev/null +++ b/src/engine/events/Disconnection.hpp @@ -0,0 +1,88 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 DISCONNECTIONEVENT_H +#define DISCONNECTIONEVENT_H + +#include "raul/Path.hpp" +#include "QueuedEvent.hpp" +#include "types.hpp" +#include "PatchImpl.hpp" + +namespace Raul { + template class ListNode; + template class Array; +} + +namespace Ingen { + +class NodeImpl; +class ConnectionImpl; +class MidiMessage; +class PortImpl; +class InputPort; +class OutputPort; +class CompiledPatch; + + +/** Make a Connection between two Ports. + * + * \ingroup engine + */ +class DisconnectionEvent : public QueuedEvent +{ +public: + DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& src_port_path, const Raul::Path& dst_port_path); + DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, PortImpl* const src_port, PortImpl* const dst_port); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + + enum ErrorType { + NO_ERROR, + PARENT_PATCH_DIFFERENT, + PORT_NOT_FOUND, + TYPE_MISMATCH, + NOT_CONNECTED, + PARENTS_NOT_FOUND, + CONNECTION_NOT_FOUND + }; + + Raul::Path _src_port_path; + Raul::Path _dst_port_path; + + PatchImpl* _patch; + PortImpl* _src_port; + PortImpl* _dst_port; + OutputPort* _src_output_port; + InputPort* _dst_input_port; + + bool _lookup; + + PatchImpl::Connections::Node* _patch_connection; + CompiledPatch* _compiled_patch; ///< New process order for Patch + + ErrorType _error; +}; + + +} // namespace Ingen + +#endif // DISCONNECTIONEVENT_H diff --git a/src/engine/events/DisconnectionEvent.cpp b/src/engine/events/DisconnectionEvent.cpp deleted file mode 100644 index 26a68421..00000000 --- a/src/engine/events/DisconnectionEvent.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "raul/Maid.hpp" -#include "raul/Path.hpp" -#include "DisconnectionEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "ConnectionImpl.hpp" -#include "InputPort.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "PortImpl.hpp" -#include "EngineStore.hpp" - -using namespace std; - -namespace Ingen { - - -//// DisconnectionEvent //// - - -DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& src_port_path, const Raul::Path& dst_port_path) - : QueuedEvent(engine, responder, timestamp) - , _src_port_path(src_port_path) - , _dst_port_path(dst_port_path) - , _patch(NULL) - , _src_port(NULL) - , _dst_port(NULL) - , _lookup(true) - , _patch_connection(NULL) - , _compiled_patch(NULL) - , _error(NO_ERROR) -{ -} - - -DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, PortImpl* const src_port, PortImpl* const dst_port) -: QueuedEvent(engine, responder, timestamp), - _src_port_path(src_port->path()), - _dst_port_path(dst_port->path()), - _patch(src_port->parent_node()->parent_patch()), - _src_port(src_port), - _dst_port(dst_port), - _lookup(false), - _compiled_patch(NULL), - _error(NO_ERROR) -{ - // FIXME: These break for patch ports.. is that ok? - /*assert(src_port->is_output()); - assert(dst_port->is_input()); - assert(src_port->type() == dst_port->type()); - assert(src_port->parent_node()->parent_patch() - == dst_port->parent_node()->parent_patch()); */ -} - - -void -DisconnectionEvent::pre_process() -{ - if (_lookup) { - if (_src_port_path.parent().parent() != _dst_port_path.parent().parent() - && _src_port_path.parent() != _dst_port_path.parent().parent() - && _src_port_path.parent().parent() != _dst_port_path.parent()) { - _error = PARENT_PATCH_DIFFERENT; - QueuedEvent::pre_process(); - return; - } - - _src_port = _engine.engine_store()->find_port(_src_port_path); - _dst_port = _engine.engine_store()->find_port(_dst_port_path); - } - - if (_src_port == NULL || _dst_port == NULL) { - _error = PORT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - _dst_input_port = dynamic_cast(_dst_port); - _src_output_port = dynamic_cast(_src_port); - assert(_src_output_port); - assert(_dst_input_port); - - NodeImpl* const src_node = _src_port->parent_node(); - NodeImpl* const dst_node = _dst_port->parent_node(); - - // Connection to a patch port from inside the patch - if (src_node->parent_patch() != dst_node->parent_patch()) { - - assert(src_node->parent() == dst_node || dst_node->parent() == src_node); - if (src_node->parent() == dst_node) - _patch = dynamic_cast(dst_node); - else - _patch = dynamic_cast(src_node); - - // Connection from a patch input to a patch output (pass through) - } else if (src_node == dst_node && dynamic_cast(src_node)) { - _patch = dynamic_cast(src_node); - - // Normal connection between nodes with the same parent - } else { - _patch = src_node->parent_patch(); - } - - assert(_patch); - - if (!_patch->has_connection(_src_output_port, _dst_input_port)) { - _error = NOT_CONNECTED; - QueuedEvent::pre_process(); - return; - } - - if (src_node == NULL || dst_node == NULL) { - _error = PARENTS_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - for (Raul::List::iterator i = dst_node->providers()->begin(); i != dst_node->providers()->end(); ++i) - if ((*i) == src_node) { - delete dst_node->providers()->erase(i); - break; - } - - for (Raul::List::iterator i = src_node->dependants()->begin(); i != src_node->dependants()->end(); ++i) - if ((*i) == dst_node) { - delete src_node->dependants()->erase(i); - break; - } - - _patch_connection = _patch->remove_connection(_src_port, _dst_port); - - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - - QueuedEvent::pre_process(); -} - - -void -DisconnectionEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_error == NO_ERROR) { - InputPort::Connections::Node* const port_connection - = _dst_input_port->remove_connection(_src_output_port); - - if (port_connection != NULL) { - assert(_patch_connection); - - if (port_connection->elem() != _patch_connection->elem()) { - cerr << "ERROR: Corrupt connections:" << endl; - cerr << "\t" << port_connection->elem() << ": " - << port_connection->elem()->src_port_path() - << " -> " << port_connection->elem()->dst_port_path() << endl - << "!=" << endl - << "\t" << _patch_connection->elem() << ": " - << _patch_connection->elem()->src_port_path() - << " -> " << _patch_connection->elem()->dst_port_path() << endl; - } - assert(port_connection->elem() == _patch_connection->elem()); - - // Destroy list node, which will drop reference to connection itself - _engine.maid()->push(port_connection); - _engine.maid()->push(_patch_connection); - - if (_patch->compiled_patch() != NULL) - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(_compiled_patch); - } else { - _error = CONNECTION_NOT_FOUND; - } - } -} - - -void -DisconnectionEvent::post_process() -{ - if (_error == NO_ERROR) { - _responder->respond_ok(); - _engine.broadcaster()->send_disconnection(_src_port->path(), _dst_port->path()); - } else { - // FIXME: better error messages - string msg = "Unable to disconnect "; - msg.append(_src_port_path.str() + " -> " + _dst_port_path.str()); - cerr << "DISCONNECTION ERROR " << (unsigned)_error << endl; - _responder->respond_error(msg); - } -} - - -} // namespace Ingen - diff --git a/src/engine/events/DisconnectionEvent.hpp b/src/engine/events/DisconnectionEvent.hpp deleted file mode 100644 index 24766462..00000000 --- a/src/engine/events/DisconnectionEvent.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 DISCONNECTIONEVENT_H -#define DISCONNECTIONEVENT_H - -#include "raul/Path.hpp" -#include "QueuedEvent.hpp" -#include "types.hpp" -#include "PatchImpl.hpp" - -namespace Raul { - template class ListNode; - template class Array; -} - -namespace Ingen { - -class NodeImpl; -class ConnectionImpl; -class MidiMessage; -class PortImpl; -class InputPort; -class OutputPort; -class CompiledPatch; - - -/** Make a Connection between two Ports. - * - * \ingroup engine - */ -class DisconnectionEvent : public QueuedEvent -{ -public: - DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& src_port_path, const Raul::Path& dst_port_path); - DisconnectionEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, PortImpl* const src_port, PortImpl* const dst_port); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - - enum ErrorType { - NO_ERROR, - PARENT_PATCH_DIFFERENT, - PORT_NOT_FOUND, - TYPE_MISMATCH, - NOT_CONNECTED, - PARENTS_NOT_FOUND, - CONNECTION_NOT_FOUND - }; - - Raul::Path _src_port_path; - Raul::Path _dst_port_path; - - PatchImpl* _patch; - PortImpl* _src_port; - PortImpl* _dst_port; - OutputPort* _src_output_port; - InputPort* _dst_input_port; - - bool _lookup; - - PatchImpl::Connections::Node* _patch_connection; - CompiledPatch* _compiled_patch; ///< New process order for Patch - - ErrorType _error; -}; - - -} // namespace Ingen - -#endif // DISCONNECTIONEVENT_H diff --git a/src/engine/events/Get.cpp b/src/engine/events/Get.cpp new file mode 100644 index 00000000..a5193004 --- /dev/null +++ b/src/engine/events/Get.cpp @@ -0,0 +1,86 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "Get.hpp" +#include "interface/ClientInterface.hpp" +#include "Responder.hpp" +#include "Engine.hpp" +#include "EngineStore.hpp" +#include "ClientBroadcaster.hpp" +#include "PatchImpl.hpp" +#include "NodeImpl.hpp" +#include "PortImpl.hpp" +#include "ObjectSender.hpp" +#include "ProcessContext.hpp" + +using namespace Raul; + +namespace Ingen { + + +GetEvent::GetEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const URI& uri) + : QueuedEvent(engine, responder, timestamp) + , _uri(uri) + , _object(NULL) + , _plugin(NULL) +{ +} + + +void +GetEvent::pre_process() +{ + if (Path::is_valid(_uri.str())) + _object = _engine.engine_store()->find_object(Path(_uri.str())); + else + _plugin = _engine.node_factory()->plugin(_uri); + + QueuedEvent::pre_process(); +} + + +void +GetEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + assert(_time >= context.start() && _time <= context.end()); +} + + +void +GetEvent::post_process() +{ + if (!_object && !_plugin) { + _responder->respond_error("Unable to find object requested."); + } else if (_responder->client()) { + _responder->respond_ok(); + if (_object) + _responder->client()->put(_uri, _object->properties()); + else if (_plugin) + _responder->client()->put(_uri, _plugin->properties()); + } else { + _responder->respond_error("Unable to find client to send object."); + } +} + + +} // namespace Ingen + diff --git a/src/engine/events/Get.hpp b/src/engine/events/Get.hpp new file mode 100644 index 00000000..d2413043 --- /dev/null +++ b/src/engine/events/Get.hpp @@ -0,0 +1,56 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "QueuedEvent.hpp" +#include "types.hpp" + +namespace Ingen { + +class GraphObjectImpl; +class PluginImpl; + + +/** A request from a client to send an object. + * + * \ingroup engine + */ +class GetEvent : public QueuedEvent +{ +public: + GetEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::URI& uri); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + const Raul::URI _uri; + GraphObjectImpl* _object; + const PluginImpl* _plugin; +}; + + +} // namespace Ingen + +#endif // REQUESTOBJECTEVENT_H diff --git a/src/engine/events/GetEvent.cpp b/src/engine/events/GetEvent.cpp deleted file mode 100644 index 6479c94f..00000000 --- a/src/engine/events/GetEvent.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "GetEvent.hpp" -#include "interface/ClientInterface.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "ClientBroadcaster.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PortImpl.hpp" -#include "ObjectSender.hpp" -#include "ProcessContext.hpp" - -using namespace Raul; - -namespace Ingen { - - -GetEvent::GetEvent( - Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const URI& uri) - : QueuedEvent(engine, responder, timestamp) - , _uri(uri) - , _object(NULL) - , _plugin(NULL) -{ -} - - -void -GetEvent::pre_process() -{ - if (Path::is_valid(_uri.str())) - _object = _engine.engine_store()->find_object(Path(_uri.str())); - else - _plugin = _engine.node_factory()->plugin(_uri); - - QueuedEvent::pre_process(); -} - - -void -GetEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - assert(_time >= context.start() && _time <= context.end()); -} - - -void -GetEvent::post_process() -{ - if (!_object && !_plugin) { - _responder->respond_error("Unable to find object requested."); - } else if (_responder->client()) { - _responder->respond_ok(); - if (_object) - _responder->client()->put(_uri, _object->properties()); - else if (_plugin) - _responder->client()->put(_uri, _plugin->properties()); - } else { - _responder->respond_error("Unable to find client to send object."); - } -} - - -} // namespace Ingen - diff --git a/src/engine/events/GetEvent.hpp b/src/engine/events/GetEvent.hpp deleted file mode 100644 index d2413043..00000000 --- a/src/engine/events/GetEvent.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "QueuedEvent.hpp" -#include "types.hpp" - -namespace Ingen { - -class GraphObjectImpl; -class PluginImpl; - - -/** A request from a client to send an object. - * - * \ingroup engine - */ -class GetEvent : public QueuedEvent -{ -public: - GetEvent( - Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const Raul::URI& uri); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const Raul::URI _uri; - GraphObjectImpl* _object; - const PluginImpl* _plugin; -}; - - -} // namespace Ingen - -#endif // REQUESTOBJECTEVENT_H diff --git a/src/engine/events/LoadPlugins.cpp b/src/engine/events/LoadPlugins.cpp new file mode 100644 index 00000000..14c9c915 --- /dev/null +++ b/src/engine/events/LoadPlugins.cpp @@ -0,0 +1,53 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "LoadPlugins.hpp" +#include "Responder.hpp" +#include "Engine.hpp" +#include "NodeFactory.hpp" +#include "ClientBroadcaster.hpp" +#include "QueuedEventSource.hpp" + +namespace Ingen { + + +LoadPluginsEvent::LoadPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, QueuedEventSource* source) +: QueuedEvent(engine, responder, timestamp, true, source) +{ + /* FIXME: Not sure why this has to be blocking, but it fixes some nasty bugs.. */ +} + +void +LoadPluginsEvent::pre_process() +{ + _engine.node_factory()->load_plugins(); + + QueuedEvent::pre_process(); +} + +void +LoadPluginsEvent::post_process() +{ + if (_source) + _source->unblock(); + + _responder->respond_ok(); +} + + +} // namespace Ingen + diff --git a/src/engine/events/LoadPlugins.hpp b/src/engine/events/LoadPlugins.hpp new file mode 100644 index 00000000..cf134aea --- /dev/null +++ b/src/engine/events/LoadPlugins.hpp @@ -0,0 +1,45 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 LOADPLUGINSEVENT_H +#define LOADPLUGINSEVENT_H + +#include "QueuedEvent.hpp" + +namespace Ingen { + + +/** Loads all plugins into the internal plugin database (in NodeFactory). + * + * \ingroup engine + */ +class LoadPluginsEvent : public QueuedEvent +{ +public: + LoadPluginsEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + QueuedEventSource* source); + + void pre_process(); + void post_process(); +}; + + +} // namespace Ingen + +#endif // LOADPLUGINSEVENT_H diff --git a/src/engine/events/LoadPluginsEvent.cpp b/src/engine/events/LoadPluginsEvent.cpp deleted file mode 100644 index ab3823dd..00000000 --- a/src/engine/events/LoadPluginsEvent.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "LoadPluginsEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "NodeFactory.hpp" -#include "ClientBroadcaster.hpp" -#include "QueuedEventSource.hpp" - -namespace Ingen { - - -LoadPluginsEvent::LoadPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, QueuedEventSource* source) -: QueuedEvent(engine, responder, timestamp, true, source) -{ - /* FIXME: Not sure why this has to be blocking, but it fixes some nasty bugs.. */ -} - -void -LoadPluginsEvent::pre_process() -{ - _engine.node_factory()->load_plugins(); - - QueuedEvent::pre_process(); -} - -void -LoadPluginsEvent::post_process() -{ - if (_source) - _source->unblock(); - - _responder->respond_ok(); -} - - -} // namespace Ingen - diff --git a/src/engine/events/LoadPluginsEvent.hpp b/src/engine/events/LoadPluginsEvent.hpp deleted file mode 100644 index cf134aea..00000000 --- a/src/engine/events/LoadPluginsEvent.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 LOADPLUGINSEVENT_H -#define LOADPLUGINSEVENT_H - -#include "QueuedEvent.hpp" - -namespace Ingen { - - -/** Loads all plugins into the internal plugin database (in NodeFactory). - * - * \ingroup engine - */ -class LoadPluginsEvent : public QueuedEvent -{ -public: - LoadPluginsEvent(Engine& engine, - SharedPtr responder, - SampleCount timestamp, - QueuedEventSource* source); - - void pre_process(); - void post_process(); -}; - - -} // namespace Ingen - -#endif // LOADPLUGINSEVENT_H diff --git a/src/engine/events/MidiLearn.cpp b/src/engine/events/MidiLearn.cpp new file mode 100644 index 00000000..8a06508a --- /dev/null +++ b/src/engine/events/MidiLearn.cpp @@ -0,0 +1,83 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "events/MidiLearn.hpp" +#include "Responder.hpp" +#include "Engine.hpp" +#include "EngineStore.hpp" +#include "NodeImpl.hpp" +#include "InternalController.hpp" +#include "ClientBroadcaster.hpp" +#include "PluginImpl.hpp" + +using namespace std; + +namespace Ingen { + + +MidiLearnEvent::MidiLearnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& node_path) + : QueuedEvent(engine, responder, timestamp) + , _error(NO_ERROR) + , _node_path(node_path) + , _node(NULL) +{ +} + + +void +MidiLearnEvent::pre_process() +{ + _node = _engine.engine_store()->find_node(_node_path); + + QueuedEvent::pre_process(); +} + + +void +MidiLearnEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + + if (_node != NULL) { + if (_node->plugin_impl()->type() == Shared::Plugin::Internal) { + ((NodeBase*)_node)->learn(); + } else { + _error = INVALID_NODE_TYPE; + } + } +} + + +void +MidiLearnEvent::post_process() +{ + if (_error == NO_ERROR) { + _responder->respond_ok(); + } else if (_node == NULL) { + string msg = "Did not find node '"; + msg.append(_node_path.str()).append("' for MIDI learn."); + _responder->respond_error(msg); + } else { + const string msg = string("Node '") + _node_path.str() + "' is not capable of MIDI learn."; + _responder->respond_error(msg); + } +} + + +} // namespace Ingen + + diff --git a/src/engine/events/MidiLearn.hpp b/src/engine/events/MidiLearn.hpp new file mode 100644 index 00000000..e718cd00 --- /dev/null +++ b/src/engine/events/MidiLearn.hpp @@ -0,0 +1,58 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 MIDILEARNEVENT_H +#define MIDILEARNEVENT_H + +#include "QueuedEvent.hpp" +#include "InternalController.hpp" +#include "types.hpp" + +namespace Ingen { + +class NodeImpl; +class ControlChangeEvent; + + +/** A MIDI learn event (used by control node to learn controller number). + * + * \ingroup engine + */ +class MidiLearnEvent : public QueuedEvent +{ +public: + MidiLearnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& node_path); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + enum ErrorType { + NO_ERROR, + INVALID_NODE_TYPE + }; + + ErrorType _error; + const Raul::Path _node_path; + NodeImpl* _node; +}; + + +} // namespace Ingen + +#endif // MIDILEARNEVENT_H diff --git a/src/engine/events/MidiLearnEvent.cpp b/src/engine/events/MidiLearnEvent.cpp deleted file mode 100644 index 57d7efce..00000000 --- a/src/engine/events/MidiLearnEvent.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "MidiLearnEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "NodeImpl.hpp" -#include "InternalController.hpp" -#include "ClientBroadcaster.hpp" -#include "PluginImpl.hpp" - -using namespace std; - -namespace Ingen { - - -MidiLearnEvent::MidiLearnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& node_path) - : QueuedEvent(engine, responder, timestamp) - , _error(NO_ERROR) - , _node_path(node_path) - , _node(NULL) -{ -} - - -void -MidiLearnEvent::pre_process() -{ - _node = _engine.engine_store()->find_node(_node_path); - - QueuedEvent::pre_process(); -} - - -void -MidiLearnEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_node != NULL) { - if (_node->plugin_impl()->type() == Shared::Plugin::Internal) { - ((NodeBase*)_node)->learn(); - } else { - _error = INVALID_NODE_TYPE; - } - } -} - - -void -MidiLearnEvent::post_process() -{ - if (_error == NO_ERROR) { - _responder->respond_ok(); - } else if (_node == NULL) { - string msg = "Did not find node '"; - msg.append(_node_path.str()).append("' for MIDI learn."); - _responder->respond_error(msg); - } else { - const string msg = string("Node '") + _node_path.str() + "' is not capable of MIDI learn."; - _responder->respond_error(msg); - } -} - - -} // namespace Ingen - - diff --git a/src/engine/events/MidiLearnEvent.hpp b/src/engine/events/MidiLearnEvent.hpp deleted file mode 100644 index e718cd00..00000000 --- a/src/engine/events/MidiLearnEvent.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 MIDILEARNEVENT_H -#define MIDILEARNEVENT_H - -#include "QueuedEvent.hpp" -#include "InternalController.hpp" -#include "types.hpp" - -namespace Ingen { - -class NodeImpl; -class ControlChangeEvent; - - -/** A MIDI learn event (used by control node to learn controller number). - * - * \ingroup engine - */ -class MidiLearnEvent : public QueuedEvent -{ -public: - MidiLearnEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Raul::Path& node_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum ErrorType { - NO_ERROR, - INVALID_NODE_TYPE - }; - - ErrorType _error; - const Raul::Path _node_path; - NodeImpl* _node; -}; - - -} // namespace Ingen - -#endif // MIDILEARNEVENT_H diff --git a/src/engine/events/Move.cpp b/src/engine/events/Move.cpp new file mode 100644 index 00000000..cb439a3f --- /dev/null +++ b/src/engine/events/Move.cpp @@ -0,0 +1,142 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "raul/Path.hpp" +#include "events/Move.hpp" +#include "ClientBroadcaster.hpp" +#include "Engine.hpp" +#include "NodeImpl.hpp" +#include "EngineStore.hpp" +#include "PatchImpl.hpp" +#include "Responder.hpp" +#include "AudioDriver.hpp" +#include "MidiDriver.hpp" + +using namespace std; +using namespace Raul; + +namespace Ingen { + +using namespace Shared; + + +MoveEvent::MoveEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Path& path, const Path& new_path) + : QueuedEvent(engine, responder, timestamp) + , _old_path(path) + , _new_path(new_path) + , _parent_patch(NULL) + , _store_iterator(engine.engine_store()->end()) + , _error(NO_ERROR) +{ +} + + +MoveEvent::~MoveEvent() +{ +} + + +void +MoveEvent::pre_process() +{ + if (!_old_path.parent().is_parent_of(_new_path)) { + _error = PARENT_DIFFERS; + QueuedEvent::pre_process(); + return; + } + _store_iterator = _engine.engine_store()->find(_old_path); + if (_store_iterator == _engine.engine_store()->end()) { + _error = OBJECT_NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + if (_engine.engine_store()->find_object(_new_path)) { + _error = OBJECT_EXISTS; + QueuedEvent::pre_process(); + return; + } + + SharedPtr< Table > > removed + = _engine.engine_store()->remove(_store_iterator); + + assert(removed->size() > 0); + + for (Table >::iterator i = removed->begin(); i != removed->end(); ++i) { + const Path& child_old_path = i->first; + assert(Path::descendant_comparator(_old_path, child_old_path)); + + Path child_new_path; + if (child_old_path == _old_path) + child_new_path = _new_path; + else + child_new_path = Path(_new_path).base() + child_old_path.substr(_old_path.length()+1); + + PtrCast(i->second)->set_path(child_new_path); + i->first = child_new_path; + } + + _engine.engine_store()->add(*removed.get()); + + QueuedEvent::pre_process(); +} + + +void +MoveEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + + SharedPtr port = PtrCast(_store_iterator->second); + if (port && port->parent()->parent() == NULL) { + DriverPort* driver_port = NULL; + + if (port->type() == DataType::AUDIO) + driver_port = _engine.audio_driver()->driver_port(_new_path); + else if (port->type() == DataType::EVENT) + driver_port = _engine.midi_driver()->driver_port(_new_path); + + if (driver_port) + driver_port->set_name(_new_path.str()); + } +} + + +void +MoveEvent::post_process() +{ + string msg = "Unable to rename object - "; + + if (_error == NO_ERROR) { + _responder->respond_ok(); + _engine.broadcaster()->send_move(_old_path, _new_path); + } else { + if (_error == OBJECT_EXISTS) + msg.append("Object already exists at ").append(_new_path.str()); + else if (_error == OBJECT_NOT_FOUND) + msg.append("Could not find object ").append(_old_path.str()); + else if (_error == OBJECT_NOT_RENAMABLE) + msg.append(_old_path.str()).append(" is not renamable"); + else if (_error == PARENT_DIFFERS) + msg.append(_new_path.str()).append(" is a child of a different patch"); + + _responder->respond_error(msg); + } +} + + +} // namespace Ingen diff --git a/src/engine/events/Move.hpp b/src/engine/events/Move.hpp new file mode 100644 index 00000000..06b410fb --- /dev/null +++ b/src/engine/events/Move.hpp @@ -0,0 +1,76 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 RENAMEEVENT_H +#define RENAMEEVENT_H + +#include "raul/Path.hpp" +#include "QueuedEvent.hpp" +#include "EngineStore.hpp" + +namespace Ingen { + +class PatchImpl; + +/** \page methods + *

MOVE

+ * As per WebDAV (RFC4918 S9.9). + * + * Move an object from its current location and insert it at a new location + * in a single operation. + * + * MOVE to a path with a different parent is currently not supported. + */ + +/** MOVE a graph object to a new path (see \ref methods). + * \ingroup engine + */ +class MoveEvent : public QueuedEvent +{ +public: + MoveEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::Path& old_path, + const Raul::Path& new_path); + ~MoveEvent(); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + enum ErrorType { + NO_ERROR, + OBJECT_NOT_FOUND, + OBJECT_EXISTS, + OBJECT_NOT_RENAMABLE, + PARENT_DIFFERS + }; + + Raul::Path _old_path; + Raul::Path _new_path; + PatchImpl* _parent_patch; + EngineStore::iterator _store_iterator; + ErrorType _error; +}; + + +} // namespace Ingen + +#endif // RENAMEEVENT_H diff --git a/src/engine/events/MoveEvent.cpp b/src/engine/events/MoveEvent.cpp deleted file mode 100644 index 661bc4c1..00000000 --- a/src/engine/events/MoveEvent.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "raul/Path.hpp" -#include "ClientBroadcaster.hpp" -#include "Engine.hpp" -#include "NodeImpl.hpp" -#include "EngineStore.hpp" -#include "PatchImpl.hpp" -#include "MoveEvent.hpp" -#include "Responder.hpp" -#include "AudioDriver.hpp" -#include "MidiDriver.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { - -using namespace Shared; - - -MoveEvent::MoveEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Path& path, const Path& new_path) - : QueuedEvent(engine, responder, timestamp) - , _old_path(path) - , _new_path(new_path) - , _parent_patch(NULL) - , _store_iterator(engine.engine_store()->end()) - , _error(NO_ERROR) -{ -} - - -MoveEvent::~MoveEvent() -{ -} - - -void -MoveEvent::pre_process() -{ - if (!_old_path.parent().is_parent_of(_new_path)) { - _error = PARENT_DIFFERS; - QueuedEvent::pre_process(); - return; - } - _store_iterator = _engine.engine_store()->find(_old_path); - if (_store_iterator == _engine.engine_store()->end()) { - _error = OBJECT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if (_engine.engine_store()->find_object(_new_path)) { - _error = OBJECT_EXISTS; - QueuedEvent::pre_process(); - return; - } - - SharedPtr< Table > > removed - = _engine.engine_store()->remove(_store_iterator); - - assert(removed->size() > 0); - - for (Table >::iterator i = removed->begin(); i != removed->end(); ++i) { - const Path& child_old_path = i->first; - assert(Path::descendant_comparator(_old_path, child_old_path)); - - Path child_new_path; - if (child_old_path == _old_path) - child_new_path = _new_path; - else - child_new_path = Path(_new_path).base() + child_old_path.substr(_old_path.length()+1); - - PtrCast(i->second)->set_path(child_new_path); - i->first = child_new_path; - } - - _engine.engine_store()->add(*removed.get()); - - QueuedEvent::pre_process(); -} - - -void -MoveEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - SharedPtr port = PtrCast(_store_iterator->second); - if (port && port->parent()->parent() == NULL) { - DriverPort* driver_port = NULL; - - if (port->type() == DataType::AUDIO) - driver_port = _engine.audio_driver()->driver_port(_new_path); - else if (port->type() == DataType::EVENT) - driver_port = _engine.midi_driver()->driver_port(_new_path); - - if (driver_port) - driver_port->set_name(_new_path.str()); - } -} - - -void -MoveEvent::post_process() -{ - string msg = "Unable to rename object - "; - - if (_error == NO_ERROR) { - _responder->respond_ok(); - _engine.broadcaster()->send_move(_old_path, _new_path); - } else { - if (_error == OBJECT_EXISTS) - msg.append("Object already exists at ").append(_new_path.str()); - else if (_error == OBJECT_NOT_FOUND) - msg.append("Could not find object ").append(_old_path.str()); - else if (_error == OBJECT_NOT_RENAMABLE) - msg.append(_old_path.str()).append(" is not renamable"); - else if (_error == PARENT_DIFFERS) - msg.append(_new_path.str()).append(" is a child of a different patch"); - - _responder->respond_error(msg); - } -} - - -} // namespace Ingen diff --git a/src/engine/events/MoveEvent.hpp b/src/engine/events/MoveEvent.hpp deleted file mode 100644 index 06b410fb..00000000 --- a/src/engine/events/MoveEvent.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 RENAMEEVENT_H -#define RENAMEEVENT_H - -#include "raul/Path.hpp" -#include "QueuedEvent.hpp" -#include "EngineStore.hpp" - -namespace Ingen { - -class PatchImpl; - -/** \page methods - *

MOVE

- * As per WebDAV (RFC4918 S9.9). - * - * Move an object from its current location and insert it at a new location - * in a single operation. - * - * MOVE to a path with a different parent is currently not supported. - */ - -/** MOVE a graph object to a new path (see \ref methods). - * \ingroup engine - */ -class MoveEvent : public QueuedEvent -{ -public: - MoveEvent( - Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const Raul::Path& old_path, - const Raul::Path& new_path); - ~MoveEvent(); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum ErrorType { - NO_ERROR, - OBJECT_NOT_FOUND, - OBJECT_EXISTS, - OBJECT_NOT_RENAMABLE, - PARENT_DIFFERS - }; - - Raul::Path _old_path; - Raul::Path _new_path; - PatchImpl* _parent_patch; - EngineStore::iterator _store_iterator; - ErrorType _error; -}; - - -} // namespace Ingen - -#endif // RENAMEEVENT_H diff --git a/src/engine/events/Note.cpp b/src/engine/events/Note.cpp new file mode 100644 index 00000000..79ebcb10 --- /dev/null +++ b/src/engine/events/Note.cpp @@ -0,0 +1,104 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "Note.hpp" +#include "Responder.hpp" +#include "Engine.hpp" +#include "EngineStore.hpp" +#include "NodeImpl.hpp" +#include "InternalNote.hpp" +#include "InternalTrigger.hpp" +#include "PluginImpl.hpp" +#include "InternalPlugin.hpp" +#include "ProcessContext.hpp" + +using namespace Raul; + +namespace Ingen { + + +/** Note on with Patch explicitly passed. + * + * Used to be triggered by MIDI. Not used anymore. + */ +NoteEvent::NoteEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, NodeImpl* node, bool on, uint8_t note_num, uint8_t velocity) +: Event(engine, responder, timestamp), + _node(node), + _on(on), + _note_num(note_num), + _velocity(velocity) +{ +} + + +/** Note on with Node lookup. + * + * Triggered by OSC. + */ +NoteEvent::NoteEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Path& node_path, bool on, uint8_t note_num, uint8_t velocity) +: Event(engine, responder, timestamp), + _node(NULL), + _node_path(node_path), + _on(on), + _note_num(note_num), + _velocity(velocity) +{ +} + + +void +NoteEvent::execute(ProcessContext& context) +{ + Event::execute(context); + assert(_time >= context.start() && _time <= context.end()); + + // Lookup if neccessary + if (!_node) + _node = _engine.engine_store()->find_node(_node_path); + + // FIXME: barf + + if (_node != NULL && _node->plugin()->type() == Shared::Plugin::Internal) { + if (_on) { + if (_node->plugin_impl()->uri().str() == NS_INTERNALS "Note") + ((NoteNode*)_node)->note_on(context, _note_num, _velocity, _time); + else if (_node->plugin_impl()->uri().str() == NS_INTERNALS "Trigger") + ((TriggerNode*)_node)->note_on(context, _note_num, _velocity, _time); + } else { + if (_node->plugin_impl()->uri().str() == NS_INTERNALS "Note") + ((NoteNode*)_node)->note_off(context, _note_num, _time); + else if (_node->plugin_impl()->uri().str() == NS_INTERNALS "Trigger") + ((TriggerNode*)_node)->note_off(context, _note_num, _time); + } + } +} + + +void +NoteEvent::post_process() +{ + if (_responder) { + if (_node) + _responder->respond_ok(); + else + _responder->respond_error("Did not find node for note on event"); + } +} + + +} // namespace Ingen + diff --git a/src/engine/events/Note.hpp b/src/engine/events/Note.hpp new file mode 100644 index 00000000..eba0ff6b --- /dev/null +++ b/src/engine/events/Note.hpp @@ -0,0 +1,66 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 NOTEEVENT_H +#define NOTEEVENT_H + +#include "Event.hpp" +#include "types.hpp" + +namespace Ingen { + +class NodeImpl; + + +/** A note on event. + * + * \ingroup engine + */ +class NoteEvent : public Event +{ +public: + NoteEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + NodeImpl* node, + bool on, + uint8_t note_num, + uint8_t velocity); + + NoteEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::Path& node_path, + bool on, + uint8_t note_num, + uint8_t velocity); + + void execute(ProcessContext& context); + void post_process(); + +private: + NodeImpl* _node; + const Raul::Path _node_path; + bool _on; + uint8_t _note_num; + uint8_t _velocity; +}; + + +} // namespace Ingen + +#endif // NOTEEVENT_H diff --git a/src/engine/events/NoteEvent.cpp b/src/engine/events/NoteEvent.cpp deleted file mode 100644 index bdb5e92d..00000000 --- a/src/engine/events/NoteEvent.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "NoteEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "NodeImpl.hpp" -#include "InternalNote.hpp" -#include "InternalTrigger.hpp" -#include "PluginImpl.hpp" -#include "InternalPlugin.hpp" -#include "ProcessContext.hpp" - -using namespace Raul; - -namespace Ingen { - - -/** Note on with Patch explicitly passed. - * - * Used to be triggered by MIDI. Not used anymore. - */ -NoteEvent::NoteEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, NodeImpl* node, bool on, uint8_t note_num, uint8_t velocity) -: Event(engine, responder, timestamp), - _node(node), - _on(on), - _note_num(note_num), - _velocity(velocity) -{ -} - - -/** Note on with Node lookup. - * - * Triggered by OSC. - */ -NoteEvent::NoteEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const Path& node_path, bool on, uint8_t note_num, uint8_t velocity) -: Event(engine, responder, timestamp), - _node(NULL), - _node_path(node_path), - _on(on), - _note_num(note_num), - _velocity(velocity) -{ -} - - -void -NoteEvent::execute(ProcessContext& context) -{ - Event::execute(context); - assert(_time >= context.start() && _time <= context.end()); - - // Lookup if neccessary - if (!_node) - _node = _engine.engine_store()->find_node(_node_path); - - // FIXME: barf - - if (_node != NULL && _node->plugin()->type() == Shared::Plugin::Internal) { - if (_on) { - if (_node->plugin_impl()->uri().str() == NS_INTERNALS "Note") - ((NoteNode*)_node)->note_on(context, _note_num, _velocity, _time); - else if (_node->plugin_impl()->uri().str() == NS_INTERNALS "Trigger") - ((TriggerNode*)_node)->note_on(context, _note_num, _velocity, _time); - } else { - if (_node->plugin_impl()->uri().str() == NS_INTERNALS "Note") - ((NoteNode*)_node)->note_off(context, _note_num, _time); - else if (_node->plugin_impl()->uri().str() == NS_INTERNALS "Trigger") - ((TriggerNode*)_node)->note_off(context, _note_num, _time); - } - } -} - - -void -NoteEvent::post_process() -{ - if (_responder) { - if (_node) - _responder->respond_ok(); - else - _responder->respond_error("Did not find node for note on event"); - } -} - - -} // namespace Ingen - diff --git a/src/engine/events/NoteEvent.hpp b/src/engine/events/NoteEvent.hpp deleted file mode 100644 index eba0ff6b..00000000 --- a/src/engine/events/NoteEvent.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 NOTEEVENT_H -#define NOTEEVENT_H - -#include "Event.hpp" -#include "types.hpp" - -namespace Ingen { - -class NodeImpl; - - -/** A note on event. - * - * \ingroup engine - */ -class NoteEvent : public Event -{ -public: - NoteEvent(Engine& engine, - SharedPtr responder, - SampleCount timestamp, - NodeImpl* node, - bool on, - uint8_t note_num, - uint8_t velocity); - - NoteEvent(Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const Raul::Path& node_path, - bool on, - uint8_t note_num, - uint8_t velocity); - - void execute(ProcessContext& context); - void post_process(); - -private: - NodeImpl* _node; - const Raul::Path _node_path; - bool _on; - uint8_t _note_num; - uint8_t _velocity; -}; - - -} // namespace Ingen - -#endif // NOTEEVENT_H diff --git a/src/engine/events/PingQueued.hpp b/src/engine/events/PingQueued.hpp new file mode 100644 index 00000000..108948a0 --- /dev/null +++ b/src/engine/events/PingQueued.hpp @@ -0,0 +1,48 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 PINGQUEUEDEVENT_H +#define PINGQUEUEDEVENT_H + +#include "QueuedEvent.hpp" +#include "types.hpp" +#include "Responder.hpp" + +namespace Ingen { + +class PortImpl; + + +/** A ping that travels through the pre-processed event queue before responding + * (useful for the order guarantee). + * + * \ingroup engine + */ +class PingQueuedEvent : public QueuedEvent +{ +public: + PingQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) + : QueuedEvent(engine, responder, timestamp) + {} + + void post_process() { _responder->respond_ok(); } +}; + + +} // namespace Ingen + +#endif // PINGQUEUEDEVENT_H diff --git a/src/engine/events/PingQueuedEvent.hpp b/src/engine/events/PingQueuedEvent.hpp deleted file mode 100644 index 108948a0..00000000 --- a/src/engine/events/PingQueuedEvent.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 PINGQUEUEDEVENT_H -#define PINGQUEUEDEVENT_H - -#include "QueuedEvent.hpp" -#include "types.hpp" -#include "Responder.hpp" - -namespace Ingen { - -class PortImpl; - - -/** A ping that travels through the pre-processed event queue before responding - * (useful for the order guarantee). - * - * \ingroup engine - */ -class PingQueuedEvent : public QueuedEvent -{ -public: - PingQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) - : QueuedEvent(engine, responder, timestamp) - {} - - void post_process() { _responder->respond_ok(); } -}; - - -} // namespace Ingen - -#endif // PINGQUEUEDEVENT_H diff --git a/src/engine/events/RegisterClient.cpp b/src/engine/events/RegisterClient.cpp new file mode 100644 index 00000000..dab1c739 --- /dev/null +++ b/src/engine/events/RegisterClient.cpp @@ -0,0 +1,57 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "Responder.hpp" +#include "events/RegisterClient.hpp" +#include "Engine.hpp" +#include "ClientBroadcaster.hpp" + +using namespace Raul; + +namespace Ingen { + + +RegisterClientEvent::RegisterClientEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const URI& uri, + Shared::ClientInterface* client) + : QueuedEvent(engine, responder, timestamp) + , _uri(uri) + , _client(client) +{ +} + + +void +RegisterClientEvent::pre_process() +{ + _engine.broadcaster()->register_client(_uri, _client); + + QueuedEvent::pre_process(); +} + + +void +RegisterClientEvent::post_process() +{ + _responder->respond_ok(); +} + + +} // namespace Ingen + diff --git a/src/engine/events/RegisterClient.hpp b/src/engine/events/RegisterClient.hpp new file mode 100644 index 00000000..6016d949 --- /dev/null +++ b/src/engine/events/RegisterClient.hpp @@ -0,0 +1,52 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 REGISTERCLIENTEVENT_H +#define REGISTERCLIENTEVENT_H + +#include "raul/URI.hpp" +#include "interface/ClientInterface.hpp" +#include "QueuedEvent.hpp" + +namespace Ingen { + + +/** Registers a new client with the OSC system, so it can receive updates. + * + * \ingroup engine + */ +class RegisterClientEvent : public QueuedEvent +{ +public: + RegisterClientEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::URI& uri, + Shared::ClientInterface* client); + + void pre_process(); + void post_process(); + +private: + Raul::URI _uri; + Shared::ClientInterface* _client; +}; + + +} // namespace Ingen + +#endif // REGISTERCLIENTEVENT_H diff --git a/src/engine/events/RegisterClientEvent.cpp b/src/engine/events/RegisterClientEvent.cpp deleted file mode 100644 index 67d5654d..00000000 --- a/src/engine/events/RegisterClientEvent.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "Responder.hpp" -#include "RegisterClientEvent.hpp" -#include "Engine.hpp" -#include "ClientBroadcaster.hpp" - -using namespace Raul; - -namespace Ingen { - - -RegisterClientEvent::RegisterClientEvent(Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const URI& uri, - Shared::ClientInterface* client) - : QueuedEvent(engine, responder, timestamp) - , _uri(uri) - , _client(client) -{ -} - - -void -RegisterClientEvent::pre_process() -{ - _engine.broadcaster()->register_client(_uri, _client); - - QueuedEvent::pre_process(); -} - - -void -RegisterClientEvent::post_process() -{ - _responder->respond_ok(); -} - - -} // namespace Ingen - diff --git a/src/engine/events/RegisterClientEvent.hpp b/src/engine/events/RegisterClientEvent.hpp deleted file mode 100644 index 6016d949..00000000 --- a/src/engine/events/RegisterClientEvent.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 REGISTERCLIENTEVENT_H -#define REGISTERCLIENTEVENT_H - -#include "raul/URI.hpp" -#include "interface/ClientInterface.hpp" -#include "QueuedEvent.hpp" - -namespace Ingen { - - -/** Registers a new client with the OSC system, so it can receive updates. - * - * \ingroup engine - */ -class RegisterClientEvent : public QueuedEvent -{ -public: - RegisterClientEvent(Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const Raul::URI& uri, - Shared::ClientInterface* client); - - void pre_process(); - void post_process(); - -private: - Raul::URI _uri; - Shared::ClientInterface* _client; -}; - - -} // namespace Ingen - -#endif // REGISTERCLIENTEVENT_H diff --git a/src/engine/events/RequestAllObjects.cpp b/src/engine/events/RequestAllObjects.cpp new file mode 100644 index 00000000..986cbb0c --- /dev/null +++ b/src/engine/events/RequestAllObjects.cpp @@ -0,0 +1,60 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "events/RequestAllObjects.hpp" +#include "Responder.hpp" +#include "Engine.hpp" +#include "ObjectSender.hpp" +#include "ClientBroadcaster.hpp" +#include "EngineStore.hpp" +#include "PatchImpl.hpp" + +namespace Ingen { + + +RequestAllObjectsEvent::RequestAllObjectsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) +: QueuedEvent(engine, responder, timestamp) +{ +} + + +void +RequestAllObjectsEvent::pre_process() +{ + QueuedEvent::pre_process(); +} + + +void +RequestAllObjectsEvent::post_process() +{ + if (_responder->client()) { + _responder->respond_ok(); + + // Everything is a child of the root patch, so this sends it all + PatchImpl* root = _engine.engine_store()->find_patch("/"); + if (root && _responder->client()) + ObjectSender::send_object(_responder->client(), root, true); + + } else { + _responder->respond_error("Unable to find client to send all objects"); + } +} + + +} // namespace Ingen + diff --git a/src/engine/events/RequestAllObjects.hpp b/src/engine/events/RequestAllObjects.hpp new file mode 100644 index 00000000..c473512c --- /dev/null +++ b/src/engine/events/RequestAllObjects.hpp @@ -0,0 +1,42 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 REQUESTALLOBJECTSEVENT_H +#define REQUESTALLOBJECTSEVENT_H + +#include "QueuedEvent.hpp" + +namespace Ingen { + + +/** A request from a client to send notification of all objects (ie refresh). + * + * \ingroup engine + */ +class RequestAllObjectsEvent : public QueuedEvent +{ +public: + RequestAllObjectsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp); + + void pre_process(); + void post_process(); +}; + + +} // namespace Ingen + +#endif // REQUESTALLOBJECTSEVENT_H diff --git a/src/engine/events/RequestAllObjectsEvent.cpp b/src/engine/events/RequestAllObjectsEvent.cpp deleted file mode 100644 index cae8e180..00000000 --- a/src/engine/events/RequestAllObjectsEvent.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "RequestAllObjectsEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "ObjectSender.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" -#include "PatchImpl.hpp" - -namespace Ingen { - - -RequestAllObjectsEvent::RequestAllObjectsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) -: QueuedEvent(engine, responder, timestamp) -{ -} - - -void -RequestAllObjectsEvent::pre_process() -{ - QueuedEvent::pre_process(); -} - - -void -RequestAllObjectsEvent::post_process() -{ - if (_responder->client()) { - _responder->respond_ok(); - - // Everything is a child of the root patch, so this sends it all - PatchImpl* root = _engine.engine_store()->find_patch("/"); - if (root && _responder->client()) - ObjectSender::send_object(_responder->client(), root, true); - - } else { - _responder->respond_error("Unable to find client to send all objects"); - } -} - - -} // namespace Ingen - diff --git a/src/engine/events/RequestAllObjectsEvent.hpp b/src/engine/events/RequestAllObjectsEvent.hpp deleted file mode 100644 index c473512c..00000000 --- a/src/engine/events/RequestAllObjectsEvent.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 REQUESTALLOBJECTSEVENT_H -#define REQUESTALLOBJECTSEVENT_H - -#include "QueuedEvent.hpp" - -namespace Ingen { - - -/** A request from a client to send notification of all objects (ie refresh). - * - * \ingroup engine - */ -class RequestAllObjectsEvent : public QueuedEvent -{ -public: - RequestAllObjectsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp); - - void pre_process(); - void post_process(); -}; - - -} // namespace Ingen - -#endif // REQUESTALLOBJECTSEVENT_H diff --git a/src/engine/events/RequestMetadata.cpp b/src/engine/events/RequestMetadata.cpp new file mode 100644 index 00000000..26400fef --- /dev/null +++ b/src/engine/events/RequestMetadata.cpp @@ -0,0 +1,128 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "interface/ClientInterface.hpp" +#include "events/RequestMetadata.hpp" +#include "Responder.hpp" +#include "Engine.hpp" +#include "GraphObjectImpl.hpp" +#include "EngineStore.hpp" +#include "ClientBroadcaster.hpp" +#include "PortImpl.hpp" +#include "PluginImpl.hpp" +#include "AudioBuffer.hpp" + +using namespace std; +using namespace Raul; + +namespace Ingen { + +using namespace Shared; + + +RequestMetadataEvent::RequestMetadataEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + bool is_meta, + const URI& subject, + const URI& key) + : QueuedEvent(engine, responder, timestamp) + , _error(NO_ERROR) + , _special_type(NONE) + , _uri(subject) + , _key(key) + , _resource(0) + , _is_meta(is_meta) +{ +} + + +void +RequestMetadataEvent::pre_process() +{ + const bool is_object = (_uri.scheme() == Path::scheme && Path::is_valid(_uri.str())); + if (_responder->client()) { + if (is_object) + _resource = _engine.engine_store()->find_object(Path(_uri.str())); + else + _resource = _engine.node_factory()->plugin(_uri); + + if (!_resource) { + QueuedEvent::pre_process(); + return; + } + } + + GraphObjectImpl* obj = dynamic_cast(_resource); + if (obj) { + if (_key.str() == "ingen:value") + _special_type = PORT_VALUE; + else if (_is_meta) + _value = obj->meta().get_property(_key); + else + _value = obj->get_property(_key); + } else { + _value = _resource->get_property(_key); + } + + QueuedEvent::pre_process(); +} + + +void +RequestMetadataEvent::execute(ProcessContext& context) +{ + QueuedEvent::execute(context); + if (_special_type == PORT_VALUE) { + PortImpl* port = dynamic_cast(_resource); + if (port) { + if (port->type() == DataType::CONTROL || port->type() == DataType::AUDIO) + _value = ((AudioBuffer*)port->buffer(0))->value_at(0); // TODO: offset + } else { + _resource = 0; + } + } +} + + +void +RequestMetadataEvent::post_process() +{ + if (_responder->client()) { + if (_special_type == PORT_VALUE) { + if (_resource) { + _responder->respond_ok(); + _responder->client()->set_port_value(_uri.str(), _value); + } else { + const string msg = "Get value for non-port " + _uri.str(); + _responder->respond_error(msg); + } + } else if (!_resource) { + const string msg = "Unable to find subject " + _uri.str(); + _responder->respond_error(msg); + } else { + _responder->respond_ok(); + _responder->client()->set_property(_uri, _key, _value); + } + } else { + _responder->respond_error("Unknown client"); + } +} + + +} // namespace Ingen + diff --git a/src/engine/events/RequestMetadata.hpp b/src/engine/events/RequestMetadata.hpp new file mode 100644 index 00000000..ead39a50 --- /dev/null +++ b/src/engine/events/RequestMetadata.hpp @@ -0,0 +1,73 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 REQUESTMETADATAEVENT_H +#define REQUESTMETADATAEVENT_H + +#include "QueuedEvent.hpp" +#include "raul/Atom.hpp" +#include "raul/URI.hpp" + +namespace Ingen { + +namespace Shared { class ResourceImpl; } + +class GraphObjectImpl; + +/** \page methods + *

GET

+ * As per HTTP (RFC2616 S9.3). + * + * Get the description of a graph object. + */ + +/** GET an object (see \ref methods). + * + * \ingroup engine + */ +class RequestMetadataEvent : public QueuedEvent +{ +public: + RequestMetadataEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + bool meta, + const Raul::URI& subject, + const Raul::URI& key); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + enum { NO_ERROR, NOT_FOUND } _error; + enum { + NONE, + PORT_VALUE + } _special_type; + + Raul::URI _uri; + Raul::URI _key; + Raul::Atom _value; + Shared::ResourceImpl* _resource; + bool _is_meta; +}; + + +} // namespace Ingen + +#endif // REQUESTMETADATAEVENT_H diff --git a/src/engine/events/RequestMetadataEvent.cpp b/src/engine/events/RequestMetadataEvent.cpp deleted file mode 100644 index 5d0b15bc..00000000 --- a/src/engine/events/RequestMetadataEvent.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "interface/ClientInterface.hpp" -#include "RequestMetadataEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "GraphObjectImpl.hpp" -#include "EngineStore.hpp" -#include "ClientBroadcaster.hpp" -#include "PortImpl.hpp" -#include "PluginImpl.hpp" -#include "AudioBuffer.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { - -using namespace Shared; - - -RequestMetadataEvent::RequestMetadataEvent(Engine& engine, - SharedPtr responder, - SampleCount timestamp, - bool is_meta, - const URI& subject, - const URI& key) - : QueuedEvent(engine, responder, timestamp) - , _error(NO_ERROR) - , _special_type(NONE) - , _uri(subject) - , _key(key) - , _resource(0) - , _is_meta(is_meta) -{ -} - - -void -RequestMetadataEvent::pre_process() -{ - const bool is_object = (_uri.scheme() == Path::scheme && Path::is_valid(_uri.str())); - if (_responder->client()) { - if (is_object) - _resource = _engine.engine_store()->find_object(Path(_uri.str())); - else - _resource = _engine.node_factory()->plugin(_uri); - - if (!_resource) { - QueuedEvent::pre_process(); - return; - } - } - - GraphObjectImpl* obj = dynamic_cast(_resource); - if (obj) { - if (_key.str() == "ingen:value") - _special_type = PORT_VALUE; - else if (_is_meta) - _value = obj->meta().get_property(_key); - else - _value = obj->get_property(_key); - } else { - _value = _resource->get_property(_key); - } - - QueuedEvent::pre_process(); -} - - -void -RequestMetadataEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - if (_special_type == PORT_VALUE) { - PortImpl* port = dynamic_cast(_resource); - if (port) { - if (port->type() == DataType::CONTROL || port->type() == DataType::AUDIO) - _value = ((AudioBuffer*)port->buffer(0))->value_at(0); // TODO: offset - } else { - _resource = 0; - } - } -} - - -void -RequestMetadataEvent::post_process() -{ - if (_responder->client()) { - if (_special_type == PORT_VALUE) { - if (_resource) { - _responder->respond_ok(); - _responder->client()->set_port_value(_uri.str(), _value); - } else { - const string msg = "Get value for non-port " + _uri.str(); - _responder->respond_error(msg); - } - } else if (!_resource) { - const string msg = "Unable to find subject " + _uri.str(); - _responder->respond_error(msg); - } else { - _responder->respond_ok(); - _responder->client()->set_property(_uri, _key, _value); - } - } else { - _responder->respond_error("Unknown client"); - } -} - - -} // namespace Ingen - diff --git a/src/engine/events/RequestMetadataEvent.hpp b/src/engine/events/RequestMetadataEvent.hpp deleted file mode 100644 index ead39a50..00000000 --- a/src/engine/events/RequestMetadataEvent.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 REQUESTMETADATAEVENT_H -#define REQUESTMETADATAEVENT_H - -#include "QueuedEvent.hpp" -#include "raul/Atom.hpp" -#include "raul/URI.hpp" - -namespace Ingen { - -namespace Shared { class ResourceImpl; } - -class GraphObjectImpl; - -/** \page methods - *

GET

- * As per HTTP (RFC2616 S9.3). - * - * Get the description of a graph object. - */ - -/** GET an object (see \ref methods). - * - * \ingroup engine - */ -class RequestMetadataEvent : public QueuedEvent -{ -public: - RequestMetadataEvent(Engine& engine, - SharedPtr responder, - SampleCount timestamp, - bool meta, - const Raul::URI& subject, - const Raul::URI& key); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum { NO_ERROR, NOT_FOUND } _error; - enum { - NONE, - PORT_VALUE - } _special_type; - - Raul::URI _uri; - Raul::URI _key; - Raul::Atom _value; - Shared::ResourceImpl* _resource; - bool _is_meta; -}; - - -} // namespace Ingen - -#endif // REQUESTMETADATAEVENT_H diff --git a/src/engine/events/RequestPlugins.cpp b/src/engine/events/RequestPlugins.cpp new file mode 100644 index 00000000..9daa24d1 --- /dev/null +++ b/src/engine/events/RequestPlugins.cpp @@ -0,0 +1,57 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "RequestPlugins.hpp" +#include "Responder.hpp" +#include "Engine.hpp" +#include "ClientBroadcaster.hpp" +#include "NodeFactory.hpp" + +namespace Ingen { + + +RequestPluginsEvent::RequestPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) +: QueuedEvent(engine, responder, timestamp) +{ +} + + +void +RequestPluginsEvent::pre_process() +{ + // Take a copy to send in the post processing thread (to avoid problems + // because std::map isn't thread safe) + _plugins = _engine.node_factory()->plugins(); + + QueuedEvent::pre_process(); +} + + +void +RequestPluginsEvent::post_process() +{ + if (_responder->client()) { + _engine.broadcaster()->send_plugins_to(_responder->client(), _plugins); + _responder->respond_ok(); + } else { + _responder->respond_error("Unable to find client to send plugins"); + } +} + + +} // namespace Ingen + diff --git a/src/engine/events/RequestPlugins.hpp b/src/engine/events/RequestPlugins.hpp new file mode 100644 index 00000000..d4f2d05a --- /dev/null +++ b/src/engine/events/RequestPlugins.hpp @@ -0,0 +1,47 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 REQUESTPLUGINSEVENT_H +#define REQUESTPLUGINSEVENT_H + +#include "QueuedEvent.hpp" +#include "NodeFactory.hpp" + +namespace Ingen { + +class Responder; + +/** A request from a client to send notification of all objects (ie refresh). + * + * \ingroup engine + */ +class RequestPluginsEvent : public QueuedEvent +{ +public: + RequestPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp); + + void pre_process(); + void post_process(); + +private: + NodeFactory::Plugins _plugins; +}; + + +} // namespace Ingen + +#endif // REQUESTPLUGINSEVENT_H diff --git a/src/engine/events/RequestPluginsEvent.cpp b/src/engine/events/RequestPluginsEvent.cpp deleted file mode 100644 index 3f6f60e0..00000000 --- a/src/engine/events/RequestPluginsEvent.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "RequestPluginsEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "ClientBroadcaster.hpp" -#include "NodeFactory.hpp" - -namespace Ingen { - - -RequestPluginsEvent::RequestPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp) -: QueuedEvent(engine, responder, timestamp) -{ -} - - -void -RequestPluginsEvent::pre_process() -{ - // Take a copy to send in the post processing thread (to avoid problems - // because std::map isn't thread safe) - _plugins = _engine.node_factory()->plugins(); - - QueuedEvent::pre_process(); -} - - -void -RequestPluginsEvent::post_process() -{ - if (_responder->client()) { - _engine.broadcaster()->send_plugins_to(_responder->client(), _plugins); - _responder->respond_ok(); - } else { - _responder->respond_error("Unable to find client to send plugins"); - } -} - - -} // namespace Ingen - diff --git a/src/engine/events/RequestPluginsEvent.hpp b/src/engine/events/RequestPluginsEvent.hpp deleted file mode 100644 index d4f2d05a..00000000 --- a/src/engine/events/RequestPluginsEvent.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 REQUESTPLUGINSEVENT_H -#define REQUESTPLUGINSEVENT_H - -#include "QueuedEvent.hpp" -#include "NodeFactory.hpp" - -namespace Ingen { - -class Responder; - -/** A request from a client to send notification of all objects (ie refresh). - * - * \ingroup engine - */ -class RequestPluginsEvent : public QueuedEvent -{ -public: - RequestPluginsEvent(Engine& engine, SharedPtr responder, SampleCount timestamp); - - void pre_process(); - void post_process(); - -private: - NodeFactory::Plugins _plugins; -}; - - -} // namespace Ingen - -#endif // REQUESTPLUGINSEVENT_H diff --git a/src/engine/events/SendPortActivity.cpp b/src/engine/events/SendPortActivity.cpp new file mode 100644 index 00000000..9dc26365 --- /dev/null +++ b/src/engine/events/SendPortActivity.cpp @@ -0,0 +1,34 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "events/SendPortActivity.hpp" +#include "Engine.hpp" +#include "PortImpl.hpp" +#include "ClientBroadcaster.hpp" + +namespace Ingen { + + +void +SendPortActivityEvent::post_process() +{ + _engine.broadcaster()->send_activity(_port->path()); +} + + +} // namespace Ingen + diff --git a/src/engine/events/SendPortActivity.hpp b/src/engine/events/SendPortActivity.hpp new file mode 100644 index 00000000..45a4cd36 --- /dev/null +++ b/src/engine/events/SendPortActivity.hpp @@ -0,0 +1,65 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 SENDPORTACTIVITYEVENT_H +#define SENDPORTACTIVITYEVENT_H + +#include "Event.hpp" +#include "types.hpp" + +namespace Ingen { + +class PortImpl; + + +/** A special event used internally to send port activity notification (e.g. + * MIDI event activity) from the audio thread. + * + * This is created in the audio thread (directly in a ringbuffer, not new'd) + * for processing in the post processing thread (unlike normal events which + * are created in the pre-processor thread then run through the audio + * thread). This event's job is done entirely in post_process. + * + * This only really makes sense for message ports. + * + * \ingroup engine + */ +class SendPortActivityEvent : public Event +{ +public: + inline SendPortActivityEvent(Engine& engine, + SampleCount timestamp, + PortImpl* port) + : Event(engine, SharedPtr(), timestamp) + , _port(port) + { + } + + inline void operator=(const SendPortActivityEvent& ev) { + _port = ev._port; + } + + void post_process(); + +private: + PortImpl* _port; +}; + + +} // namespace Ingen + +#endif // SENDPORTACTIVITYEVENT_H diff --git a/src/engine/events/SendPortActivityEvent.cpp b/src/engine/events/SendPortActivityEvent.cpp deleted file mode 100644 index ea2c8d04..00000000 --- a/src/engine/events/SendPortActivityEvent.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "SendPortActivityEvent.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "ClientBroadcaster.hpp" - -namespace Ingen { - - -void -SendPortActivityEvent::post_process() -{ - _engine.broadcaster()->send_activity(_port->path()); -} - - -} // namespace Ingen - diff --git a/src/engine/events/SendPortActivityEvent.hpp b/src/engine/events/SendPortActivityEvent.hpp deleted file mode 100644 index 45a4cd36..00000000 --- a/src/engine/events/SendPortActivityEvent.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 SENDPORTACTIVITYEVENT_H -#define SENDPORTACTIVITYEVENT_H - -#include "Event.hpp" -#include "types.hpp" - -namespace Ingen { - -class PortImpl; - - -/** A special event used internally to send port activity notification (e.g. - * MIDI event activity) from the audio thread. - * - * This is created in the audio thread (directly in a ringbuffer, not new'd) - * for processing in the post processing thread (unlike normal events which - * are created in the pre-processor thread then run through the audio - * thread). This event's job is done entirely in post_process. - * - * This only really makes sense for message ports. - * - * \ingroup engine - */ -class SendPortActivityEvent : public Event -{ -public: - inline SendPortActivityEvent(Engine& engine, - SampleCount timestamp, - PortImpl* port) - : Event(engine, SharedPtr(), timestamp) - , _port(port) - { - } - - inline void operator=(const SendPortActivityEvent& ev) { - _port = ev._port; - } - - void post_process(); - -private: - PortImpl* _port; -}; - - -} // namespace Ingen - -#endif // SENDPORTACTIVITYEVENT_H diff --git a/src/engine/events/SendPortValue.cpp b/src/engine/events/SendPortValue.cpp new file mode 100644 index 00000000..56292bf0 --- /dev/null +++ b/src/engine/events/SendPortValue.cpp @@ -0,0 +1,43 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 +#include "events/SendPortValue.hpp" +#include "Engine.hpp" +#include "PortImpl.hpp" +#include "ClientBroadcaster.hpp" + +using namespace std; + +namespace Ingen { + + +void +SendPortValueEvent::post_process() +{ + // FIXME... + + if (_omni) { + _engine.broadcaster()->send_port_value(_port->path(), _value); + } else { + _engine.broadcaster()->send_port_value(_port->path(), _value); + } +} + + +} // namespace Ingen + diff --git a/src/engine/events/SendPortValue.hpp b/src/engine/events/SendPortValue.hpp new file mode 100644 index 00000000..87d42e7a --- /dev/null +++ b/src/engine/events/SendPortValue.hpp @@ -0,0 +1,76 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 SENDPORTVALUEEVENT_H +#define SENDPORTVALUEEVENT_H + +#include "engine/Event.hpp" +#include "engine/types.hpp" + +namespace Ingen { + +class PortImpl; + + +/** A special event used internally to send port values from the audio thread. + * + * This is created in the audio thread (using in-place new on a preallocated + * buffer) for processing in the post processing thread (unlike normal events + * which are created in the pre-processor thread then run through the audio + * thread). This event's job is done entirely in post_process. + * + * This only works for control ports right now. + * + * \ingroup engine + */ +class SendPortValueEvent : public Event +{ +public: + inline SendPortValueEvent(Engine& engine, + SampleCount timestamp, + PortImpl* port, + bool omni, + uint32_t voice_num, + Sample value) + : Event(engine, SharedPtr(), timestamp) + , _port(port) + , _omni(omni) + , _voice_num(voice_num) + , _value(value) + { + } + + inline void operator=(const SendPortValueEvent& ev) { + _port = ev._port; + _omni = ev._omni; + _voice_num = ev._voice_num; + _value = ev._value; + } + + void post_process(); + +private: + PortImpl* _port; + bool _omni; + uint32_t _voice_num; + Sample _value; +}; + + +} // namespace Ingen + +#endif // SENDPORTVALUEEVENT_H diff --git a/src/engine/events/SendPortValueEvent.cpp b/src/engine/events/SendPortValueEvent.cpp deleted file mode 100644 index 8ef38dd3..00000000 --- a/src/engine/events/SendPortValueEvent.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 -#include "SendPortValueEvent.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "ClientBroadcaster.hpp" - -using namespace std; - -namespace Ingen { - - -void -SendPortValueEvent::post_process() -{ - // FIXME... - - if (_omni) { - _engine.broadcaster()->send_port_value(_port->path(), _value); - } else { - _engine.broadcaster()->send_port_value(_port->path(), _value); - } -} - - -} // namespace Ingen - diff --git a/src/engine/events/SendPortValueEvent.hpp b/src/engine/events/SendPortValueEvent.hpp deleted file mode 100644 index 87d42e7a..00000000 --- a/src/engine/events/SendPortValueEvent.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 SENDPORTVALUEEVENT_H -#define SENDPORTVALUEEVENT_H - -#include "engine/Event.hpp" -#include "engine/types.hpp" - -namespace Ingen { - -class PortImpl; - - -/** A special event used internally to send port values from the audio thread. - * - * This is created in the audio thread (using in-place new on a preallocated - * buffer) for processing in the post processing thread (unlike normal events - * which are created in the pre-processor thread then run through the audio - * thread). This event's job is done entirely in post_process. - * - * This only works for control ports right now. - * - * \ingroup engine - */ -class SendPortValueEvent : public Event -{ -public: - inline SendPortValueEvent(Engine& engine, - SampleCount timestamp, - PortImpl* port, - bool omni, - uint32_t voice_num, - Sample value) - : Event(engine, SharedPtr(), timestamp) - , _port(port) - , _omni(omni) - , _voice_num(voice_num) - , _value(value) - { - } - - inline void operator=(const SendPortValueEvent& ev) { - _port = ev._port; - _omni = ev._omni; - _voice_num = ev._voice_num; - _value = ev._value; - } - - void post_process(); - -private: - PortImpl* _port; - bool _omni; - uint32_t _voice_num; - Sample _value; -}; - - -} // namespace Ingen - -#endif // SENDPORTVALUEEVENT_H diff --git a/src/engine/events/SetMetadata.cpp b/src/engine/events/SetMetadata.cpp new file mode 100644 index 00000000..f722d3b2 --- /dev/null +++ b/src/engine/events/SetMetadata.cpp @@ -0,0 +1,242 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 +#include +#include "interface/DataType.hpp" +#include "ClientBroadcaster.hpp" +#include "CreateNode.hpp" +#include "CreatePatch.hpp" +#include "CreatePort.hpp" +#include "Engine.hpp" +#include "EngineStore.hpp" +#include "GraphObjectImpl.hpp" +#include "PatchImpl.hpp" +#include "PluginImpl.hpp" +#include "PortImpl.hpp" +#include "QueuedEventSource.hpp" +#include "Responder.hpp" +#include "SetMetadata.hpp" + +using namespace std; +using namespace Raul; + +namespace Ingen { + +using namespace Shared; +typedef Shared::Resource::Properties Properties; + + +SetMetadataEvent::SetMetadataEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + QueuedEventSource* source, + bool meta, + const URI& subject, + const Properties& properties) + : QueuedEvent(engine, responder, timestamp, false, source) + , _error(NO_ERROR) + , _create_event(NULL) + , _subject(subject) + , _properties(properties) + , _object(NULL) + , _patch(NULL) + , _compiled_patch(NULL) + , _is_meta(meta) + , _success(false) +{ +} + + +void +SetMetadataEvent::pre_process() +{ + typedef Properties::const_iterator iterator; + + bool is_graph_object = (_subject.scheme() == Path::scheme && Path::is_valid(_subject.str())); + + _object = is_graph_object + ? _engine.engine_store()->find_object(Path(_subject.str())) + : _object = _engine.node_factory()->plugin(_subject); + + if (!_object && !is_graph_object) { + _error = NOT_FOUND; + QueuedEvent::pre_process(); + return; + } + + if (is_graph_object && !_object) { + Path path(_subject.str()); + bool is_patch = false, is_node = false, is_port = false, is_output = false; + DataType data_type(DataType::UNKNOWN); + ResourceImpl::type(_properties, is_patch, is_node, is_port, is_output, data_type); + if (is_patch) { + uint32_t poly = 1; + iterator p = _properties.find("ingen:polyphony"); + if (p != _properties.end() && p->second.is_valid() && p->second.type() == Atom::INT) + poly = p->second.get_int32(); + _create_event = new CreatePatchEvent(_engine, _responder, _time, + path, poly, _properties); + } else if (is_node) { + const iterator p = _properties.find("rdf:instanceOf"); + _create_event = new CreateNodeEvent(_engine, _responder, _time, + path, p->second.get_uri(), true, _properties); + } else if (is_port) { + _blocking = true; + _create_event = new CreatePortEvent(_engine, _responder, _time, + path, data_type.uri(), is_output, _source, _properties); + } + if (_create_event) + _create_event->pre_process(); + else + _error = BAD_TYPE; + QueuedEvent::pre_process(); + return; + } + + _types.reserve(_properties.size()); + + for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p) { + const Raul::URI& key = p->first; + const Raul::Atom& value = p->second; + GraphObjectImpl* obj = dynamic_cast(_object); + SpecialType op = NONE; + if (obj) { + if (_is_meta) + obj->meta().set_property(key, value); + else + obj->set_property(key, value); + + _patch = dynamic_cast(_object); + + if (key.str() == "ingen:broadcast") { + op = ENABLE_BROADCAST; + } else if (_patch) { + if (key.str() == "ingen:enabled") { + if (value.type() == Atom::BOOL) { + op = ENABLE; + if (value.get_bool() && !_patch->compiled_patch()) + _compiled_patch = _patch->compile(); + } else { + _error = BAD_TYPE; + } + } else if (key.str() == "ingen:polyphonic") { + if (value.type() == Atom::BOOL) { + op = POLYPHONIC; + } else { + _error = BAD_TYPE; + } + } else if (key.str() == "ingen:polyphony") { + if (value.type() == Atom::INT) { + op = POLYPHONY; + _patch->prepare_internal_poly(value.get_int32()); + } else { + _error = BAD_TYPE; + } + } + } + } + + if (_error != NO_ERROR) + break; + + _types.push_back(op); + } + + QueuedEvent::pre_process(); +} + + +void +SetMetadataEvent::execute(ProcessContext& context) +{ + if (_error != NO_ERROR) { + QueuedEvent::execute(context); + return; + } + + if (_create_event) { + QueuedEvent::execute(context); + _create_event->execute(context); + if (_blocking) + _source->unblock(); + return; + } + + std::vector::const_iterator t = _types.begin(); + for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p, ++t) { + const Raul::Atom& value = p->second; + PortImpl* port = 0; + GraphObjectImpl* object = 0; + switch (*t) { + case ENABLE_BROADCAST: + if ((port = dynamic_cast(_object))) + port->broadcast(value.get_bool()); + break; + case ENABLE: + if (value.get_bool()) { + if (!_patch->compiled_patch()) + _patch->compiled_patch(_compiled_patch); + _patch->enable(); + } else { + _patch->disable(); + } + break; + case POLYPHONIC: + if ((object = dynamic_cast(_object))) + if (!object->set_polyphonic(*_engine.maid(), value.get_bool())) + _error = INTERNAL; + break; + case POLYPHONY: + if (!_patch->apply_internal_poly(*_engine.maid(), value.get_int32())) + _error = INTERNAL; + break; + default: + _success = true; + } + } + + QueuedEvent::execute(context); +} + + +void +SetMetadataEvent::post_process() +{ + switch (_error) { + case NO_ERROR: + _responder->respond_ok(); + _engine.broadcaster()->send_put(_subject, _properties); + if (_create_event) + _create_event->post_process(); + break; + case NOT_FOUND: + _responder->respond_error((boost::format( + "Unable to find object '%1%'") % _subject).str()); + case INTERNAL: + _responder->respond_error("Internal error"); + break; + case BAD_TYPE: + _responder->respond_error("Bad type"); + break; + } +} + + +} // namespace Ingen + diff --git a/src/engine/events/SetMetadata.hpp b/src/engine/events/SetMetadata.hpp new file mode 100644 index 00000000..a3aadfa9 --- /dev/null +++ b/src/engine/events/SetMetadata.hpp @@ -0,0 +1,100 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 SETMETADATAEVENT_H +#define SETMETADATAEVENT_H + +#include +#include "raul/URI.hpp" +#include "raul/Atom.hpp" +#include "shared/ResourceImpl.hpp" +#include "QueuedEvent.hpp" + +namespace Ingen { + +class GraphObjectImpl; +class PatchImpl; +class CompiledPatch; + +/** \page methods + *

POST

+ * As per HTTP (RFC2616 S9.5). + * + * Append properties to a graph object. + * + * An object can have several properties with a single predicate. + * POST appends properties without modifying or removing existing properties. + */ + +/** \page methods + *

PUT

+ * As per HTTP (RFC2616 S9.6). + * + * Set properties of a graph object, or create an object. + * + * An object can have several properties with a single predicate. + * \li If the object does not yet exist, the message must contain sufficient + * information to create the object (e.g. known rdf:type properties, etc.) + * \li If the object does exist, a PUT removes all existing object properties + * with predicates that match any property in the message, then adds all + * properties from the message. + */ + +/** Set properties of a graph object. + * \ingroup engine + */ +class SetMetadataEvent : public QueuedEvent +{ +public: + SetMetadataEvent( + Engine& engine, + SharedPtr responder, + SampleCount timestamp, + QueuedEventSource* source, + bool meta, + const Raul::URI& subject, + const Shared::Resource::Properties& properties); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + enum { NO_ERROR, NOT_FOUND, INTERNAL, BAD_TYPE } _error; + enum SpecialType { + NONE, + ENABLE, + ENABLE_BROADCAST, + POLYPHONY, + POLYPHONIC + }; + + QueuedEvent* _create_event; + std::vector _types; + Raul::URI _subject; + Shared::Resource::Properties _properties; + Shared::ResourceImpl* _object; + PatchImpl* _patch; + CompiledPatch* _compiled_patch; + bool _is_meta; + bool _success; +}; + + +} // namespace Ingen + +#endif // SETMETADATAEVENT_H diff --git a/src/engine/events/SetMetadataEvent.cpp b/src/engine/events/SetMetadataEvent.cpp deleted file mode 100644 index 24dbce88..00000000 --- a/src/engine/events/SetMetadataEvent.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "SetMetadataEvent.hpp" -#include -#include -#include "interface/DataType.hpp" -#include "ClientBroadcaster.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "GraphObjectImpl.hpp" -#include "PatchImpl.hpp" -#include "PluginImpl.hpp" -#include "PortImpl.hpp" -#include "Responder.hpp" -#include "CreatePatchEvent.hpp" -#include "CreateNodeEvent.hpp" -#include "CreatePortEvent.hpp" -#include "QueuedEventSource.hpp" - - -using namespace std; -using namespace Raul; - -namespace Ingen { - -using namespace Shared; -typedef Shared::Resource::Properties Properties; - - -SetMetadataEvent::SetMetadataEvent( - Engine& engine, - SharedPtr responder, - SampleCount timestamp, - QueuedEventSource* source, - bool meta, - const URI& subject, - const Properties& properties) - : QueuedEvent(engine, responder, timestamp, false, source) - , _error(NO_ERROR) - , _create_event(NULL) - , _subject(subject) - , _properties(properties) - , _object(NULL) - , _patch(NULL) - , _compiled_patch(NULL) - , _is_meta(meta) - , _success(false) -{ -} - - -void -SetMetadataEvent::pre_process() -{ - typedef Properties::const_iterator iterator; - - bool is_graph_object = (_subject.scheme() == Path::scheme && Path::is_valid(_subject.str())); - - _object = is_graph_object - ? _engine.engine_store()->find_object(Path(_subject.str())) - : _object = _engine.node_factory()->plugin(_subject); - - if (!_object && !is_graph_object) { - _error = NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if (is_graph_object && !_object) { - Path path(_subject.str()); - bool is_patch = false, is_node = false, is_port = false, is_output = false; - DataType data_type(DataType::UNKNOWN); - ResourceImpl::type(_properties, is_patch, is_node, is_port, is_output, data_type); - if (is_patch) { - uint32_t poly = 1; - iterator p = _properties.find("ingen:polyphony"); - if (p != _properties.end() && p->second.is_valid() && p->second.type() == Atom::INT) - poly = p->second.get_int32(); - _create_event = new CreatePatchEvent(_engine, _responder, _time, - path, poly, _properties); - } else if (is_node) { - const iterator p = _properties.find("rdf:instanceOf"); - _create_event = new CreateNodeEvent(_engine, _responder, _time, - path, p->second.get_uri(), true, _properties); - } else if (is_port) { - _blocking = true; - _create_event = new CreatePortEvent(_engine, _responder, _time, - path, data_type.uri(), is_output, _source, _properties); - } - if (_create_event) - _create_event->pre_process(); - else - _error = BAD_TYPE; - QueuedEvent::pre_process(); - return; - } - - _types.reserve(_properties.size()); - - for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p) { - const Raul::URI& key = p->first; - const Raul::Atom& value = p->second; - GraphObjectImpl* obj = dynamic_cast(_object); - SpecialType op = NONE; - if (obj) { - if (_is_meta) - obj->meta().set_property(key, value); - else - obj->set_property(key, value); - - _patch = dynamic_cast(_object); - - if (key.str() == "ingen:broadcast") { - op = ENABLE_BROADCAST; - } else if (_patch) { - if (key.str() == "ingen:enabled") { - if (value.type() == Atom::BOOL) { - op = ENABLE; - if (value.get_bool() && !_patch->compiled_patch()) - _compiled_patch = _patch->compile(); - } else { - _error = BAD_TYPE; - } - } else if (key.str() == "ingen:polyphonic") { - if (value.type() == Atom::BOOL) { - op = POLYPHONIC; - } else { - _error = BAD_TYPE; - } - } else if (key.str() == "ingen:polyphony") { - if (value.type() == Atom::INT) { - op = POLYPHONY; - _patch->prepare_internal_poly(value.get_int32()); - } else { - _error = BAD_TYPE; - } - } - } - } - - if (_error != NO_ERROR) - break; - - _types.push_back(op); - } - - QueuedEvent::pre_process(); -} - - -void -SetMetadataEvent::execute(ProcessContext& context) -{ - if (_error != NO_ERROR) { - QueuedEvent::execute(context); - return; - } - - if (_create_event) { - QueuedEvent::execute(context); - _create_event->execute(context); - if (_blocking) - _source->unblock(); - return; - } - - std::vector::const_iterator t = _types.begin(); - for (Properties::iterator p = _properties.begin(); p != _properties.end(); ++p, ++t) { - const Raul::Atom& value = p->second; - PortImpl* port = 0; - GraphObjectImpl* object = 0; - switch (*t) { - case ENABLE_BROADCAST: - if ((port = dynamic_cast(_object))) - port->broadcast(value.get_bool()); - break; - case ENABLE: - if (value.get_bool()) { - if (!_patch->compiled_patch()) - _patch->compiled_patch(_compiled_patch); - _patch->enable(); - } else { - _patch->disable(); - } - break; - case POLYPHONIC: - if ((object = dynamic_cast(_object))) - if (!object->set_polyphonic(*_engine.maid(), value.get_bool())) - _error = INTERNAL; - break; - case POLYPHONY: - if (!_patch->apply_internal_poly(*_engine.maid(), value.get_int32())) - _error = INTERNAL; - break; - default: - _success = true; - } - } - - QueuedEvent::execute(context); -} - - -void -SetMetadataEvent::post_process() -{ - switch (_error) { - case NO_ERROR: - _responder->respond_ok(); - _engine.broadcaster()->send_put(_subject, _properties); - if (_create_event) - _create_event->post_process(); - break; - case NOT_FOUND: - _responder->respond_error((boost::format( - "Unable to find object '%1%'") % _subject).str()); - case INTERNAL: - _responder->respond_error("Internal error"); - break; - case BAD_TYPE: - _responder->respond_error("Bad type"); - break; - } -} - - -} // namespace Ingen - diff --git a/src/engine/events/SetMetadataEvent.hpp b/src/engine/events/SetMetadataEvent.hpp deleted file mode 100644 index a3aadfa9..00000000 --- a/src/engine/events/SetMetadataEvent.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 SETMETADATAEVENT_H -#define SETMETADATAEVENT_H - -#include -#include "raul/URI.hpp" -#include "raul/Atom.hpp" -#include "shared/ResourceImpl.hpp" -#include "QueuedEvent.hpp" - -namespace Ingen { - -class GraphObjectImpl; -class PatchImpl; -class CompiledPatch; - -/** \page methods - *

POST

- * As per HTTP (RFC2616 S9.5). - * - * Append properties to a graph object. - * - * An object can have several properties with a single predicate. - * POST appends properties without modifying or removing existing properties. - */ - -/** \page methods - *

PUT

- * As per HTTP (RFC2616 S9.6). - * - * Set properties of a graph object, or create an object. - * - * An object can have several properties with a single predicate. - * \li If the object does not yet exist, the message must contain sufficient - * information to create the object (e.g. known rdf:type properties, etc.) - * \li If the object does exist, a PUT removes all existing object properties - * with predicates that match any property in the message, then adds all - * properties from the message. - */ - -/** Set properties of a graph object. - * \ingroup engine - */ -class SetMetadataEvent : public QueuedEvent -{ -public: - SetMetadataEvent( - Engine& engine, - SharedPtr responder, - SampleCount timestamp, - QueuedEventSource* source, - bool meta, - const Raul::URI& subject, - const Shared::Resource::Properties& properties); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum { NO_ERROR, NOT_FOUND, INTERNAL, BAD_TYPE } _error; - enum SpecialType { - NONE, - ENABLE, - ENABLE_BROADCAST, - POLYPHONY, - POLYPHONIC - }; - - QueuedEvent* _create_event; - std::vector _types; - Raul::URI _subject; - Shared::Resource::Properties _properties; - Shared::ResourceImpl* _object; - PatchImpl* _patch; - CompiledPatch* _compiled_patch; - bool _is_meta; - bool _success; -}; - - -} // namespace Ingen - -#endif // SETMETADATAEVENT_H diff --git a/src/engine/events/SetPortValue.cpp b/src/engine/events/SetPortValue.cpp new file mode 100644 index 00000000..14892bcf --- /dev/null +++ b/src/engine/events/SetPortValue.cpp @@ -0,0 +1,230 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 +#include "lv2ext/lv2_event.h" +#include "shared/LV2URIMap.hpp" +#include "shared/LV2Features.hpp" +#include "module/World.hpp" +#include "Responder.hpp" +#include "SetPortValue.hpp" +#include "Engine.hpp" +#include "PortImpl.hpp" +#include "ClientBroadcaster.hpp" +#include "NodeImpl.hpp" +#include "EngineStore.hpp" +#include "AudioBuffer.hpp" +#include "EventBuffer.hpp" +#include "ProcessContext.hpp" +#include "MessageContext.hpp" + +using namespace std; +using namespace Raul; + +namespace Ingen { + +using namespace Shared; + + +/** Omni (all voices) control setting */ +SetPortValueEvent::SetPortValueEvent(Engine& engine, + SharedPtr responder, + bool queued, + SampleCount timestamp, + const Raul::Path& port_path, + const Raul::Atom& value) + : QueuedEvent(engine, responder, timestamp) + , _queued(queued) + , _omni(true) + , _voice_num(0) + , _port_path(port_path) + , _value(value) + , _port(NULL) + , _error(NO_ERROR) +{ +} + + +/** Voice-specific control setting */ +SetPortValueEvent::SetPortValueEvent(Engine& engine, + SharedPtr responder, + bool queued, + SampleCount timestamp, + uint32_t voice_num, + const Raul::Path& port_path, + const Raul::Atom& value) + : QueuedEvent(engine, responder, timestamp) + , _queued(queued) + , _omni(false) + , _voice_num(voice_num) + , _port_path(port_path) + , _value(value) + , _port(NULL) + , _error(NO_ERROR) +{ +} + + +SetPortValueEvent::~SetPortValueEvent() +{ +} + + +void +SetPortValueEvent::pre_process() +{ + if (_queued) { + if (_port == NULL) + _port = _engine.engine_store()->find_port(_port_path); + if (_port == NULL) + _error = PORT_NOT_FOUND; + } + + // Port is a message context port, set its value and + // call the plugin's message run function once + if (_port && _port->context() == Context::MESSAGE) { + apply(0, 0); + _engine.message_context()->run(_port->parent_node()); + } + + QueuedEvent::pre_process(); +} + + +void +SetPortValueEvent::execute(ProcessContext& context) +{ + Event::execute(context); + assert(_time >= context.start() && _time <= context.end()); + + if (_port && _port->context() == Context::MESSAGE) + return; + + apply(context.start(), context.nframes()); +} + + +void +SetPortValueEvent::apply(uint32_t start, uint32_t nframes) +{ + if (_error == NO_ERROR && !_port) + _port = _engine.engine_store()->find_port(_port_path); + + if (!_port) { + if (_error == NO_ERROR) + _error = PORT_NOT_FOUND; + /*} else if (_port->buffer(0)->capacity() < _data_size) { + _error = NO_SPACE;*/ + } else { + Buffer* const buf = _port->buffer(0); + AudioBuffer* const abuf = dynamic_cast(buf); + if (abuf) { + if (_value.type() != Atom::FLOAT) { + _error = TYPE_MISMATCH; + return; + } + + if (_omni) { + for (uint32_t i=0; i < _port->poly(); ++i) + ((AudioBuffer*)_port->buffer(i))->set_value( + _value.get_float(), start, _time); + } else { + if (_voice_num < _port->poly()) + ((AudioBuffer*)_port->buffer(_voice_num))->set_value( + _value.get_float(), start, _time); + else + _error = ILLEGAL_VOICE; + } + return; + } + + EventBuffer* const ebuf = dynamic_cast(buf); + + const LV2Features::Feature* f = _engine.world()->lv2_features->feature(LV2_URI_MAP_URI); + LV2URIMap* map = (LV2URIMap*)f->controller; + + // FIXME: eliminate lookups + // FIXME: need a proper prefix system + if (ebuf && _value.type() == Atom::BLOB) { + const uint32_t frames = std::max( + (uint32_t)(_time - start), + ebuf->latest_frames()); + + // Size 0 event, pass it along to the plugin as a typed but empty event + if (_value.data_size() == 0) { + cout << "BANG!" << endl; + const uint32_t type_id = map->uri_to_id(NULL, _value.get_blob_type()); + ebuf->append(frames, 0, type_id, 0, NULL); + _port->raise_set_by_user_flag(); + return; + + } else if (!strcmp(_value.get_blob_type(), "lv2midi:MidiEvent")) { + const uint32_t type_id = map->uri_to_id(NULL, + "http://lv2plug.in/ns/ext/midi#MidiEvent"); + + ebuf->prepare_write(start, nframes); + // FIXME: use OSC midi type? avoid MIDI over OSC entirely? + ebuf->append(frames, 0, type_id, _value.data_size(), + (const uint8_t*)_value.get_blob()); + _port->raise_set_by_user_flag(); + return; + } + } + + if (_value.type() == Atom::BLOB) + cerr << "WARNING: Unknown value blob type " << _value.get_blob_type() << endl; + else + cerr << "WARNING: Unknown value type " << (int)_value.type() << endl; + } +} + + +void +SetPortValueEvent::post_process() +{ + string msg; + std::ostringstream ss; + switch (_error) { + case NO_ERROR: + assert(_port != NULL); + _responder->respond_ok(); + _engine.broadcaster()->send_port_value(_port_path, _value); + break; + case TYPE_MISMATCH: + _responder->respond_error("type mismatch"); + break; + case ILLEGAL_VOICE: + ss << "Illegal voice number " << _voice_num; + _responder->respond_error(ss.str()); + break; + case PORT_NOT_FOUND: + msg = "Unable to find port "; + msg.append(_port_path.str()).append(" for set_port_value"); + _responder->respond_error(msg); + break; + case NO_SPACE: + ss << "Attempt to write " << _value.data_size() << " bytes to " + << _port_path.str() << ", with capacity " + << _port->buffer_size() << endl; + _responder->respond_error(ss.str()); + break; + } +} + + +} // namespace Ingen + diff --git a/src/engine/events/SetPortValue.hpp b/src/engine/events/SetPortValue.hpp new file mode 100644 index 00000000..31eb67de --- /dev/null +++ b/src/engine/events/SetPortValue.hpp @@ -0,0 +1,86 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 SETPORTVALUEEVENT_H +#define SETPORTVALUEEVENT_H + +#include "raul/Atom.hpp" +#include "QueuedEvent.hpp" +#include "types.hpp" + +namespace Ingen { + +class PortImpl; + + +/** An event to change the value of a port. + * + * This event can either be queued or immediate, depending on the queued + * parameter passed to the constructor. It must be passed to the appropriate + * place (ie queued event passed to the event queue and non-queued event + * processed in the audio thread) or nasty things will happen. + * + * \ingroup engine + */ +class SetPortValueEvent : public QueuedEvent +{ +public: + SetPortValueEvent(Engine& engine, + SharedPtr responder, + bool queued, + SampleCount timestamp, + const Raul::Path& port_path, + const Raul::Atom& value); + + SetPortValueEvent(Engine& engine, + SharedPtr responder, + bool queued, + SampleCount timestamp, + uint32_t voice_num, + const Raul::Path& port_path, + const Raul::Atom& value); + + ~SetPortValueEvent(); + + void pre_process(); + void execute(ProcessContext& context); + void post_process(); + +private: + enum ErrorType { + NO_ERROR, + PORT_NOT_FOUND, + NO_SPACE, + ILLEGAL_VOICE, + TYPE_MISMATCH + }; + + void apply(uint32_t start, uint32_t nframes); + + bool _queued; + bool _omni; + uint32_t _voice_num; + const Raul::Path _port_path; + const Raul::Atom _value; + PortImpl* _port; + ErrorType _error; +}; + + +} // namespace Ingen + +#endif // SETPORTVALUEEVENT_H diff --git a/src/engine/events/SetPortValueEvent.cpp b/src/engine/events/SetPortValueEvent.cpp deleted file mode 100644 index 733de6f9..00000000 --- a/src/engine/events/SetPortValueEvent.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 -#include "lv2ext/lv2_event.h" -#include "shared/LV2URIMap.hpp" -#include "shared/LV2Features.hpp" -#include "module/World.hpp" -#include "Responder.hpp" -#include "SetPortValueEvent.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "NodeImpl.hpp" -#include "EngineStore.hpp" -#include "AudioBuffer.hpp" -#include "EventBuffer.hpp" -#include "ProcessContext.hpp" -#include "MessageContext.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { - -using namespace Shared; - - -/** Omni (all voices) control setting */ -SetPortValueEvent::SetPortValueEvent(Engine& engine, - SharedPtr responder, - bool queued, - SampleCount timestamp, - const Raul::Path& port_path, - const Raul::Atom& value) - : QueuedEvent(engine, responder, timestamp) - , _queued(queued) - , _omni(true) - , _voice_num(0) - , _port_path(port_path) - , _value(value) - , _port(NULL) - , _error(NO_ERROR) -{ -} - - -/** Voice-specific control setting */ -SetPortValueEvent::SetPortValueEvent(Engine& engine, - SharedPtr responder, - bool queued, - SampleCount timestamp, - uint32_t voice_num, - const Raul::Path& port_path, - const Raul::Atom& value) - : QueuedEvent(engine, responder, timestamp) - , _queued(queued) - , _omni(false) - , _voice_num(voice_num) - , _port_path(port_path) - , _value(value) - , _port(NULL) - , _error(NO_ERROR) -{ -} - - -SetPortValueEvent::~SetPortValueEvent() -{ -} - - -void -SetPortValueEvent::pre_process() -{ - if (_queued) { - if (_port == NULL) - _port = _engine.engine_store()->find_port(_port_path); - if (_port == NULL) - _error = PORT_NOT_FOUND; - } - - // Port is a message context port, set its value and - // call the plugin's message run function once - if (_port && _port->context() == Context::MESSAGE) { - apply(0, 0); - _engine.message_context()->run(_port->parent_node()); - } - - QueuedEvent::pre_process(); -} - - -void -SetPortValueEvent::execute(ProcessContext& context) -{ - Event::execute(context); - assert(_time >= context.start() && _time <= context.end()); - - if (_port && _port->context() == Context::MESSAGE) - return; - - apply(context.start(), context.nframes()); -} - - -void -SetPortValueEvent::apply(uint32_t start, uint32_t nframes) -{ - if (_error == NO_ERROR && !_port) - _port = _engine.engine_store()->find_port(_port_path); - - if (!_port) { - if (_error == NO_ERROR) - _error = PORT_NOT_FOUND; - /*} else if (_port->buffer(0)->capacity() < _data_size) { - _error = NO_SPACE;*/ - } else { - Buffer* const buf = _port->buffer(0); - AudioBuffer* const abuf = dynamic_cast(buf); - if (abuf) { - if (_value.type() != Atom::FLOAT) { - _error = TYPE_MISMATCH; - return; - } - - if (_omni) { - for (uint32_t i=0; i < _port->poly(); ++i) - ((AudioBuffer*)_port->buffer(i))->set_value( - _value.get_float(), start, _time); - } else { - if (_voice_num < _port->poly()) - ((AudioBuffer*)_port->buffer(_voice_num))->set_value( - _value.get_float(), start, _time); - else - _error = ILLEGAL_VOICE; - } - return; - } - - EventBuffer* const ebuf = dynamic_cast(buf); - - const LV2Features::Feature* f = _engine.world()->lv2_features->feature(LV2_URI_MAP_URI); - LV2URIMap* map = (LV2URIMap*)f->controller; - - // FIXME: eliminate lookups - // FIXME: need a proper prefix system - if (ebuf && _value.type() == Atom::BLOB) { - const uint32_t frames = std::max( - (uint32_t)(_time - start), - ebuf->latest_frames()); - - // Size 0 event, pass it along to the plugin as a typed but empty event - if (_value.data_size() == 0) { - cout << "BANG!" << endl; - const uint32_t type_id = map->uri_to_id(NULL, _value.get_blob_type()); - ebuf->append(frames, 0, type_id, 0, NULL); - _port->raise_set_by_user_flag(); - return; - - } else if (!strcmp(_value.get_blob_type(), "lv2midi:MidiEvent")) { - const uint32_t type_id = map->uri_to_id(NULL, - "http://lv2plug.in/ns/ext/midi#MidiEvent"); - - ebuf->prepare_write(start, nframes); - // FIXME: use OSC midi type? avoid MIDI over OSC entirely? - ebuf->append(frames, 0, type_id, _value.data_size(), - (const uint8_t*)_value.get_blob()); - _port->raise_set_by_user_flag(); - return; - } - } - - if (_value.type() == Atom::BLOB) - cerr << "WARNING: Unknown value blob type " << _value.get_blob_type() << endl; - else - cerr << "WARNING: Unknown value type " << (int)_value.type() << endl; - } -} - - -void -SetPortValueEvent::post_process() -{ - string msg; - std::ostringstream ss; - switch (_error) { - case NO_ERROR: - assert(_port != NULL); - _responder->respond_ok(); - _engine.broadcaster()->send_port_value(_port_path, _value); - break; - case TYPE_MISMATCH: - _responder->respond_error("type mismatch"); - break; - case ILLEGAL_VOICE: - ss << "Illegal voice number " << _voice_num; - _responder->respond_error(ss.str()); - break; - case PORT_NOT_FOUND: - msg = "Unable to find port "; - msg.append(_port_path.str()).append(" for set_port_value"); - _responder->respond_error(msg); - break; - case NO_SPACE: - ss << "Attempt to write " << _value.data_size() << " bytes to " - << _port_path.str() << ", with capacity " - << _port->buffer_size() << endl; - _responder->respond_error(ss.str()); - break; - } -} - - -} // namespace Ingen - diff --git a/src/engine/events/SetPortValueEvent.hpp b/src/engine/events/SetPortValueEvent.hpp deleted file mode 100644 index 31eb67de..00000000 --- a/src/engine/events/SetPortValueEvent.hpp +++ /dev/null @@ -1,86 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 SETPORTVALUEEVENT_H -#define SETPORTVALUEEVENT_H - -#include "raul/Atom.hpp" -#include "QueuedEvent.hpp" -#include "types.hpp" - -namespace Ingen { - -class PortImpl; - - -/** An event to change the value of a port. - * - * This event can either be queued or immediate, depending on the queued - * parameter passed to the constructor. It must be passed to the appropriate - * place (ie queued event passed to the event queue and non-queued event - * processed in the audio thread) or nasty things will happen. - * - * \ingroup engine - */ -class SetPortValueEvent : public QueuedEvent -{ -public: - SetPortValueEvent(Engine& engine, - SharedPtr responder, - bool queued, - SampleCount timestamp, - const Raul::Path& port_path, - const Raul::Atom& value); - - SetPortValueEvent(Engine& engine, - SharedPtr responder, - bool queued, - SampleCount timestamp, - uint32_t voice_num, - const Raul::Path& port_path, - const Raul::Atom& value); - - ~SetPortValueEvent(); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum ErrorType { - NO_ERROR, - PORT_NOT_FOUND, - NO_SPACE, - ILLEGAL_VOICE, - TYPE_MISMATCH - }; - - void apply(uint32_t start, uint32_t nframes); - - bool _queued; - bool _omni; - uint32_t _voice_num; - const Raul::Path _port_path; - const Raul::Atom _value; - PortImpl* _port; - ErrorType _error; -}; - - -} // namespace Ingen - -#endif // SETPORTVALUEEVENT_H diff --git a/src/engine/events/UnregisterClient.cpp b/src/engine/events/UnregisterClient.cpp new file mode 100644 index 00000000..9e0572d5 --- /dev/null +++ b/src/engine/events/UnregisterClient.cpp @@ -0,0 +1,47 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 "interface/ClientInterface.hpp" +#include "Responder.hpp" +#include "UnregisterClient.hpp" +#include "Engine.hpp" +#include "ClientBroadcaster.hpp" + +using namespace Raul; + +namespace Ingen { + + +UnregisterClientEvent::UnregisterClientEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const URI& uri) + : QueuedEvent(engine, responder, timestamp) + , _uri(uri) +{ +} + + +void +UnregisterClientEvent::post_process() +{ + if (_engine.broadcaster()->unregister_client(_uri)) + _responder->respond_ok(); + else + _responder->respond_error("Unable to unregister client"); +} + + +} // namespace Ingen + diff --git a/src/engine/events/UnregisterClient.hpp b/src/engine/events/UnregisterClient.hpp new file mode 100644 index 00000000..d33ea554 --- /dev/null +++ b/src/engine/events/UnregisterClient.hpp @@ -0,0 +1,48 @@ +/* This file is part of Ingen. + * Copyright (C) 2007-2009 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 UNREGISTERCLIENTEVENT_H +#define UNREGISTERCLIENTEVENT_H + +#include "QueuedEvent.hpp" +#include "raul/URI.hpp" + +namespace Ingen { + + +/** Unregisters an OSC client so it no longer receives notifications. + * + * \ingroup engine + */ +class UnregisterClientEvent : public QueuedEvent +{ +public: + UnregisterClientEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const Raul::URI& uri); + + void post_process(); + +private: + Raul::URI _uri; +}; + + +} // namespace Ingen + +#endif // UNREGISTERCLIENTEVENT_H diff --git a/src/engine/events/UnregisterClientEvent.cpp b/src/engine/events/UnregisterClientEvent.cpp deleted file mode 100644 index 6de6c373..00000000 --- a/src/engine/events/UnregisterClientEvent.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 "interface/ClientInterface.hpp" -#include "Responder.hpp" -#include "UnregisterClientEvent.hpp" -#include "Engine.hpp" -#include "ClientBroadcaster.hpp" - -using namespace Raul; - -namespace Ingen { - - -UnregisterClientEvent::UnregisterClientEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const URI& uri) - : QueuedEvent(engine, responder, timestamp) - , _uri(uri) -{ -} - - -void -UnregisterClientEvent::post_process() -{ - if (_engine.broadcaster()->unregister_client(_uri)) - _responder->respond_ok(); - else - _responder->respond_error("Unable to unregister client"); -} - - -} // namespace Ingen - diff --git a/src/engine/events/UnregisterClientEvent.hpp b/src/engine/events/UnregisterClientEvent.hpp deleted file mode 100644 index d33ea554..00000000 --- a/src/engine/events/UnregisterClientEvent.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2009 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 UNREGISTERCLIENTEVENT_H -#define UNREGISTERCLIENTEVENT_H - -#include "QueuedEvent.hpp" -#include "raul/URI.hpp" - -namespace Ingen { - - -/** Unregisters an OSC client so it no longer receives notifications. - * - * \ingroup engine - */ -class UnregisterClientEvent : public QueuedEvent -{ -public: - UnregisterClientEvent(Engine& engine, - SharedPtr responder, - SampleCount timestamp, - const Raul::URI& uri); - - void post_process(); - -private: - Raul::URI _uri; -}; - - -} // namespace Ingen - -#endif // UNREGISTERCLIENTEVENT_H -- cgit v1.2.1