aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormescalinum <mescalinum@users.sourceforge.net>2011-10-15 20:44:27 +0000
committermescalinum <mescalinum@users.sourceforge.net>2011-10-15 20:44:27 +0000
commitb43ebdb4ebbe583218d5e7802835b8d7a56c7292 (patch)
treee59f84be8dddff155270fcc94c44fa61ff47a662
parent5d7b51638d572ab41557c5a80ebff69d9320e740 (diff)
rename pdlib.tcl to tclpd.tcl
svn path=/trunk/externals/loaders/tclpd/; revision=15605
-rw-r--r--Makefile4
-rw-r--r--README.txt59
-rw-r--r--tclpd.c2
-rw-r--r--tclpd.tcl (renamed from pdlib.tcl)5
4 files changed, 26 insertions, 44 deletions
diff --git a/Makefile b/Makefile
index 12a467c..7b64039 100644
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,7 @@ TCLPD_SOURCES = hashtable.c tcl_class.c tcl_loader.c tcl_proxyinlet.c tcl_typema
# list them here. This can be anything from header files, test patches,
# documentation, etc. README.txt and LICENSE.txt are required and therefore
# automatically included
-EXTRA_DIST = tcl.i tcl_extras.h pdlib.tcl $(TCLPD_SOURCES) ChangeLog.txt AUTHORS.txt TODO.txt
+EXTRA_DIST = tcl.i tcl_extras.h tclpd.tcl $(TCLPD_SOURCES) ChangeLog.txt AUTHORS.txt TODO.txt
@@ -312,7 +312,7 @@ single_install: $(LIBRARY_NAME) install-doc install-examples install-manual
$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
$(INSTALL_PROGRAM) $(LIBRARY_NAME).$(EXTENSION) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
$(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION)
- $(INSTALL_DATA) pdlib.tcl $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ $(INSTALL_DATA) tclpd.tcl $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
ifeq ($(UNAME),Darwin)
# force tclpd to use the Tcl.framework built into Pd-extended
install_name_tool -change \
diff --git a/README.txt b/README.txt
index 0276171..cec7a92 100644
--- a/README.txt
+++ b/README.txt
@@ -3,14 +3,12 @@
==========
This library allows to to write externals for Pd using the Tcl language.
-
-It is based on the standard API of PD (defined in m_pd.h, plus some other
-private header files, like g_canvas.h, s_stuff.h, ...).
+It wraps quite closely the pd API (m_pd.h, plus some private functions)
Also a library of Tcl helper functions is provided. It is not mandatory to use
it (moreover: it requires Tcl 8.5, while the tclpd external alone requires only
Tcl 8.4), but it is a syntactic sugar and can simplify a lot the code.
-Using it is as simple as sourcing pdlib.tcl in your Tcl external.
+To use it simply add 'package require TclpdLib' in your Tcl external.
Anyway, disregarding any approach chosen to develop Tcl externals, a general
knowledge of Pd internals (atoms, symbols, symbol table, inlets, objects) is
@@ -37,40 +35,29 @@ pure-data).
=====================
Pd is split into two processes: pd (the core) and pd-gui.
-A simple pd external just runs in the core. A simple Tcl externals still runs
-in the core, because tclpd creates a Tcl interpreter for that.
-
-Instead, pd-gui has its own Tcl interpreter. In order to to GUI things (i.e.
-draw on the canvas, or react to mouse events), the core process needs to
-communicate with the pd-gui process (generally sending Tk commands, or calling
-procedures defined in the pd-gui interp.
-This is done with the sys_gui() function, if using the plain API.
-
-Also pdlib.tcl provide means to simplify this task, with the guiproc function,
-which defines procedures directly into the pd-gui interpreter.
+A pd external executes in the core. The same applies for a Tcl external loaded
+by tclpd, because tclpd creates a Tcl interpreter for that, running in the
+same process as pd.
-As a counterexample, I'd like to cite tot/toxy/widget externals, which you may
-be familiar with.
-Such externals run in the pd-gui process. That was fine for writing simple gui
-externals, that don't need to react to any message.
-But, for instance, you cannot do a metronome or anything which is timing
-accurate, or heavy IO, as that is not the purpose of the gui process.
-Tclpd instead, by running in the core process, allows that.
+On the gui side (pd-gui) there is another Tcl interpreter living in a separate
+process, which communicates with pd using a network socket.
+Communication happens in one way (pd to gui) with the sys_gui function, and in
+the other way using ::pdsend. (needs to set up a receiver using pdbind, check
+the examples).
Data conversion between Tcl <=> Pd
==================================
-In pd exists 'atoms'. An atom is a float, a symbol, a list item, and such.
-Tcl does not have data types. In Tcl everything is a string, also numbers and
-lists. Just when something needs to be read as number, then evaluation comes
-in.
-This leads to loss of information about atom types. Imagine a
-symbol '456' comes into tclpd, you won't know anymore if "456"
-is a symbol or a float.
+In pd objects communicate using messages, and messages are made up of atoms.
+An atom could be a float, a symbol, a list, and so on.
+Tcl usually doesn't make distinction between strings and numbers. This means
+that simply translating a message text into a string could lose information
+about the atom type (to pd, symbol 456 is different from float 456, but if we
+just convert it as a string "456" the type information is lost).
-Here a little convention comes in: in tclpd an atom gets converted into a
-two-item list, where first item is atom type, and second item is its value.
+To maintain atom type infrmation, pd atoms are represented in Tcl as two
+element lists, where the first element indicates the atom type.
Some examples of this conversion:
@@ -87,15 +74,7 @@ Some examples of this conversion:
Examples
========
-I provided small examples.
-after loading pd with option '-lib tcl', just type the filename
-(minus the .tcl extension) to load the Tcl externals examples.
-
-actually there is one simple example: list_change (behaves like
-[change] object, but work with lists only)
-
-examples make use of pdlib.tcl. It's still possible to port the example to use
-only the plain Pd api. Contributions are welcome.
+Some examples externals are provided, including their helpfile.
Authors
diff --git a/tclpd.c b/tclpd.c
index 4bc0b5a..0440952 100644
--- a/tclpd.c
+++ b/tclpd.c
@@ -25,7 +25,7 @@ void tclpd_setup(void) {
t_class* foo_class = class_new(gensym("tclpd_init"), 0, 0, 0, 0, 0);
char buf[PATH_MAX];
- snprintf(buf, PATH_MAX, "%s/pdlib.tcl", foo_class->c_externdir->s_name);
+ snprintf(buf, PATH_MAX, "%s/tclpd.tcl", foo_class->c_externdir->s_name);
if(Tcl_EvalFile(tcl_for_pd, buf) != TCL_OK) {
error("tclpd loader: error loading %s", buf);
}
diff --git a/pdlib.tcl b/tclpd.tcl
index 0766ae4..e3b2583 100644
--- a/pdlib.tcl
+++ b/tclpd.tcl
@@ -122,7 +122,10 @@ namespace eval ::pd {
} elseif {\$function == \"widgetbehavior\"} {
set subfunction \[lindex \$args 0\]
set argsr \[lrange \$args 1 end\]
- uplevel \[linsert \$argsr 0 ::${classname}::\${function}_\${subfunction} \$self]
+ set f ::${classname}::\${function}_\${subfunction}
+ if {\[info procs \$f\] != {}} {
+ uplevel \[linsert \$argsr 0 \$f \$self]
+ }
} else {
uplevel \[linsert \$args 0 ::${classname}::\$function \$self\]
}