summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-07-31 23:17:02 +0000
committerDavid Robillard <d@drobilla.net>2007-07-31 23:17:02 +0000
commit22395ab7d817dec53e2c2fff07de6d88db70492e (patch)
treee1b4d749e96bfe31f1ba545ad979ca4bbe8807c5
parent012890277d8c3124bc8dd1df20b8e016c8d6d811 (diff)
downloadingen-22395ab7d817dec53e2c2fff07de6d88db70492e.tar.gz
ingen-22395ab7d817dec53e2c2fff07de6d88db70492e.tar.bz2
ingen-22395ab7d817dec53e2c2fff07de6d88db70492e.zip
Functional engine Python bindings (e.g. ingen -e -r patchomatic.py).
Rename window nitpick fix from Andrew Greenwood. git-svn-id: http://svn.drobilla.net/lad/ingen@663 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/bindings/Makefile.am11
-rw-r--r--src/bindings/ingen.i28
-rwxr-xr-xsrc/bindings/test_ingen.py16
-rw-r--r--src/libs/gui/RenameWindow.cpp3
-rw-r--r--src/libs/module/Module.cpp5
-rw-r--r--src/libs/module/module.cpp18
-rw-r--r--src/libs/module/module.h9
-rw-r--r--src/progs/ingen/Makefile.am2
-rw-r--r--src/progs/ingen/cmdline.c45
-rw-r--r--src/progs/ingen/cmdline.ggo1
-rw-r--r--src/progs/ingen/cmdline.h6
-rw-r--r--src/progs/ingen/main.cpp32
-rwxr-xr-xsrc/set_dev_environment.sh2
13 files changed, 139 insertions, 39 deletions
diff --git a/src/bindings/Makefile.am b/src/bindings/Makefile.am
index 083cb5a6..48a5ad4f 100644
--- a/src/bindings/Makefile.am
+++ b/src/bindings/Makefile.am
@@ -1,22 +1,22 @@
FLAGS = @RAUL_CFLAGS@ @GLIBMM_CFLAGS@ -I$(top_srcdir)/ingen/src/common
-LIBS = @RAUL_LIBS@ @GLIBMM_LIBS@
+LIBS = @RAUL_LIBS@ @GLIBMM_LIBS@ -lpython2.4
AM_CXXFLAGS = -I/usr/include/python2.4 $(FLAGS)
-EXTRA_DIST = ingen.i ingen_test.py
+EXTRA_DIST = ingen.i test_ingen.py
if WITH_SWIG
bindingsdir = $(libdir)/ingen
bindings_LTLIBRARIES = libingen_bindings.la
libingen_bindings_la_LDFLAGS = -no-undefined -module -avoid-version
-libingen_bindings_la_LIBADD = @RAUL_LIBS@ @GLIBMM_LIBS@ ../libs/module/libingen_module.la
-libingen_bindings_la_SOURCES = ingen_wrap.cxx
+libingen_bindings_la_LIBADD = @RAUL_LIBS@ @GLIBMM_LIBS@ #../libs/module/libingen_module.la
+libingen_bindings_la_SOURCES = ingen_wrap.cxx ingen_bindings.cpp ingen_bindings.hpp
swig: ingen.i
swig -c++ -Wall $(FLAGS) -python ingen.i
ingen_wrap.cxx: swig
-libingen_bindings_la: swig ingen_wrap.cxx
+libingen_bindings_la: swig ingen_wrap.cxx ingen_bindings.cpp
all-local: swig
ln -sf .libs/libingen_bindings.so _ingen.so
@@ -28,3 +28,4 @@ clean-local:
rm -f *.cxx
rm -f *.so
rm -f *.o
+ rm -f ingen.py
diff --git a/src/bindings/ingen.i b/src/bindings/ingen.i
index e9a13dc3..dbf5ab10 100644
--- a/src/bindings/ingen.i
+++ b/src/bindings/ingen.i
@@ -4,16 +4,12 @@
#include "../common/interface/ClientInterface.hpp"
#include "../common/interface/EngineInterface.hpp"
#include "../libs/module/World.hpp"
-#include "../libs/module/module.h"
+/*#include "../libs/module/module.h"*/
+#include "ingen_bindings.hpp"
namespace Ingen { namespace Shared {
class World;
} }
-typedef Ingen::Shared::World World;
-/*struct World {
- World() { me = Ingen::Shared::get_world(); }
- Ingen::Shared::World* me;
-};*/
%}
/*%ignore Ingen::Shared::EngineInterface;*/
@@ -22,18 +18,28 @@ typedef Ingen::Shared::World World;
%include "../common/interface/EngineInterface.hpp"
/*%include "../libs/module/World.hpp"
%include "../libs/module/module.h"*/
-%include "../libs/module/module.h"
+%include "../libs/module/World.hpp"
+//%include "../libs/module/module.h"
+%include "ingen_bindings.hpp"
using namespace Ingen::Shared;
namespace Ingen { namespace Shared {
class World;
} }
-%typedef Ingen::Shared::World World;
-/*struct World {};*/
+typedef Ingen::Shared::World World;
+namespace Ingen { namespace Shared {
%extend World {
- World() { return Ingen::Shared::get_world(); }
+ World() {
+ if (!Ingen::Shared::ingen_world) {
+ fprintf(stderr, "ERROR: World uninitialized (running within Ingen?)\n");
+ abort();
+ } else {
+ return Ingen::Shared::ingen_world;
+ }
+ }
/*SLV2World slv2() { return $self->me->slv2_world; }*/
+};
+} }
/*SharedPtr<Ingen::Shared::EngineInterface> engine() { return $self->me->engine; }*/
-};
diff --git a/src/bindings/test_ingen.py b/src/bindings/test_ingen.py
index 93d524c6..794e51ba 100755
--- a/src/bindings/test_ingen.py
+++ b/src/bindings/test_ingen.py
@@ -1,8 +1,18 @@
#!/usr/bin/env python
import ingen
+import time
world = ingen.World()
-#w = ingen.get_world()
-print world
e = world.engine
-print e
+
+e.activate()
+e.create_port("/I", "ingen:midi", False)
+e.create_port("/made", "ingen:audio", False)
+e.create_port("/these", "ingen:audio", False)
+e.create_port("/in", "ingen:midi", True)
+e.create_port("/a", "ingen:audio", True)
+e.create_port("/script", "ingen:audio", True)
+
+while True:
+ time.sleep(1)
+
diff --git a/src/libs/gui/RenameWindow.cpp b/src/libs/gui/RenameWindow.cpp
index 6567799e..d5ef1b24 100644
--- a/src/libs/gui/RenameWindow.cpp
+++ b/src/libs/gui/RenameWindow.cpp
@@ -74,7 +74,8 @@ RenameWindow::name_changed()
} else if (!Path::is_valid_name(name)) {
_message_label->set_text("Name contains invalid characters");
_ok_button->property_sensitive() = false;
- } else if (App::instance().store()->object(_object->parent()->path().base() + name)) {
+ } else if ((App::instance().store()->object(_object->parent()->path().base() + name)) &&
+ (name != _object->path().name())) {
_message_label->set_text("An object already exists with that name.");
_ok_button->property_sensitive() = false;
} else if (name.length() == 0) {
diff --git a/src/libs/module/Module.cpp b/src/libs/module/Module.cpp
index 9aacd0cc..e5a137e7 100644
--- a/src/libs/module/Module.cpp
+++ b/src/libs/module/Module.cpp
@@ -56,7 +56,7 @@ load_module(const string& name)
string filename = Glib::Module::build_path(dir, name);
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) {
return SharedPtr<Glib::Module>(module);
@@ -70,8 +70,7 @@ load_module(const string& name)
// Try default directory if not found
module = new Glib::Module(
- Glib::Module::build_path(INGEN_MODULE_DIR, name),
- Glib::MODULE_BIND_LAZY);
+ Glib::Module::build_path(INGEN_MODULE_DIR, name));
if (*module) {
return SharedPtr<Glib::Module>(module);
diff --git a/src/libs/module/module.cpp b/src/libs/module/module.cpp
index 68ddc2b5..ab73c09e 100644
--- a/src/libs/module/module.cpp
+++ b/src/libs/module/module.cpp
@@ -15,6 +15,7 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <iostream>
#include "module.h"
#include "World.hpp"
@@ -23,15 +24,25 @@
#include <slv2/slv2.h>
#endif
+using namespace std;
+
namespace Ingen {
namespace Shared {
-World* world = NULL;
+static World* world = NULL;
World*
get_world()
{
+ static World* world = NULL;
+
+ if (!&world) {
+ cerr << "ERROR: Ingen::Shared::world undefined." << endl;
+ return NULL;
+ }
+
if (!world) {
+ cerr << "NEW WORLD\n" << endl;
world = new World();
world->rdf_world = new Raul::RDF::World();
#ifdef HAVE_SLV2
@@ -46,6 +57,11 @@ get_world()
void
destroy_world()
{
+ if (!&world) {
+ cerr << "ERROR: Ingen::Shared::world undefined." << endl;
+ return;
+ }
+
if (world) {
#ifdef HAVE_SLV2
slv2_world_free(world->slv2_world);
diff --git a/src/libs/module/module.h b/src/libs/module/module.h
index 48bdeedf..4fe0d4cc 100644
--- a/src/libs/module/module.h
+++ b/src/libs/module/module.h
@@ -25,13 +25,8 @@
namespace Ingen {
namespace Shared {
-extern "C" {
-
- World* get_world();
- void destroy_world();
-
-}
-
+World* get_world();
+void destroy_world();
} // namesace Shared
} // namespace Ingen
diff --git a/src/progs/ingen/Makefile.am b/src/progs/ingen/Makefile.am
index ff408ab2..2a471c73 100644
--- a/src/progs/ingen/Makefile.am
+++ b/src/progs/ingen/Makefile.am
@@ -1,4 +1,4 @@
-AM_CXXFLAGS = @GTHREAD_CFLAGS@ @GLIBMM_CFLAGS@ @RAUL_CFLAGS@ @SLV2_CFLAGS@ -I$(top_srcdir)/ingen/src/common -I$(top_srcdir)/ingen/src/libs -DINGEN_MODULE_DIR=\"$(libdir)/ingen\"
+AM_CXXFLAGS = @GTHREAD_CFLAGS@ @GLIBMM_CFLAGS@ @RAUL_CFLAGS@ @SLV2_CFLAGS@ -I$(top_srcdir)/ingen/src/common -I$(top_srcdir)/ingen/src/libs -I$(top_srcdir)/ingen/src -DINGEN_MODULE_DIR=\"$(libdir)/ingen\"
MAINTAINERCLEANFILES = Makefile.in
diff --git a/src/progs/ingen/cmdline.c b/src/progs/ingen/cmdline.c
index 6c37d78e..462c6a3e 100644
--- a/src/progs/ingen/cmdline.c
+++ b/src/progs/ingen/cmdline.c
@@ -1,5 +1,5 @@
/*
- File autogenerated by gengetopt version 2.19.1
+ File autogenerated by gengetopt version 2.20
generated with the following command:
gengetopt
@@ -37,6 +37,7 @@ const char *gengetopt_args_info_help[] = {
" -C, --client-port=INT Client OSC port",
" -l, --load=STRING Load patch",
" -p, --path=STRING Target path for loaded patch",
+ " -r, --run=STRING Run script",
0
};
@@ -64,6 +65,7 @@ void clear_given (struct gengetopt_args_info *args_info)
args_info->client_port_given = 0 ;
args_info->load_given = 0 ;
args_info->path_given = 0 ;
+ args_info->run_given = 0 ;
}
static
@@ -80,6 +82,8 @@ void clear_args (struct gengetopt_args_info *args_info)
args_info->load_orig = NULL;
args_info->path_arg = NULL;
args_info->path_orig = NULL;
+ args_info->run_arg = NULL;
+ args_info->run_orig = NULL;
}
@@ -95,6 +99,7 @@ void init_args_info(struct gengetopt_args_info *args_info)
args_info->client_port_help = gengetopt_args_info_help[6] ;
args_info->load_help = gengetopt_args_info_help[7] ;
args_info->path_help = gengetopt_args_info_help[8] ;
+ args_info->run_help = gengetopt_args_info_help[9] ;
}
@@ -174,6 +179,16 @@ cmdline_parser_release (struct gengetopt_args_info *args_info)
free (args_info->path_orig); /* free previous argument */
args_info->path_orig = 0;
}
+ if (args_info->run_arg)
+ {
+ free (args_info->run_arg); /* free previous argument */
+ args_info->run_arg = 0;
+ }
+ if (args_info->run_orig)
+ {
+ free (args_info->run_orig); /* free previous argument */
+ args_info->run_orig = 0;
+ }
clear_given (args_info);
}
@@ -239,6 +254,13 @@ cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_
fprintf(outfile, "%s\n", "path");
}
}
+ if (args_info->run_given) {
+ if (args_info->run_orig) {
+ fprintf(outfile, "%s=\"%s\"\n", "run", args_info->run_orig);
+ } else {
+ fprintf(outfile, "%s\n", "run");
+ }
+ }
fclose (outfile);
@@ -330,11 +352,12 @@ cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_inf
{ "client-port", 1, NULL, 'C' },
{ "load", 1, NULL, 'l' },
{ "path", 1, NULL, 'p' },
+ { "run", 1, NULL, 'r' },
{ NULL, 0, NULL, 0 }
};
stop_char = 0;
- c = getopt_long (argc, argv, "hVeE:c:gC:l:p:", long_options, &option_index);
+ c = getopt_long (argc, argv, "hVeE:c:gC:l:p:r:", long_options, &option_index);
if (c == -1) break; /* Exit from `while (1)' loop. */
@@ -470,6 +493,24 @@ cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_inf
args_info->path_orig = gengetopt_strdup (optarg);
break;
+ case 'r': /* Run script. */
+ if (local_args_info.run_given)
+ {
+ fprintf (stderr, "%s: `--run' (`-r') option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
+ goto failure;
+ }
+ if (args_info->run_given && ! override)
+ continue;
+ local_args_info.run_given = 1;
+ args_info->run_given = 1;
+ if (args_info->run_arg)
+ free (args_info->run_arg); /* free previous string */
+ args_info->run_arg = gengetopt_strdup (optarg);
+ if (args_info->run_orig)
+ free (args_info->run_orig); /* free previous string */
+ args_info->run_orig = gengetopt_strdup (optarg);
+ break;
+
case 0: /* Long option with no short option */
case '?': /* Invalid option. */
diff --git a/src/progs/ingen/cmdline.ggo b/src/progs/ingen/cmdline.ggo
index 45eae5b0..f844fa2d 100644
--- a/src/progs/ingen/cmdline.ggo
+++ b/src/progs/ingen/cmdline.ggo
@@ -16,4 +16,5 @@ option "gui" g "Launch the GTK graphical interface" flag on
option "client-port" C "Client OSC port" int no
option "load" l "Load patch" string no
option "path" p "Target path for loaded patch" string no
+option "run" r "Run script" string no
diff --git a/src/progs/ingen/cmdline.h b/src/progs/ingen/cmdline.h
index 6f1f9259..d96f5adb 100644
--- a/src/progs/ingen/cmdline.h
+++ b/src/progs/ingen/cmdline.h
@@ -1,6 +1,6 @@
/* cmdline.h */
-/* File autogenerated by gengetopt version 2.19.1 */
+/* File autogenerated by gengetopt version 2.20 */
#ifndef CMDLINE_H
#define CMDLINE_H
@@ -45,6 +45,9 @@ struct gengetopt_args_info
char * path_arg; /* Target path for loaded patch. */
char * path_orig; /* Target path for loaded patch original value given at command line. */
const char *path_help; /* Target path for loaded patch help description. */
+ char * run_arg; /* Run script. */
+ char * run_orig; /* Run script original value given at command line. */
+ const char *run_help; /* Run script help description. */
int help_given ; /* Whether help was given. */
int version_given ; /* Whether version was given. */
@@ -55,6 +58,7 @@ struct gengetopt_args_info
int client_port_given ; /* Whether client-port was given. */
int load_given ; /* Whether load was given. */
int path_given ; /* Whether path was given. */
+ int run_given ; /* Whether run was given. */
} ;
diff --git a/src/progs/ingen/main.cpp b/src/progs/ingen/main.cpp
index eff265c6..145ec463 100644
--- a/src/progs/ingen/main.cpp
+++ b/src/progs/ingen/main.cpp
@@ -19,8 +19,10 @@
#include <iostream>
#include <string>
#include <signal.h>
+#include <dlfcn.h>
#include <glibmm/convert.h>
#include <glibmm/miscutils.h>
+#include <glibmm/spawn.h>
#include <boost/optional.hpp>
#include <glibmm/thread.h>
#include <raul/Path.hpp>
@@ -30,13 +32,14 @@
#include "engine/Engine.hpp"
#include "engine/QueuedEngineInterface.hpp"
#include "serialisation/Loader.hpp"
+#include "bindings/ingen_bindings.hpp"
#include "cmdline.h"
using namespace std;
using namespace Ingen;
-SharedPtr<Engine> engine;
+SharedPtr<Engine> engine;
void
catch_int(int)
@@ -48,7 +51,6 @@ catch_int(int)
engine->quit();
}
-
int
main(int argc, char** argv)
{
@@ -69,6 +71,7 @@ main(int argc, char** argv)
SharedPtr<Glib::Module> engine_module;
SharedPtr<Glib::Module> client_module;
SharedPtr<Glib::Module> gui_module;
+ SharedPtr<Glib::Module> bindings_module;
SharedPtr<Shared::EngineInterface> engine_interface;
@@ -118,8 +121,9 @@ main(int argc, char** argv)
}
/* Load queued (direct in-process) engine interface */
- if (engine && !engine_interface && (args.load_given || args.gui_given))
+ if (engine && !engine_interface && (args.load_given || args.gui_given || args.run_given)) {
engine_interface = engine->new_queued_interface();
+ }
if (engine && engine_interface) {
@@ -130,6 +134,8 @@ main(int argc, char** argv)
engine->activate();
}
+
+ world->engine = engine_interface.get();
/* Load a patch */
if (args.load_given && engine_interface) {
@@ -193,6 +199,26 @@ main(int argc, char** argv)
}
}
+ /* Run a script */
+ if (args.run_given) {
+ bool (*run_script)(Ingen::Shared::World*, const char*) = NULL;
+ SharedPtr<Glib::Module> 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;
+ }
+ }
+
/* Didn't run the GUI, listen to OSC and do our own main thing. */
if (engine && !ran_gui) {
diff --git a/src/set_dev_environment.sh b/src/set_dev_environment.sh
index c06ed450..63031123 100755
--- a/src/set_dev_environment.sh
+++ b/src/set_dev_environment.sh
@@ -4,5 +4,5 @@
# environment so dynamic modules in the source tree will be found and the
# executables can be run directly, or in gdb/valgrind/etc.
-export INGEN_MODULE_PATH="`pwd`/libs/engine/.libs:`pwd`/libs/serialisation/.libs:`pwd`/libs/gui/.libs:`pwd`/libs/client/.libs"
+export INGEN_MODULE_PATH="`pwd`/libs/engine/.libs:`pwd`/libs/serialisation/.libs:`pwd`/libs/gui/.libs:`pwd`/libs/client/.libs:`pwd`/bindings/.libs"
export INGEN_GLADE_PATH="`pwd`/libs/gui/ingen_gui.glade"