Fix crash on Scicos exiting when simulation was stoped and some scope closed
[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    \file cmscope.c
23    \author Benoit Bayol
24    \version 1.0
25    \date September 2006 - January 2007
26    \brief CMSCOPE is a typical scope which links its input to the simulation time
27    \see CMSCOPE.sci in macros/scicos_blocks/Sinks/
28 */
29 #include "CurrentObjectsManagement.h"
30 #include "scoMemoryScope.h"
31 #include "scoWindowScope.h"
32 #include "scoMisc.h"
33 #include "scoGetProperty.h"
34 #include "scoSetProperty.h"
35 #include "scicos_block4.h"
36 #include "SetJavaProperty.h"
37
38 /** \fn cmscope_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
39     \brief Function to draw or redraw the window
40 */
41 void cmscope_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
42 {
43   int i; //As usual
44   int * ipar; //Integer Parameters
45   int * colors; //Colors
46   int win; //Windows ID : To give a name to the window
47   int buffer_size; //Buffer Size
48   int win_pos[2]; //Position of the Window
49   int win_dim[2]; //Dimension of the Window
50   int inherited_events;
51   int nipar;
52   int dimension = 2;
53   double * rpar; //Reals parameters
54   double dt; //Time++
55   double * period; //Refresh Period of the scope is a vector here
56   double * ymin,* ymax; //Ymin and Ymax are vectors here
57   double * xmin, *xmax;
58   int nbr_period;
59   int * number_of_curves_by_subwin;
60   int number_of_subwin;
61   int nbr_total_curves;
62
63
64   rpar = GetRparPtrs(block);
65   ipar = GetIparPtrs(block);
66   nipar = GetNipar(block);
67   win = ipar[0];
68   number_of_subwin = ipar[1];
69   buffer_size = ipar[2];
70   win_pos[0] = ipar[3];
71   win_pos[1] = ipar[4];
72   win_dim[0] = ipar[5];
73   win_dim[1] = ipar[6];
74   nbr_total_curves = 0;
75   //Don't forget malloc for 'type *'
76   number_of_curves_by_subwin = (int*)scicos_malloc(number_of_subwin*sizeof(int));
77   for (i = 7; i < 7+number_of_subwin ; i++)
78     {
79       number_of_curves_by_subwin[i-7] = ipar[i];
80       nbr_total_curves = nbr_total_curves + ipar[i];
81     }
82   colors = (int*)scicos_malloc(nbr_total_curves*sizeof(int));
83   for(i = 0; i < nbr_total_curves ; i++)
84     {
85       colors[i] = ipar[i+7+number_of_subwin];
86     }
87   inherited_events = ipar[7+number_of_subwin+number_of_subwin];
88
89   dt = rpar[0];
90
91   nbr_period = 0;
92   period = (double*)scicos_malloc(number_of_subwin*sizeof(double));
93   for (i = 0 ; i < number_of_subwin ; i++)
94     {
95       period[i] = rpar[i+1];
96       nbr_period++; 
97     }
98   ymin = (double*)scicos_malloc(number_of_subwin*sizeof(double));
99   ymax = (double*)scicos_malloc(number_of_subwin*sizeof(double));
100   for (i = 0 ; i < number_of_subwin ; i++)
101     {
102       ymin[i] = rpar[2*i+nbr_period+1];
103       ymax[i] = rpar[2*i+nbr_period+2];
104     }
105
106   /*Allocating memory*/
107   if(firstdraw == 1)
108     {
109
110       scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, number_of_curves_by_subwin);
111       for(i = 0 ; i < number_of_subwin ; i++)
112         {
113           scoSetLongDrawSize(*pScopeMemory, i, 5000);
114           scoSetShortDrawSize(*pScopeMemory,i,buffer_size);
115           scoSetPeriod(*pScopeMemory,i,period[i]);
116         }    
117     }
118
119   /* 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*/
120   xmin = (double*)scicos_malloc(number_of_subwin*sizeof(double));
121   xmax = (double*)scicos_malloc(number_of_subwin*sizeof(double));
122   for (i = 0 ; i < number_of_subwin ; i++)
123     {
124       xmin[i] = period[i]*(scoGetPeriodCounter(*pScopeMemory,i));
125       xmax[i] = period[i]*(scoGetPeriodCounter(*pScopeMemory,i)+1);
126     }
127
128   /*Creating the Scope*/
129   scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, xmin, xmax, ymin, ymax, NULL, NULL);
130   if(scoGetScopeActivation(*pScopeMemory) == 1)
131     {
132       scoAddTitlesScope(*pScopeMemory,"t","y",NULL);
133
134   /*Add a couple of polyline : one for the shortdraw and one for the longdraw*/
135   /*    scoAddPolylineLineStyle(*pScopeMemory,colors); */
136       scoAddCoupleOfPolylines(*pScopeMemory,colors);
137     }
138   scicos_free(number_of_curves_by_subwin);
139   scicos_free(colors);
140   scicos_free(period);
141   scicos_free(ymin);
142   scicos_free(ymax);
143   scicos_free(xmin);
144   scicos_free(xmax);
145
146         /* use only single buffering to be sure to draw on the screen */
147         sciSetJavaUseSingleBuffer(scoGetPointerScopeWindow(*pScopeMemory), TRUE);
148 }
149
150 /** \fn void cmscope(scicos_block * block, int flag)
151     \brief the computational function
152     \param block A pointer to a scicos_block
153     \param flag An int which indicates the state of the block (init, update, ending)
154 */
155 void cmscope(scicos_block * block, int flag)
156 {
157   /* Declarations */
158   ScopeMemory * pScopeMemory;
159   int NbrPtsShort;
160   double * u1;
161   double t; //get_scicos_time()
162   scoGraphicalObject pShortDraw;
163   int i,j;
164
165   double d_current_real_time ; 
166
167   /* Initializations and Allocations*/
168   //Allocations are done here because there are dependent of some values presents below
169  
170   /* State Machine Control */
171   switch(flag)
172     {
173     case Initialization:
174       {
175         cmscope_draw(block,&pScopeMemory,1);
176         
177         //** Init the real time section
178           //** current real time as double [second] 
179           d_current_real_time = scoGetRealTime();
180           pScopeMemory->d_last_scope_update_time = d_current_real_time ; //** update the ds for the next step 
181
182         break; //Break of the switch condition: dont forget it 
183       } //End of Initialization
184   
185     case StateUpdate:
186       {
187         /*Retreiving Scope in the block->work*/
188         scoRetrieveScopeMemory(block->work,&pScopeMemory);
189         if(scoGetScopeActivation(pScopeMemory) == 1)
190           {
191             /* Charging Elements */
192             t = get_scicos_time();
193             /* If window has been destroyed we recreate it */
194             if(scoGetPointerScopeWindow(pScopeMemory) == NULL)
195               {
196                 cmscope_draw(block,&pScopeMemory,0);
197               }
198
199             scoRefreshDataBoundsX(pScopeMemory,t);
200
201             //Here we are calculating the points in the polylines
202             for (i = 0 ; i < scoGetNumberOfSubwin(pScopeMemory) ; i++)
203               {
204                 u1 = GetRealInPortPtrs(block,i+1);
205                 pShortDraw = scoGetPointerShortDraw(pScopeMemory,i,0);
206                 NbrPtsShort = pPOLYLINE_FEATURE(pShortDraw)->n1;
207                 for (j = 0; j < scoGetNumberOfCurvesBySubwin(pScopeMemory,i) ; j++)
208                   {
209                     pShortDraw = scoGetPointerShortDraw(pScopeMemory,i,j);
210                     pPOLYLINE_FEATURE(pShortDraw)->pvx[NbrPtsShort] = t;
211                     pPOLYLINE_FEATURE(pShortDraw)->pvy[NbrPtsShort] = u1[j];
212                     pPOLYLINE_FEATURE(pShortDraw)->n1++;
213                   }
214               }
215
216             // Draw the Scope
217             scoDrawScopeAmplitudeTimeStyle(pScopeMemory, t); //** the scope update condition
218                                                              //** is hidden here 
219
220           } 
221         break; 
222
223       } //**End of stateupdate
224     
225    //** Ending is activated when the simulation is done or when we close Scicos
226     case Ending:
227       {
228         scoRetrieveScopeMemory(block->work, &pScopeMemory);
229         if(scoGetScopeActivation(pScopeMemory) == 1)
230           {
231           //  sciSetUsedWindow(scoGetWindowID(pScopeMemory));
232           //  pShortDraw = sciGetCurrentFigure();
233           //  pFIGURE_FEATURE(pShortDraw)->user_data = NULL;
234           //  pFIGURE_FEATURE(pShortDraw)->size_of_user_data = 0;
235                         ///* restore double buffering */
236                         //sciSetJavaUseSingleBuffer(pShortDraw, FALSE);
237           //  scoDelCoupleOfPolylines(pScopeMemory);
238
239
240                         /* Check if figure is still opened, otherwise, don't try to destroy it again. */
241                         scoGraphicalObject figure = scoGetPointerScopeWindow(pScopeMemory);
242                         if (figure != NULL)
243                         {
244                                 /*pShortDraw = scoGetPointerScopeWindow(pScopeMemory);*/
245                                 clearUserData(figure);
246
247                                 sciSetJavaUseSingleBuffer(figure, FALSE);
248                           scoDelCoupleOfPolylines(pScopeMemory);
249                         }
250
251           }
252
253         scoFreeScopeMemory(block->work, &pScopeMemory);
254
255         break;
256       }
257     }
258 }