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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
/*
* Pure Data Packet system implementation: control object
* Copyright (c) by Tom Schouten <tom@zwizwa.be>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/* this is an actual pd class that is used for communication with the
pdp framework */
#include "pdp_internals.h"
#include "pdp_control.h"
#include "pdp_packet.h"
#include <stdio.h>
/* all symbols are C style */
#ifdef __cplusplus
extern "C"
{
#endif
static long dropped_packets;
static t_class* pdp_control_class;
/* pdp control instance data */
struct _pdp_control;
typedef struct _pdp_control
{
t_object x_obj;
t_outlet *x_outlet0;
struct _pdp_control *x_next;
} t_pdp_control;
static t_pdp_control *pdp_control_list;
static void pdp_control_info(t_pdp_control __attribute__((unused)) *x)
{
}
static void pdp_control_collectgarbage(t_pdp_control __attribute__((unused)) *x)
{
int nb_packets_freed = pdp_pool_collect_garbage();
post("pdp_control: freed %d packets", nb_packets_freed);
}
static void pdp_control_set_mem_limit(t_pdp_control __attribute__((unused)) *x,
t_floatarg f)
{
int limit = (int)f;
if (limit < 0) limit = 0;
pdp_pool_set_max_mem_usage(limit);
if (limit) post("pdp_control: set memory limit to %d bytes", limit);
else post("pdp_control: disabled memory limit");
}
static void pdp_control_thread(t_pdp_control __attribute__((unused)) *x, t_floatarg f)
{
int t = (int)f;
if (t){
post("pdp_control: pdp is now using its own processing thread");
pdp_queue_use_thread(1);
}
else {
post("pdp_control: pdp is now using the main pd thread");
pdp_queue_use_thread(0);
}
}
static void pdp_control_send_drop_message(t_pdp_control *x)
{
t_atom atom[1];
t_symbol *s = gensym("pdp_drop");
SETFLOAT(atom+0, (float)dropped_packets);
outlet_anything(x->x_outlet0, s, 1, atom);
}
static void pdp_control_free(t_pdp_control *x)
{
/* remove from linked list */
t_pdp_control *curr = pdp_control_list;
if (pdp_control_list == x) pdp_control_list = x->x_next;
else while (curr){
if (curr->x_next == x) {
curr->x_next = x->x_next;
break;
}
else {
curr = curr->x_next;
}
}
}
static void *pdp_control_new(void)
{
t_pdp_control *x = (t_pdp_control *)pd_new(pdp_control_class);
x->x_outlet0 = outlet_new(&x->x_obj, &s_anything);
/* add to list */
x->x_next = pdp_control_list;
pdp_control_list = x;
return x;
}
/************************* class methods ***************************************/
void pdp_control_addmethod(t_method m, t_symbol *s)
{
class_addmethod(pdp_control_class, m, s, A_GIMME, A_NULL);
}
void pdp_control_setup(void)
{
pdp_control_list = 0;
dropped_packets = 0;
/* setup pd class data */
pdp_control_class = class_new(gensym("pdp_control"), (t_newmethod)pdp_control_new,
(t_method)pdp_control_free, sizeof(t_pdp_control), 0, A_NULL);
class_addmethod(pdp_control_class, (t_method)pdp_control_info, gensym("info"), A_NULL);
class_addmethod(pdp_control_class, (t_method)pdp_control_thread, gensym("thread"), A_DEFFLOAT, A_NULL);
class_addmethod(pdp_control_class, (t_method)pdp_control_collectgarbage, gensym("collectgarbage"), A_NULL);
class_addmethod(pdp_control_class, (t_method)pdp_control_set_mem_limit, gensym("memlimit"), A_FLOAT, A_NULL);
}
void pdp_control_notify_broadcast(t_pdp_control_method_notify *notify)
{
t_pdp_control *curr = pdp_control_list;
while (curr){
(*notify)(curr);
curr = curr->x_next;
}
}
/************************* notify class methods *************************/
void pdp_control_notify_drop(int __attribute__((unused)) packet)
{
dropped_packets++;
/* send drop notify to controller class instances */
pdp_control_notify_broadcast(pdp_control_send_drop_message);
//post("dropped packet");
}
#ifdef __cplusplus
}
#endif
|