summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-02-12 09:11:17 +0000
committerDavid Robillard <d@drobilla.net>2011-02-12 09:11:17 +0000
commit7dd771da2752cb3d012575869d905ba1f77697bf (patch)
tree825a750f4fb153fcf37303f8c79a73e7ce0c8e02
parent79f72150ed0b552962fbe4377208f2dea4db2cf1 (diff)
downloadlilv-7dd771da2752cb3d012575869d905ba1f77697bf.tar.gz
lilv-7dd771da2752cb3d012575869d905ba1f77697bf.tar.bz2
lilv-7dd771da2752cb3d012575869d905ba1f77697bf.zip
Add C++ and Python bindings.
git-svn-id: http://svn.drobilla.net/lad/trunk/slv2@2940 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--slv2/slv2.h2
-rw-r--r--slv2/slv2mm.hpp157
-rwxr-xr-xswig/python/lv2_list.py14
-rw-r--r--swig/slv2.i137
-rw-r--r--wscript26
5 files changed, 213 insertions, 123 deletions
diff --git a/slv2/slv2.h b/slv2/slv2.h
index 2817fac..45fe597 100644
--- a/slv2/slv2.h
+++ b/slv2/slv2.h
@@ -842,7 +842,7 @@ SLV2_API
void
slv2_port_get_range(SLV2Plugin plugin,
SLV2Port port,
- SLV2Value* def,
+ SLV2Value* deflt,
SLV2Value* min,
SLV2Value* max);
diff --git a/slv2/slv2mm.hpp b/slv2/slv2mm.hpp
new file mode 100644
index 0000000..f41c2f8
--- /dev/null
+++ b/slv2/slv2mm.hpp
@@ -0,0 +1,157 @@
+/* SLV2
+ * Copyright (C) 2007-2011 David Robillard <http://drobilla.net>
+ *
+ * This library 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.
+ *
+ * This library 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 more 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 SLV2_SLV2MM_HPP__
+#define SLV2_SLV2MM_HPP__
+
+#include "slv2/slv2.h"
+
+namespace SLV2 {
+
+const char* uri_to_path(const char* uri) { return slv2_uri_to_path(uri); }
+
+class Value {
+public:
+ inline Value(SLV2Value value) : me(value) {}
+ inline Value(const Value& copy) : me(slv2_value_duplicate(copy.me)) {}
+
+ inline ~Value() { slv2_value_free(me); }
+
+ inline bool equals(const Value& other) const {
+ return slv2_value_equals(me, other.me);
+ }
+
+ inline bool operator==(const Value& other) const { return equals(other); }
+
+ inline operator SLV2Value() const { return me; }
+
+#define VAL_WRAP0(RetType, name) \
+ inline RetType name () { return slv2_value_ ## name (me); }
+
+ VAL_WRAP0(char*, get_turtle_token);
+ VAL_WRAP0(bool, is_uri);
+ VAL_WRAP0(const char*, as_uri);
+ VAL_WRAP0(bool, is_blank);
+ VAL_WRAP0(const char*, as_blank);
+ VAL_WRAP0(bool, is_literal);
+ VAL_WRAP0(bool, is_string);
+ VAL_WRAP0(const char*, as_string);
+ VAL_WRAP0(bool, is_float);
+ VAL_WRAP0(float, as_float);
+ VAL_WRAP0(bool, is_int);
+ VAL_WRAP0(int, as_int);
+ VAL_WRAP0(bool, is_bool);
+ VAL_WRAP0(bool, as_bool);
+
+ SLV2Value me;
+};
+
+class Plugins {
+public:
+ inline Plugins(SLV2Plugins c_obj) : me(c_obj) {}
+
+ inline operator SLV2Plugins() const { return me; }
+
+ SLV2Plugins me;
+};
+
+class World {
+public:
+ inline World() : me(slv2_world_new()) {}
+
+ inline ~World() { /*slv2_world_free(me);*/ }
+
+#define WORLD_WRAP_VOID0(name) \
+ inline void name () { slv2_world_ ## name (me); }
+
+#define WORLD_WRAP0(RetType, name) \
+ inline RetType name () { return slv2_world_ ## name (me); }
+
+#define WORLD_WRAP1(RetType, name, T1, a1) \
+ inline RetType name (T1 a1) { return slv2_world_ ## name (me, a1); }
+
+#define WORLD_WRAP2(RetType, name, T1, a1, T2, a2) \
+ inline RetType name (T1 a1, T2 a2) { return slv2_world_ ## name (me, a1, a2); }
+
+ WORLD_WRAP2(void, set_option, const char*, uri, SLV2Value, value);
+ WORLD_WRAP_VOID0(free);
+ WORLD_WRAP_VOID0(load_all);
+ WORLD_WRAP1(void, load_bundle, SLV2Value, bundle_uri);
+ WORLD_WRAP0(SLV2PluginClass, get_plugin_class);
+ WORLD_WRAP0(SLV2PluginClasses, get_plugin_classes);
+ WORLD_WRAP0(Plugins, get_all_plugins);
+ // TODO: get_plugins_by_filter (takes a function parameter)
+
+ SLV2World me;
+};
+
+class Port {
+public:
+ inline Port(SLV2Port c_obj) : me(c_obj) {}
+
+ inline operator SLV2Port() const { return me; }
+
+ SLV2Port me;
+};
+
+class Plugin {
+public:
+ inline Plugin(SLV2Plugin c_obj) : me(c_obj) {}
+
+ inline operator SLV2Plugin() const { return me; }
+
+#define PLUGIN_WRAP0(RetType, name) \
+ inline RetType name () { return slv2_plugin_ ## name (me); }
+
+#define PLUGIN_WRAP1(RetType, name, T1, a1) \
+ inline RetType name (T1 a1) { return slv2_plugin_ ## name (me, a1); }
+
+#define PLUGIN_WRAP2(RetType, name, T1, a1, T2, a2) \
+ inline RetType name (T1 a1, T2 a2) { return slv2_plugin_ ## name (me, a1, a2); }
+
+ PLUGIN_WRAP0(bool, verify);
+ PLUGIN_WRAP0(Value, get_uri);
+ PLUGIN_WRAP0(Value, get_bundle_uri);
+ //PLUGIN_WRAP0(Values, get_data_uris);
+ PLUGIN_WRAP0(Value, get_library_uri);
+ PLUGIN_WRAP0(Value, get_name);
+ //PLUGIN_WRAP0(PluginClass, get_class);
+ //PLUGIN_WRAP1(Values, get_value, Value, predicate);
+ //PLUGIN_WRAP1(Values, get_value_by_qname, const char*, predicate);
+ //PLUGIN_WRAP2(Values, get_value_for_subject, Value, subject, Value, predicate);
+ PLUGIN_WRAP1(bool, has_feature, Value, feature_uri);
+ //PLUGIN_WRAP0(Values, get_supported_features);
+ //PLUGIN_WRAP0(Values, get_required_features);
+ //PLUGIN_WRAP0(Values, get_optional_features);
+ PLUGIN_WRAP0(uint32_t, get_num_ports);
+ // slv2_plugin_get_port_ranges_float
+ // slv2_plugin_get_num_ports_of_class
+ PLUGIN_WRAP0(bool, has_latency);
+ PLUGIN_WRAP0(uint32_t, get_latency_port_index);
+ PLUGIN_WRAP1(Port, get_port_by_index, uint32_t, index);
+ PLUGIN_WRAP1(Port, get_port_by_symbol, SLV2Value, symbol);
+ PLUGIN_WRAP0(Value, get_author_name);
+ PLUGIN_WRAP0(Value, get_author_email);
+ PLUGIN_WRAP0(Value, get_author_homepage);
+
+ SLV2Plugin me;
+};
+
+} /* namespace SLV2 */
+
+#endif /* SLV2_SLV2MM_HPP__ */
diff --git a/swig/python/lv2_list.py b/swig/python/lv2_list.py
index 685b62b..ef99cf2 100755
--- a/swig/python/lv2_list.py
+++ b/swig/python/lv2_list.py
@@ -1,8 +1,12 @@
#!/usr/bin/env python
-import slv2;
-w = slv2.World()
-w.load_all()
+import slv2
+
+world = slv2.World()
+world.load_all()
+
+plugins = world.get_all_plugins()
+
+for i in plugins:
+ print(i.get_uri().as_uri())
-for p in w.get_all_plugins():
- print p.uri(), "-", p.name()
diff --git a/swig/slv2.i b/swig/slv2.i
index 5bc9a5d..7d0c664 100644
--- a/swig/slv2.i
+++ b/swig/slv2.i
@@ -1,125 +1,30 @@
%module slv2
%{
-#include "slv2/plugin.h"
-#include "slv2/pluginclass.h"
-#include "slv2/pluginclasses.h"
-#include "slv2/plugininstance.h"
-#include "slv2/plugins.h"
-#include "slv2/port.h"
#include "slv2/slv2.h"
-#include "slv2/types.h"
-#include "slv2/value.h"
-#include "slv2/values.h"
-#include "slv2/world.h"
-typedef struct { SLV2World me; } World;
-typedef struct { SLV2World world; SLV2Plugins me; } Plugins;
-typedef struct { SLV2World world; SLV2Plugin me; } Plugin;
+#include "slv2/slv2mm.hpp"
%}
-
-%include "slv2/plugin.h"
-%include "slv2/pluginclass.h"
-%include "slv2/pluginclasses.h"
-%include "slv2/plugininstance.h"
-%include "slv2/plugins.h"
-%include "slv2/port.h"
%include "slv2/slv2.h"
-%include "slv2/types.h"
-%include "slv2/value.h"
-%include "slv2/values.h"
-%include "slv2/world.h"
-
-typedef struct { SLV2Plugin me; } Plugin;
-%extend Plugin {
- Plugin(SLV2Plugin p) {
- Plugin* ret = (Plugin*)malloc(sizeof(Plugin));
- ret->me = p;
- return ret;
- }
-
- ~Plugin() {
- /* FIXME: free SLV2Plugin here? */
- free($self);
- }
-
- char* name() {
- SLV2Value nm = slv2_plugin_get_name($self->me);
- char* ret = nm ? strdup((char*)slv2_value_as_string(nm)) : strdup("");
- slv2_value_free(nm);
- return ret;
- }
- const char* uri() {
- return strdup((char*)slv2_value_as_string(slv2_plugin_get_uri($self->me)));
- }
-};
-
-typedef struct { SLV2World world; SLV2Plugins me; } Plugins;
+%include "slv2/slv2mm.hpp"
+namespace SLV2 {
%extend Plugins {
- Plugins(SLV2World w, SLV2Plugins p) {
- Plugins* ret = (Plugins*)malloc(sizeof(Plugins));
- ret->world = w;
- ret->me = p;
- return ret;
- }
-
- ~Plugins() {
- slv2_plugins_free($self->world, $self->me);
- free($self);
- }
-
- inline unsigned size() const { return slv2_plugins_size($self->me); }
-
-#ifdef PYTHON
- Plugin* __getitem__(unsigned i) {
- if (i < slv2_plugins_size($self->me))
- return new_Plugin(slv2_plugins_get_at($self->me, i));
- else
- return NULL;
- }
-
- inline unsigned __len__() const { return slv2_plugins_size($self->me); }
-
%pythoncode %{
- def __iter__(self):
- class Iterator(object):
- def __init__(self, plugins):
- self.plugins = plugins
- self.iter = 0
-
- def next(self):
- if self.iter < self.plugins.size():
- self.iter += 1
- return Plugin(slv2_plugins_get_at(self.plugins.me, self.iter-1))
- else:
- raise StopIteration
-
- return Iterator(self)
+ def __iter__(self):
+ class Iterator(object):
+ def __init__(self, plugins):
+ self.plugins = plugins
+ self.index = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ self.index += 1
+ if self.index < slv2_plugins_size(self.plugins.me):
+ return Plugin(slv2_plugins_get_at(self.plugins.me, self.index))
+ else:
+ raise StopIteration
+
+ return Iterator(self)
%}
-#endif
-};
-
-typedef struct { SLV2World me; } World;
-%extend World {
- World() {
- World* ret = (World*)malloc(sizeof(World));
- ret->me = slv2_world_new();
- return ret;
- }
-
- ~World() {
- slv2_world_free($self->me);
- free($self);
- }
-
- void load_all() { slv2_world_load_all($self->me); }
- void load_bundle(const char* uri) {
- SLV2Value bundle_uri = slv2_value_new_uri($self->me, uri);
- slv2_world_load_bundle($self->me, bundle_uri);
- slv2_value_free(bundle_uri);
- }
-
- Plugins* get_all_plugins() {
- return new_Plugins($self->me, slv2_world_get_all_plugins($self->me));
- }
};
-
-
+}
diff --git a/wscript b/wscript
index a525526..5d09d38 100644
--- a/wscript
+++ b/wscript
@@ -1,5 +1,6 @@
#!/usr/bin/env python
import autowaf
+import os
import sys
import Options
@@ -60,6 +61,14 @@ def configure(conf):
autowaf.configure(conf)
autowaf.display_header('SLV2 Configuration')
conf.check_tool('compiler_cc')
+
+ try:
+ conf.load('swig python')
+ conf.check_python_headers()
+ autowaf.define(conf, 'SLV2_SWIG', 1);
+ except:
+ pass
+
autowaf.check_pkg(conf, 'lv2core', uselib_store='LV2CORE', mandatory=True)
autowaf.check_pkg(conf, 'glib-2.0', uselib_store='GLIB',
atleast_version='2.0.0', mandatory=True)
@@ -126,9 +135,10 @@ def configure(conf):
autowaf.display_msg(conf, "Utilities", str(conf.env['BUILD_UTILS'] == 1))
autowaf.display_msg(conf, "Jack clients", str(conf.env['USE_JACK'] == 1))
autowaf.display_msg(conf, "Unit tests", str(conf.env['BUILD_TESTS']))
- autowaf.display_msg(conf, "Dynamic Manifest Support", str(conf.env['SLV2_DYN_MANIFEST'] == 1))
+ autowaf.display_msg(conf, "Dynamic manifest support", str(conf.env['SLV2_DYN_MANIFEST'] == 1))
autowaf.display_msg(conf, "Default LV2_PATH", str(conf.env['SLV2_DEFAULT_LV2_PATH']))
autowaf.display_msg(conf, "UI support", str(conf.env['SLV2_WITH_UI'] == 1))
+ autowaf.display_msg(conf, "Python bindings", str(conf.env['SLV2_SWIG'] == 1))
print
@@ -229,9 +239,23 @@ def build(bld):
bld.install_as(
'/etc/bash_completion.d/slv2', 'utils/slv2.bash_completion')
+ if bld.env['SLV2_SWIG']:
+ # Python Wrapper
+ bld(
+ features = 'cxx cxxshlib pyext',
+ source = 'swig/slv2.i',
+ target = 'swig/_slv2',
+ swig_flags = '-c++ -python -Wall -I.. -lslv2 -features autodoc=1',
+ vnum = SLV2_LIB_VERSION,
+ use = 'libslv2')
+
bld.add_post_fun(autowaf.run_ldconfig)
def test(ctx):
autowaf.pre_test(ctx, APPNAME)
autowaf.run_tests(ctx, APPNAME, tests.split(), dirs=['./src','./test'])
autowaf.post_test(ctx, APPNAME)
+
+def wrap(ctx):
+ os.chdir(out)
+ os.system('swig -DPYTHON -Wall -python -I/usr/include -I/usr/local/include -I.. -o slv2_python.c -oh slv2_python.h ../swig/slv2.i')