* bug 8630 fixed - Scopes crashed Scilab on simulation when they had the same
[scilab.git] / scilab / modules / scicos_blocks / src / c / cmscope.c
1 /*  Scicos
2 *
3 *  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 * See the file ./license.txt
20 */
21 /*--------------------------------------------------------------------------*/ 
22 /**
23    \file cmscope.c
24    \author Benoit Bayol
25    \version 1.0
26    \date September 2006 - January 2007
27    \brief CMSCOPE is a typical scope which links its input to the simulation time
28    \see CMSCOPE.sci in macros/scicos_blocks/Sinks/
29 */
30 /*--------------------------------------------------------------------------*/ 
31 #include "CurrentObjectsManagement.h"
32 #include "scicos.h"
33 #include "scoMemoryScope.h"
34 #include "scoWindowScope.h"
35 #include "scoMisc.h"
36 #include "scoGetProperty.h"
37 #include "scoSetProperty.h"
38 #include "scicos_block4.h"
39 #include "SetJavaProperty.h"
40 #include "scicos_malloc.h"
41 #include "scicos_free.h"
42 #include "MALLOC.h"
43 #include "dynlib_scicos_blocks.h"
44 /*--------------------------------------------------------------------------*/ 
45 /** \fn cmscope_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
46     \brief Function to draw or redraw the window
47 */
48 SCICOS_BLOCKS_IMPEXP void cmscope_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
49 {
50   int i = 0; //As usual
51   int * ipar = NULL; //Integer Parameters
52   int * colors = NULL; //Colors
53   int win = 0; //Windows ID : To give a name to the window
54   int buffer_size = 0; //Buffer Size
55   int win_pos[2]; //Position of the Window
56   int win_dim[2]; //Dimension of the Window
57   int inherited_events = 0;
58   int nipar = 0;
59   int dimension = 2;
60   double * rpar = NULL; //Reals parameters
61   double dt = 0.; //Time++
62   double * period = NULL; //Refresh Period of the scope is a vector here
63   double * ymin = NULL,* ymax = NULL; //Ymin and Ymax are vectors here
64   double * xmin = NULL, *xmax = NULL;
65   int nbr_period = 0;
66   int * number_of_curves_by_subwin = NULL;
67   int number_of_subwin = 0;
68   int nbr_total_curves = 0;
69   char *label = NULL;
70
71
72   rpar = GetRparPtrs(block);
73   ipar = GetIparPtrs(block);
74   nipar = GetNipar(block);
75   win = ipar[0];
76   number_of_subwin = ipar[1];
77   buffer_size = ipar[2];
78   win_pos[0] = ipar[3];
79   win_pos[1] = ipar[4];
80   win_dim[0] = ipar[5];
81   win_dim[1] = ipar[6];
82   label = GetLabelPtrs(block);
83   nbr_total_curves = 0;
84   //Don't forget malloc for 'type *'
85   number_of_curves_by_subwin = (int*)scicos_malloc(number_of_subwin*sizeof(int));
86   for (i = 7; i < 7+number_of_subwin ; i++)
87     {
88       number_of_curves_by_subwin[i-7] = ipar[i];
89       nbr_total_curves = nbr_total_curves + ipar[i];
90     }
91   colors = (int*)scicos_malloc(nbr_total_curves*sizeof(int));
92   for(i = 0; i < nbr_total_curves ; i++)
93     {
94       colors[i] = ipar[i+7+number_of_subwin];
95     }
96   inherited_events = ipar[7+number_of_subwin+number_of_subwin];
97
98   dt = rpar[0];
99
100   nbr_period = 0;
101   period = (double*)scicos_malloc(number_of_subwin*sizeof(double));
102   for (i = 0 ; i < number_of_subwin ; i++)
103     {
104       period[i] = rpar[i+1];
105       nbr_period++; 
106     }
107   ymin = (double*)scicos_malloc(number_of_subwin*sizeof(double));
108   ymax = (double*)scicos_malloc(number_of_subwin*sizeof(double));
109   for (i = 0 ; i < number_of_subwin ; i++)
110     {
111       ymin[i] = rpar[2*i+nbr_period+1];
112       ymax[i] = rpar[2*i+nbr_period+2];
113     }
114
115   /*Allocating memory*/
116   if(firstdraw == 1)
117     {
118
119       scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, number_of_curves_by_subwin);
120       for(i = 0 ; i < number_of_subwin ; i++)
121         {
122           scoSetLongDrawSize(*pScopeMemory, i, 5000);
123           scoSetShortDrawSize(*pScopeMemory,i,buffer_size);
124           scoSetPeriod(*pScopeMemory,i,period[i]);
125         }    
126     }
127
128   /* Xmin and Xmax are calculated here because we need a variable which is only existing in the pScopeMemory. pScopeMemory is allocated just few lines before. Indeed in this TimeAmplitudeScope Xmin and Xmax have to change often. To be sure to redraw in the correct scale we have to calculate xmin and xmax thanks to the period_counter. If the window haven't to be redraw (recreate)  it wouldn't be necessary*/
129   xmin = (double*)scicos_malloc(number_of_subwin*sizeof(double));
130   xmax = (double*)scicos_malloc(number_of_subwin*sizeof(double));
131   for (i = 0 ; i < number_of_subwin ; i++)
132     {
133       xmin[i] = period[i]*(scoGetPeriodCounter(*pScopeMemory,i));
134       xmax[i] = period[i]*(scoGetPeriodCounter(*pScopeMemory,i)+1);
135     }
136
137   /*Creating the Scope*/
138   scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, xmin, xmax, ymin, ymax, NULL, NULL);
139   if(scoGetScopeActivation(*pScopeMemory) == 1)
140     {
141       scoAddTitlesScope(*pScopeMemory,label,"t","y",NULL);
142
143   /*Add a couple of polyline : one for the shortdraw and one for the longdraw*/
144   /*    scoAddPolylineLineStyle(*pScopeMemory,colors); */
145       scoAddCoupleOfPolylines(*pScopeMemory,colors);
146     }
147   scicos_free(number_of_curves_by_subwin);
148   scicos_free(colors);
149   scicos_free(period);
150   scicos_free(ymin);
151   scicos_free(ymax);
152   scicos_free(xmin);
153   scicos_free(xmax);
154
155   /* use only single buffering to be sure to draw on the screen */
156   if (scoGetPointerScopeWindow(*pScopeMemory) != NULL) {
157     sciSetJavaUseSingleBuffer(scoGetPointerScopeWindow(*pScopeMemory), TRUE);
158   }
159 }
160 /*--------------------------------------------------------------------------*/ 
161 /** \fn void cmscope(scicos_block * block, int flag)
162     \brief the computational function
163     \param block A pointer to a scicos_block
164     \param flag An int which indicates the state of the block (init, update, ending)
165 */
166 SCICOS_BLOCKS_IMPEXP cmscope(scicos_block * block, int flag)
167 {
168   /* Declarations */
169   ScopeMemory * pScopeMemory = NULL;
170   int NbrPtsShort = 0;
171   double * u1 = NULL;
172   double t = 0.; //get_scicos_time()
173   scoGraphicalObject pShortDraw;
174   int i = 0,j = 0;
175
176   double d_current_real_time = 0. ; 
177
178   /* Initializations and Allocations*/
179   //Allocations are done here because there are dependent of some values presents below
180  
181   /* State Machine Control */
182   switch(flag)
183     {
184     case Initialization:
185       {
186         cmscope_draw(block,&pScopeMemory,1);
187         
188         //** Init the real time section
189           //** current real time as double [second] 
190           d_current_real_time = scoGetRealTime();
191           pScopeMemory->d_last_scope_update_time = d_current_real_time ; //** update the ds for the next step 
192
193         break; //Break of the switch condition: dont forget it 
194       } //End of Initialization
195   
196     case StateUpdate:
197       {
198         /*Retreiving Scope in the block->work*/
199         scoRetrieveScopeMemory(block->work,&pScopeMemory);
200         if(scoGetScopeActivation(pScopeMemory) == 1)
201           {
202             /* Charging Elements */
203             t = get_scicos_time();
204             /* If window has been destroyed we recreate it */
205             if(scoGetPointerScopeWindow(pScopeMemory) == NULL)
206               {
207                 cmscope_draw(block,&pScopeMemory,0);
208               }
209
210             scoRefreshDataBoundsX(pScopeMemory,t);
211
212             //Here we are calculating the points in the polylines
213             for (i = 0 ; i < scoGetNumberOfSubwin(pScopeMemory) ; i++)
214               {
215                 u1 = GetRealInPortPtrs(block,i+1);
216                 pShortDraw = scoGetPointerShortDraw(pScopeMemory,i,0);
217                 NbrPtsShort = pPOLYLINE_FEATURE(pShortDraw)->n1;
218                 for (j = 0; j < scoGetNumberOfCurvesBySubwin(pScopeMemory,i) ; j++)
219                   {
220                     pShortDraw = scoGetPointerShortDraw(pScopeMemory,i,j);
221                     pPOLYLINE_FEATURE(pShortDraw)->pvx[NbrPtsShort] = t;
222                     pPOLYLINE_FEATURE(pShortDraw)->pvy[NbrPtsShort] = u1[j];
223                     pPOLYLINE_FEATURE(pShortDraw)->n1++;
224                   }
225               }
226
227             // Draw the Scope
228             scoDrawScopeAmplitudeTimeStyle(pScopeMemory, t); //** the scope update condition
229                                                              //** is hidden here 
230
231           } 
232         break; 
233
234       } //**End of stateupdate
235     
236    //** Ending is activated when the simulation is done or when we close Scicos
237     case Ending:
238       {
239         scoRetrieveScopeMemory(block->work, &pScopeMemory);
240         if(scoGetScopeActivation(pScopeMemory) == 1)
241           {
242           //  sciSetUsedWindow(scoGetWindowID(pScopeMemory));
243           //  pShortDraw = sciGetCurrentFigure();
244           //  pFIGURE_FEATURE(pShortDraw)->user_data = NULL;
245           //  pFIGURE_FEATURE(pShortDraw)->size_of_user_data = 0;
246                         ///* restore double buffering */
247                         //sciSetJavaUseSingleBuffer(pShortDraw, FALSE);
248           //  scoDelCoupleOfPolylines(pScopeMemory);
249
250
251                         /* Check if figure is still opened, otherwise, don't try to destroy it again. */
252                         scoGraphicalObject figure = scoGetPointerScopeWindow(pScopeMemory);
253                         if (figure != NULL)
254                         {
255                                 /*pShortDraw = scoGetPointerScopeWindow(pScopeMemory);*/
256                                 clearUserData(figure);
257
258                                 /* restore double buffering */
259                                 if (figure) {
260                     sciSetJavaUseSingleBuffer(figure, FALSE);
261                 }
262                         }
263
264           }
265
266         scoFreeScopeMemory(block->work, &pScopeMemory);
267
268         break;
269       }
270     }
271 }
272 /*--------------------------------------------------------------------------*/