Fix crash on Scicos exiting when simulation was stoped and some scope closed
[scilab.git] / scilab / modules / scicos_blocks / src / c / cfscope.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 cfscope.c
23    \author Benoit Bayol
24    \version 1.0
25    \date September 2006 - January 2007
26    \brief CFSCOPE This scope has no input port because it displays the values on the designated link
27    \see CFSCOPE.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
37 /** \fn cfscope_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
38     \brief Function to draw or redraw the window
39 */
40 void cfscope_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
41 {
42
43   double *rpar;
44   int *ipar, nipar;   
45
46   double period;
47   int i;
48   int dimension;
49   double ymin, ymax, xmin, xmax;
50   int buffer_size;
51   int win_pos[2];
52   int win_dim[2];
53   int win;
54   int number_of_subwin;
55   int number_of_curves_by_subwin;
56   double dt;
57   int nbr_of_curves;
58   int color_flag;
59   int * colors;
60
61   rpar = GetRparPtrs(block);
62   ipar = GetIparPtrs(block);
63   nipar = GetNipar(block);
64   win = ipar[0];
65   color_flag = ipar[1];
66   buffer_size = ipar[2];
67   dt = rpar[0];
68   period = rpar[3];
69   ymin  = rpar[1];
70   ymax = rpar[2];
71
72   dimension = 2;
73   win_pos[0] = ipar[11];
74   win_pos[1] = ipar[12];
75   win_dim[0] = ipar[13];
76   win_dim[1] = ipar[14];
77   number_of_curves_by_subwin = ipar[15]; //Here is not really what we will see i.e. if you give [2:9] there is 8 curves but in the kalman filter demo you will only see 6 curves (and 8 in the figure handle description) because only 6 are really existing.
78   nbr_of_curves = number_of_curves_by_subwin;
79   number_of_subwin = 1;
80
81   colors=(int*)scicos_malloc(8*sizeof(int));
82   for( i = 3 ; i < 10 ; i++)
83     {
84       colors[i-3] = ipar[i];
85     }
86
87   /*Allocating memory*/
88   if(firstdraw == 1)
89     {
90       scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
91       /*Must be placed before adding polyline or other elements*/
92       scoSetLongDrawSize(*pScopeMemory, 0, 5000);
93       scoSetShortDrawSize(*pScopeMemory,0,buffer_size);
94       scoSetPeriod(*pScopeMemory,0,period);
95     }
96
97   xmin = period*scoGetPeriodCounter(*pScopeMemory,0);
98   xmax = period*(scoGetPeriodCounter(*pScopeMemory,0)+1);
99
100   /*Creating the Scope*/
101   scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, NULL, NULL);
102   if(scoGetScopeActivation(*pScopeMemory) == 1)
103     {
104       scoAddTitlesScope(*pScopeMemory,"t","y",NULL);
105       
106   /*Add a couple of polyline : one for the shortdraw and one for the longdraw*/
107       scoAddCoupleOfPolylines(*pScopeMemory,colors);
108       scicos_free(colors);
109     }
110 }
111
112 extern int C2F(getouttb)();
113 /** \fn void cfscope(scicos_block * block,int flag)
114     \brief the computational function
115     \param block A pointer to a scicos_block
116     \param flag An int which indicates the state of the block (init, update, ending)
117 */
118 void cfscope(scicos_block * block,int flag)
119 {
120   ScopeMemory * pScopeMemory;
121   scoGraphicalObject pShortDraw;
122   double * sortie;
123   int  *  index_of_view;
124   double t;
125   int nbr_of_curves;
126   int *ipar;
127   int i,j;
128   int NbrPtsShort;
129
130   switch(flag)
131     {
132     case Initialization:
133       {
134         /*Retrieving Parameters*/
135         cfscope_draw(block,&pScopeMemory,1);
136         break;
137       }
138     case StateUpdate:
139       { 
140         
141
142         /*Retreiving Scope in the block->work*/
143         scoRetrieveScopeMemory(block->work,&pScopeMemory);
144         if(scoGetScopeActivation(pScopeMemory) == 1)
145           {
146             t = get_scicos_time();
147             /* If window has been destroyed we recreate it */
148         if(scoGetPointerScopeWindow(pScopeMemory) == NULL)
149           {
150             cfscope_draw(block,&pScopeMemory,0);
151           }
152         /*Maybe we are in the end of axes so we have to draw new ones */
153         scoRefreshDataBoundsX(pScopeMemory,t);
154
155         //Cannot be factorized depends of the scope
156         nbr_of_curves = scoGetNumberOfCurvesBySubwin(pScopeMemory,0);
157
158         ipar = GetIparPtrs(block);
159         sortie = (double*)scicos_malloc(nbr_of_curves*sizeof(double));
160         index_of_view =(int*)scicos_malloc(nbr_of_curves*sizeof(int));
161         for(i = 16 ; i < 16+nbr_of_curves ; i++)
162           {
163             index_of_view[i-16] = ipar[i];
164           }
165
166         C2F(getouttb)(&nbr_of_curves,index_of_view,sortie);
167         for(i = 0; i < scoGetNumberOfSubwin(pScopeMemory) ; i++)
168           {
169             for (j = 0; j < nbr_of_curves ; j++)
170               {
171                 pShortDraw = scoGetPointerShortDraw(pScopeMemory,i,j);
172                 NbrPtsShort = pPOLYLINE_FEATURE(pShortDraw)->n1;
173                 pPOLYLINE_FEATURE(pShortDraw)->pvx[NbrPtsShort] = t;         // get time 
174                 pPOLYLINE_FEATURE(pShortDraw)->pvy[NbrPtsShort] = sortie[j]; // get value
175                 pPOLYLINE_FEATURE(pShortDraw)->n1++;
176               }
177           }
178         //End of cannot
179         /*Main drawing function*/
180         scoDrawScopeAmplitudeTimeStyle(pScopeMemory, t);
181         
182         scicos_free(sortie);
183         scicos_free(index_of_view);
184           }
185         break;
186       }
187     case Ending:
188       {
189         scoRetrieveScopeMemory(block->work, &pScopeMemory);
190         if(scoGetScopeActivation(pScopeMemory) == 1)
191           {
192             /*sciSetUsedWindow(scoGetWindowID(pScopeMemory));
193             pShortDraw = sciGetCurrentFigure();
194             pFIGURE_FEATURE(pShortDraw)->user_data = NULL;
195             pFIGURE_FEATURE(pShortDraw)->size_of_user_data = 0;
196             
197             scoDelCoupleOfPolylines(pScopeMemory);*/
198
199                         /* Check if figure is still opened, otherwise, don't try to destroy it again. */
200                         scoGraphicalObject figure = scoGetPointerScopeWindow(pScopeMemory);
201                         if (figure != NULL)
202                         {
203                                 /*pShortDraw = scoGetPointerScopeWindow(pScopeMemory);*/
204                                 clearUserData(figure);
205
206                                 scoDelCoupleOfPolylines(pScopeMemory);
207                         }
208           }
209         scoFreeScopeMemory(block->work, &pScopeMemory);
210         break;  
211       }
212     }
213 }