From 93850c202de8b073a1ce1dd8bd246d407bce4e2f Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 30 Sep 2008 16:50:21 +0000 Subject: Flatten ingen source directory heirarchy a bit. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@1551 a436a847-0d15-0410-975c-d299462d15a1 --- src/ingen/main.cpp | 259 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 src/ingen/main.cpp (limited to 'src/ingen/main.cpp') diff --git a/src/ingen/main.cpp b/src/ingen/main.cpp new file mode 100644 index 00000000..c8adf207 --- /dev/null +++ b/src/ingen/main.cpp @@ -0,0 +1,259 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 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 CONFIG_H_PATH +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "module/global.hpp" +#include "module/Module.hpp" +#include "module/World.hpp" +#include "engine/Engine.hpp" +#include "engine/QueuedEngineInterface.hpp" +#include "serialisation/Parser.hpp" +#include "cmdline.h" + +#ifdef WITH_BINDINGS +#include "bindings/ingen_bindings.hpp" +#endif + + +using namespace std; +using namespace Ingen; + + +SharedPtr engine; + +void +catch_int(int) +{ + signal(SIGINT, catch_int); + signal(SIGTERM, catch_int); + + cout << "[Main] Ingen interrupted." << endl; + engine->quit(); +} + +int +main(int argc, char** argv) +{ + /* Parse command line options */ + gengetopt_args_info args; + if (cmdline_parser (argc, argv, &args) != 0) + return 1; + + if (argc <= 1) { + cmdline_parser_print_help(); + cerr << endl << "*** Ingen requires at least one command line parameter" << endl; + cerr << "*** Just want to use a graphical app? Try 'ingen -eg'" << endl; + return 1; + } else if (args.connect_given && args.engine_flag) { + cerr << "\n*** Nonsense arguments, can't both run a local engine " + << "and connect to a remote one." << endl + << "*** Run separate instances if that is what you want" << endl; + return 1; + } + + SharedPtr engine_module; + SharedPtr client_module; + SharedPtr gui_module; + SharedPtr bindings_module; + + SharedPtr engine_interface; + + Glib::thread_init(); +#if HAVE_SOUP + g_type_init(); +#endif + + Ingen::Shared::World* world = Ingen::Shared::get_world(); + + /* Set up RDF world */ + world->rdf_world->add_prefix("xsd", "http://www.w3.org/2001/XMLSchema#"); + world->rdf_world->add_prefix("ingen", "http://drobilla.net/ns/ingen#"); + world->rdf_world->add_prefix("ingenuity", "http://drobilla.net/ns/ingenuity#"); + world->rdf_world->add_prefix("lv2", "http://lv2plug.in/ns/lv2core#"); + world->rdf_world->add_prefix("lv2var", "http://lv2plug.in/ns/ext/instance-var#"); + world->rdf_world->add_prefix("lv2_midi", "http://lv2plug.in/ns/ext/midi"); + world->rdf_world->add_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); + world->rdf_world->add_prefix("doap", "http://usefulinc.com/ns/doap#"); + world->rdf_world->add_prefix("dc", "http://purl.org/dc/elements/1.1/"); + + /* Run engine */ + if (args.engine_flag) { + engine_module = Ingen::Shared::load_module("ingen_engine"); + if (engine_module) { + Engine* (*new_engine)(Ingen::Shared::World* world) = NULL; + if (engine_module->get_symbol("new_engine", (void*&)new_engine)) { + engine = SharedPtr(new_engine(world)); + world->local_engine = engine; + /* Load queued (direct in-process) engine interface */ + if (args.gui_given) { + engine_interface = engine->new_queued_interface(); + world->engine = engine_interface; + } else { + engine->start_osc_driver(args.engine_port_arg); + engine->start_http_driver(args.engine_port_arg); + } + } else { + engine_module.reset(); + } + } else { + cerr << "Unable to load engine module." << endl; + } + } + + /* Load client library */ + if (args.load_given || args.gui_given) { + client_module = Ingen::Shared::load_module("ingen_client"); + if (!client_module) + cerr << "Unable to load client module." << endl; + } + + /* If we don't have a local engine interface (for GUI), use network */ + if (client_module && ! engine_interface) { + SharedPtr (*new_remote_interface)(const std::string&) = NULL; + + if (client_module->get_symbol("new_remote_interface", (void*&)new_remote_interface)) { + engine_interface = new_remote_interface(args.connect_arg); + } else { + cerr << "Unable to find symbol 'new_remote_interface' in " + "ingen_client module, aborting." << endl; + return -1; + } + } + + /* Activate the engine, if we have one */ + if (engine) { + engine->start_jack_driver(); + engine->activate(args.parallelism_arg); + } + + world->engine = engine_interface; + + /* Load a patch */ + if (args.load_given && engine_interface) { + + Glib::ustring engine_base = "/"; + if (args.path_given) + engine_base = string(args.path_arg) + "/"; + + bool found = false; + if (!world->serialisation_module) + world->serialisation_module = Ingen::Shared::load_module("ingen_serialisation"); + + Serialisation::Parser* (*new_parser)() = NULL; + + if (world->serialisation_module) + found = world->serialisation_module->get_symbol("new_parser", (void*&)new_parser); + + if (world->serialisation_module && found) { + SharedPtr parser(new_parser()); + + // Assumption: Containing ':' means URI, otherwise filename + string uri = args.load_arg; + if (uri.find(':') == string::npos) { + if (Glib::path_is_absolute(args.load_arg)) + uri = Glib::filename_to_uri(args.load_arg); + else + uri = Glib::filename_to_uri(Glib::build_filename( + Glib::get_current_dir(), args.load_arg)); + } + + + engine_interface->load_plugins(); + parser->parse_document(world, engine_interface.get(), uri, engine_base, uri); + + } else { + cerr << "Unable to load serialisation module, aborting." << endl; + return -1; + } + } + + + /* Run GUI */ + bool ran_gui = false; + if (args.gui_given) { + gui_module = Ingen::Shared::load_module("ingen_gui"); + void (*run)(int, char**, Ingen::Shared::World*); + bool found = gui_module->get_symbol("run", (void*&)run); + + if (found) { + ran_gui = true; + run(argc, argv, world); + } else { + cerr << "Unable to find GUI module, GUI not loaded." << endl; + } + } + + /* Run a script */ + if (args.run_given) { +#ifdef WITH_BINDINGS + bool (*run_script)(Ingen::Shared::World*, const char*) = NULL; + SharedPtr bindings_module = Ingen::Shared::load_module("ingen_bindings"); + if (!bindings_module) + cerr << Glib::Module::get_last_error() << endl; + + bindings_module->make_resident(); + + bool found = bindings_module->get_symbol("run", (void*&)(run_script)); + if (found) { + cerr << "WORLD: " << world << endl; + cerr << "ENGINE: " << world->engine << endl; + setenv("PYTHONPATH", "../../bindings", 1); + run_script(world, args.run_arg); + } else { + cerr << "FAILED: " << Glib::Module::get_last_error() << endl; + } +#else + cerr << "This build of ingen does not support scripting." << endl; +#endif + + /* Listen to OSC and do our own main thing. */ + } else if (engine && !ran_gui) { + signal(SIGINT, catch_int); + signal(SIGTERM, catch_int); + engine->main(); + } + + cout << "Exiting." << endl; + + if (engine) { + engine->deactivate(); + engine.reset(); + } + + engine_interface.reset(); + client_module.reset(); + world->serialisation_module.reset(); + gui_module.reset(); + engine_module.reset(); + + Ingen::Shared::destroy_world(); + + return 0; +} + -- cgit v1.2.1