summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-05-18 18:03:24 +0000
committerDavid Robillard <d@drobilla.net>2012-05-18 18:03:24 +0000
commitec4fd6dd3809a055b66c28f841df277e4cd9f62e (patch)
tree229dbb5f8046753c433853c890c32b1fdac97a48 /src
parentda03dbe262f38fa0cc5eaacd176a4d8efe5029db (diff)
downloadingen-ec4fd6dd3809a055b66c28f841df277e4cd9f62e.tar.gz
ingen-ec4fd6dd3809a055b66c28f841df277e4cd9f62e.tar.bz2
ingen-ec4fd6dd3809a055b66c28f841df277e4cd9f62e.zip
Beginnings of a test framework.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4427 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/server/DirectDriver.hpp78
-rw-r--r--src/server/Engine.cpp25
-rw-r--r--src/server/Engine.hpp1
-rw-r--r--src/server/events/CreatePort.cpp112
-rw-r--r--src/server/wscript13
-rw-r--r--src/shared/Module.cpp33
-rw-r--r--src/shared/World.cpp65
-rw-r--r--src/shared/wscript45
8 files changed, 241 insertions, 131 deletions
diff --git a/src/server/DirectDriver.hpp b/src/server/DirectDriver.hpp
new file mode 100644
index 00000000..b6d66df6
--- /dev/null
+++ b/src/server/DirectDriver.hpp
@@ -0,0 +1,78 @@
+/*
+ This file is part of Ingen.
+ Copyright 2007-2012 David Robillard <http://drobilla.net/>
+
+ Ingen is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or 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 Affero General Public License for details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Ingen. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef INGEN_ENGINE_DIRECT_DRIVER_HPP
+#define INGEN_ENGINE_DIRECT_DRIVER_HPP
+
+#include "Driver.hpp"
+
+namespace Ingen {
+namespace Server {
+
+/** Driver for running Ingen directly as a library.
+ * \ingroup engine
+ */
+class DirectDriver : public Driver {
+public:
+ DirectDriver(double sample_rate, SampleCount block_length)
+ : _sample_rate(sample_rate)
+ , _block_length(block_length)
+ {}
+
+ virtual ~DirectDriver() {}
+
+ virtual void activate() {}
+
+ virtual void deactivate() {}
+
+ virtual EnginePort* create_port(DuplexPort* patch_port) {
+ return NULL;
+ }
+
+ virtual EnginePort* engine_port(ProcessContext& context,
+ const Raul::Path& path) {
+ return NULL;
+ }
+
+ virtual void add_port(ProcessContext& context, EnginePort* port) {}
+
+ virtual Raul::Deletable* remove_port(ProcessContext& context,
+ const Raul::Path& path,
+ EnginePort** port = NULL) {
+ return NULL;
+ }
+
+ virtual SampleCount block_length() const { return _block_length; }
+
+ virtual SampleCount sample_rate() const { return _sample_rate; }
+
+ virtual SampleCount frame_time() const {
+ return 0;
+ }
+
+ virtual bool is_realtime() const {
+ return false;
+ }
+
+private:
+ SampleCount _sample_rate;
+ SampleCount _block_length;
+};
+
+} // namespace Server
+} // namespace Ingen
+
+#endif // INGEN_ENGINE_DIRECT_DRIVER_HPP
diff --git a/src/server/Engine.cpp b/src/server/Engine.cpp
index 69ad435b..9359bacf 100644
--- a/src/server/Engine.cpp
+++ b/src/server/Engine.cpp
@@ -14,7 +14,6 @@
along with Ingen. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <cassert>
#include <sys/mman.h>
#include <unistd.h>
@@ -31,6 +30,7 @@
#include "Broadcaster.hpp"
#include "BufferFactory.hpp"
+#include "DirectDriver.hpp"
#include "ControlBindings.hpp"
#include "Driver.hpp"
#include "Engine.hpp"
@@ -142,14 +142,24 @@ execute_and_delete_event(ProcessContext& context, Event* ev)
delete ev;
}
+void
+Engine::init(double sample_rate, uint32_t block_length)
+{
+ set_driver(SharedPtr<Driver>(new DirectDriver(sample_rate, block_length)));
+}
+
bool
Engine::activate()
{
- assert(_driver);
+ if (!_driver) {
+ return false;
+ }
+
ThreadManager::single_threaded = true;
_buffer_factory->set_block_length(_driver->block_length());
+ _pre_processor->start();
_message_context.Thread::start();
const Ingen::Shared::URIs& uris = world()->uris();
@@ -226,8 +236,15 @@ Engine::activate()
void
Engine::deactivate()
{
- _driver->deactivate();
- _root_patch->deactivate();
+ _pre_processor->stop();
+
+ if (_driver) {
+ _driver->deactivate();
+ }
+
+ if (_root_patch) {
+ _root_patch->deactivate();
+ }
ThreadManager::single_threaded = true;
}
diff --git a/src/server/Engine.hpp b/src/server/Engine.hpp
index 8fcb5ce6..edbe33ae 100644
--- a/src/server/Engine.hpp
+++ b/src/server/Engine.hpp
@@ -65,6 +65,7 @@ public:
virtual ~Engine();
// EngineBase methods
+ virtual void init(double sample_rate, uint32_t block_length);
virtual bool activate();
virtual void deactivate();
virtual unsigned run(uint32_t sample_count);
diff --git a/src/server/events/CreatePort.cpp b/src/server/events/CreatePort.cpp
index d8c183cd..a783512f 100644
--- a/src/server/events/CreatePort.cpp
+++ b/src/server/events/CreatePort.cpp
@@ -90,73 +90,85 @@ CreatePort::CreatePort(Engine& engine,
void
CreatePort::pre_process()
{
- if (_status == UNKNOWN_TYPE || _engine.engine_store()->find_object(_path)) {
+ if (_status) {
Event::pre_process();
return;
}
- _patch = _engine.engine_store()->find_patch(_path.parent());
+ if (_engine.engine_store()->find_object(_path)) {
+ _status = EXISTS;
+ Event::pre_process();
+ return;
+ }
+
+ if (!(_patch = _engine.engine_store()->find_patch(_path.parent()))) {
+ _status = PARENT_NOT_FOUND;
+ Event::pre_process();
+ return;
+ }
const Ingen::Shared::URIs& uris = _engine.world()->uris();
- if (_patch != NULL) {
- assert(_patch->path() == _path.parent());
-
- size_t buffer_size = _engine.buffer_factory()->default_buffer_size(_buffer_type);
-
- const uint32_t old_num_ports = (_patch->external_ports())
- ? _patch->external_ports()->size()
- : 0;
-
- Resource::Properties::const_iterator index_i = _properties.find(uris.lv2_index);
- if (index_i == _properties.end()) {
- index_i = _properties.insert(
- std::make_pair(uris.lv2_index,
- _engine.world()->forge().make(int32_t(old_num_ports))));
- } else if (index_i->second.type() != uris.forge.Int
- || index_i->second.get_int32() != static_cast<int32_t>(old_num_ports)) {
- Event::pre_process();
- _status = BAD_INDEX;
- return;
- }
+ assert(_patch->path() == _path.parent());
- Resource::Properties::const_iterator poly_i = _properties.find(uris.ingen_polyphonic);
- bool polyphonic = (poly_i != _properties.end() &&
- poly_i->second.type() == uris.forge.Bool &&
- poly_i->second.get_bool());
+ size_t buffer_size = _engine.buffer_factory()->default_buffer_size(_buffer_type);
- _patch_port = _patch->create_port(*_engine.buffer_factory(), _path.symbol(),
- _port_type, _buffer_type, buffer_size,
- _is_output, polyphonic);
+ const uint32_t old_num_ports = (_patch->external_ports())
+ ? _patch->external_ports()->size()
+ : 0;
- _patch_port->properties().insert(_properties.begin(), _properties.end());
+ Resource::Properties::const_iterator index_i = _properties.find(uris.lv2_index);
+ if (index_i == _properties.end()) {
+ index_i = _properties.insert(
+ std::make_pair(uris.lv2_index,
+ _engine.world()->forge().make(int32_t(old_num_ports))));
+ } else if (index_i->second.type() != uris.forge.Int
+ || index_i->second.get_int32() != static_cast<int32_t>(old_num_ports)) {
+ _status = BAD_INDEX;
+ Event::pre_process();
+ return;
+ }
- assert(index_i->second == _engine.world()->forge().make((int)_patch_port->index()));
+ Resource::Properties::const_iterator poly_i = _properties.find(uris.ingen_polyphonic);
+ bool polyphonic = (poly_i != _properties.end() &&
+ poly_i->second.type() == uris.forge.Bool &&
+ poly_i->second.get_bool());
- if (_patch_port) {
- if (_is_output)
- _patch->add_output(new Raul::List<PortImpl*>::Node(_patch_port));
- else
- _patch->add_input(new Raul::List<PortImpl*>::Node(_patch_port));
+ if (!(_patch_port = _patch->create_port(
+ *_engine.buffer_factory(), _path.symbol(),
+ _port_type, _buffer_type, buffer_size, _is_output, polyphonic))) {
+ _status = CREATION_FAILED;
+ Event::pre_process();
+ return;
+ }
- if (_patch->external_ports())
- _ports_array = new Raul::Array<PortImpl*>(old_num_ports + 1, *_patch->external_ports(), NULL);
- else
- _ports_array = new Raul::Array<PortImpl*>(old_num_ports + 1, NULL);
+ _patch_port->properties().insert(_properties.begin(), _properties.end());
- _ports_array->at(old_num_ports) = _patch_port;
- _engine.engine_store()->add(_patch_port);
+ assert(index_i->second == _engine.world()->forge().make((int)_patch_port->index()));
- if (!_patch->parent()) {
- _engine_port = _engine.driver()->create_port(
- dynamic_cast<DuplexPort*>(_patch_port));
- }
+ if (_patch_port) {
+ if (_is_output)
+ _patch->add_output(new Raul::List<PortImpl*>::Node(_patch_port));
+ else
+ _patch->add_input(new Raul::List<PortImpl*>::Node(_patch_port));
+
+ if (_patch->external_ports())
+ _ports_array = new Raul::Array<PortImpl*>(old_num_ports + 1, *_patch->external_ports(), NULL);
+ else
+ _ports_array = new Raul::Array<PortImpl*>(old_num_ports + 1, NULL);
+
+ _ports_array->at(old_num_ports) = _patch_port;
+ _engine.engine_store()->add(_patch_port);
+
+ if (!_patch->parent()) {
+ _engine_port = _engine.driver()->create_port(
+ dynamic_cast<DuplexPort*>(_patch_port));
+ }
- assert(_ports_array->size() == _patch->num_ports_non_rt());
+ assert(_ports_array->size() == _patch->num_ports_non_rt());
- } else {
- _status = CREATION_FAILED;
- }
+ } else {
+ _status = CREATION_FAILED;
}
_update = _patch_port->properties();
diff --git a/src/server/wscript b/src/server/wscript
index 4cb61be5..8f505983 100644
--- a/src/server/wscript
+++ b/src/server/wscript
@@ -60,6 +60,19 @@ def build(bld):
core_libs = 'GLIBMM GTHREAD LV2 LILV RAUL SORD'
autowaf.use_lib(bld, obj, core_libs)
+ if bld.env['BUILD_TESTS']:
+ obj = bld(features = 'cxx cxxshlib',
+ source = core_source,
+ export_includes = ['../..'],
+ includes = ['.', '../..'],
+ name = 'libingen_server_profiled',
+ target = 'ingen_server_profiled',
+ install_path = '${LIBDIR}',
+ use = 'libingen_shared_profiled',
+ lib = bld.env['INGEN_TEST_LIBS'],
+ cxxflags = bld.env['INGEN_TEST_CXXFLAGS'])
+ autowaf.use_lib(bld, obj, core_libs)
+
if bld.is_defined('HAVE_JACK'):
obj = bld(features = 'cxx cxxshlib',
source = 'JackDriver.cpp ingen_jack.cpp',
diff --git a/src/shared/Module.cpp b/src/shared/Module.cpp
deleted file mode 100644
index 9ef8f0d6..00000000
--- a/src/shared/Module.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2012 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or 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 Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <glibmm/module.h>
-
-#include "raul/log.hpp"
-#include "raul/SharedPtr.hpp"
-
-#include "ingen/shared/Module.hpp"
-
-namespace Ingen {
-namespace Shared {
-
-Module::~Module()
-{
- Raul::info("[Module] ")(Raul::fmt("Unloading %1%\n") % library->get_name());
-}
-
-} // namespace Shared
-} // namespace Ingen
diff --git a/src/shared/World.cpp b/src/shared/World.cpp
index b71ea8c8..608a8409 100644
--- a/src/shared/World.cpp
+++ b/src/shared/World.cpp
@@ -50,7 +50,7 @@ namespace Shared {
*
* \param name The base name of the module, e.g. "ingen_serialisation"
*/
-static SharedPtr<Glib::Module>
+Glib::Module*
ingen_load_module(const string& name)
{
Glib::Module* module = NULL;
@@ -61,15 +61,14 @@ ingen_load_module(const string& name)
if (module_path_found) {
string dir;
istringstream iss(module_path);
- while (getline(iss, dir, ':')) {
+ while (getline(iss, dir, G_SEARCHPATH_SEPARATOR)) {
string filename = Shared::module_path(name, dir);
if (Glib::file_test(filename, Glib::FILE_TEST_EXISTS)) {
- module = new Glib::Module(filename, Glib::MODULE_BIND_LAZY);
+ module = new Glib::Module(filename);
if (*module) {
LOG(Raul::info)(Raul::fmt("Loading %1%\n") % filename);
- return SharedPtr<Glib::Module>(module);
+ return module;
} else {
- delete module;
Raul::error << Glib::Module::get_last_error() << endl;
}
}
@@ -77,23 +76,20 @@ ingen_load_module(const string& name)
}
// Try default directory if not found
- module = new Glib::Module(Shared::module_path(name), Glib::MODULE_BIND_LAZY);
+ module = new Glib::Module(Shared::module_path(name));
- // FIXME: SEGV on exit without this
- module->make_resident();
-
- if (*module) {
+ if (module) {
LOG(Raul::info)(Raul::fmt("Loading %1%\n") % Shared::module_path(name));
- return SharedPtr<Glib::Module>(module);
+ return module;
} else if (!module_path_found) {
LOG(Raul::error)(Raul::fmt("Unable to find %1% (%2%)\n")
% name % Glib::Module::get_last_error());
- return SharedPtr<Glib::Module>();
+ return NULL;
} else {
LOG(Raul::error)(Raul::fmt("Unable to load %1% from %2% (%3%)\n")
% name % module_path % Glib::Module::get_last_error());
LOG(Raul::error)("Is Ingen installed?\n");
- return SharedPtr<Glib::Module>();
+ return NULL;
}
}
@@ -131,28 +127,39 @@ public:
rdf_world->add_prefix("xsd", "http://www.w3.org/2001/XMLSchema#");
}
- virtual ~Impl()
+ ~Impl()
{
serialiser.reset();
parser.reset();
-
+ interface.reset();
engine.reset();
store.reset();
- modules.clear();
interface_factories.clear();
script_runners.clear();
- lilv_world_free(lilv_world);
-
delete rdf_world;
delete lv2_features;
delete uris;
delete forge;
delete uri_map;
+
+ lilv_world_free(lilv_world);
+
+
+ for (Modules::iterator i = modules.begin(); i != modules.end(); ++i) {
+ // Keep a reference to the library
+ Glib::Module* lib = i->second->library;
+
+ // Destroy the Ingen module
+ delete i->second;
+
+ // Now all references to library code should be done, close it
+ delete lib;
+ }
}
- typedef std::map< const std::string, SharedPtr<Module> > Modules;
+ typedef std::map<const std::string, Module*> Modules;
Modules modules;
typedef std::map<const std::string, World::InterfaceFactory> InterfaceFactories;
@@ -189,7 +196,6 @@ World::World(int& argc,
World::~World()
{
- unload_modules();
delete _impl;
}
@@ -225,18 +231,21 @@ World::load_module(const char* name)
LOG(Raul::info)(Raul::fmt("Module `%1%' already loaded\n") % name);
return true;
}
- SharedPtr<Glib::Module> lib = ingen_load_module(name);
+ Glib::Module* lib = ingen_load_module(name);
Ingen::Shared::Module* (*module_load)() = NULL;
if (lib && lib->get_symbol("ingen_module_load", (void*&)module_load)) {
Module* module = module_load();
- module->library = lib;
- module->load(this);
- _impl->modules.insert(make_pair(string(name), module));
- return true;
- } else {
- LOG(Raul::error)(Raul::fmt("Failed to load module `%1%'\n") % name);
- return false;
+ if (module) {
+ module->library = lib;
+ module->load(this);
+ _impl->modules.insert(make_pair(string(name), module));
+ return true;
+ }
}
+
+ LOG(Raul::error)(Raul::fmt("Failed to load module `%1%'\n") % name);
+ delete lib;
+ return false;
}
bool
diff --git a/src/shared/wscript b/src/shared/wscript
index 15e6097e..751951e1 100644
--- a/src/shared/wscript
+++ b/src/shared/wscript
@@ -1,8 +1,25 @@
#!/usr/bin/env python
from waflib.extras import autowaf as autowaf
+sources = [
+ 'AtomReader.cpp',
+ 'AtomWriter.cpp',
+ 'Builder.cpp',
+ 'ClashAvoider.cpp',
+ 'Configuration.cpp',
+ 'Forge.cpp',
+ 'LV2Features.cpp',
+ 'ResourceImpl.cpp',
+ 'Store.cpp',
+ 'URIMap.cpp',
+ 'URIs.cpp',
+ 'World.cpp',
+ 'runtime_paths.cpp',
+]
+
def build(bld):
obj = bld(features = 'cxx cxxshlib',
+ source = sources,
export_includes = ['../..'],
includes = ['../..'],
name = 'libingen_shared',
@@ -12,19 +29,15 @@ def build(bld):
lib = ['dl'])
autowaf.use_lib(bld, obj, 'GLIBMM LV2 LILV RAUL SORD LV2_MIDI')
- obj.source = '''
- AtomReader.cpp
- AtomWriter.cpp
- Builder.cpp
- ClashAvoider.cpp
- Configuration.cpp
- Forge.cpp
- LV2Features.cpp
- Module.cpp
- ResourceImpl.cpp
- Store.cpp
- URIMap.cpp
- URIs.cpp
- World.cpp
- runtime_paths.cpp
- '''
+ if bld.env['BUILD_TESTS']:
+ obj = bld(features = 'cxx cxxshlib',
+ source = sources,
+ export_includes = ['../..'],
+ includes = ['../..'],
+ name = 'libingen_shared_profiled',
+ target = 'ingen_shared_profiled',
+ install_path = '',
+ lib = ['dl'] + bld.env['INGEN_TEST_LIBS'],
+ cxxflags = bld.env['INGEN_TEST_CXXFLAGS'])
+ autowaf.use_lib(bld, obj, 'GLIBMM LV2 LILV RAUL SORD LV2_MIDI')
+