aboutsummaryrefslogtreecommitdiff
path: root/cyclone/shadow/cyclone.c
blob: 10ae1425308c003980a0b70c4f7ccbb520392b46 (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
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
/* Copyright (c) 2003 krzYszcz and others.
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */

/* Never use forked calls in shadow code... */

#include <stdio.h>
#include "m_pd.h"
#include "common/loud.h"
#include "common/port.h"
#include "hammer/file.h"
#include "unstable/fragile.h"
#include "unstable/loader.h"
#include "shadow.h"
#include "../build_counter"

typedef struct _cyclone
{
    t_object       x_ob;
    t_symbol      *x_dir;
    t_hammerfile  *x_filehandle;
} t_cyclone;

static t_class *cyclone_class;
static int cyclone_hammerndx;
static int cyclone_sicklendx;
static int cyclone_nettlesndx;
static int cyclone_dummiesndx;
static int cyclone_lastndx;

static t_pd *cyclone_dproxy = 0;

static void cyclone_readhook(t_pd *z, t_symbol *fn, int ac, t_atom *av)
{
    import_max(fn->s_name, "");
}

static void cyclone_import(t_cyclone *x, t_symbol *fn, t_symbol *dir)
{
    if (fn && fn != &s_)
    {
	if (!dir || dir == &s_) dir = x->x_dir;
	import_max(fn->s_name, (dir && dir != &s_) ? dir->s_name : "");
    }
    else
	hammerpanel_open(x->x_filehandle);
}

static void cyclone_click(t_cyclone *x, t_floatarg xpos, t_floatarg ypos,
			  t_floatarg shift, t_floatarg ctrl, t_floatarg alt)
{
    cyclone_import(x, 0, 0);
}

static void cyclone_bang(t_cyclone *x)
{
    int i;
    fragile_class_printnames("hammer classes are: ",
			     cyclone_hammerndx, cyclone_sicklendx - 1);
    fragile_class_printnames("sickle classes are: ",
			     cyclone_sicklendx, cyclone_nettlesndx - 1);
    fragile_class_printnames("nettles are: ",
			     cyclone_nettlesndx, cyclone_dummiesndx - 1);
    if (cyclone_dproxy)
	pd_bang(cyclone_dproxy);
    else
	post("no replacement abstractions");
    if (cyclone_lastndx > cyclone_dummiesndx)
	post("send 'dummies' message to see the list of %d dummy classes",
	     /* cyclone_lastndx points to the "_dummy" sentinel class */
	     cyclone_lastndx - cyclone_dummiesndx);
    else
	post("no dummies");
}

static void cyclone_reps(t_cyclone *x)
{
    if (cyclone_dproxy)
	typedmess(cyclone_dproxy, gensym("reps"), 0, 0);
    else
	post("no replacement abstractions");
}

static void cyclone_dummies(t_cyclone *x)
{
    if (cyclone_lastndx > cyclone_dummiesndx)
	fragile_class_printnames("dummies are: ",
				 cyclone_dummiesndx, cyclone_lastndx);
    else
	post("no dummies");
}

static void cyclone_free(t_cyclone *x)
{
    hammerfile_free(x->x_filehandle);
}

static void *cyclone_new(t_symbol *s)
{
    t_cyclone *x = (t_cyclone *)pd_new(cyclone_class);
    x->x_filehandle = hammerfile_new((t_pd *)x, 0, cyclone_readhook, 0, 0);
    x->x_dir = (s && s != &s_ ? s : canvas_getdir(x->x_filehandle->f_canvas));
    return (x);
}

void cyclone_setup(void)
{
    int hresult, sresult, dresult;
    hresult = sresult = dresult = LOADER_OK;
    if (canvas_getcurrent())
    {
	/* Loading the library by object creation is banned, because of a danger
	   of having some of the classes already loaded. LATER rethink. */
	loud_error(0, "apparently an attempt to create a 'cyclone' object");
	loud_errand(0, "without having cyclone library preloaded");
	return;
    }
    post("this is cyclone %s, %s %s build",
	 CYCLONE_VERSION, loud_ordinal(CYCLONE_BUILD), CYCLONE_RELEASE);
    cyclone_class = class_new(gensym("cyclone"),
			      (t_newmethod)cyclone_new,
			      (t_method)cyclone_free,
			      sizeof(t_cyclone), 0, A_DEFSYM, 0);
    class_addbang(cyclone_class, cyclone_bang);
    class_addmethod(cyclone_class, (t_method)cyclone_reps,
		    gensym("reps"), 0);
    class_addmethod(cyclone_class, (t_method)cyclone_dummies,
		    gensym("dummies"), 0);
    class_addmethod(cyclone_class, (t_method)cyclone_import,
		    gensym("import"), A_DEFSYM, A_DEFSYM, 0);
    class_addmethod(cyclone_class, (t_method)cyclone_click,
		    gensym("click"),
		    A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
    hammerfile_setup(cyclone_class, 0);

    cyclone_hammerndx = fragile_class_count();
    if (zgetfn(&pd_objectmaker, gensym("hammer")))
	loud_warning(0, "hammer is already loaded");
    else
	hresult = unstable_load_lib("", "hammer");

    cyclone_sicklendx = fragile_class_count();
    if (zgetfn(&pd_objectmaker, gensym("sickle")))
	loud_warning(0, "sickle is already loaded");
    else
	sresult = unstable_load_lib("", "sickle");

    cyclone_nettlesndx = fragile_class_count();
    allnettles_setup();

    cyclone_dummiesndx = fragile_class_count();
    if (zgetfn(&pd_objectmaker, gensym("dummies")))
	loud_warning(0, "dummies are already loaded");
    else
	dresult = unstable_load_lib("", "dummies");

    cyclone_lastndx = fragile_class_count() - 1;

    if (hresult == LOADER_NOFILE)
	loud_error(0, "hammer library is missing");
    else if (sresult == LOADER_NOFILE)
	loud_error(0, "sickle library is missing");
    else if (!zgetfn(&pd_objectmaker, gensym("hammer")) ||
	     !zgetfn(&pd_objectmaker, gensym("sickle")))
    {
	loud_error(0, "version mismatch");
	loud_errand(0,
		    "use a more recent Pd release (or recompile the cyclone).");
    }
    else if (dresult == LOADER_NOFILE)
	loud_warning(0, "dummies not found");
    else
    {
	t_symbol *s = gensym("_ccdummies");
	if (s->s_thing && !s->s_next
	    && !strcmp(class_getname(*s->s_thing), "_ccdummies"))
	    cyclone_dproxy = s->s_thing;
	else
	    bug("cyclone_setup");  /* FIXME */
    }
}