2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2011-2012 - 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
15 #include "dynlib_scicos_blocks.h"
19 #include "elementary_functions.h"
21 #include "getGraphicObjectProperty.h"
22 #include "setGraphicObjectProperty.h"
23 #include "graphicObjectProperties.h"
24 #include "createGraphicObject.h"
25 #include "deleteGraphicObject.h"
27 #include "CurrentFigure.h"
28 #include "CurrentObject.h"
30 #include "scicos_block4.h"
33 #include "localization.h"
35 #include "strdup_windows.h"
38 #include "FigureList.h"
39 #include "BuildObjects.h"
40 #include "AxesModel.h"
43 // #define LOG(...) printf(__VA_ARGS__)
46 #define HISTORY_POINTS_THRESHOLD 4096
48 /*****************************************************************************
49 * Internal container structure
50 ****************************************************************************/
60 double ***bufferCoordinates;
61 int *maxNumberOfPoints;
62 double ***historyCoordinates;
69 BOOL *disableBufferUpdate;
70 int *historyUpdateCounter;
72 char const* cachedFigureUID;
74 char ***cachedBufferPolylinesUIDs;
75 char ***cachedHistoryPolylinesUIDs;
80 * Get (and allocate on demand) the internal data used on this scope
81 * \param block the block
82 * \return the scope data
84 static sco_data *getScoData(scicos_block * block);
87 * Release any internal data
89 * \param block the block
91 static void freeScoData(scicos_block * block);
94 * Realloc the history buffer data
96 * \param block the block
97 * \param input the selected input
98 * \param numberOfPoints realloc to store this number of points
100 static sco_data *reallocHistoryBuffer(scicos_block * block, int input, int numberOfPoints);
103 * Set values into the coordinates buffer.
105 * \param block the block
106 * \param input the selected input
107 * \param coordinates the buffer
108 * \param numberOfPoints the number of points to set (actual)
109 * \param bufferPoints the buffer size (max)
110 * \param t the time to set
111 * \param value the value to set
113 static void setBuffersCoordinates(scicos_block * block, int input, double* coordinates, const int numberOfPoints,
114 const int bufferPoints, const double t, const double value);
117 * Append the data to the current data
119 * \param block the block
120 * \param input the input (0-indexed)
121 * \param t the current time
122 * \param data the data to append
124 static void appendData(scicos_block * block, int input, double t, double *data);
127 * Push the block data to the polyline
129 * \param block the block
130 * \param input the selected input
131 * \param row the selected row
132 * \param pPolylineUID the polyline uid
135 static BOOL pushData(scicos_block * block, int input, int row);
137 /*****************************************************************************
139 ****************************************************************************/
142 * Get (and allocate on demand) the figure associated with the block
143 * \param block the block
144 * \return a valid figure UID or NULL on error
146 static char const* getFigure(scicos_block * block);
149 * Get (and allocate on demand) the axe associated with the input
151 * \param pFigureUID the parent figure UID
152 * \param block the block
153 * \param input the current input index (0-indexed)
154 * \return a valid axe UID or NULL on error
156 static char *getAxe(char const* pFigureUID, scicos_block * block, int input);
159 * Get (and allocate on demand) the polyline associated with the row
161 * \param pAxeUID the parent axe UID
162 * \param block the block
163 * \param input the current input index (0-indexed)
164 * \param row the current row index (0-indexed)
165 * \param history get the history polyline
166 * \return a valid polyline UID or NULL on error
168 static char *getPolyline(char *pAxeUID, scicos_block * block, int input, int row, BOOL history);
171 * Delete all the buffer polylines.
173 * \param block the block
175 static void deleteBufferPolylines(scicos_block * block);
178 * Set the polylines history size and push the history buffer
180 * \param block the block
181 * \param input the input port index
182 * \param maxNumberOfPoints the size of the buffer
184 static BOOL pushHistory(scicos_block * block, int input, int maxNumberOfPoints);
187 * Set the polylines bounds
189 * \param block the block
190 * \param input the input port index
191 * \param periodCounter number of past periods since startup
193 static BOOL setPolylinesBounds(scicos_block * block, int input, int periodCounter);
195 /*****************************************************************************
196 * Simulation function
197 ****************************************************************************/
199 /** \fn void cmscope(scicos_block * block,int flag)
200 \brief the computational function
201 \param block A pointer to a scicos_block
202 \param flag An int which indicates the state of the block (init, update, ending)
204 SCICOS_BLOCKS_IMPEXP void cmscope(scicos_block * block, scicos_flag flag)
206 char const* pFigureUID;
219 sco = getScoData(block);
225 pFigureUID = getFigure(block);
226 if (pFigureUID == NULL)
235 pFigureUID = getFigure(block);
236 if (pFigureUID == NULL)
243 t = get_scicos_time();
244 for (i = 0; i < block->nin; i++)
246 u = (double *)block->inptr[i];
248 appendData(block, i, t, u);
249 for (j = 0; j < block->insz[i]; j++)
251 result = pushData(block, i, j);
254 Coserror("%s: unable to push some data.", "cmscope");
262 sco = getScoData(block);
263 for (i = 0; i < block->nin; i++)
265 sco = reallocHistoryBuffer(block, i, sco->internal.maxNumberOfPoints[i] + sco->internal.numberOfPoints[i]);
266 sco->scope.disableBufferUpdate[i] = FALSE;
267 sco->scope.historyUpdateCounter[i] = 0;
268 pushHistory(block, i, sco->internal.maxNumberOfPoints[i]);
270 deleteBufferPolylines(block);
279 /*-------------------------------------------------------------------------*/
281 /*****************************************************************************
283 * Container management
285 ****************************************************************************/
287 static sco_data *getScoData(scicos_block * block)
289 sco_data *sco = (sco_data *) * (block->work);
298 sco = (sco_data *) MALLOC(sizeof(sco_data));
301 goto error_handler_sco;
304 sco->internal.numberOfPoints = (int *) MALLOC(block->nin * sizeof(int));
305 if (sco->internal.numberOfPoints == NULL)
307 goto error_handler_numberOfPoints;
309 sco->internal.maxNumberOfPoints = (int *) MALLOC(block->nin * sizeof(int));
310 if (sco->internal.maxNumberOfPoints == NULL)
312 goto error_handler_maxNumberOfPoints;
315 for (i = 0; i < block->nin; i++)
317 // 0 points out of a block->ipar[2] points buffer
318 sco->internal.numberOfPoints[i] = 0;
319 // 0 points out of a 0 points history
320 sco->internal.maxNumberOfPoints[i] = 0;
323 sco->internal.bufferCoordinates = (double ***)CALLOC(block->nin, sizeof(double **));
324 if (sco->internal.bufferCoordinates == NULL)
326 goto error_handler_bufferCoordinates;
329 for (i = 0; i < block->nin; i++)
331 sco->internal.bufferCoordinates[i] = (double **)CALLOC(block->insz[i], sizeof(double *));
332 if (sco->internal.bufferCoordinates[i] == NULL)
334 goto error_handler_bufferCoordinates_i;
337 for (i = 0; i < block->nin; i++)
339 for (j = 0; j < block->insz[i]; j++)
341 sco->internal.bufferCoordinates[i][j] = (double *)CALLOC(3 * block->ipar[2], sizeof(double));
343 if (sco->internal.bufferCoordinates[i][j] == NULL)
345 goto error_handler_bufferCoordinates_ij;
350 sco->internal.historyCoordinates = (double ***)CALLOC(block->nin, sizeof(double **));
351 if (sco->internal.historyCoordinates == NULL)
353 goto error_handler_historyCoordinates;
356 for (i = 0; i < block->nin; i++)
358 sco->internal.historyCoordinates[i] = (double **)CALLOC(block->insz[i], sizeof(double *));
359 if (sco->internal.historyCoordinates[i] == NULL)
361 goto error_handler_historyCoordinates_i;
365 sco->scope.periodCounter = (int *) CALLOC(block->nin, sizeof(int));
366 if (sco->scope.periodCounter == NULL)
368 goto error_handler_periodCounter;
371 sco->scope.disableBufferUpdate = (int *) CALLOC(block->nin, sizeof(BOOL));
372 if (sco->scope.disableBufferUpdate == NULL)
374 goto error_handler_disableBufferUpdate;
376 sco->scope.historyUpdateCounter = (int *) CALLOC(block->nin, sizeof(int));
377 if (sco->scope.historyUpdateCounter == NULL)
379 goto error_handler_historyUpdateCounter;
382 sco->scope.cachedFigureUID = NULL;
383 sco->scope.cachedAxeUID = (char **)CALLOC(block->nin, sizeof(char *));
385 sco->scope.cachedBufferPolylinesUIDs = (char ***)CALLOC(block->nin, sizeof(char **));
386 sco->scope.cachedHistoryPolylinesUIDs = (char ***)CALLOC(block->nin, sizeof(char **));
387 for (i = 0; i < block->nin; i++)
389 sco->scope.cachedBufferPolylinesUIDs[i] = (char **)CALLOC(block->insz[i], sizeof(char *));
390 sco->scope.cachedHistoryPolylinesUIDs[i] = (char **)CALLOC(block->insz[i], sizeof(char *));
393 *(block->work) = sco;
399 * Error management (out of normal flow)
402 error_handler_historyUpdateCounter:
403 FREE(sco->scope.disableBufferUpdate);
404 error_handler_disableBufferUpdate:
405 FREE(sco->scope.periodCounter);
406 error_handler_periodCounter:
408 error_handler_historyCoordinates_i:
409 for (j = 0; j < i; j++)
411 FREE(sco->internal.historyCoordinates[i]);
413 FREE(sco->internal.historyCoordinates);
414 error_handler_historyCoordinates:
416 j = block->insz[i] - 1;
417 error_handler_bufferCoordinates_ij:
418 for (k = 0; k < i; k++)
420 for (l = 0; l < j; l++)
422 FREE(sco->internal.bufferCoordinates[k][l]);
426 error_handler_bufferCoordinates_i:
427 for (j = 0; j < i; j++)
429 FREE(sco->internal.bufferCoordinates[i]);
431 FREE(sco->internal.bufferCoordinates);
432 error_handler_bufferCoordinates:
433 FREE(sco->internal.maxNumberOfPoints);
434 error_handler_maxNumberOfPoints:
435 FREE(sco->internal.numberOfPoints);
436 error_handler_numberOfPoints:
444 static void freeScoData(scicos_block * block)
446 sco_data *sco = (sco_data *) * (block->work);
451 for (i = 0; i < block->nin; i++)
453 for (j = 0; j < block->insz[i]; j++)
455 if (sco->internal.historyCoordinates[i][j] != NULL)
457 FREE(sco->internal.historyCoordinates[i][j]);
459 FREE(sco->internal.bufferCoordinates[i][j]);
461 FREE(sco->internal.historyCoordinates[i]);
462 FREE(sco->internal.bufferCoordinates[i]);
464 FREE(sco->internal.historyCoordinates);
465 FREE(sco->internal.bufferCoordinates);
467 FREE(sco->scope.periodCounter);
469 FREE(sco->scope.disableBufferUpdate);
470 FREE(sco->scope.historyUpdateCounter);
472 for (i = 0; i < block->insz[0]; i++)
474 FREE(sco->scope.cachedHistoryPolylinesUIDs[i]);
475 FREE(sco->scope.cachedBufferPolylinesUIDs[i]);
477 FREE(sco->scope.cachedAxeUID);
480 *(block->work) = NULL;
484 static sco_data *reallocHistoryBuffer(scicos_block * block, int input, int numberOfPoints)
486 sco_data *sco = (sco_data *) * (block->work);
490 int allocatedNumberOfPoints;
492 int previousNumberOfPoints = sco->internal.maxNumberOfPoints[input];
493 int numberOfCopiedPoints = numberOfPoints - sco->internal.maxNumberOfPoints[input];
496 int bufferNumberOfPoints = block->ipar[2];
497 int bufferNewPointInc;
499 if (previousNumberOfPoints == 0)
501 allocatedNumberOfPoints = numberOfPoints;
502 bufferNewPointInc = 0;
506 allocatedNumberOfPoints = numberOfPoints - 1;
507 bufferNewPointInc = 1;
510 if (sco->scope.historyUpdateCounter[input] <= 0)
512 if (numberOfPoints > HISTORY_POINTS_THRESHOLD)
514 sco->scope.disableBufferUpdate[input] = TRUE;
515 sco->scope.historyUpdateCounter[input] = numberOfPoints / HISTORY_POINTS_THRESHOLD;
519 sco->scope.disableBufferUpdate[input] = FALSE;
520 sco->scope.historyUpdateCounter[input] = 0;
524 for (i = 0; i < block->insz[input]; i++)
526 ptr = (double *)MALLOC(3 * allocatedNumberOfPoints * sizeof(double));
532 // memcpy existing X-axis values from the history
533 memcpy(ptr, sco->internal.historyCoordinates[input][i], previousNumberOfPoints * sizeof(double));
534 // memcpy existing Y-axis values from the history
535 memcpy(ptr + allocatedNumberOfPoints, sco->internal.historyCoordinates[input][i] + previousNumberOfPoints, previousNumberOfPoints * sizeof(double));
536 // clear the last points, the Z-axis values
537 memset(ptr + 2 * allocatedNumberOfPoints, 0, allocatedNumberOfPoints * sizeof(double));
539 // then set the last points to the last values for X-axis and Y-axis values from the buffer points
540 buffer = sco->internal.bufferCoordinates[input][i];
541 memcpy(ptr + previousNumberOfPoints, buffer + bufferNewPointInc, (numberOfCopiedPoints - bufferNewPointInc) * sizeof(double));
542 memcpy(ptr + allocatedNumberOfPoints + previousNumberOfPoints, buffer + bufferNumberOfPoints + bufferNewPointInc, (numberOfCopiedPoints - bufferNewPointInc) * sizeof(double));
544 FREE(sco->internal.historyCoordinates[input][i]);
545 sco->internal.historyCoordinates[input][i] = ptr;
548 sco->internal.maxNumberOfPoints[input] = allocatedNumberOfPoints;
558 static void setBuffersCoordinates(scicos_block * block, int input, double* coordinates, const int numberOfPoints,
559 const int bufferPoints, const double t, const double value)
562 sco_data *sco = (sco_data *) * (block->work);
564 if (sco->scope.disableBufferUpdate[input] == TRUE)
566 coordinates[numberOfPoints] = t;
567 coordinates[bufferPoints + numberOfPoints] = value;
571 // X-axis values first
572 for (setLen = numberOfPoints; setLen < bufferPoints; setLen++)
574 coordinates[setLen] = t;
576 // then Y-axis values
577 for (setLen = numberOfPoints; setLen < bufferPoints; setLen++)
579 coordinates[bufferPoints + setLen] = value;
581 // then Z-axis values (always clear'ed)
584 static void appendData(scicos_block * block, int input, double t, double *data)
588 sco_data *sco = (sco_data *) * (block->work);
591 * Handle the case where the t is greater than the data_bounds
593 if (t > ((sco->scope.periodCounter[input] + 1) * block->rpar[1 + input]))
595 sco->scope.periodCounter[input]++;
597 // set the buffer coordinates to the last point
598 for (i = 0; i < block->insz[input]; i++)
600 sco->internal.bufferCoordinates[input][i][0] = sco->internal.bufferCoordinates[input][i][sco->internal.numberOfPoints[input] - 1];
601 sco->internal.bufferCoordinates[input][i][block->ipar[2]] = sco->internal.bufferCoordinates[input][i][block->ipar[2] + sco->internal.numberOfPoints[input] - 1];
603 sco->internal.numberOfPoints[input] = 1;
605 // clear the history coordinates
606 sco->internal.maxNumberOfPoints[input] = 0;
607 for (i = 0; i < block->insz[input]; i++)
609 if (sco->internal.historyCoordinates[input][i] != NULL)
611 FREE(sco->internal.historyCoordinates[input][i]);
612 sco->internal.historyCoordinates[input][i] = NULL;
616 // configure scope setting
617 if (setPolylinesBounds(block, input, sco->scope.periodCounter[input]) == FALSE)
626 * Handle the case where the scope has more points than maxNumberOfPoints
628 if (sco != NULL && sco->internal.numberOfPoints[input] >= block->ipar[2])
630 int maxNumberOfPoints = sco->internal.maxNumberOfPoints[input];
632 // on a full scope, re-alloc history coordinates
633 maxNumberOfPoints = maxNumberOfPoints + block->ipar[2];
634 sco = reallocHistoryBuffer(block, input, maxNumberOfPoints);
636 // set the buffer coordinates to the last point
637 for (i = 0; i < block->insz[input]; i++)
639 sco->internal.bufferCoordinates[input][i][0] = sco->internal.bufferCoordinates[input][i][block->ipar[2] - 1];
640 sco->internal.bufferCoordinates[input][i][block->ipar[2]] = sco->internal.bufferCoordinates[input][i][2 * block->ipar[2] - 1];
642 sco->internal.numberOfPoints[input] = 1;
644 // reconfigure related graphic objects
645 if (pushHistory(block, input, sco->internal.maxNumberOfPoints[input]) == FALSE)
658 for (i = 0; i < block->insz[input]; i++)
660 const double value = data[i];
661 setBuffersCoordinates(block, input, sco->internal.bufferCoordinates[input][i], sco->internal.numberOfPoints[input], block->ipar[2], t, value);
664 sco->internal.numberOfPoints[input]++;
668 static BOOL pushData(scicos_block * block, int input, int row)
670 char const* pFigureUID;
677 pFigureUID = getFigure(block);
678 pAxeUID = getAxe(pFigureUID, block, input);
679 pPolylineUID = getPolyline(pAxeUID, block, input, row, FALSE);
681 sco = getScoData(block);
687 // do not push any data if disabled
688 if (sco->scope.disableBufferUpdate[input] == TRUE)
693 // select the right input and row
694 data = sco->internal.bufferCoordinates[input][row];
696 return setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_COORDINATES__, data, jni_double_vector, block->ipar[2]);
699 /*****************************************************************************
703 ****************************************************************************/
706 * Set properties on the figure.
708 * \param pFigureUID the figure uid
709 * \param block the current block
711 static void setFigureSettings(char const* pFigureUID, scicos_block * block)
717 int *ipar = block->ipar;
719 win_pos[0] = ipar[3];
720 win_pos[1] = ipar[4];
721 win_dim[0] = ipar[5];
722 win_dim[1] = ipar[6];
724 if (win_pos[0] > 0 && win_pos[1] > 0)
726 setGraphicObjectProperty(pFigureUID, __GO_POSITION__, &win_pos, jni_int_vector, 2);
729 if (win_dim[0] > 0 && win_dim[1] > 0)
731 setGraphicObjectProperty(pFigureUID, __GO_SIZE__, &win_dim, jni_int_vector, 2);
734 label = GetLabelPtrs(block);
737 if (strlen(label) > 0)
739 setGraphicObjectProperty(pFigureUID, __GO_NAME__, label, jni_string, 1);
745 * Set properties on the axes.
747 * \param pAxeUID the axe uid
748 * \param block the current block
749 * \param index axe index (0-indexed)
751 static void setAxesSettings(char *pAxeUID, scicos_block * block, int index)
753 double axesBounds[4];
756 double nin = (double) block->nin;
758 axesBounds[0] = 0; // x
759 axesBounds[1] = index / nin; // y
760 axesBounds[2] = 1.0; // w
761 axesBounds[3] = 1 / nin; // h
762 setGraphicObjectProperty(pAxeUID, __GO_AXES_BOUNDS__, axesBounds, jni_double_vector, 4);
768 setGraphicObjectProperty(pAxeUID, __GO_MARGINS__, margins, jni_double_vector, 4);
772 /*****************************************************************************
776 ****************************************************************************/
778 static char const* getFigure(scicos_block * block)
781 char const* pFigureUID = NULL;
784 sco_data *sco = (sco_data *) * (block->work);
788 // assert the sco is not NULL
794 // fast path for an existing object
795 if (sco->scope.cachedFigureUID != NULL)
797 return sco->scope.cachedFigureUID;
800 figNum = block->ipar[0];
802 // with a negative id, use the block number indexed from a constant.
805 figNum = 20000 + get_block_number();
808 pFigureUID = getFigureFromIndex(figNum);
810 if (pFigureUID == NULL)
812 pFigureUID = createNewFigureWithAxes();
813 setGraphicObjectProperty(pFigureUID, __GO_ID__, &figNum, jni_int, 1);
815 // the stored uid is a reference to the figure map, not to the current figure
816 pFigureUID = getFigureFromIndex(figNum);
817 sco->scope.cachedFigureUID = pFigureUID;
819 // set configured parameters
820 setFigureSettings(pFigureUID, block);
822 // allocate the axes through the getter
823 for (i = 0; i < GetNin(block); i++)
825 pAxe = getAxe(pFigureUID, block, i);
828 * Setup according to block settings
830 setLabel(pAxe, __GO_X_AXIS_LABEL__, "t");
831 setLabel(pAxe, __GO_Y_AXIS_LABEL__, "y");
833 setGraphicObjectProperty(pAxe, __GO_X_AXIS_VISIBLE__, &i__1, jni_bool, 1);
834 setGraphicObjectProperty(pAxe, __GO_Y_AXIS_VISIBLE__, &i__1, jni_bool, 1);
836 setPolylinesBounds(block, i, 0);
840 if (sco->scope.cachedFigureUID == NULL)
842 sco->scope.cachedFigureUID = pFigureUID;
847 static char *getAxe(char const* pFigureUID, scicos_block * block, int input)
851 sco_data *sco = (sco_data *) * (block->work);
853 // assert the sco is not NULL
859 // fast path for an existing object
860 if (sco->scope.cachedAxeUID != NULL && sco->scope.cachedAxeUID[input] != NULL)
862 return sco->scope.cachedAxeUID[input];
865 pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, input);
868 * Allocate if necessary
872 cloneAxesModel(pFigureUID);
873 pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, input);
877 * Setup on first access
881 // allocate the polylines through the getter
882 for (i = 0; i < block->insz[input]; i++)
884 getPolyline(pAxe, block, input, i, TRUE);
886 for (i = 0; i < block->insz[input]; i++)
888 getPolyline(pAxe, block, input, i, FALSE);
891 setAxesSettings(pAxe, block, input);
895 * then cache with local storage
897 if (pAxe != NULL && sco->scope.cachedAxeUID != NULL && sco->scope.cachedAxeUID[input] == NULL)
899 sco->scope.cachedAxeUID[input] = strdup(pAxe);
900 releaseGraphicObjectProperty(__GO_PARENT__, pAxe, jni_string, 1);
902 return sco->scope.cachedAxeUID[input];
905 static char *getPolyline(char *pAxeUID, scicos_block * block, int input, int row, BOOL history)
912 char*** polylinesUIDs;
914 int polylineDefaultNumElement;
916 sco_data *sco = (sco_data *) * (block->work);
918 // assert the sco is not NULL
926 polylinesUIDs = sco->scope.cachedBufferPolylinesUIDs;
927 polylineIndex = block->insz[input] + row;
928 polylineDefaultNumElement = block->ipar[2];
932 polylinesUIDs = sco->scope.cachedHistoryPolylinesUIDs;
934 polylineDefaultNumElement = 0;
937 // fast path for an existing object
938 if (polylinesUIDs != NULL && polylinesUIDs[input] != NULL && polylinesUIDs[input][row] != NULL)
940 return polylinesUIDs[input][row];
943 pPolyline = findChildWithKindAt(pAxeUID, __GO_POLYLINE__, polylineIndex);
946 * Allocate if necessary
948 if (pPolyline == NULL)
950 pPolyline = createGraphicObject(__GO_POLYLINE__);
952 if (pPolyline != NULL)
954 createDataObject(pPolyline, __GO_POLYLINE__);
955 setGraphicObjectRelationship(pAxeUID, pPolyline);
960 * Setup on first access
962 if (pPolyline != NULL)
966 * Default setup (will crash if removed)
969 int polylineSize[2] = { 1, polylineDefaultNumElement };
970 setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
973 // ipar=[win;size(in,'*');N;wpos(:);wdim(:);in(:);clrs(:);heritance]
974 // 1 1 1 2 2 nin nin 1
975 color = block->ipar[7 + block->nin + input + row];
978 LOG("%s: %s at %d at %d to %d\n", "cmscope", "set lines mode", input, row, color);
980 setGraphicObjectProperty(pPolyline, __GO_LINE_MODE__, &b__true, jni_bool, 1);
981 setGraphicObjectProperty(pPolyline, __GO_LINE_COLOR__, &color, jni_int, 1);
987 LOG("%s: %s at %d at %d to %d\n", "cmscope", "set mark mode", input, row, -color);
989 setGraphicObjectProperty(pPolyline, __GO_MARK_MODE__, &b__true, jni_bool, 1);
990 setGraphicObjectProperty(pPolyline, __GO_MARK_STYLE__, &color, jni_int, 1);
994 int iClipState = 1; //on
995 setGraphicObjectProperty(pPolyline, __GO_CLIP_STATE__, &iClipState, jni_int, 1);
1000 * then cache with local storage
1002 if (pPolyline != NULL && polylinesUIDs != NULL && polylinesUIDs[input] != NULL)
1004 polylinesUIDs[input][row] = strdup(pPolyline);
1005 releaseGraphicObjectProperty(__GO_PARENT__, pPolyline, jni_string, 1);
1007 return polylinesUIDs[input][row];
1010 static void deleteBufferPolylines(scicos_block * block)
1018 sco = getScoData(block);
1019 for (i = 0; i < block->nin; i++)
1021 for (j = 0; j < block->insz[i]; j++)
1023 pPolylineUID = sco->scope.cachedBufferPolylinesUIDs[i][j];
1024 deleteGraphicObject(pPolylineUID);
1029 static BOOL pushHistory(scicos_block * block, int input, int maxNumberOfPoints)
1033 char const* pFigureUID;
1041 int polylineSize[2] = { 1, maxNumberOfPoints };
1043 sco = getScoData(block);
1044 pFigureUID = getFigure(block);
1045 pAxeUID = getAxe(pFigureUID, block, input);
1047 // push the data only if the counter == 0, decrement the counter if positive
1048 if (sco->scope.historyUpdateCounter[input] > 0)
1050 sco->scope.historyUpdateCounter[input]--;
1052 if (sco->scope.historyUpdateCounter[input] > 0)
1057 for (i = 0; i < block->insz[input]; i++)
1059 pPolylineUID = getPolyline(pAxeUID, block, input, i, TRUE);
1060 result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
1062 data = sco->internal.historyCoordinates[input][i];
1063 result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_COORDINATES__, data, jni_double_vector, maxNumberOfPoints);
1069 static BOOL setPolylinesBounds(scicos_block * block, int input, int periodCounter)
1071 char const* pFigureUID;
1074 double dataBounds[6];
1075 int nin = block->nin;
1076 double period = block->rpar[block->nrpar - 3 * nin + input];
1078 dataBounds[0] = periodCounter * period; // xMin
1079 dataBounds[1] = (periodCounter + 1) * period; // xMax
1080 dataBounds[2] = block->rpar[block->nrpar - 2 * nin + 2 * input]; // yMin
1081 dataBounds[3] = block->rpar[block->nrpar - 2 * nin + 2 * input + 1]; // yMax
1082 dataBounds[4] = -1.0; // zMin
1083 dataBounds[5] = 1.0; // zMax
1085 LOG("%s: %s at %d to %f\n", "cmscope", "setPolylinesBounds", input, dataBounds[1]);
1087 pFigureUID = getFigure(block);
1088 pAxeUID = getAxe(pFigureUID, block, input);
1089 return setGraphicObjectProperty(pAxeUID, __GO_DATA_BOUNDS__, dataBounds, jni_double_vector, 6);