summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/x_connective.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/x_connective.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/x_connective.c1451
1 files changed, 0 insertions, 1451 deletions
diff --git a/apps/plugins/pdbox/PDa/src/x_connective.c b/apps/plugins/pdbox/PDa/src/x_connective.c
index d68192ea9a..52bc0920a1 100644
--- a/apps/plugins/pdbox/PDa/src/x_connective.c
+++ b/apps/plugins/pdbox/PDa/src/x_connective.c
@@ -1450,1455 +1450,4 @@ void x_connective_setup(void)
1450 change_setup(); 1450 change_setup();
1451 value_setup(); 1451 value_setup();
1452} 1452}
1453/* Copyright (c) 1997-1999 Miller Puckette.
1454* For information on usage and redistribution, and for a DISCLAIMER OF ALL
1455* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
1456
1457/* connective objects */
1458
1459#include "m_pd.h"
1460
1461#include <string.h>
1462#include <stdio.h>
1463extern t_pd *newest;
1464
1465/* -------------------------- int ------------------------------ */
1466static t_class *pdint_class;
1467
1468typedef struct _pdint
1469{
1470 t_object x_obj;
1471 t_float x_f;
1472} t_pdint;
1473
1474static void *pdint_new(t_floatarg f)
1475{
1476 t_pdint *x = (t_pdint *)pd_new(pdint_class);
1477 x->x_f = f;
1478 outlet_new(&x->x_obj, &s_float);
1479 floatinlet_new(&x->x_obj, &x->x_f);
1480 return (x);
1481}
1482
1483static void pdint_bang(t_pdint *x)
1484{
1485 outlet_float(x->x_obj.ob_outlet, (t_float)(int)(x->x_f));
1486}
1487
1488static void pdint_float(t_pdint *x, t_float f)
1489{
1490 outlet_float(x->x_obj.ob_outlet, (t_float)(int)(x->x_f = f));
1491}
1492
1493void pdint_setup(void)
1494{
1495 pdint_class = class_new(gensym("int"), (t_newmethod)pdint_new, 0,
1496 sizeof(t_pdint), 0, A_DEFFLOAT, 0);
1497 class_addcreator((t_newmethod)pdint_new, gensym("i"), A_DEFFLOAT, 0);
1498 class_addbang(pdint_class, pdint_bang);
1499 class_addfloat(pdint_class, pdint_float);
1500}
1501
1502/* -------------------------- float ------------------------------ */
1503static t_class *pdfloat_class;
1504
1505typedef struct _pdfloat
1506{
1507 t_object x_obj;
1508 t_float x_f;
1509} t_pdfloat;
1510
1511 /* "float," "symbol," and "bang" are special because
1512 they're created by short-circuited messages to the "new"
1513 object which are handled specially in pd_typedmess(). */
1514
1515static void *pdfloat_new(t_pd *dummy, t_float f)
1516{
1517 t_pdfloat *x = (t_pdfloat *)pd_new(pdfloat_class);
1518 x->x_f = f;
1519 outlet_new(&x->x_obj, &s_float);
1520 floatinlet_new(&x->x_obj, &x->x_f);
1521 newest = &x->x_obj.ob_pd;
1522 return (x);
1523}
1524
1525static void *pdfloat_new2(t_floatarg f)
1526{
1527 return (pdfloat_new(0, f));
1528}
1529
1530static void pdfloat_bang(t_pdfloat *x)
1531{
1532 outlet_float(x->x_obj.ob_outlet, x->x_f);
1533}
1534
1535static void pdfloat_float(t_pdfloat *x, t_float f)
1536{
1537 outlet_float(x->x_obj.ob_outlet, x->x_f = f);
1538}
1539
1540void pdfloat_setup(void)
1541{
1542 pdfloat_class = class_new(gensym("float"), (t_newmethod)pdfloat_new, 0,
1543 sizeof(t_pdfloat), 0, A_FLOAT, 0);
1544 class_addcreator((t_newmethod)pdfloat_new2, gensym("f"), A_DEFFLOAT, 0);
1545 class_addbang(pdfloat_class, pdfloat_bang);
1546 class_addfloat(pdfloat_class, (t_method)pdfloat_float);
1547}
1548
1549/* -------------------------- symbol ------------------------------ */
1550static t_class *pdsymbol_class;
1551
1552typedef struct _pdsymbol
1553{
1554 t_object x_obj;
1555 t_symbol *x_s;
1556} t_pdsymbol;
1557
1558static void *pdsymbol_new(t_pd *dummy, t_symbol *s)
1559{
1560 t_pdsymbol *x = (t_pdsymbol *)pd_new(pdsymbol_class);
1561 x->x_s = s;
1562 outlet_new(&x->x_obj, &s_symbol);
1563 symbolinlet_new(&x->x_obj, &x->x_s);
1564 newest = &x->x_obj.ob_pd;
1565 return (x);
1566}
1567
1568static void pdsymbol_bang(t_pdsymbol *x)
1569{
1570 outlet_symbol(x->x_obj.ob_outlet, x->x_s);
1571}
1572
1573static void pdsymbol_symbol(t_pdsymbol *x, t_symbol *s)
1574{
1575 outlet_symbol(x->x_obj.ob_outlet, x->x_s = s);
1576}
1577
1578static void pdsymbol_anything(t_pdsymbol *x, t_symbol *s, int ac, t_atom *av)
1579{
1580 outlet_symbol(x->x_obj.ob_outlet, x->x_s = s);
1581}
1582
1583void pdsymbol_setup(void)
1584{
1585 pdsymbol_class = class_new(gensym("symbol"), (t_newmethod)pdsymbol_new, 0,
1586 sizeof(t_pdsymbol), 0, A_SYMBOL, 0);
1587 class_addbang(pdsymbol_class, pdsymbol_bang);
1588 class_addsymbol(pdsymbol_class, pdsymbol_symbol);
1589 class_addanything(pdsymbol_class, pdsymbol_anything);
1590}
1591
1592/* -------------------------- bang ------------------------------ */
1593static t_class *bang_class;
1594
1595typedef struct _bang
1596{
1597 t_object x_obj;
1598} t_bang;
1599
1600static void *bang_new(t_pd *dummy)
1601{
1602 t_bang *x = (t_bang *)pd_new(bang_class);
1603 outlet_new(&x->x_obj, &s_bang);
1604 newest = &x->x_obj.ob_pd;
1605 return (x);
1606}
1607
1608static void *bang_new2(t_bang f)
1609{
1610 return (bang_new(0));
1611}
1612
1613static void bang_bang(t_bang *x)
1614{
1615 outlet_bang(x->x_obj.ob_outlet);
1616}
1617
1618void bang_setup(void)
1619{
1620 bang_class = class_new(gensym("bang"), (t_newmethod)bang_new, 0,
1621 sizeof(t_bang), 0, 0);
1622 class_addcreator((t_newmethod)bang_new2, gensym("b"), 0);
1623 class_addbang(bang_class, bang_bang);
1624 class_addfloat(bang_class, bang_bang);
1625 class_addsymbol(bang_class, bang_bang);
1626 class_addlist(bang_class, bang_bang);
1627 class_addanything(bang_class, bang_bang);
1628}
1629
1630/* -------------------- send ------------------------------ */
1631
1632static t_class *send_class;
1633
1634typedef struct _send
1635{
1636 t_object x_obj;
1637 t_symbol *x_sym;
1638} t_send;
1639
1640static void send_bang(t_send *x)
1641{
1642 if (x->x_sym->s_thing) pd_bang(x->x_sym->s_thing);
1643}
1644
1645static void send_float(t_send *x, t_float f)
1646{
1647 if (x->x_sym->s_thing) pd_float(x->x_sym->s_thing, f);
1648}
1649
1650static void send_symbol(t_send *x, t_symbol *s)
1651{
1652 if (x->x_sym->s_thing) pd_symbol(x->x_sym->s_thing, s);
1653}
1654
1655static void send_pointer(t_send *x, t_gpointer *gp)
1656{
1657 if (x->x_sym->s_thing) pd_pointer(x->x_sym->s_thing, gp);
1658}
1659
1660static void send_list(t_send *x, t_symbol *s, int argc, t_atom *argv)
1661{
1662 if (x->x_sym->s_thing) pd_list(x->x_sym->s_thing, s, argc, argv);
1663}
1664
1665static void send_anything(t_send *x, t_symbol *s, int argc, t_atom *argv)
1666{
1667 if (x->x_sym->s_thing) typedmess(x->x_sym->s_thing, s, argc, argv);
1668}
1669
1670static void *send_new(t_symbol *s)
1671{
1672 t_send *x = (t_send *)pd_new(send_class);
1673 x->x_sym = s;
1674 return (x);
1675}
1676
1677static void send_setup(void)
1678{
1679 send_class = class_new(gensym("send"), (t_newmethod)send_new, 0,
1680 sizeof(t_send), 0, A_DEFSYM, 0);
1681 class_addcreator((t_newmethod)send_new, gensym("s"), A_DEFSYM, 0);
1682 class_addbang(send_class, send_bang);
1683 class_addfloat(send_class, send_float);
1684 class_addsymbol(send_class, send_symbol);
1685 class_addpointer(send_class, send_pointer);
1686 class_addlist(send_class, send_list);
1687 class_addanything(send_class, send_anything);
1688}
1689/* -------------------- receive ------------------------------ */
1690
1691static t_class *receive_class;
1692
1693typedef struct _receive
1694{
1695 t_object x_obj;
1696 t_symbol *x_sym;
1697} t_receive;
1698
1699static void receive_bang(t_receive *x)
1700{
1701 outlet_bang(x->x_obj.ob_outlet);
1702}
1703
1704static void receive_float(t_receive *x, t_float f)
1705{
1706 outlet_float(x->x_obj.ob_outlet, f);
1707}
1708
1709static void receive_symbol(t_receive *x, t_symbol *s)
1710{
1711 outlet_symbol(x->x_obj.ob_outlet, s);
1712}
1713
1714static void receive_pointer(t_receive *x, t_gpointer *gp)
1715{
1716 outlet_pointer(x->x_obj.ob_outlet, gp);
1717}
1718
1719static void receive_list(t_receive *x, t_symbol *s, int argc, t_atom *argv)
1720{
1721 outlet_list(x->x_obj.ob_outlet, s, argc, argv);
1722}
1723
1724static void receive_anything(t_receive *x, t_symbol *s, int argc, t_atom *argv)
1725{
1726 outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
1727}
1728
1729static void *receive_new(t_symbol *s)
1730{
1731 t_receive *x = (t_receive *)pd_new(receive_class);
1732 x->x_sym = s;
1733 pd_bind(&x->x_obj.ob_pd, s);
1734 outlet_new(&x->x_obj, 0);
1735 return (x);
1736}
1737
1738static void receive_free(t_receive *x)
1739{
1740 pd_unbind(&x->x_obj.ob_pd, x->x_sym);
1741}
1742
1743static void receive_setup(void)
1744{
1745 receive_class = class_new(gensym("receive"), (t_newmethod)receive_new,
1746 (t_method)receive_free, sizeof(t_receive), CLASS_NOINLET, A_DEFSYM, 0);
1747 class_addcreator((t_newmethod)receive_new, gensym("r"), A_DEFSYM, 0);
1748 class_addbang(receive_class, receive_bang);
1749 class_addfloat(receive_class, (t_method)receive_float);
1750 class_addsymbol(receive_class, receive_symbol);
1751 class_addpointer(receive_class, receive_pointer);
1752 class_addlist(receive_class, receive_list);
1753 class_addanything(receive_class, receive_anything);
1754}
1755
1756/* -------------------------- select ------------------------------ */
1757
1758static t_class *sel1_class;
1759
1760typedef struct _sel1
1761{
1762 t_object x_obj;
1763 t_atom x_atom;
1764 t_outlet *x_outlet1;
1765 t_outlet *x_outlet2;
1766} t_sel1;
1767
1768static void sel1_float(t_sel1 *x, t_float f)
1769{
1770 if (x->x_atom.a_type == A_FLOAT && f == x->x_atom.a_w.w_float)
1771 outlet_bang(x->x_outlet1);
1772 else outlet_float(x->x_outlet2, f);
1773}
1774
1775static void sel1_symbol(t_sel1 *x, t_symbol *s)
1776{
1777 if (x->x_atom.a_type == A_SYMBOL && s == x->x_atom.a_w.w_symbol)
1778 outlet_bang(x->x_outlet1);
1779 else outlet_symbol(x->x_outlet2, s);
1780}
1781
1782static t_class *sel2_class;
1783
1784typedef struct _selectelement
1785{
1786 t_word e_w;
1787 t_outlet *e_outlet;
1788} t_selectelement;
1789
1790typedef struct _sel2
1791{
1792 t_object x_obj;
1793 t_atomtype x_type;
1794 t_int x_nelement;
1795 t_selectelement *x_vec;
1796 t_outlet *x_rejectout;
1797} t_sel2;
1798
1799static void sel2_float(t_sel2 *x, t_float f)
1800{
1801 t_selectelement *e;
1802 int nelement;
1803 if (x->x_type == A_FLOAT)
1804 {
1805 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1806 if (e->e_w.w_float == f)
1807 {
1808 outlet_bang(e->e_outlet);
1809 return;
1810 }
1811 }
1812 outlet_float(x->x_rejectout, f);
1813}
1814
1815static void sel2_symbol(t_sel2 *x, t_symbol *s)
1816{
1817 t_selectelement *e;
1818 int nelement;
1819 if (x->x_type == A_SYMBOL)
1820 {
1821 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1822 if (e->e_w.w_symbol == s)
1823 {
1824 outlet_bang(e->e_outlet);
1825 return;
1826 }
1827 }
1828 outlet_symbol(x->x_rejectout, s);
1829}
1830
1831static void sel2_free(t_sel2 *x)
1832{
1833 freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec));
1834}
1835
1836static void *select_new(t_symbol *s, int argc, t_atom *argv)
1837{
1838 t_atom a;
1839 if (argc == 0)
1840 {
1841 argc = 1;
1842 SETFLOAT(&a, 0);
1843 argv = &a;
1844 }
1845 if (argc == 1)
1846 {
1847 t_sel1 *x = (t_sel1 *)pd_new(sel1_class);
1848 x->x_atom = *argv;
1849 x->x_outlet1 = outlet_new(&x->x_obj, &s_bang);
1850 if (argv->a_type == A_FLOAT)
1851 {
1852 floatinlet_new(&x->x_obj, &x->x_atom.a_w.w_float);
1853 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
1854 }
1855 else
1856 {
1857 symbolinlet_new(&x->x_obj, &x->x_atom.a_w.w_symbol);
1858 x->x_outlet2 = outlet_new(&x->x_obj, &s_symbol);
1859 }
1860 return (x);
1861 }
1862 else
1863 {
1864 int n;
1865 t_selectelement *e;
1866 t_sel2 *x = (t_sel2 *)pd_new(sel2_class);
1867 x->x_nelement = argc;
1868 x->x_vec = (t_selectelement *)getbytes(argc * sizeof(*x->x_vec));
1869 x->x_type = argv[0].a_type;
1870 for (n = 0, e = x->x_vec; n < argc; n++, e++)
1871 {
1872 e->e_outlet = outlet_new(&x->x_obj, &s_bang);
1873 if ((x->x_type = argv->a_type) == A_FLOAT)
1874 e->e_w.w_float = atom_getfloatarg(n, argc, argv);
1875 else e->e_w.w_symbol = atom_getsymbolarg(n, argc, argv);
1876 }
1877 x->x_rejectout = outlet_new(&x->x_obj, &s_float);
1878 return (x);
1879 }
1880
1881}
1882
1883void select_setup(void)
1884{
1885 sel1_class = class_new(gensym("select"), 0, 0,
1886 sizeof(t_sel1), 0, 0);
1887 class_addfloat(sel1_class, sel1_float);
1888 class_addsymbol(sel1_class, sel1_symbol);
1889
1890 sel2_class = class_new(gensym("select"), 0, (t_method)sel2_free,
1891 sizeof(t_sel2), 0, 0);
1892 class_addfloat(sel2_class, sel2_float);
1893 class_addsymbol(sel2_class, sel2_symbol);
1894
1895 class_addcreator((t_newmethod)select_new, gensym("select"), A_GIMME, 0);
1896 class_addcreator((t_newmethod)select_new, gensym("sel"), A_GIMME, 0);
1897}
1898
1899/* -------------------------- route ------------------------------ */
1900
1901static t_class *route_class;
1902
1903typedef struct _routeelement
1904{
1905 t_word e_w;
1906 t_outlet *e_outlet;
1907} t_routeelement;
1908
1909typedef struct _route
1910{
1911 t_object x_obj;
1912 t_atomtype x_type;
1913 t_int x_nelement;
1914 t_routeelement *x_vec;
1915 t_outlet *x_rejectout;
1916} t_route;
1917
1918static void route_anything(t_route *x, t_symbol *sel, int argc, t_atom *argv)
1919{
1920 t_routeelement *e;
1921 int nelement;
1922 if (x->x_type == A_SYMBOL)
1923 {
1924 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1925 if (e->e_w.w_symbol == sel)
1926 {
1927 if (argc > 0 && argv[0].a_type == A_SYMBOL)
1928 outlet_anything(e->e_outlet, argv[0].a_w.w_symbol,
1929 argc-1, argv+1);
1930 else outlet_list(e->e_outlet, 0, argc, argv);
1931 return;
1932 }
1933 }
1934 outlet_anything(x->x_rejectout, sel, argc, argv);
1935}
1936
1937static void route_list(t_route *x, t_symbol *sel, int argc, t_atom *argv)
1938{
1939 t_routeelement *e;
1940 int nelement;
1941 if (x->x_type == A_FLOAT)
1942 {
1943 float f;
1944 if (!argc) return;
1945 f = atom_getfloat(argv);
1946 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1947 if (e->e_w.w_float == f)
1948 {
1949 if (argc > 1 && argv[1].a_type == A_SYMBOL)
1950 outlet_anything(e->e_outlet, argv[1].a_w.w_symbol,
1951 argc-2, argv+2);
1952 else outlet_list(e->e_outlet, 0, argc-1, argv+1);
1953 return;
1954 }
1955 }
1956 else /* symbol arguments */
1957 {
1958 if (argc > 1) /* 2 or more args: treat as "list" */
1959 {
1960 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1961 {
1962 if (e->e_w.w_symbol == &s_list)
1963 {
1964 if (argc > 0 && argv[0].a_type == A_SYMBOL)
1965 outlet_anything(e->e_outlet, argv[0].a_w.w_symbol,
1966 argc-1, argv+1);
1967 else outlet_list(e->e_outlet, 0, argc, argv);
1968 return;
1969 }
1970 }
1971 }
1972 else if (argc == 0) /* no args: treat as "bang" */
1973 {
1974 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1975 {
1976 if (e->e_w.w_symbol == &s_bang)
1977 {
1978 outlet_bang(e->e_outlet);
1979 return;
1980 }
1981 }
1982 }
1983 else if (argv[0].a_type == A_FLOAT) /* one float arg */
1984 {
1985 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1986 {
1987 if (e->e_w.w_symbol == &s_float)
1988 {
1989 outlet_float(e->e_outlet, argv[0].a_w.w_float);
1990 return;
1991 }
1992 }
1993 }
1994 else
1995 {
1996 for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
1997 {
1998 if (e->e_w.w_symbol == &s_symbol)
1999 {
2000 outlet_symbol(e->e_outlet, argv[0].a_w.w_symbol);
2001 return;
2002 }
2003 }
2004 }
2005 }
2006 outlet_list(x->x_rejectout, 0, argc, argv);
2007}
2008
2009
2010static void route_free(t_route *x)
2011{
2012 freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec));
2013}
2014
2015static void *route_new(t_symbol *s, int argc, t_atom *argv)
2016{
2017 int n;
2018 t_routeelement *e;
2019 t_route *x = (t_route *)pd_new(route_class);
2020 t_atom a;
2021 if (argc == 0)
2022 {
2023 argc = 1;
2024 SETFLOAT(&a, 0);
2025 argv = &a;
2026 }
2027 x->x_type = argv[0].a_type;
2028 x->x_nelement = argc;
2029 x->x_vec = (t_routeelement *)getbytes(argc * sizeof(*x->x_vec));
2030 for (n = 0, e = x->x_vec; n < argc; n++, e++)
2031 {
2032 e->e_outlet = outlet_new(&x->x_obj, &s_list);
2033 if (x->x_type == A_FLOAT)
2034 e->e_w.w_float = atom_getfloatarg(n, argc, argv);
2035 else e->e_w.w_symbol = atom_getsymbolarg(n, argc, argv);
2036 }
2037 x->x_rejectout = outlet_new(&x->x_obj, &s_list);
2038 return (x);
2039}
2040
2041void route_setup(void)
2042{
2043 route_class = class_new(gensym("route"), (t_newmethod)route_new,
2044 (t_method)route_free, sizeof(t_route), 0, A_GIMME, 0);
2045 class_addlist(route_class, route_list);
2046 class_addanything(route_class, route_anything);
2047}
2048
2049/* -------------------------- pack ------------------------------ */
2050
2051static t_class *pack_class;
2052
2053typedef struct _pack
2054{
2055 t_object x_obj;
2056 t_int x_n; /* number of args */
2057 t_atom *x_vec; /* input values */
2058 t_int x_nptr; /* number of pointers */
2059 t_gpointer *x_gpointer; /* the pointers */
2060 t_atom *x_outvec; /* space for output values */
2061} t_pack;
2062
2063static void *pack_new(t_symbol *s, int argc, t_atom *argv)
2064{
2065 t_pack *x = (t_pack *)pd_new(pack_class);
2066 t_atom defarg[2], *ap, *vec, *vp;
2067 t_gpointer *gp;
2068 int nptr = 0;
2069 int i;
2070 if (!argc)
2071 {
2072 argv = defarg;
2073 argc = 2;
2074 SETFLOAT(&defarg[0], 0);
2075 SETFLOAT(&defarg[1], 0);
2076 }
2077
2078 x->x_n = argc;
2079 vec = x->x_vec = (t_atom *)getbytes(argc * sizeof(*x->x_vec));
2080 x->x_outvec = (t_atom *)getbytes(argc * sizeof(*x->x_outvec));
2081
2082 for (i = argc, ap = argv; i--; ap++)
2083 if (ap->a_type == A_SYMBOL && *ap->a_w.w_symbol->s_name == 'p')
2084 nptr++;
2085
2086 gp = x->x_gpointer = (t_gpointer *)t_getbytes(nptr * sizeof (*gp));
2087 x->x_nptr = nptr;
2088
2089 for (i = 0, vp = x->x_vec, ap = argv; i < argc; i++, ap++, vp++)
2090 {
2091 if (ap->a_type == A_FLOAT)
2092 {
2093 *vp = *ap;
2094 if (i) floatinlet_new(&x->x_obj, &vp->a_w.w_float);
2095 }
2096 else if (ap->a_type == A_SYMBOL)
2097 {
2098 char c = *ap->a_w.w_symbol->s_name;
2099 if (c == 's')
2100 {
2101 SETSYMBOL(vp, &s_symbol);
2102 if (i) symbolinlet_new(&x->x_obj, &vp->a_w.w_symbol);
2103 }
2104 else if (c == 'p')
2105 {
2106 vp->a_type = A_POINTER;
2107 vp->a_w.w_gpointer = gp;
2108 gpointer_init(gp);
2109 if (i) pointerinlet_new(&x->x_obj, gp);
2110 gp++;
2111 }
2112 else
2113 {
2114 if (c != 'f') pd_error(x, "pack: %s: bad type",
2115 ap->a_w.w_symbol->s_name);
2116 SETFLOAT(vp, 0);
2117 if (i) floatinlet_new(&x->x_obj, &vp->a_w.w_float);
2118 }
2119 }
2120 }
2121 outlet_new(&x->x_obj, &s_list);
2122 return (x);
2123}
2124
2125static void pack_bang(t_pack *x)
2126{
2127 int i, reentered = 0, size = x->x_n * sizeof (t_atom);
2128 t_gpointer *gp;
2129 t_atom *outvec;
2130 for (i = x->x_nptr, gp = x->x_gpointer; i--; gp++)
2131 if (!gpointer_check(gp, 1))
2132 {
2133 pd_error(x, "pack: stale pointer");
2134 return;
2135 }
2136 /* reentrancy protection. The first time through use the pre-allocated
2137 x_outvec; if we're reentered we have to allocate new memory. */
2138 if (!x->x_outvec)
2139 {
2140 /* LATER figure out how to deal with reentrancy and pointers... */
2141 if (x->x_nptr)
2142 post("pack_bang: warning: reentry with pointers unprotected");
2143 outvec = t_getbytes(size);
2144 reentered = 1;
2145 }
2146 else
2147 {
2148 outvec = x->x_outvec;
2149 x->x_outvec = 0;
2150 }
2151 memcpy(outvec, x->x_vec, size);
2152 outlet_list(x->x_obj.ob_outlet, &s_list, x->x_n, outvec);
2153 if (reentered)
2154 t_freebytes(outvec, size);
2155 else x->x_outvec = outvec;
2156}
2157
2158static void pack_pointer(t_pack *x, t_gpointer *gp)
2159{
2160 if (x->x_vec->a_type == A_POINTER)
2161 {
2162 gpointer_unset(x->x_gpointer);
2163 *x->x_gpointer = *gp;
2164 if (gp->gp_stub) gp->gp_stub->gs_refcount++;
2165 pack_bang(x);
2166 }
2167 else pd_error(x, "pack_pointer: wrong type");
2168}
2169
2170static void pack_float(t_pack *x, t_float f)
2171{
2172 if (x->x_vec->a_type == A_FLOAT)
2173 {
2174 x->x_vec->a_w.w_float = f;
2175 pack_bang(x);
2176 }
2177 else pd_error(x, "pack_float: wrong type");
2178}
2179 1453
2180static void pack_symbol(t_pack *x, t_symbol *s)
2181{
2182 if (x->x_vec->a_type == A_SYMBOL)
2183 {
2184 x->x_vec->a_w.w_symbol = s;
2185 pack_bang(x);
2186 }
2187 else pd_error(x, "pack_symbol: wrong type");
2188}
2189
2190static void pack_list(t_pack *x, t_symbol *s, int ac, t_atom *av)
2191{
2192 obj_list(&x->x_obj, 0, ac, av);
2193}
2194
2195static void pack_anything(t_pack *x, t_symbol *s, int ac, t_atom *av)
2196{
2197 t_atom *av2 = (t_atom *)getbytes((ac + 1) * sizeof(t_atom));
2198 int i;
2199 for (i = 0; i < ac; i++)
2200 av2[i + 1] = av[i];
2201 SETSYMBOL(av2, s);
2202 obj_list(&x->x_obj, 0, ac+1, av2);
2203 freebytes(av2, (ac + 1) * sizeof(t_atom));
2204}
2205
2206static void pack_free(t_pack *x)
2207{
2208 t_gpointer *gp;
2209 int i;
2210 for (gp = x->x_gpointer, i = x->x_nptr; i--; gp++)
2211 gpointer_unset(gp);
2212 freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
2213 freebytes(x->x_outvec, x->x_n * sizeof(*x->x_outvec));
2214 freebytes(x->x_gpointer, x->x_nptr * sizeof(*x->x_gpointer));
2215}
2216
2217static void pack_setup(void)
2218{
2219 pack_class = class_new(gensym("pack"), (t_newmethod)pack_new,
2220 (t_method)pack_free, sizeof(t_pack), 0, A_GIMME, 0);
2221 class_addbang(pack_class, pack_bang);
2222 class_addpointer(pack_class, pack_pointer);
2223 class_addfloat(pack_class, pack_float);
2224 class_addsymbol(pack_class, pack_symbol);
2225 class_addlist(pack_class, pack_list);
2226 class_addanything(pack_class, pack_anything);
2227}
2228
2229/* -------------------------- unpack ------------------------------ */
2230
2231static t_class *unpack_class;
2232
2233typedef struct unpackout
2234{
2235 t_atomtype u_type;
2236 t_outlet *u_outlet;
2237} t_unpackout;
2238
2239typedef struct _unpack
2240{
2241 t_object x_obj;
2242 t_int x_n;
2243 t_unpackout *x_vec;
2244} t_unpack;
2245
2246static void *unpack_new(t_symbol *s, int argc, t_atom *argv)
2247{
2248 t_unpack *x = (t_unpack *)pd_new(unpack_class);
2249 t_atom defarg[2], *ap;
2250 t_unpackout *u;
2251 int i;
2252 if (!argc)
2253 {
2254 argv = defarg;
2255 argc = 2;
2256 SETFLOAT(&defarg[0], 0);
2257 SETFLOAT(&defarg[1], 0);
2258 }
2259 x->x_n = argc;
2260 x->x_vec = (t_unpackout *)getbytes(argc * sizeof(*x->x_vec));
2261 for (i = 0, ap = argv, u = x->x_vec; i < argc; u++, ap++, i++)
2262 {
2263 t_atomtype type = ap->a_type;
2264 if (type == A_SYMBOL)
2265 {
2266 char c = *ap->a_w.w_symbol->s_name;
2267 if (c == 's')
2268 {
2269 u->u_type = A_SYMBOL;
2270 u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
2271 }
2272 else if (c == 'p')
2273 {
2274 u->u_type = A_POINTER;
2275 u->u_outlet = outlet_new(&x->x_obj, &s_pointer);
2276 }
2277 else
2278 {
2279 if (c != 'f') pd_error(x, "unpack: %s: bad type",
2280 ap->a_w.w_symbol->s_name);
2281 u->u_type = A_FLOAT;
2282 u->u_outlet = outlet_new(&x->x_obj, &s_float);
2283 }
2284 }
2285 else
2286 {
2287 u->u_type = A_FLOAT;
2288 u->u_outlet = outlet_new(&x->x_obj, &s_float);
2289 }
2290 }
2291 return (x);
2292}
2293
2294static void unpack_list(t_unpack *x, t_symbol *s, int argc, t_atom *argv)
2295{
2296 t_atom *ap;
2297 t_unpackout *u;
2298 int i;
2299 if (argc > x->x_n) argc = x->x_n;
2300 for (i = argc, u = x->x_vec + i, ap = argv + i; u--, ap--, i--;)
2301 {
2302 t_atomtype type = u->u_type;
2303 if (type != ap->a_type)
2304 pd_error(x, "unpack: type mismatch");
2305 else if (type == A_FLOAT)
2306 outlet_float(u->u_outlet, ap->a_w.w_float);
2307 else if (type == A_SYMBOL)
2308 outlet_symbol(u->u_outlet, ap->a_w.w_symbol);
2309 else outlet_pointer(u->u_outlet, ap->a_w.w_gpointer);
2310 }
2311}
2312
2313static void unpack_anything(t_unpack *x, t_symbol *s, int ac, t_atom *av)
2314{
2315 t_atom *av2 = (t_atom *)getbytes((ac + 1) * sizeof(t_atom));
2316 int i;
2317 for (i = 0; i < ac; i++)
2318 av2[i + 1] = av[i];
2319 SETSYMBOL(av2, s);
2320 unpack_list(x, 0, ac+1, av2);
2321 freebytes(av2, (ac + 1) * sizeof(t_atom));
2322}
2323
2324static void unpack_free(t_unpack *x)
2325{
2326 freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
2327}
2328
2329static void unpack_setup(void)
2330{
2331 unpack_class = class_new(gensym("unpack"), (t_newmethod)unpack_new,
2332 (t_method)unpack_free, sizeof(t_unpack), 0, A_GIMME, 0);
2333 class_addlist(unpack_class, unpack_list);
2334 class_addanything(unpack_class, unpack_anything);
2335}
2336
2337/* -------------------------- trigger ------------------------------ */
2338
2339static t_class *trigger_class;
2340#define TR_BANG 0
2341#define TR_FLOAT 1
2342#define TR_SYMBOL 2
2343#define TR_POINTER 3
2344#define TR_LIST 4
2345#define TR_ANYTHING 5
2346
2347typedef struct triggerout
2348{
2349 int u_type; /* outlet type from above */
2350 t_outlet *u_outlet;
2351} t_triggerout;
2352
2353typedef struct _trigger
2354{
2355 t_object x_obj;
2356 t_int x_n;
2357 t_triggerout *x_vec;
2358} t_trigger;
2359
2360static void *trigger_new(t_symbol *s, int argc, t_atom *argv)
2361{
2362 t_trigger *x = (t_trigger *)pd_new(trigger_class);
2363 t_atom defarg[2], *ap;
2364 t_triggerout *u;
2365 int i;
2366 if (!argc)
2367 {
2368 argv = defarg;
2369 argc = 2;
2370 SETSYMBOL(&defarg[0], &s_bang);
2371 SETSYMBOL(&defarg[1], &s_bang);
2372 }
2373 x->x_n = argc;
2374 x->x_vec = (t_triggerout *)getbytes(argc * sizeof(*x->x_vec));
2375 for (i = 0, ap = argv, u = x->x_vec; i < argc; u++, ap++, i++)
2376 {
2377 t_atomtype thistype = ap->a_type;
2378 char c;
2379 if (thistype == TR_SYMBOL) c = ap->a_w.w_symbol->s_name[0];
2380 else if (thistype == TR_FLOAT) c = 'f';
2381 else c = 0;
2382 if (c == 'p')
2383 u->u_type = TR_POINTER,
2384 u->u_outlet = outlet_new(&x->x_obj, &s_pointer);
2385 else if (c == 'f')
2386 u->u_type = TR_FLOAT, u->u_outlet = outlet_new(&x->x_obj, &s_float);
2387 else if (c == 'b')
2388 u->u_type = TR_BANG, u->u_outlet = outlet_new(&x->x_obj, &s_bang);
2389 else if (c == 'l')
2390 u->u_type = TR_LIST, u->u_outlet = outlet_new(&x->x_obj, &s_list);
2391 else if (c == 's')
2392 u->u_type = TR_SYMBOL,
2393 u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
2394 else if (c == 'a')
2395 u->u_type = TR_ANYTHING,
2396 u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
2397 else
2398 {
2399 pd_error(x, "trigger: %s: bad type", ap->a_w.w_symbol->s_name);
2400 u->u_type = TR_FLOAT, u->u_outlet = outlet_new(&x->x_obj, &s_float);
2401 }
2402 }
2403 return (x);
2404}
2405
2406static void trigger_list(t_trigger *x, t_symbol *s, int argc, t_atom *argv)
2407{
2408 t_triggerout *u;
2409 int i;
2410 t_atom at;
2411 if (!argc)
2412 {
2413 argc = 1;
2414 SETFLOAT(&at, 0);
2415 argv = &at;
2416 }
2417 for (i = x->x_n, u = x->x_vec + i; u--, i--;)
2418 {
2419 if (u->u_type == TR_FLOAT)
2420 outlet_float(u->u_outlet, atom_getfloat(argv));
2421 else if (u->u_type == TR_BANG)
2422 outlet_bang(u->u_outlet);
2423 else if (u->u_type == TR_SYMBOL)
2424 outlet_symbol(u->u_outlet, atom_getsymbol(argv));
2425 else if (u->u_type == TR_POINTER)
2426 {
2427 if (argv->a_type != TR_POINTER)
2428 pd_error(x, "unpack: bad pointer");
2429 else outlet_pointer(u->u_outlet, argv->a_w.w_gpointer);
2430 }
2431 else outlet_list(u->u_outlet, &s_list, argc, argv);
2432 }
2433}
2434
2435static void trigger_anything(t_trigger *x, t_symbol *s, int argc, t_atom *argv)
2436{
2437 t_triggerout *u;
2438 int i;
2439 for (i = x->x_n, u = x->x_vec + i; u--, i--;)
2440 {
2441 if (u->u_type == TR_BANG)
2442 outlet_bang(u->u_outlet);
2443 else if (u->u_type == TR_ANYTHING)
2444 outlet_anything(u->u_outlet, s, argc, argv);
2445 else pd_error(x, "trigger: can only convert 's' to 'b' or 'a'",
2446 s->s_name);
2447 }
2448}
2449
2450static void trigger_bang(t_trigger *x)
2451{
2452 trigger_list(x, 0, 0, 0);
2453}
2454
2455static void trigger_pointer(t_trigger *x, t_gpointer *gp)
2456{
2457 t_atom at;
2458 SETPOINTER(&at, gp);
2459 trigger_list(x, 0, 1, &at);
2460}
2461
2462static void trigger_float(t_trigger *x, t_float f)
2463{
2464 t_atom at;
2465 SETFLOAT(&at, f);
2466 trigger_list(x, 0, 1, &at);
2467}
2468
2469static void trigger_symbol(t_trigger *x, t_symbol *s)
2470{
2471 t_atom at;
2472 SETSYMBOL(&at, s);
2473 trigger_list(x, 0, 1, &at);
2474}
2475
2476static void trigger_free(t_trigger *x)
2477{
2478 freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
2479}
2480
2481static void trigger_setup(void)
2482{
2483 trigger_class = class_new(gensym("trigger"), (t_newmethod)trigger_new,
2484 (t_method)trigger_free, sizeof(t_trigger), 0, A_GIMME, 0);
2485 class_addcreator((t_newmethod)trigger_new, gensym("t"), A_GIMME, 0);
2486 class_addlist(trigger_class, trigger_list);
2487 class_addbang(trigger_class, trigger_bang);
2488 class_addpointer(trigger_class, trigger_pointer);
2489 class_addfloat(trigger_class, (t_method)trigger_float);
2490 class_addsymbol(trigger_class, trigger_symbol);
2491 class_addanything(trigger_class, trigger_anything);
2492}
2493
2494/* -------------------------- spigot ------------------------------ */
2495static t_class *spigot_class;
2496
2497typedef struct _spigot
2498{
2499 t_object x_obj;
2500 float x_state;
2501} t_spigot;
2502
2503static void *spigot_new(void)
2504{
2505 t_spigot *x = (t_spigot *)pd_new(spigot_class);
2506 floatinlet_new(&x->x_obj, &x->x_state);
2507 outlet_new(&x->x_obj, 0);
2508 x->x_state = 0;
2509 return (x);
2510}
2511
2512static void spigot_bang(t_spigot *x)
2513{
2514 if (x->x_state != 0) outlet_bang(x->x_obj.ob_outlet);
2515}
2516
2517static void spigot_pointer(t_spigot *x, t_gpointer *gp)
2518{
2519 if (x->x_state != 0) outlet_pointer(x->x_obj.ob_outlet, gp);
2520}
2521
2522static void spigot_float(t_spigot *x, t_float f)
2523{
2524 if (x->x_state != 0) outlet_float(x->x_obj.ob_outlet, f);
2525}
2526
2527static void spigot_symbol(t_spigot *x, t_symbol *s)
2528{
2529 if (x->x_state != 0) outlet_symbol(x->x_obj.ob_outlet, s);
2530}
2531
2532static void spigot_list(t_spigot *x, t_symbol *s, int argc, t_atom *argv)
2533{
2534 if (x->x_state != 0) outlet_list(x->x_obj.ob_outlet, s, argc, argv);
2535}
2536
2537static void spigot_anything(t_spigot *x, t_symbol *s, int argc, t_atom *argv)
2538{
2539 if (x->x_state != 0) outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
2540}
2541
2542static void spigot_setup(void)
2543{
2544 spigot_class = class_new(gensym("spigot"), (t_newmethod)spigot_new, 0,
2545 sizeof(t_spigot), 0, A_DEFSYM, 0);
2546 class_addbang(spigot_class, spigot_bang);
2547 class_addpointer(spigot_class, spigot_pointer);
2548 class_addfloat(spigot_class, spigot_float);
2549 class_addsymbol(spigot_class, spigot_symbol);
2550 class_addlist(spigot_class, spigot_list);
2551 class_addanything(spigot_class, spigot_anything);
2552}
2553
2554/* --------------------------- moses ----------------------------- */
2555static t_class *moses_class;
2556
2557typedef struct _moses
2558{
2559 t_object x_ob;
2560 t_outlet *x_out2;
2561 float x_y;
2562} t_moses;
2563
2564static void *moses_new(t_floatarg f)
2565{
2566 t_moses *x = (t_moses *)pd_new(moses_class);
2567 floatinlet_new(&x->x_ob, &x->x_y);
2568 outlet_new(&x->x_ob, &s_float);
2569 x->x_out2 = outlet_new(&x->x_ob, &s_float);
2570 x->x_y = f;
2571 return (x);
2572}
2573
2574static void moses_float(t_moses *x, t_float f)
2575{
2576 if (f < x->x_y) outlet_float(x->x_ob.ob_outlet, f);
2577 else outlet_float(x->x_out2, f);
2578}
2579
2580static void moses_setup(void)
2581{
2582 moses_class = class_new(gensym("moses"), (t_newmethod)moses_new, 0,
2583 sizeof(t_moses), 0, A_DEFFLOAT, 0);
2584 class_addfloat(moses_class, moses_float);
2585}
2586
2587/* ----------------------- until --------------------- */
2588
2589static t_class *until_class;
2590
2591typedef struct _until
2592{
2593 t_object x_obj;
2594 int x_run;
2595 int x_count;
2596} t_until;
2597
2598static void *until_new(void)
2599{
2600 t_until *x = (t_until *)pd_new(until_class);
2601 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("bang"), gensym("bang2"));
2602 outlet_new(&x->x_obj, &s_bang);
2603 x->x_run = 0;
2604 return (x);
2605}
2606
2607static void until_bang(t_until *x)
2608{
2609 x->x_run = 1;
2610 x->x_count = -1;
2611 while (x->x_run && x->x_count)
2612 x->x_count--, outlet_bang(x->x_obj.ob_outlet);
2613}
2614
2615static void until_float(t_until *x, t_float f)
2616{
2617 x->x_run = 1;
2618 x->x_count = f;
2619 while (x->x_run && x->x_count)
2620 x->x_count--, outlet_bang(x->x_obj.ob_outlet);
2621}
2622
2623static void until_bang2(t_until *x)
2624{
2625 x->x_run = 0;
2626}
2627
2628static void until_setup(void)
2629{
2630 until_class = class_new(gensym("until"), (t_newmethod)until_new, 0,
2631 sizeof(t_until), 0, 0);
2632 class_addbang(until_class, until_bang);
2633 class_addfloat(until_class, until_float);
2634 class_addmethod(until_class, (t_method)until_bang2, gensym("bang2"), 0);
2635}
2636
2637/* ----------------------- makefilename --------------------- */
2638
2639static t_class *makefilename_class;
2640
2641typedef struct _makefilename
2642{
2643 t_object x_obj;
2644 t_symbol *x_format;
2645} t_makefilename;
2646
2647static void *makefilename_new(t_symbol *s)
2648{
2649 t_makefilename *x = (t_makefilename *)pd_new(makefilename_class);
2650 if (!s->s_name) s = gensym("file.%d");
2651 outlet_new(&x->x_obj, &s_symbol);
2652 x->x_format = s;
2653 return (x);
2654}
2655
2656static void makefilename_float(t_makefilename *x, t_floatarg f)
2657{
2658 char buf[MAXPDSTRING];
2659 sprintf(buf, x->x_format->s_name, (int)f);
2660 outlet_symbol(x->x_obj.ob_outlet, gensym(buf));
2661}
2662
2663static void makefilename_symbol(t_makefilename *x, t_symbol *s)
2664{
2665 char buf[MAXPDSTRING];
2666 sprintf(buf, x->x_format->s_name, s->s_name);
2667 outlet_symbol(x->x_obj.ob_outlet, gensym(buf));
2668}
2669
2670static void makefilename_setup(void)
2671{
2672 makefilename_class = class_new(gensym("makefilename"),
2673 (t_newmethod)makefilename_new, 0,
2674 sizeof(t_makefilename), 0, A_DEFSYM, 0);
2675 class_addfloat(makefilename_class, makefilename_float);
2676 class_addsymbol(makefilename_class, makefilename_symbol);
2677}
2678
2679/* -------------------------- swap ------------------------------ */
2680static t_class *swap_class;
2681
2682typedef struct _swap
2683{
2684 t_object x_obj;
2685 t_outlet *x_out2;
2686 t_float x_f1;
2687 t_float x_f2;
2688} t_swap;
2689
2690static void *swap_new(t_floatarg f)
2691{
2692 t_swap *x = (t_swap *)pd_new(swap_class);
2693 x->x_f2 = f;
2694 x->x_f1 = 0;
2695 outlet_new(&x->x_obj, &s_float);
2696 x->x_out2 = outlet_new(&x->x_obj, &s_float);
2697 floatinlet_new(&x->x_obj, &x->x_f2);
2698 return (x);
2699}
2700
2701static void swap_bang(t_swap *x)
2702{
2703 outlet_float(x->x_out2, x->x_f1);
2704 outlet_float(x->x_obj.ob_outlet, x->x_f2);
2705}
2706
2707static void swap_float(t_swap *x, t_float f)
2708{
2709 x->x_f1 = f;
2710 swap_bang(x);
2711}
2712
2713void swap_setup(void)
2714{
2715 swap_class = class_new(gensym("swap"), (t_newmethod)swap_new, 0,
2716 sizeof(t_swap), 0, A_DEFFLOAT, 0);
2717 class_addcreator((t_newmethod)swap_new, gensym("fswap"), A_DEFFLOAT, 0);
2718 class_addbang(swap_class, swap_bang);
2719 class_addfloat(swap_class, swap_float);
2720}
2721
2722/* -------------------------- change ------------------------------ */
2723static t_class *change_class;
2724
2725typedef struct _change
2726{
2727 t_object x_obj;
2728 t_float x_f;
2729} t_change;
2730
2731static void *change_new(t_floatarg f)
2732{
2733 t_change *x = (t_change *)pd_new(change_class);
2734 x->x_f = f;
2735 outlet_new(&x->x_obj, &s_float);
2736 return (x);
2737}
2738
2739static void change_bang(t_change *x)
2740{
2741 outlet_float(x->x_obj.ob_outlet, x->x_f);
2742}
2743
2744static void change_float(t_change *x, t_float f)
2745{
2746 if (f != x->x_f)
2747 {
2748 x->x_f = f;
2749 outlet_float(x->x_obj.ob_outlet, x->x_f);
2750 }
2751}
2752
2753static void change_set(t_change *x, t_float f)
2754{
2755 x->x_f = f;
2756}
2757
2758void change_setup(void)
2759{
2760 change_class = class_new(gensym("change"), (t_newmethod)change_new, 0,
2761 sizeof(t_change), 0, A_DEFFLOAT, 0);
2762 class_addbang(change_class, change_bang);
2763 class_addfloat(change_class, change_float);
2764 class_addmethod(change_class, (t_method)change_set, gensym("set"),
2765 A_DEFFLOAT, 0);
2766}
2767
2768/* -------------------- value ------------------------------ */
2769
2770static t_class *value_class, *vcommon_class;
2771
2772typedef struct vcommon
2773{
2774 t_pd c_pd;
2775 int c_refcount;
2776 t_float c_f;
2777} t_vcommon;
2778
2779typedef struct _value
2780{
2781 t_object x_obj;
2782 t_symbol *x_sym;
2783 t_float *x_floatstar;
2784} t_value;
2785
2786 /* get a pointer to a named floating-point variable. The variable
2787 belongs to a "vcommon" object, which is created if necessary. */
2788t_float *value_get(t_symbol *s)
2789{
2790 t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
2791 if (!c)
2792 {
2793 c = (t_vcommon *)pd_new(vcommon_class);
2794 c->c_f = 0;
2795 c->c_refcount = 0;
2796 pd_bind(&c->c_pd, s);
2797 }
2798 c->c_refcount++;
2799 return (&c->c_f);
2800}
2801
2802 /* release a variable. This only frees the "vcommon" resource when the
2803 last interested party releases it. */
2804void value_release(t_symbol *s)
2805{
2806 t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
2807 if (c)
2808 {
2809 if (!--c->c_refcount)
2810 {
2811 pd_unbind(&c->c_pd, s);
2812 pd_free(&c->c_pd);
2813 }
2814 }
2815 else bug("value_release");
2816}
2817
2818/*
2819 * value_getfloat -- obtain the float value of a "value" object
2820 * return 0 on success, 1 otherwise
2821 */
2822int
2823value_getfloat(t_symbol *s, t_float *f)
2824{
2825 t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
2826 if (!c)
2827 return (1);
2828 *f = c->c_f;
2829 return (0);
2830}
2831
2832/*
2833 * value_setfloat -- set the float value of a "value" object
2834 * return 0 on success, 1 otherwise
2835 */
2836int
2837value_setfloat(t_symbol *s, t_float f)
2838{
2839 t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
2840 if (!c)
2841 return (1);
2842 c->c_f = f;
2843 return (0);
2844}
2845
2846static void *value_new(t_symbol *s)
2847{
2848 t_value *x = (t_value *)pd_new(value_class);
2849 x->x_sym = s;
2850 x->x_floatstar = value_get(s);
2851 outlet_new(&x->x_obj, &s_float);
2852 return (x);
2853}
2854
2855static void value_bang(t_value *x)
2856{
2857 outlet_float(x->x_obj.ob_outlet, *x->x_floatstar);
2858}
2859
2860static void value_float(t_value *x, t_float f)
2861{
2862 *x->x_floatstar = f;
2863}
2864
2865static void value_ff(t_value *x)
2866{
2867 value_release(x->x_sym);
2868}
2869
2870static void value_setup(void)
2871{
2872 value_class = class_new(gensym("value"), (t_newmethod)value_new,
2873 (t_method)value_ff,
2874 sizeof(t_value), 0, A_DEFSYM, 0);
2875 class_addcreator((t_newmethod)value_new, gensym("v"), A_DEFSYM, 0);
2876 class_addbang(value_class, value_bang);
2877 class_addfloat(value_class, value_float);
2878 vcommon_class = class_new(gensym("value"), 0, 0,
2879 sizeof(t_vcommon), CLASS_PD, 0);
2880}
2881
2882/* -------------- overall setup routine for this file ----------------- */
2883
2884void x_connective_setup(void)
2885{
2886 pdint_setup();
2887 pdfloat_setup();
2888 pdsymbol_setup();
2889 bang_setup();
2890 send_setup();
2891 receive_setup();
2892 select_setup();
2893 route_setup();
2894 pack_setup();
2895 unpack_setup();
2896 trigger_setup();
2897 spigot_setup();
2898 moses_setup();
2899 until_setup();
2900 makefilename_setup();
2901 swap_setup();
2902 change_setup();
2903 value_setup();
2904}