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 *,void *data),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 argc,t_atom *argv,void *data),void *data)
{
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,data);
#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,c->data);
}
|