2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2011 - Scilab Enterprises - Clement DAVID
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
17 #include "dynlib_scicos_blocks.h"
21 #include "core_math.h"
22 #include "elementary_functions.h"
24 #include "getGraphicObjectProperty.h"
25 #include "setGraphicObjectProperty.h"
26 #include "graphicObjectProperties.h"
27 #include "createGraphicObject.h"
29 #include "CurrentFigure.h"
31 #include "scicos_block4.h"
35 #include "localization.h"
37 #include "strdup_windows.h"
40 #include "FigureList.h"
41 #include "BuildObjects.h"
42 #include "AxesModel.h"
44 /*****************************************************************************
45 * Internal container structure
46 ****************************************************************************/
55 char const* cachedFigureUID;
57 char *cachedGrayplotUID;
62 * Get (and allocate on demand) the internal data used on this scope
63 * \param block the block
64 * \return the scope data
66 static sco_data *getScoData(scicos_block * block);
69 * Release any internal data
71 * \param block the block
73 static void freeScoData(scicos_block * block);
76 * Push the block data to the polyline
78 * \param data the data to push
81 static BOOL pushData(scicos_block * block, double *data);
83 /*****************************************************************************
85 ****************************************************************************/
88 * Get (and allocate on demand) the figure associated with the block
89 * \param block the block
90 * \return a valid figure UID or NULL on error
92 static char const* getFigure(scicos_block * block);
95 * Get (and allocate on demand) the axe associated with the input
97 * \param pFigureUID the parent figure UID
98 * \param block the block
99 * \return a valid axe UID or NULL on error
101 static char *getAxe(char const* pFigureUID, scicos_block * block);
104 * Get (and allocate on demand) the grayplot
106 * \param pAxeUID the parent axe UID
107 * \param block the block
108 * \return a valid grayplot UID or NULL on error
110 static char *getGrayplot(char *pAxeUID, scicos_block * block);
113 * Set the grayplot and axes bounds
115 * \param block the block
116 * \param pAxeUID the axe
117 * \param pGrayplotUID the grayplot
119 static BOOL setBounds(scicos_block * block, char *pAxeUID, char *pGrayplotUID);
122 * Set the grayplot default values
124 * \param block the block
125 * \param pGrayplotUID the grayplot
127 static BOOL setDefaultValues(scicos_block * block, char *pGrayplotUID);
129 /*****************************************************************************
130 * Simulation function
131 ****************************************************************************/
133 /** \fn void cmatview(scicos_block * block,int flag)
134 \brief the computational function
135 \param block A pointer to a scicos_block
136 \param flag An int which indicates the state of the block (init, update, ending)
138 SCICOS_BLOCKS_IMPEXP void cmatview(scicos_block * block, scicos_flag flag)
140 char const* pFigureUID;
151 sco = getScoData(block);
157 pFigureUID = getFigure(block);
158 if (pFigureUID == NULL)
167 pFigureUID = getFigure(block);
168 if (pFigureUID == NULL)
175 u = GetRealInPortPtrs(block, 1);
177 result = pushData(block, u);
180 Coserror("%s: unable to push some data.", "cmatview");
194 /*-------------------------------------------------------------------------*/
196 /*****************************************************************************
198 * Container management
200 ****************************************************************************/
202 static sco_data *getScoData(scicos_block * block)
204 sco_data *sco = (sco_data *) * (block->work);
212 sco = (sco_data *) MALLOC(sizeof(sco_data));
214 goto error_handler_sco;
216 sco->scope.cachedFigureUID = NULL;
217 sco->scope.cachedAxeUID = NULL;
218 sco->scope.cachedGrayplotUID = NULL;
220 *(block->work) = sco;
226 * Error management (out of normal flow)
235 static void freeScoData(scicos_block * block)
237 sco_data *sco = (sco_data *) * (block->work);
241 FREE(sco->scope.cachedAxeUID);
242 FREE(sco->scope.cachedGrayplotUID);
248 static BOOL pushData(scicos_block * block, double *data)
250 char const* pFigureUID;
261 pFigureUID = getFigure(block);
262 pAxeUID = getAxe(pFigureUID, block);
263 pGrayplotUID = getGrayplot(pAxeUID, block);
265 m = GetInPortSize(block, 1, 1);
266 n = GetInPortSize(block, 1, 2);
276 alpha = block->rpar[0];
277 beta = block->rpar[1];
279 scaledData = (double *)MALLOC(m * n * sizeof(double));
280 if (scaledData == NULL)
285 for (i = 0; i < m * n; i++)
287 scaledData[i] = floor(alpha * data[i] + beta);
290 result = setGraphicObjectProperty(pGrayplotUID, __GO_DATA_MODEL_Z__, scaledData, jni_double_vector, m * n);
296 /*****************************************************************************
300 ****************************************************************************/
302 /*****************************************************************************
306 ****************************************************************************/
308 static char const* getFigure(scicos_block * block)
311 char const* pFigureUID = NULL;
314 sco_data *sco = (sco_data *) * (block->work);
316 // fast path for an existing object
317 if (sco->scope.cachedFigureUID != NULL)
319 return sco->scope.cachedFigureUID;
322 figNum = block->ipar[0];
324 // with a negative id, use the block number indexed from a constant.
327 figNum = 20000 + get_block_number();
330 pFigureUID = getFigureFromIndex(figNum);
332 if (pFigureUID == NULL)
334 pFigureUID = createNewFigureWithAxes();
335 setGraphicObjectProperty(pFigureUID, __GO_ID__, &figNum, jni_int, 1);
337 // the stored uid is a reference to the figure map, not to the current figure
338 pFigureUID = getFigureFromIndex(figNum);
339 sco->scope.cachedFigureUID = pFigureUID;
341 setGraphicObjectProperty(pFigureUID, __GO_COLORMAP__, &block->rpar[2], jni_double_vector, block->ipar[2]);
343 // allocate the axes through the getter
344 pAxe = getAxe(pFigureUID, block);
347 * Setup according to block settings
349 setLabel(pAxe, __GO_X_AXIS_LABEL__, "x");
350 setLabel(pAxe, __GO_Y_AXIS_LABEL__, "y");
352 setGraphicObjectProperty(pAxe, __GO_X_AXIS_VISIBLE__, &i__1, jni_bool, 1);
353 setGraphicObjectProperty(pAxe, __GO_Y_AXIS_VISIBLE__, &i__1, jni_bool, 1);
356 if (pFigureUID != NULL && sco->scope.cachedFigureUID == NULL)
358 sco->scope.cachedFigureUID = pFigureUID;
363 static char *getAxe(char const* pFigureUID, scicos_block * block)
366 sco_data *sco = (sco_data *) * (block->work);
368 // fast path for an existing object
369 if (sco->scope.cachedAxeUID != NULL)
371 return sco->scope.cachedAxeUID;
374 pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, 0);
377 * Allocate if necessary
381 cloneAxesModel(pFigureUID);
382 pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, 0);
386 * Setup on first access
390 getGrayplot(pAxe, block);
395 * then cache with local storage
397 if (pAxe != NULL && sco->scope.cachedAxeUID == NULL)
399 sco->scope.cachedAxeUID = strdup(pAxe);
400 releaseGraphicObjectProperty(__GO_PARENT__, pAxe, jni_string, 1);
402 return sco->scope.cachedAxeUID;
405 static char *getGrayplot(char *pAxeUID, scicos_block * block)
410 sco_data *sco = (sco_data *) * (block->work);
412 // fast path for an existing object
413 if (sco->scope.cachedGrayplotUID != NULL)
415 return sco->scope.cachedGrayplotUID;
418 pGrayplot = findChildWithKindAt(pAxeUID, __GO_GRAYPLOT__, 0);
421 * Allocate if necessary
423 if (pGrayplot == NULL)
425 pGrayplot = createGraphicObject(__GO_GRAYPLOT__);
427 if (pGrayplot != NULL)
429 createDataObject(pGrayplot, __GO_GRAYPLOT__);
430 setGraphicObjectRelationship(pAxeUID, pGrayplot);
435 * Setup on first access
437 if (pGrayplot != NULL)
440 setGraphicObjectProperty(pGrayplot, __GO_DATA_MAPPING__, &i__0, jni_int, 1);
441 setBounds(block, pAxeUID, pGrayplot);
442 setDefaultValues(block, pGrayplot);
445 int iClipState = 1; //on
446 setGraphicObjectProperty(pGrayplot, __GO_CLIP_STATE__, &iClipState, jni_int, 1);
451 * then cache with a local storage
453 if (pGrayplot != NULL && sco->scope.cachedGrayplotUID == NULL)
455 sco->scope.cachedGrayplotUID = strdup(pGrayplot);
456 releaseGraphicObjectProperty(__GO_PARENT__, pGrayplot, jni_string, 1);
458 return sco->scope.cachedGrayplotUID;
461 static BOOL setBounds(scicos_block * block, char *pAxeUID, char *pGrayplotUID)
466 double dataBounds[6];
470 m = GetInPortSize(block, 1, 1);
471 n = GetInPortSize(block, 1, 2);
478 dataBounds[0] = 0; // xMin
479 dataBounds[1] = (double)m; // xMax
480 dataBounds[2] = 0; // yMin
481 dataBounds[3] = (double)n; // yMax
482 dataBounds[4] = -1.0; // zMin
483 dataBounds[5] = 1.0; // zMax
485 result = setGraphicObjectProperty(pGrayplotUID, __GO_DATA_MODEL_GRID_SIZE__, gridSize, jni_int_vector, 4);
486 result &= setGraphicObjectProperty(pAxeUID, __GO_DATA_BOUNDS__, dataBounds, jni_double_vector, 6);
491 static BOOL setDefaultValues(scicos_block * block, char *pGrayplotUID)
499 m = GetInPortSize(block, 1, 1);
500 n = GetInPortSize(block, 1, 2);
504 values = (double *)CALLOC(n * m, sizeof(double));
510 result = setGraphicObjectProperty(pGrayplotUID, __GO_DATA_MODEL_Z__, values, jni_double_vector, m * n);
512 for (i = 1; i <= len; i++)
514 values[i] = (double)i;
516 result &= setGraphicObjectProperty(pGrayplotUID, __GO_DATA_MODEL_X__, values, jni_double_vector, m);
517 result &= setGraphicObjectProperty(pGrayplotUID, __GO_DATA_MODEL_Y__, values, jni_double_vector, n);