1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
pdlua
===
The Lua loader included in -lib pdlua allows externals for Pd to be
written in the Lua programming language.
If you try to create an object [foo] in Pd, Pd checks if the class
"foo" exists. If it doesn't, it tries to load an external file that
"probably" will contain code for "foo". The Lua loader adds support
for loading "foo.pd_lua" when you try to create [foo].
Class Creation
--------------
The first expression/statement in the file should be of the form:
local foo = pd.Class:new():register("foo")
This creates a new Pd class called "foo". The 'local' declaration
is optional, but recommended -- without it, 'foo' is global, which
means any Lua code can modify it (possibly by accident).
Object Initialization
---------------------
Then you can add methods to the Pd class. The most important one
is 'initialize', which is executed when a new object is created.
function foo:initialize(sel, atoms)
-- code
end
or equivalently:
foo.initialize = function (self, sel, atoms)
-- code
end
'sel' is usually (always?) the class name, 'atoms' are the creation
arguments in a Lua table. An example:
Pd :: [foo a b 1 2 3 c]
sel == "foo"
atoms == { "a", "b", 1, 2, 3, "c" }
Being a method, 'initialize' has a 'self' variable (which is the
object to be created), and if you want your objects to have inlets
or outlets you need need to set those fields in this method (Pd
doesn't support changing the number of inlets or outlets after an
object is created):
self.inlets = 1
self.outlets = atoms[1]
The default inlet/outlet counts are 0.
The return value of 'initialize' is used to allow objects to fail
to create (for example, if the creation arguments are bad). Most
of the time you will 'return true', but if you really can't create
then you can 'return false'.
If you need to do things after the Pd object is created, but before
control is returned to Pd, you can use the 'postinitialize' method:
function foo:postinitialize()
-- code
end
Object Finalization
-------------------
The 'finalize' method is called when the object is deleted by Pd.
You can clean up stuff here if needed. The default implementation
does nothing.
Inlet Methods
-------------
FIXME: write about inlet methods/dispatching
FIXME: for now, see examples/*.pd_lua and src/pd.lua
Sending To Outlets
------------------
FIXME: write about self:outlet(outletNumber, selector, atoms)
FIXME: for now, see examples/*.pd_lua and src/pd.lua
Sending To Receivers
--------------------
You can send messages to receivers like this:
pd.send("receiver", "selector", { "a", "message", 1, 2, 3 }
See examples/lsend.pd_lua for details.
Receivers
---------
You can bind methods to receivers, to get messages from
[send receiver] and "; receiver message".
See examples/lreceive.pd_lua for details.
Remember to clean up your receivers in object:finalize(), or weird
things will happen.
Clocks
------
You can bind methods to clocks, for timing based on Pd's logical clock.
See examples/ldelay.pd_lua for details.
Remember to clean up your clocks in object:finalize(), or weird things
will happen.
Miscellaneous Object Methods
----------------------------
Execute a Lua file using Pd's path to find it:
self:dofile("filename")
Report an error to Pd's console:
self:error("message")
Miscellaneous Functions
-----------------------
Print a string to Pd's console:
pd.post("a string")
Note that pd.post() should not really be used for errors.
FIXME: add pd.error() for error messages
|