aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Peach <mrpeach@users.sourceforge.net>2012-02-01 20:20:44 +0000
committerIOhannes m zmölnig <zmoelnig@iem.at>2015-10-14 14:28:31 +0200
commit607d389cf44a877b7de7b55a4800efe0469848de (patch)
treec17c4703a9aaa4914952ee4fc2214c12314f4612
parentc001c1b19cf46b5db0c7abfe3d92aad0f49282b0 (diff)
Editor will open script for pdluax and pdlua objects, added function prototypes in pdlua.c, grouped globals together.
svn path=/trunk/externals/loaders/pdlua/; revision=15932
-rw-r--r--src/pd.lua40
-rw-r--r--src/pdlua.c211
2 files changed, 189 insertions, 62 deletions
diff --git a/src/pd.lua b/src/pd.lua
index 311330d..7ad18e9 100644
--- a/src/pd.lua
+++ b/src/pd.lua
@@ -1,6 +1,7 @@
--[[
pdlua -- a Lua embedding for Pd
Copyright (C) 2007,2008 Claude Heiland-Allen <claudiusmaximus@goto10.org>
+Copyright (C) 2012 Martin Peach martin.peach@sympatico.ca
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -92,6 +93,7 @@ end
-- prototypical OO system
pd.Prototype = { }
+
function pd.Prototype:new(o)
o = o or {}
setmetatable(o, self)
@@ -99,9 +101,9 @@ function pd.Prototype:new(o)
return o
end
-
-- clocks
pd.Clock = pd.Prototype:new()
+
function pd.Clock:register(object, method)
if nil ~= object then
if nil ~= object._object then
@@ -114,11 +116,13 @@ function pd.Clock:register(object, method)
end
return nil
end
+
function pd.Clock:destruct()
pd._clocks[self._clock] = nil
pd._clockfree(self._clock)
self._clock = nil
end
+
function pd.Clock:dispatch()
local m = self._target[self._method]
if type(m) == "function" then
@@ -130,18 +134,22 @@ function pd.Clock:dispatch()
)
end
end
+
function pd.Clock:set(systime)
pd._clockset(self._clock, systime)
end
+
function pd.Clock:delay(delaytime)
pd._clockdelay(self._clock, delaytime)
end
+
function pd.Clock:unset()
pd._clockunset(self._clock)
end
-- tables
pd.Table = pd.Prototype:new()
+
function pd.Table:sync(name)
self.name = name
self._length, self._array = pd._getarray(name)
@@ -151,10 +159,12 @@ function pd.Table:sync(name)
return self
end
end
+
function pd.Table:destruct()
self._length = -3
self._array = nil
end
+
function pd.Table:get(i)
if type(i) == "number" and 0 <= i and i < self._length then
return pd._readarray(self._length, self._array, i)
@@ -162,6 +172,7 @@ function pd.Table:get(i)
return nil
end
end
+
function pd.Table:set(i, f)
if type(i) == "number" and type(f) == "number" and 0 <= i and i < self._length then
return pd._writearray(self._length, self._array, i, f)
@@ -169,6 +180,7 @@ function pd.Table:set(i, f)
return nil
end
end
+
function pd.Table:length()
if self._length >= 0 then
return self._length
@@ -176,6 +188,7 @@ function pd.Table:length()
return nil
end
end
+
function pd.Table:redraw()
pd._redrawarray(self.name)
end
@@ -186,7 +199,9 @@ function pd._receivedispatch(receive, sel, atoms)
pd._receives[receive]:dispatch(sel, atoms)
end
end
+
pd.Receive = pd.Prototype:new()
+
function pd.Receive:register(object, name, method)
if nil ~= object then
if nil ~= object._object then
@@ -200,6 +215,7 @@ function pd.Receive:register(object, name, method)
end
return nil
end
+
function pd.Receive:destruct()
pd._receives[self._receive] = nil
pd._receivefree(self._receive)
@@ -208,12 +224,14 @@ function pd.Receive:destruct()
self._target = nil
self._method = nil
end
+
function pd.Receive:dispatch(sel, atoms)
self._target[self._method](self._target, sel, atoms)
end
-- patchable objects
pd.Class = pd.Prototype:new()
+
function pd.Class:register(name)
if nil ~= pd._classes[name] then -- already registered
return pd._classes[name] -- return existing
@@ -229,6 +247,7 @@ function pd.Class:register(name)
return self -- return new
end
end
+
function pd.Class:construct(sel, atoms)
self._object = pd._create(self._class)
self.inlets = 0
@@ -242,11 +261,13 @@ function pd.Class:construct(sel, atoms)
return nil
end
end
+
function pd.Class:destruct()
pd._objects[self] = nil
self:finalize()
pd._destroy(self._object)
end
+
function pd.Class:dispatch(inlet, sel, atoms)
local m = self["in_" .. inlet .. "_" .. sel]
if type(m) == "function" then
@@ -280,41 +301,52 @@ function pd.Class:dispatch(inlet, sel, atoms)
" of Lua object `" .. self._name .. "'"
)
end
+
function pd.Class:outlet(outlet, sel, atoms)
pd._outlet(self._object, outlet, sel, atoms)
end
+
function pd.Class:initialize(sel, atoms) end
+
function pd.Class:postinitialize() end
+
function pd.Class:finalize() end
+
function pd.Class:dofile(file)
return pd._dofile(self._object, file)
end
+
function pd.Class:error(msg)
pd._error(self._object, msg)
end
+
function pd.Class:whoami()
return self._scriptname or self._name
end
+
function pd.Class:get_class() -- accessor for t_class*
return self._class or nil
end
local lua = pd.Class:new():register("pdlua") -- global controls (the [pdlua] object only)
+
function lua:initialize(sel, atoms)
self.inlets = 1
self.outlets = 0 -- FIXME: might be nice to have errors go here?
return true
end
+
function lua:in_1_load(atoms) -- execute a script
self:dofile(atoms[1])
end
local luax = pd.Class:new():register("pdluax") -- classless lua externals (like [pdluax foo])
+
function luax:initialize(sel, atoms) -- motivation: pd-list 2007-09-23
- local f = self:dofile(atoms[1] .. ".pd_luax")
+ local f, pathname = self:dofile(atoms[1] .. ".pd_luax")
if nil ~= f then
- self._scriptname = atoms[1] .. ".pd_luax" -- mrpeach 20111027
+ self._scriptname = pathname .. '/' .. atoms[1] .. ".pd_luax" -- mrpeach 20120201
local atomstail = { } -- munge for better lua<->luax compatibility
for i,_ in ipairs(atoms) do
if i > 1 then
@@ -326,3 +358,5 @@ function luax:initialize(sel, atoms) -- motivation: pd-list 2007-09-23
return false -- error message already output by dofile()
end
end
+
+-- fin pd.lua
diff --git a/src/pdlua.c b/src/pdlua.c
index 09e264c..0b946ca 100644
--- a/src/pdlua.c
+++ b/src/pdlua.c
@@ -82,6 +82,7 @@
/* If defined, PDLUA_DEBUG lets pdlua post a lot of text */
//#define PDLUA_DEBUG
+
/** Global Lua interpreter state, needed in the constructor. */
static lua_State *L;
@@ -92,6 +93,150 @@ typedef struct pdlua_readerdata
char buffer[MAXPDSTRING]; /**< Buffer to read into. */
} t_pdlua_readerdata;
+/** Pd object data. */
+typedef struct pdlua
+{
+ t_object pd; /**< We are a Pd object. */
+ int inlets; /**< Number of inlets. */
+ struct pdlua_proxyinlet *in; /**< The inlets themselves. */
+ int outlets; /**< Number of outlets. */
+ t_outlet **out; /**< The outlets themselves. */
+ t_canvas *canvas; /**< The canvas that the object was created on. */
+} t_pdlua;
+
+/** Proxy inlet object data. */
+typedef struct pdlua_proxyinlet
+{
+ t_pd pd; /**< Minimal Pd object. */
+ struct pdlua *owner; /**< The owning object to forward inlet messages to. */
+ unsigned int id; /**< The number of this inlet. */
+} t_pdlua_proxyinlet;
+
+/** Proxy receive object data. */
+typedef struct pdlua_proxyreceive
+{
+ t_pd pd; /**< Minimal Pd object. */
+ struct pdlua *owner; /**< The owning object to forward received messages to. */
+ t_symbol *name; /**< The receive-symbol to bind to. */
+} t_pdlua_proxyreceive;
+
+/** Proxy clock object data. */
+typedef struct pdlua_proxyclock
+{
+ t_pd pd; /**< Minimal Pd object. */
+ struct pdlua *owner; /**< Object to forward messages to. */
+ t_clock *clock; /** Pd clock to use. */
+} t_pdlua_proxyclock;
+/* prototypes*/
+
+static const char *pdlua_reader (lua_State *L, void *rr, size_t *size);
+/** Proxy inlet 'anything' method. */
+static void pdlua_proxyinlet_anything (t_pdlua_proxyinlet *p, t_symbol *s, int argc, t_atom *argv);
+/** Proxy inlet initialization. */
+static void pdlua_proxyinlet_init (t_pdlua_proxyinlet *p, struct pdlua *owner, unsigned int id);
+/** Register the proxy inlet class with Pd. */
+static void pdlua_proxyinlet_setup (void);
+/** Proxy receive 'anything' method. */
+static void pdlua_proxyreceive_anything (t_pdlua_proxyreceive *r, t_symbol *s, int argc, t_atom *argv);
+/** Proxy receive allocation and initialization. */
+static t_pdlua_proxyreceive *pdlua_proxyreceive_new (struct pdlua *owner, t_symbol *name);
+/** Proxy receive cleanup and deallocation. */
+static void pdlua_proxyreceive_free (t_pdlua_proxyreceive *r /**< The proxy receive to free. */);
+/** Register the proxy receive class with Pd. */
+static void pdlua_proxyreceive_setup (void);
+/** Proxy clock 'bang' method. */
+static void pdlua_proxyclock_bang (t_pdlua_proxyclock *c);
+/** Proxy clock allocation and initialization. */
+static t_pdlua_proxyclock *pdlua_proxyclock_new (struct pdlua *owner);
+/** Register the proxy clock class with Pd. */
+static void pdlua_proxyclock_setup (void);
+/** Dump an array of atoms into a Lua table. */
+static void pdlua_pushatomtable (int argc, t_atom *argv);
+/** Pd object constructor. */
+static t_pdlua *pdlua_new (t_symbol *s, int argc, t_atom *argv);
+/** Pd object destructor. */
+static void pdlua_free (t_pdlua *o );
+/** a handler for the open item in the right-click menu (mrpeach 20111025) */
+/** Here we find the lua code for the object and open it in an editor */
+static void pdlua_menu_open (t_pdlua *o);
+/** Lua class registration. This is equivalent to the "setup" method for an ordinary Pd class */
+static int pdlua_class_new (lua_State *L);
+/** Lua object creation. */
+static int pdlua_object_new (lua_State *L);
+/** Lua object inlet creation. */
+static int pdlua_object_createinlets (lua_State *L);
+/** Lua object outlet creation. */
+static int pdlua_object_createoutlets (lua_State *L);
+/** Lua object receive creation. */
+static int pdlua_receive_new (lua_State *L);
+/** Lua object receive destruction. */
+static int pdlua_receive_free (lua_State *L);
+/** Lua object clock creation. */
+static int pdlua_clock_new (lua_State *L);
+/** Lua proxy clock delay. */
+static int pdlua_clock_delay (lua_State *L);
+/** Lua proxy clock set. */
+static int pdlua_clock_set (lua_State *L);
+/** Lua proxy clock unset. */
+static int pdlua_clock_unset (lua_State *L);
+/** Lua proxy clock destruction. */
+static int pdlua_clock_free (lua_State *L);
+/** Lua object destruction. */
+static int pdlua_object_free (lua_State *L);
+/** Dispatch Pd inlet messages to Lua objects. */
+static void pdlua_dispatch (t_pdlua *o, unsigned int inlet, t_symbol *s, int argc, t_atom *argv);
+/** Dispatch Pd receive messages to Lua objects. */
+static void pdlua_receivedispatch (t_pdlua_proxyreceive *r, t_symbol *s, int argc, t_atom *argv);
+/** Dispatch Pd clock messages to Lua objects. */
+static void pdlua_clockdispatch(t_pdlua_proxyclock *clock);
+/** Convert a Lua table into a Pd atom array. */
+static t_atom *pdlua_popatomtable (lua_State *L, int *count, t_pdlua *o);
+/** Send a message from a Lua object outlet. */
+static int pdlua_outlet (lua_State *L);
+/** Send a message from a Lua object to a Pd receiver. */
+static int pdlua_send (lua_State *L);
+/** Set a [value] object's value. */
+static int pdlua_setvalue (lua_State *L);
+/** Get a [value] object's value. */
+static int pdlua_getvalue (lua_State *L);
+/** Get a [table] object's array. */
+static int pdlua_getarray (lua_State *L);
+/** Read from a [table] object's array. */
+static int pdlua_readarray (lua_State *L);
+/** Write to a [table] object's array. */
+static int pdlua_writearray (lua_State *L);
+/** Redraw a [table] object's graph. */
+static int pdlua_redrawarray (lua_State *L);
+/** Post to Pd's console. */
+static int pdlua_post (lua_State *L);
+/** Report an error from a Lua object to Pd's console. */
+static int pdlua_error (lua_State *L);
+static void pdlua_setrequirepath (lua_State *L, const char *path);
+static void pdlua_clearrequirepath (lua_State *L);
+/** Run a Lua script using Pd's path. */
+static int pdlua_dofile (lua_State *L);
+/** Initialize the pd API for Lua. */
+static void pdlua_init (lua_State *L);
+/** Pd loader hook for loading and executing Lua scripts. */
+static int pdlua_loader (t_canvas *canvas, char *name);
+/** Start the Lua runtime and register our loader hook. */
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+void pdlua_setup (void);
+/* end prototypes*/
+
+/* globals */
+struct pdlua_proxyinlet;
+struct pdlua_proxyreceive;
+struct pdlua_proxyclock;
+/** Proxy inlet class pointer. */
+static t_class *pdlua_proxyinlet_class;
+/** Proxy receive class pointer. */
+static t_class *pdlua_proxyreceive_class;
+/** Proxy clock class pointer. */
+static t_class *pdlua_proxyclock_class;
+
/** Lua file reader callback. */
static const char *pdlua_reader
(
@@ -121,38 +266,6 @@ static const char *pdlua_reader
}
}
-/* declare some stuff in advance */
-struct pdlua_proxyinlet;
-struct pdlua_proxyreceive;
-struct pdlua_proxyclock;
-
-/** Pd object data. */
-typedef struct pdlua
-{
- t_object pd; /**< We are a Pd object. */
- int inlets; /**< Number of inlets. */
- struct pdlua_proxyinlet *in; /**< The inlets themselves. */
- int outlets; /**< Number of outlets. */
- t_outlet **out; /**< The outlets themselves. */
- t_canvas *canvas; /**< The canvas that the object was created on. */
-} t_pdlua;
-
-/* more forward declarations */
-static void pdlua_dispatch(t_pdlua *o, unsigned int inlet, t_symbol *s, int argc, t_atom *argv);
-static void pdlua_receivedispatch(struct pdlua_proxyreceive *r, t_symbol *s, int argc, t_atom *argv);
-static void pdlua_clockdispatch(struct pdlua_proxyclock *clock);
-
-/** Proxy inlet class pointer. */
-static t_class *pdlua_proxyinlet_class;
-
-/** Proxy inlet object data. */
-typedef struct pdlua_proxyinlet
-{
- t_pd pd; /**< Minimal Pd object. */
- struct pdlua *owner; /**< The owning object to forward inlet messages to. */
- unsigned int id; /**< The number of this inlet. */
-} t_pdlua_proxyinlet;
-
/** Proxy inlet 'anything' method. */
static void pdlua_proxyinlet_anything
(
@@ -185,17 +298,6 @@ static void pdlua_proxyinlet_setup(void)
class_addanything(pdlua_proxyinlet_class, pdlua_proxyinlet_anything);
}
-/** Proxy receive class pointer. */
-static t_class *pdlua_proxyreceive_class;
-
-/** Proxy receive object data. */
-typedef struct pdlua_proxyreceive
-{
- t_pd pd; /**< Minimal Pd object. */
- struct pdlua *owner; /**< The owning object to forward received messages to. */
- t_symbol *name; /**< The receive-symbol to bind to. */
-} t_pdlua_proxyreceive;
-
/** Proxy receive 'anything' method. */
static void pdlua_proxyreceive_anything(
t_pdlua_proxyreceive *r, /**< The proxy receive that received the message. */
@@ -239,18 +341,6 @@ static void pdlua_proxyreceive_setup()
class_addanything(pdlua_proxyreceive_class, pdlua_proxyreceive_anything);
}
-
-/** Proxy clock class pointer. */
-static t_class *pdlua_proxyclock_class;
-
-/** Proxy clock object data. */
-typedef struct pdlua_proxyclock
-{
- t_pd pd; /**< Minimal Pd object. */
- struct pdlua *owner; /**< Object to forward messages to. */
- t_clock *clock; /** Pd clock to use. */
-} t_pdlua_proxyclock;
-
/** Proxy clock 'bang' method. */
static void pdlua_proxyclock_bang(t_pdlua_proxyclock *c /**< The proxy clock that received the message. */)
{
@@ -1173,8 +1263,8 @@ static int pdlua_error(lua_State *L)
return 0;
}
-void pdlua_setrequirepath
-( /* FIXME: documentation */
+static void pdlua_setrequirepath
+( /* FIXME: documentation (is this of any use at all?) */
lua_State *L,
const char *path
)
@@ -1191,8 +1281,8 @@ void pdlua_setrequirepath
lua_pop(L, 1);
}
-void pdlua_clearrequirepath
-( /* FIXME: documentation */
+static void pdlua_clearrequirepath
+( /* FIXME: documentation (is this of any use at all?) */
lua_State *L
)
{
@@ -1241,6 +1331,7 @@ static int pdlua_dofile(lua_State *L)
#ifdef PDLUA_DEBUG
post("pdlua_dofile path is %s", buf);
#endif // PDLUA_DEBUG
+ //pdlua_setpathname(o, buf);/* change the scriptname to include its path */
pdlua_setrequirepath(L, buf);
reader.fd = fd;
if (lua_load(L, pdlua_reader, &reader, filename))
@@ -1271,6 +1362,7 @@ static int pdlua_dofile(lua_State *L)
else error("lua: error in object:dofile() - object is null");
}
else error("lua: error in object:dofile() - object is wrong type");
+ lua_pushstring(L, buf); /* return the path as well so we can open it later with pdlua_menu_open() */
return lua_gettop(L) - n;
}
@@ -1383,6 +1475,7 @@ static int pdlua_loader
reader.fd = fd;
if (lua_load(L, pdlua_reader, &reader, name) || lua_pcall(L, 0, 0, 0))
{
+
error("lua: error loading `%s':\n%s", name, lua_tostring(L, -1));
lua_pop(L, 1);
close(fd);