aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/flext/source/flbind.cpp
blob: 3eee25ae0b9d770e46ae2b0aabd4de1ab6b09941 (plain)
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
/* 

flext - C++ layer for Max/MSP and pd (pure data) externals

Copyright (c) 2001-2003 Thomas Grill (xovo@gmx.net)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.  

*/

/*! \file flbind.cpp
    \brief Functionality for symbol-bound methods.
*/
 
#include "flext.h"
#include "flinternal.h"


t_class *flext_base::pxbnd_class = NULL;

flext_base::binditem::binditem(int in,const t_symbol *sym,bool (*f)(flext_base *,t_symbol *s,int,t_atom *),pxbnd_object *p):
	item(sym,0,NULL),fun(f),px(p)
{}


bool flext_base::BindMethod(const t_symbol *sym,bool (*fun)(flext_base *,t_symbol *s,int,t_atom *))
{
    if(!bindhead) 
        bindhead = new itemarr;
    else {
        // Search for symbol
        if(bindhead->Find(sym,0)) {
            post("%s - Symbol already bound",thisName());
            return false;
        }
    }

    FLEXT_ASSERT(pxbnd_class); 

    pxbnd_object *px = (pxbnd_object *)object_new(pxbnd_class);

    if(px) {
	    binditem *mi = new binditem(0,sym,fun,px);
	    bindhead->Add(mi);

        px->init(this,mi);

#if FLEXT_SYS == FLEXT_SYS_PD
    	pd_bind(&px->obj.ob_pd,const_cast<t_symbol *>(sym)); 
#elif FLEXT_SYS == FLEXT_SYS_MAX
        if(!sym->s_thing) 
            const_cast<t_symbol *>(sym)->s_thing = (t_object *)px;
        else
            error("%s - Symbol is already bound",thisName());
#else
#       pragma warning("Not implemented")
#endif
    }
    else 
        error("%s - Symbol proxy could not be created",thisName());

    return true;
}


bool flext_base::UnbindMethod(const t_symbol *sym)
{
    item *it = bindhead?bindhead->Find(sym,0):NULL;
    if(it) {
        bool ok = bindhead->Remove(it);
        if(ok) {
            pxbnd_object *px = ((binditem *)it)->px;
#if FLEXT_SYS == FLEXT_SYS_PD
    	    pd_unbind(&px->obj.ob_pd,const_cast<t_symbol *>(sym)); 
#elif FLEXT_SYS == FLEXT_SYS_MAX
    	    if(sym->s_thing == (t_object *)px) 
                const_cast<t_symbol *>(sym)->s_thing = NULL; 
            else
                error("%s - Binding not found",thisName());
#else
#           pragma warning("Not implemented")
#endif
            object_free(&px->obj);
            delete it;
        }
        return ok;
    }
    else
        return true;
}

void flext_base::pxbnd_object::px_method(pxbnd_object *c,const t_symbol *s,int argc,t_atom *argv)
{
    c->item->fun(c->base,(t_symbol *)s,argc,(t_atom *)argv);
}