|
FAUST compiler
0.9.9.6b8
|
00001 /************************************************************************ 00002 ************************************************************************ 00003 FAUST compiler 00004 Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale 00005 --------------------------------------------------------------------- 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 ************************************************************************ 00020 ************************************************************************/ 00021 00022 00023 #include "seqSchema.h" 00024 #include <iostream> 00025 #include <assert.h> 00026 00027 using namespace std; 00028 00029 enum {kHorDir, kUpDir, kDownDir}; 00030 00031 static double computeHorzGap(schema* a, schema* b); 00032 static int direction(const point& a, const point& b); 00033 00034 00035 //----------------------------INTERFACE-------------------------------- 00036 00043 schema * makeSeqSchema (schema* s1, schema* s2) 00044 { 00045 unsigned int o = s1->outputs(); 00046 unsigned int i = s2->inputs(); 00047 00048 schema* a = (o < i) ? makeParSchema(s1, makeCableSchema(i-o)) : s1; 00049 schema* b = (o > i) ? makeParSchema(s2, makeCableSchema(o-i)) : s2; 00050 00051 return new seqSchema(a, b, computeHorzGap(a,b)); 00052 } 00053 00054 00055 00056 //-----------------------IMPLEMENTATION------------------------------ 00057 00062 seqSchema::seqSchema (schema* s1, schema* s2, double hgap) 00063 : schema( s1->inputs(), 00064 s2->outputs(), 00065 s1->width() + hgap + s2->width(), 00066 max(s1->height(), s2->height()) ), 00067 fSchema1(s1), 00068 fSchema2(s2), 00069 fHorzGap(hgap) 00070 { 00071 assert(s1->outputs() == s2->inputs()); 00072 } 00073 00074 00075 //-----------------------placement------------------------------ 00076 00077 00082 void seqSchema::place(double ox, double oy, int orientation) 00083 { 00084 beginPlace(ox, oy, orientation); 00085 00086 double y1 = max(0.0, 0.5*(fSchema2->height() - fSchema1->height())); 00087 double y2 = max(0.0, 0.5*(fSchema1->height() - fSchema2->height())); 00088 00089 if (orientation == kLeftRight) { 00090 fSchema1->place(ox, oy+y1, orientation); 00091 fSchema2->place(ox+fSchema1->width()+fHorzGap, oy+y2, orientation); 00092 } else { 00093 fSchema2->place(ox, oy+y2, orientation); 00094 fSchema1->place(ox+fSchema2->width()+fHorzGap, oy+y1, orientation); 00095 } 00096 endPlace(); 00097 } 00098 00099 00103 point seqSchema::inputPoint(unsigned int i) const 00104 { 00105 return fSchema1->inputPoint(i); 00106 } 00107 00108 00112 point seqSchema::outputPoint(unsigned int i) const 00113 { 00114 return fSchema2->outputPoint(i); 00115 } 00116 00117 00118 00119 //--------------------------drawing------------------------------ 00120 00121 00125 void seqSchema::draw(device& dev) 00126 { 00127 assert(placed()); 00128 assert(fSchema1->outputs() == fSchema2->inputs()); 00129 00130 fSchema1->draw(dev); 00131 fSchema2->draw(dev); 00132 //drawInternalWires(dev); 00133 } 00134 00138 void seqSchema::collectTraits(collector& c) 00139 { 00140 assert(placed()); 00141 assert(fSchema1->outputs() == fSchema2->inputs()); 00142 00143 fSchema1->collectTraits(c); 00144 fSchema2->collectTraits(c); 00145 collectInternalWires(c); 00146 } 00147 00148 00154 void seqSchema::drawInternalWires(device& dev) 00155 { 00156 assert (fSchema1->outputs() == fSchema2->inputs()); 00157 00158 const int N = fSchema1->outputs(); 00159 double dx = 0; 00160 double mx = 0; 00161 int dir =-1; 00162 00163 if (orientation() == kLeftRight) { 00164 // draw left right cables 00165 for (int i=0; i<N; i++) { 00166 point src = fSchema1->outputPoint(i); 00167 point dst = fSchema2->inputPoint(i); 00168 00169 int d = direction(src,dst); 00170 if (d != dir) { 00171 // compute attributes of new direction 00172 switch (d) { 00173 case kUpDir : mx = 0; dx = dWire; break; 00174 case kDownDir : mx = fHorzGap; dx = -dWire; break; 00175 default : mx = 0; dx = 0; break; 00176 } 00177 dir = d; 00178 } else { 00179 // move in same direction 00180 mx = mx +dx; 00181 } 00182 if (src.y == dst.y) { 00183 // draw straight cable 00184 dev.trait(src.x, src.y, dst.x, dst.y); 00185 } else { 00186 // draw zizag cable 00187 dev.trait(src.x, src.y, src.x+mx, src.y); 00188 dev.trait(src.x+mx, src.y, src.x+mx, dst.y); 00189 dev.trait(src.x+mx, dst.y, dst.x, dst.y); 00190 } 00191 00192 } 00193 } else { 00194 // draw right left cables 00195 for (int i=0; i<N; i++) { 00196 point src = fSchema1->outputPoint(i); 00197 point dst = fSchema2->inputPoint(i); 00198 00199 int d = direction(src,dst); 00200 if (d != dir) { 00201 // compute attributes of new direction 00202 switch (d) { 00203 case kUpDir : mx = -fHorzGap; dx = dWire; break; 00204 case kDownDir : mx = 0; dx = -dWire; break; 00205 default : mx = 0; dx = 0; break; 00206 } 00207 dir = d; 00208 } else { 00209 // move in same direction 00210 mx = mx +dx; 00211 } 00212 if (src.y == dst.y) { 00213 // draw straight cable 00214 dev.trait(src.x, src.y, dst.x, dst.y); 00215 } else { 00216 // draw zizag cable 00217 dev.trait(src.x, src.y, src.x+mx, src.y); 00218 dev.trait(src.x+mx, src.y, src.x+mx, dst.y); 00219 dev.trait(src.x+mx, dst.y, dst.x, dst.y); 00220 } 00221 00222 } 00223 } 00224 } 00225 00226 00227 00233 void seqSchema::collectInternalWires(collector& c) 00234 { 00235 assert (fSchema1->outputs() == fSchema2->inputs()); 00236 00237 const int N = fSchema1->outputs(); 00238 double dx = 0; 00239 double mx = 0; 00240 int dir =-1; 00241 00242 if (orientation() == kLeftRight) { 00243 // draw left right cables 00244 for (int i=0; i<N; i++) { 00245 point src = fSchema1->outputPoint(i); 00246 point dst = fSchema2->inputPoint(i); 00247 00248 int d = direction(src,dst); 00249 if (d != dir) { 00250 // compute attributes of new direction 00251 switch (d) { 00252 case kUpDir : mx = 0; dx = dWire; break; 00253 case kDownDir : mx = fHorzGap; dx = -dWire; break; 00254 default : mx = 0; dx = 0; break; 00255 } 00256 dir = d; 00257 } else { 00258 // move in same direction 00259 mx = mx +dx; 00260 } 00261 if (src.y == dst.y) { 00262 // draw straight cable 00263 c.addTrait(trait(point(src.x, src.y), point(dst.x, dst.y))); 00264 } else { 00265 // draw zizag cable 00266 c.addTrait(trait(point(src.x, src.y), point(src.x+mx, src.y))); 00267 c.addTrait(trait(point(src.x+mx, src.y), point(src.x+mx, dst.y))); 00268 c.addTrait(trait(point(src.x+mx, dst.y), point(dst.x, dst.y))); 00269 } 00270 00271 } 00272 } else { 00273 // draw right left cables 00274 for (int i=0; i<N; i++) { 00275 point src = fSchema1->outputPoint(i); 00276 point dst = fSchema2->inputPoint(i); 00277 00278 int d = direction(src,dst); 00279 if (d != dir) { 00280 // compute attributes of new direction 00281 switch (d) { 00282 case kUpDir : mx = -fHorzGap; dx = dWire; break; 00283 case kDownDir : mx = 0; dx = -dWire; break; 00284 default : mx = 0; dx = 0; break; 00285 } 00286 dir = d; 00287 } else { 00288 // move in same direction 00289 mx = mx +dx; 00290 } 00291 if (src.y == dst.y) { 00292 // draw straight cable 00293 c.addTrait(trait(point(src.x, src.y), point(dst.x, dst.y))); 00294 } else { 00295 // draw zizag cable 00296 c.addTrait(trait(point(src.x, src.y), point(src.x+mx, src.y))); 00297 c.addTrait(trait(point(src.x+mx, src.y), point(src.x+mx, dst.y))); 00298 c.addTrait(trait(point(src.x+mx, dst.y), point(dst.x, dst.y))); 00299 } 00300 00301 } 00302 } 00303 } 00304 00305 //--------------------------helpers------------------------------ 00306 00307 00308 00313 static int direction(const point& a, const point& b) 00314 { 00315 if (a.y > b.y) return kUpDir; // upward connections 00316 if (a.y < b.y) return kDownDir; // downward connection 00317 return kHorDir; // horizontal connections 00318 } 00319 00325 static double computeHorzGap(schema* a, schema* b) 00326 { 00327 assert(a->outputs() == b->inputs()); 00328 00329 if (a->outputs() == 0) { 00330 return 0; 00331 } else { 00332 // store here the size of the largest group for each direction 00333 int MaxGroupSize[3]; for(int i=0; i<3; i++) MaxGroupSize[i]=0; 00334 00335 // place a and b to have valid connection points 00336 double ya = max(0.0, 0.5*(b->height() - a->height())); 00337 double yb = max(0.0, 0.5*(a->height() - b->height())); 00338 a->place(0,ya,kLeftRight); 00339 b->place(0,yb,kLeftRight); 00340 00341 // init current group direction and size 00342 int gdir = direction(a->outputPoint(0), b->inputPoint(0)); 00343 int gsize = 1; 00344 00345 // analyze direction of remaining points 00346 for (unsigned int i=1; i<a->outputs(); i++) { 00347 int d = direction(a->outputPoint(i), b->inputPoint(i)); 00348 if (d == gdir) { 00349 gsize++; 00350 } else { 00351 if (gsize > MaxGroupSize[gdir]) MaxGroupSize[gdir]=gsize; 00352 gsize = 1; 00353 gdir = d; 00354 } 00355 } 00356 00357 // update for last group 00358 if (gsize > MaxGroupSize[gdir]) MaxGroupSize[gdir]=gsize; 00359 00360 // the gap required for the connections 00361 return dWire * max(MaxGroupSize[kUpDir],MaxGroupSize[kDownDir]); 00362 } 00363 }
1.8.0