Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Jonathan Wilkes
flext
Commits
4f489341
Commit
4f489341
authored
Apr 16, 2002
by
thomas
Browse files
no message
git-svn-id:
https://svn.grrrr.org/ext/trunk@150
4d9ac71a-51e6-0310-8455-cad1006bcd31
parent
c4cca012
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
flext.dsp
View file @
4f489341
...
...
@@ -102,7 +102,7 @@ SOURCE=.\flbuf.cpp
# End Source File
# Begin Source File
SOURCE=.\flc
wmax
.h
SOURCE=.\flc
lass
.h
# End Source File
# Begin Source File
...
...
@@ -122,6 +122,10 @@ SOURCE=.\flext.h
# End Source File
# Begin Source File
SOURCE=.\flinternal.h
# End Source File
# Begin Source File
SOURCE=.\flstdc.h
# End Source File
# End Target
...
...
readme.txt
View file @
4f489341
flext - C++ layer for Max/MSP and pd (pure data) externals
version 0.2.
2
version 0.2.
3
Copyright (c) 2001,2002 Thomas Grill (xovo@gmx.net)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
...
...
@@ -70,6 +70,10 @@ see flext.h for the documented base classes
Version history:
0.2.3:
- restructured files and started usable inline documentation
- found that there was no means to output a bang?! Ugh! -> corrected
0.2.2:
- added xgimme argument type (supplies method handlers with symbol+gimme)
- more information on DSP system with flext_dsp object (block size,number of audio inputs and outputs)
...
...
source/flbase.h
View file @
4f489341
...
...
@@ -10,56 +10,60 @@ WARRANTIES, see the file, "license.txt," in this distribution.
// This is all derived from GEM by Mark Danks
/*! \file flbase.h
\brief Declares the internal flext base classes
!Lacking Details.!
*/
#ifndef __FLEXT_BASE_H
#define __FLEXT_BASE_H
#include <flstdc.h>
class
flext_obj
;
/*-----------------------------------------------------------------
-------------------------------------------------------------------
CLASS
flext_hdr
The obligatory object header
// ----------------------------------------------------------------------------
/*! \struct flext_hdr
\brief The obligatory PD or MaxMSP object header
DESCRIPTION
This is in a separate struct to assure that obj is the very first thing.
If it were the first thing in flext_obj, then there could be problems with
the vtable.
-----------------------------------------------------------------*/
*/
// ----------------------------------------------------------------------------
struct
FLEXT_EXT
flext_hdr
{
//////////
// The obligatory object header
t_sigobj
obj
;
// MUST reside at memory offset 0
/*! \brief The obligatory object header
MUST reside at memory offset 0
*/
t_sigobj
obj
;
#ifdef PD
float
defsig
;
// float signal holder for pd
//! PD only: float signal holder for pd
float
defsig
;
#endif
#if defined(MAXMSP)
long
curinlet
;
// current inlet used by proxy objects
//! MaxMSP only: current inlet used by proxy objects
long
curinlet
;
#endif
//////////
// Our data structure
/*! \brief Our data structure
This points to the actual polymorphic C++ class
*/
flext_obj
*
data
;
};
/*-----------------------------------------------------------------
-------------------------------------------------------------------
CLASS
flext_obj
The base class for all externs written in C++
DESCRIPTION
// ----------------------------------------------------------------------------
/*! \class flext_obj
\brief The mother of base classes for all externs written in C++
Each extern which is written in C++ needs to use the #defines at the
end of this header file.
...
...
@@ -76,8 +80,9 @@ DESCRIPTION
should be the first thing in your implementation file.
NEW_CLASS is the name of your class and PARENT_CLASS is the
parent of your class.
-----------------------------------------------------------------*/
*/
// ----------------------------------------------------------------------------
class
FLEXT_EXT
flext_obj
{
public:
...
...
@@ -99,50 +104,46 @@ class FLEXT_EXT flext_obj
// ---------------------
//////////
// Constructor
//! Constructor
flext_obj
();
//////////
// Destructor
//! Destructor
virtual
~
flext_obj
()
=
0
;
//////////
// Get the object's canvas
//! Get the object's canvas
t_canvas
*
getCanvas
()
{
return
(
m_canvas
);
}
protected:
//////////
// The object header
//! The object header
flext_hdr
*
x_obj
;
private:
//////////
// The canvas (patcher) that the object is in
//! The canvas (patcher) that the object is in
t_canvas
*
m_canvas
;
public:
//////////
// Creation callback
//! Creation callback
static
void
callb_setup
(
t_class
*
)
{}
//////////
// --------------------
// This is a holder - don't touch it
static
flext_hdr
*
m_holder
;
static
const
char
*
m_holdname
;
// hold object's name during construction
//////////
// The object's name in the patcher
//! The object's name in the patcher
const
char
*
m_name
;
#ifdef _DEBUG
//! check whether the object's name has a trailing tilde
static
bool
check_tilde
(
const
char
*
objname
,
const
char
*
setupfun
);
#endif
#ifdef MAXMSP
/*! definitions for MaxMSP external libraries */
union
lib_arg
{
int
i
;
float
f
;
...
...
@@ -156,12 +157,12 @@ class FLEXT_EXT flext_obj
#endif
};
// This has a dummy arg so that NT won't complain
//
!
This has a dummy arg so that NT won't complain
inline
void
*
operator
new
(
size_t
,
void
*
location
,
void
*
)
{
return
location
;
}
//
//////////////////////////////////////
//
----------------------------------------
// This should be used in the header
//
//////////////////////////////////////
//
----------------------------------------
#ifdef PD
#define FLEXT_GETCLASS(obj) ((t_class *)((t_object *)(obj))->te_g.g_pd)
...
...
@@ -170,9 +171,7 @@ inline void *operator new(size_t, void *location, void *) { return location; }
#endif
// Header without setup callback
#define FLEXT_HEADER(NEW_CLASS, PARENT_CLASS) \
#define FLEXT_REALHDR(NEW_CLASS, PARENT_CLASS) \
public: \
typedef NEW_CLASS thisType; \
static void callb_free(flext_hdr *hdr) \
...
...
@@ -187,9 +186,7 @@ inline const char *thisName() const { return m_name; } \
static NEW_CLASS *thisObject(void *c) { return (NEW_CLASS *)((flext_hdr *)c)->data; }
// Header with setup callback
#define FLEXT_HEADER_S(NEW_CLASS, PARENT_CLASS,SETUPFUN) \
#define FLEXT_REALHDR_S(NEW_CLASS, PARENT_CLASS,SETUPFUN) \
public: \
typedef NEW_CLASS thisType; \
static void callb_free(flext_hdr *hdr) \
...
...
@@ -205,6 +202,7 @@ inline const char *thisName() const { return m_name; } \
static NEW_CLASS *thisObject(void *c) { return (NEW_CLASS *)((flext_hdr *)c)->data; }
#define REAL_NEW(NAME,NEW_CLASS,SETUP_FUNCTION) REAL_INST(0,NAME,NEW_CLASS,SETUP_FUNCTION)
#define REAL_NEW_G(NAME,NEW_CLASS,SETUP_FUNCTION) REAL_INST_G(0,NAME,NEW_CLASS,SETUP_FUNCTION)
#define REAL_NEW_1(NAME,NEW_CLASS,SETUP_FUNCTION,TYPE1) REAL_INST_1(0,NAME,NEW_CLASS,SETUP_FUNCTION,TYPE1)
...
...
@@ -227,97 +225,13 @@ static NEW_CLASS *thisObject(void *c) { return (NEW_CLASS *)((flext_hdr *)c)->da
#define REAL_LIB_3(NAME,NEW_CLASS,SETUP_FUNCTION,TYPE1,TYPE2,TYPE3) REAL_NEWLIB_3(NAME,NEW_CLASS,SETUP_FUNCTION,TYPE1,TYPE2,TYPE3)
#endif
////////////////////////////////////////
// This should be the first thing in the implementation file
////////////////////////////////////////
//
// NO ARGUMENTS
/////////////////////////////////////////////////
#define FLEXT_NEW(NAME,NEW_CLASS) \
REAL_NEW(NAME,NEW_CLASS, _setup) \
REAL_EXT(NEW_CLASS, _setup)
#define FLEXT_NEW_TILDE(NAME,NEW_CLASS) \
REAL_NEW(NAME,NEW_CLASS, _tilde_setup) \
REAL_EXT(NEW_CLASS, _tilde_setup)
// --------------------------------------------------------------------------------------
#define FLEXT_LIB(NAME,NEW_CLASS) REAL_LIB(NAME,NEW_CLASS, _setup)
#define FLEXT_LIB_TILDE(NAME,NEW_CLASS) REAL_LIB(NAME,NEW_CLASS, _tilde_setup)
//
// ONE ARGUMENT
/////////////////////////////////////////////////
#define FLEXT_NEW_1(NAME,NEW_CLASS, TYPE) \
REAL_NEW_1(NAME,NEW_CLASS, _setup, TYPE) \
REAL_EXT(NEW_CLASS, _setup)
#define FLEXT_NEW_TILDE_1(NAME,NEW_CLASS, TYPE) \
REAL_NEW_1(NAME,NEW_CLASS, _tilde_setup, TYPE) \
REAL_EXT(NEW_CLASS, _tilde_setup)
#define FLEXT_LIB_1(NAME,NEW_CLASS, TYPE) REAL_LIB_1(NAME,NEW_CLASS, _setup,TYPE)
#define FLEXT_LIB_TILDE_1(NAME,NEW_CLASS, TYPE) REAL_LIB_1(NAME,NEW_CLASS, _tilde_setup, TYPE)
//
// GIMME ARGUMENT
/////////////////////////////////////////////////
#define FLEXT_NEW_G(NAME,NEW_CLASS) \
REAL_NEW_G(NAME,NEW_CLASS, _setup) \
REAL_EXT(NEW_CLASS, _setup)
#define FLEXT_NEW_TILDE_G(NAME,NEW_CLASS) \
REAL_NEW_G(NAME,NEW_CLASS,_tilde_setup) \
REAL_EXT(NEW_CLASS, _tilde_setup)
#define FLEXT_LIB_G(NAME,NEW_CLASS) REAL_LIB_G(NAME,NEW_CLASS, _setup)
#define FLEXT_LIB_TILDE_G(NAME,NEW_CLASS) REAL_LIB_G(NAME,NEW_CLASS, _tilde_setup)
//
// TWO ARGUMENTS
/////////////////////////////////////////////////
#define FLEXT_NEW_2(NAME,NEW_CLASS, TYPE1, TYPE2) \
REAL_NEW_2(NAME,NEW_CLASS, _setup, TYPE1, TYPE2) \
REAL_EXT(NEW_CLASS, _setup)
#define FLEXT_NEW_TILDE_2(NAME,NEW_CLASS, TYPE1, TYPE2) \
REAL_NEW_2(NAME,NEW_CLASS, _tilde_setup, TYPE1, TYPE2) \
REAL_EXT(NEW_CLASS, _tilde_setup)
#define FLEXT_LIB_2(NAME,NEW_CLASS, TYPE1, TYPE2) REAL_LIB_2(NAME,NEW_CLASS, _setup, TYPE1, TYPE2)
#define FLEXT_LIB_TILDE_2(NAME,NEW_CLASS, TYPE1, TYPE2) REAL_LIB_2(NAME,NEW_CLASS, _tilde_setup, TYPE1, TYPE2)
//
// THREE ARGUMENTS
/////////////////////////////////////////////////
#define FLEXT_NEW_3(NAME,NEW_CLASS, TYPE1, TYPE2, TYPE3) \
REAL_NEW_3(NAME,NEW_CLASS, _setup, TYPE1, TYPE2, TYPE3) \
REAL_EXT(NEW_CLASS, _setup)
#define FLEXT_NEW_TILDE_3(NAME,NEW_CLASS, TYPE1, TYPE2, TYPE3) \
REAL_NEW_3(NAME,NEW_CLASS, _tilde_setup, TYPE1, TYPE2, TYPE3) \
REAL_EXT(NEW_CLASS, _tilde_setup)
#define FLEXT_LIB_3(NAME,NEW_CLASS, TYPE1, TYPE2, TYPE3) REAL_LIB_3(NAME,NEW_CLASS, _setup,TYPE1, TYPE2, TYPE3)
#define FLEXT_LIB_TILDE_3(NAME,NEW_CLASS, TYPE1, TYPE2, TYPE3) REAL_LIB_3(NAME,NEW_CLASS, _tilde_setup, TYPE1, TYPE2, TYPE3)
/*
// MaxMSP doesn't seem to be able to handle more than 3 creation arguments! -> USE GIMME
//
// FOUR ARGUMENTS
/////////////////////////////////////////////////
#define FLEXT_NEW_4(NAME,NEW_CLASS, TYPE, TTWO, TTHREE, TFOUR) \
REAL_NEW_4(NAME,NEW_CLASS, _setup, _class, TYPE, TTWO, TTHREE, TFOUR)
#define FLEXT_NEW_TILDE_4(NAME,NEW_CLASS, TYPE, TTWO, TTHREE, TFOUR) \
REAL_NEW_4(NAME,NEW_CLASS, _tilde_setup, _class, TYPE, TTWO, TTHREE, TFOUR)
*/
//////////////////////////////////////////////////////
// --------------------------------------------------
// This is to be called in the library setup function
//
////////////////////////////////////////////////////
//
---------------------------------------------------
#define FLEXT_EXP_0 extern "C" FLEXT_EXT
#define FLEXT_EXP_1
...
...
@@ -332,19 +246,23 @@ extern void cl##_tilde_setup(); \
cl##_tilde_setup()
#ifdef PD
#define FLEXT_LIB_SETUP(NAME,SETUPFUN) extern "C" FLEXT_EXT void NAME##_setup() { SETUPFUN(); }
#else // MAXMSP
#define FLEXT_LIB_SETUP(NAME,SETUPFUN) \
extern "C" FLEXT_EXT int main() { \
SETUPFUN(); \
::setup((t_messlist **)&flext_obj::lib_class,(t_newmethod)&flext_obj::libfun_new,(t_method)flext_obj::libfun_free,sizeof(flext_hdr), 0,A_GIMME,A_NULL); \
return 0; \
}
#endif
//
//////////////////////////////////////
//
----------------------------------------
// These definitions are used below
//
//////////////////////////////////////
//
----------------------------------------
// Shortcuts for PD/Max type arguments
#define FLEXTTYPE_void A_NULL
...
...
@@ -404,16 +322,15 @@ return 0; \
#endif
//
/////////////////////////////////////////////////////////////////////////////
//
----------------------------------------------------
// These should never be called or used directly!!!
//
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------
//
/////////////////////////////////////////////////////////////////////////////
//
----------------------------------------------------
// no args
//
/////////////////////////////////////////////////////////////////////////////
//
----------------------------------------------------
#define REAL_INST(LIB,NAME,NEW_CLASS, SETUP_FUNCTION) \
static t_class * NEW_CLASS ## _class; \
flext_hdr* class_ ## NEW_CLASS () \
...
...
@@ -455,9 +372,9 @@ void NEW_CLASS ## SETUP_FUNCTION() \
}
//
/////////////////////////////////////////////////////////////////////////////
//
----------------------------------------------------
// one arg
//
/////////////////////////////////////////////////////////////////////////////
//
----------------------------------------------------
#define REAL_INST_1(LIB,NAME,NEW_CLASS, SETUP_FUNCTION, TYPE1) \
static t_class * NEW_CLASS ## _class; \
flext_hdr* class_ ## NEW_CLASS (TYPE1 arg1) \
...
...
@@ -500,9 +417,9 @@ void NEW_CLASS ## SETUP_FUNCTION() \
}
//
/////////////////////////////////////////////////////////////////////////////
//
----------------------------------------------------
// gimme arg
//
/////////////////////////////////////////////////////////////////////////////
//
----------------------------------------------------
#define REAL_INST_G(LIB,NAME,NEW_CLASS, SETUP_FUNCTION) \
static t_class * NEW_CLASS ## _class; \
flext_hdr* class_ ## NEW_CLASS (t_symbol *s,int argc,t_atom *argv) \
...
...
@@ -545,9 +462,9 @@ void NEW_CLASS ## SETUP_FUNCTION() \
}
//
/////////////////////////////////////////////////////////////////////////////
//
----------------------------------------------------
// two args
//
/////////////////////////////////////////////////////////////////////////////
//
----------------------------------------------------
#define REAL_INST_2(LIB,NAME,NEW_CLASS, SETUP_FUNCTION, TYPE1, TYPE2) \
static t_class * NEW_CLASS ## _class; \
flext_hdr* class_ ## NEW_CLASS (TYPE1 arg1, TYPE2 arg2) \
...
...
@@ -590,9 +507,9 @@ void NEW_CLASS ## SETUP_FUNCTION() \
}
//
/////////////////////////////////////////////////////////////////////////////
//
----------------------------------------------------
// three args
//
/////////////////////////////////////////////////////////////////////////////
//
----------------------------------------------------
#define REAL_INST_3(LIB,NAME,NEW_CLASS, SETUP_FUNCTION, TYPE1,TYPE2,TYPE3) \
static t_class * NEW_CLASS ## _class; \
flext_hdr* class_ ## NEW_CLASS (TYPE1 arg1,TYPE2 arg2,TYPE3 arg3) \
...
...
@@ -634,9 +551,9 @@ void NEW_CLASS ## SETUP_FUNCTION() \
NEW_CLASS::callb_setup(flext_obj::lib_class); \
}
//
/////////////////////////////////////////////////////////////////////////////
//
----------------------------------------------------
// four args
//
/////////////////////////////////////////////////////////////////////////////
//
----------------------------------------------------
#define REAL_INST_4(LIB,NAME,NEW_CLASS, SETUP_FUNCTION, TYPE1,TYPE2,TYPE3,TYPE4) \
static t_class * NEW_CLASS ## _class; \
flext_hdr* class_ ## NEW_CLASS (TYPE1 arg1,TYPE2 arg2,TYPE3 arg3,TYPE4 arg4) \
...
...
@@ -678,6 +595,19 @@ void NEW_CLASS ## SETUP_FUNCTION() \
NEW_CLASS::callb_setup(flext_obj::lib_class); \
}
// Shortcuts for method arguments:
#define FLEXTARG_float a_float
#define FLEXTARG_int a_int
#define FLEXTARG_bool a_int
#define FLEXTARG_t_float a_float
#define FLEXTARG_t_symtype a_symbol
#define FLEXTARG_t_ptrtype a_pointer
#define FLEXTARG(TP) FLEXTARG_ ## TP
#endif
...
...
source/flclass.h
View file @
4f489341
/*
flext - C++ layer for Max/MSP and pd (pure data) externals
Copyright (c) 2001,2002 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 flclass.h
\brief Declares the user accessible flext base classes
!Lacking Details.!
*/
#ifndef __FLCLASS_H
#define __FLCLASS_H
//! include the header file declaring the base classes
#include <flbase.h>
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#endif
#ifdef __BORLANDC__
#pragma warn -8008 // Condition is always false
#pragma warn -8057 // Parameter is never used
#pragma warn -8066 // Unreachable code
#endif
// === flext_base ==================================================
/*! \class flext_base
\brief message only base object
*/
class
flext_base
:
public
flext_obj
{
FLEXT_HEADER_S
(
flext_base
,
flext_obj
,
Setup
)
public:
// --- compatibility mode ----------------------------------------
/*! \brief Cross-platform compatibility flag.
If set flext allows only operations valid for all platforms.
Set to true by default!
*/
static
bool
compatibility
;
// --- inheritable virtual methods --------------------------------
//! called on "help" message: should post some text
virtual
void
m_help
();
//! called on patcher load (not on mere object creation!)
virtual
void
m_loadbang
()
{}
//! quickhelp for inlets/outlets (gets calles in MaxMSP only)
virtual
void
m_assist
(
long
/*msg*/
,
long
/*arg*/
,
char
*
/*s*/
)
{}
/*! \brief Called for every incoming message.
All method handling is done in there
\return True if a handler was found and called
*/
virtual
bool
m_methodmain
(
int
inlet
,
const
t_symbol
*
s
,
int
argc
,
t_atom
*
argv
);
//! called for every unhandled message (by m_methodmain)
virtual
void
m_method_
(
int
inlet
,
const
t_symbol
*
s
,
int
argc
,
t_atom
*
argv
);
// --- buffer/array stuff -----------------------------------------
//! \class class for platform independent buffer handling
class
buffer
{
public:
/*! \brief Construct buffer.
@param delayed = true: only sets name, needs another Set(NULL) to really initialize the buffer
\remark As externals can be created prior to the buffer objects they are pointing to, initialization should be done at loadbang!
*/
buffer
(
t_symbol
*
s
=
NULL
,
bool
delayed
=
false
);
//! Destroy buffer
~
buffer
();
/*! \brief Set to specified buffer.
@param nameonly: if true sets name only, but doesn't look at buffer actually
*/
int
Set
(
t_symbol
*
s
=
NULL
,
bool
nameonly
=
false
);
/*! \brief Declare buffer content as dirty.
@param refr: if true forces immediate graphics refresh
*/
void
Dirty
(
bool
refr
=
false
);
//! Get symbol of buffer
t_symbol
*
Symbol
()
const
{
return
sym
;
}
//! Get literal name of buffer
const
char
*
Name
()
const
{
return
sym
?
sym
->
s_name
:
""
;
}
/*! \brief Get pointer to buffer, channel and frame count.
\remark Channels are interleaved
*/
float
*
Data
()
{
return
data
;
}
//! Get channel count
int
Channels
()
const
{
return
chns
;
}
//! Get frame count
int
Frames
()
const
{
return
frames
;
}
//! Graphic auto refresh interval
void
SetRefrIntv
(
float
intv
);
protected:
t_symbol
*
sym
;
float
*
data
;
int
chns
,
frames
;
#ifdef PD
float
interval
;
bool
isdirty
,
ticking
;
t_clock
*
tick
;
private:
static
void
cb_tick
(
buffer
*
b
);
#endif
};
// --- inlet/outlet stuff -----------------------------------------
// define inlets/outlets - all (also default) inlets must be defined
// argument m specifies multiple inlet/outlet count
// void AddInDef() { AddInlet(xlet::tp_def,1); }
//! add inlet(s) for anythings
void
AddInAnything
(
int
m
=
1
)
{
AddInlet
(
xlet
::
tp_any
,
m
);
}
// leftmost or via proxy
//! add inlet(s) for floats
void
AddInFloat
(
int
m
=
1
)
{
AddInlet
(
xlet
::
tp_float
,
m
);
}
//! add inlet(s) for flints
void
AddInFlint
(
int
m
=
1
)
{
AddInlet
(
xlet
::
tp_flint
,
m
);
}
//! add inlet(s) for symbols
void
AddInSymbol
(
int
m
=
1
)
{
AddInlet
(
xlet
::
tp_sym
,
m
);
}
//! add inlet(s) for lists
void
AddInList
(
int
m
=
1
)
{
AddInlet
(
xlet
::
tp_list
,
m
);
}
// via proxy
//! add outlet(s) for anythings
void
AddOutAnything
(
int
m
=
1
)
{
AddOutlet
(
xlet
::
tp_any
,
m
);
}
//! add outlet(s) for floats
void
AddOutFloat
(
int
m
=
1
)
{
AddOutlet
(
xlet
::
tp_float
,
m
);
}
//! add outlet(s) for flints
void
AddOutFlint
(
int
m
=
1
)
{
AddOutlet
(
xlet
::
tp_flint
,
m
);
}
//! add outlet(s) for symbols
void
AddOutSymbol
(
int
m
=
1
)
{
AddOutlet
(
xlet
::
tp_sym
,
m
);
}
//! add outlet(s) for lists
void
AddOutList
(
int
m
=
1
)
{
AddOutlet
(
xlet
::
tp_list
,
m
);
}
/*! \brief set up inlets and outlets
\remark Must be called ONCE to actually set up the defined inlets/outlets.
\return True on successful creation of all inlets and outlets
*/
bool
SetupInOut
();
//! get number of inlets
int
CntIn
()
const
{
return
incnt
;
}
//! get number of outlets
int
CntOut
()
const
{
return
outcnt
;
}
//! get number of signal inlets
int
CntInSig
()
const
{
return
insigs
;
}
//! get number of signal outlets
int
CntOutSig
()
const
{
return
outsigs
;
}
class
outlet
;
//! get pointer to outlet (_after_ calling setup_inout()!)
outlet
*
GetOut
(
int
ix
)
{
return
(
outlets
&&
ix
<
outcnt
)
?
outlets
[
ix
]
:
NULL
;
}
// output messages (index n starts with 0)
void
ToOutBang
(
outlet
*
o
);
//! output bang (index n starts with 0)
void
ToOutBang
(
int
n
)
{
outlet
*
o
=
GetOut
(
n
);
if
(
o
)
ToOutBang
(
o
);
}
void
ToOutFloat
(
outlet
*
o
,
float
f
);
//! output float (index n starts with 0)
void
ToOutFloat
(
int
n
,
float
f
)
{
outlet
*
o
=
GetOut
(
n
);
if
(
o
)
ToOutFloat
(
o
,
f
);
}