more slower.
- use a 2 objects approach to avoid copy cost on a huge buffer
- use a 4K points threshold on misconfiguration
- cmscope and cscope updated
- update the unit tests to check the number of points at the end
Change-Id: I700d22d3769fae517575c95ca6e1eab30992cd37
* Bug #12031 fixed - Changes in context of superblock did not always have
effect.
+* Bug #12057 fixed - Scopes with big scope buffer size simulation was much
+ more slower.
+
* Bug #12162 fixed - tbx_build_blocks did not report errors.
* Bug #12167 fixed - Text of ports in superblocks were not updated.
#include "setGraphicObjectProperty.h"
#include "graphicObjectProperties.h"
#include "createGraphicObject.h"
+#include "deleteGraphicObject.h"
#include "CurrentFigure.h"
#include "CurrentObject.h"
// #define LOG(...) printf(__VA_ARGS__)
#define LOG(...)
+#define HISTORY_POINTS_THRESHOLD 4096
+
/*****************************************************************************
* Internal container structure
****************************************************************************/
struct
{
int *numberOfPoints;
+ double ***bufferCoordinates;
int *maxNumberOfPoints;
- double ***coordinates;
+ double ***historyCoordinates;
} internal;
struct
{
int *periodCounter;
+ BOOL *disableBufferUpdate;
+ int *historyUpdateCounter;
+
char const* cachedFigureUID;
char **cachedAxeUID;
- char ***cachedPolylinesUIDs;
+ char ***cachedBufferPolylinesUIDs;
+ char ***cachedHistoryPolylinesUIDs;
} scope;
} sco_data;
static void freeScoData(scicos_block * block);
/**
- * Realloc any internal data
+ * Realloc the history buffer data
*
* \param block the block
* \param input the selected input
* \param numberOfPoints realloc to store this number of points
*/
-static sco_data *reallocScoData(scicos_block * block, int input, int numberOfPoints);
+static sco_data *reallocHistoryBuffer(scicos_block * block, int input, int numberOfPoints);
+
+/**
+ * Set values into the coordinates buffer.
+ *
+ * \param block the block
+ * \param input the selected input
+ * \param coordinates the buffer
+ * \param numberOfPoints the number of points to set (actual)
+ * \param bufferPoints the buffer size (max)
+ * \param t the time to set
+ * \param value the value to set
+ */
+static void setBuffersCoordinates(scicos_block * block, int input, double* coordinates, const int numberOfPoints,
+ const int bufferPoints, const double t, const double value);
/**
* Append the data to the current data
* \param block the block
* \param input the current input index (0-indexed)
* \param row the current row index (0-indexed)
+ * \param history get the history polyline
* \return a valid polyline UID or NULL on error
*/
-static char *getPolyline(char *pAxeUID, scicos_block * block, int input, int row);
+static char *getPolyline(char *pAxeUID, scicos_block * block, int input, int row, BOOL history);
+
+/**
+ * Delete all the buffer polylines.
+ *
+ * \param block the block
+ */
+static void deleteBufferPolylines(scicos_block * block);
/**
- * Set the polylines buffer size
+ * Set the polylines history size and push the history buffer
*
* \param block the block
* \param input the input port index
* \param maxNumberOfPoints the size of the buffer
*/
-static BOOL setPolylinesBuffers(scicos_block * block, int input, int maxNumberOfPoints);
+static BOOL pushHistory(scicos_block * block, int input, int maxNumberOfPoints);
/**
* Set the polylines bounds
break;
case Ending:
+ sco = getScoData(block);
+ for (i = 0; i < block->nin; i++)
+ {
+ sco = reallocHistoryBuffer(block, i, sco->internal.maxNumberOfPoints[i] + sco->internal.numberOfPoints[i]);
+ sco->scope.disableBufferUpdate[i] = FALSE;
+ sco->scope.historyUpdateCounter[i] = 0;
+ pushHistory(block, i, sco->internal.maxNumberOfPoints[i]);
+ }
+ deleteBufferPolylines(block);
freeScoData(block);
break;
for (i = 0; i < block->nin; i++)
{
+ // 0 points out of a block->ipar[2] points buffer
sco->internal.numberOfPoints[i] = 0;
- sco->internal.maxNumberOfPoints[i] = block->ipar[2];
+ // 0 points out of a 0 points history
+ sco->internal.maxNumberOfPoints[i] = 0;
}
- sco->internal.coordinates = (double ***)CALLOC(block->nin, sizeof(double **));
- if (sco->internal.coordinates == NULL)
+ sco->internal.bufferCoordinates = (double ***)CALLOC(block->nin, sizeof(double **));
+ if (sco->internal.bufferCoordinates == NULL)
{
- goto error_handler_coordinates;
+ goto error_handler_bufferCoordinates;
}
for (i = 0; i < block->nin; i++)
{
- sco->internal.coordinates[i] = (double **)CALLOC(block->insz[i], sizeof(double *));
- if (sco->internal.coordinates[i] == NULL)
+ sco->internal.bufferCoordinates[i] = (double **)CALLOC(block->insz[i], sizeof(double *));
+ if (sco->internal.bufferCoordinates[i] == NULL)
{
- goto error_handler_coordinates_i;
+ goto error_handler_bufferCoordinates_i;
}
}
for (i = 0; i < block->nin; i++)
{
for (j = 0; j < block->insz[i]; j++)
{
- sco->internal.coordinates[i][j] = (double *)CALLOC(3 * block->ipar[2], sizeof(double));
+ sco->internal.bufferCoordinates[i][j] = (double *)CALLOC(3 * block->ipar[2], sizeof(double));
- if (sco->internal.coordinates[i][j] == NULL)
+ if (sco->internal.bufferCoordinates[i][j] == NULL)
{
- goto error_handler_coordinates_ij;
+ goto error_handler_bufferCoordinates_ij;
}
}
}
+ sco->internal.historyCoordinates = (double ***)CALLOC(block->nin, sizeof(double **));
+ if (sco->internal.historyCoordinates == NULL)
+ {
+ goto error_handler_historyCoordinates;
+ }
+
+ for (i = 0; i < block->nin; i++)
+ {
+ sco->internal.historyCoordinates[i] = (double **)CALLOC(block->insz[i], sizeof(double *));
+ if (sco->internal.historyCoordinates[i] == NULL)
+ {
+ goto error_handler_historyCoordinates_i;
+ }
+ }
+
sco->scope.periodCounter = (int *) CALLOC(block->nin, sizeof(int));
if (sco->scope.periodCounter == NULL)
{
goto error_handler_periodCounter;
}
+ sco->scope.disableBufferUpdate = (int *) CALLOC(block->nin, sizeof(BOOL));
+ if (sco->scope.disableBufferUpdate == NULL)
+ {
+ goto error_handler_disableBufferUpdate;
+ }
+ sco->scope.historyUpdateCounter = (int *) CALLOC(block->nin, sizeof(int));
+ if (sco->scope.historyUpdateCounter == NULL)
+ {
+ goto error_handler_historyUpdateCounter;
+ }
+
sco->scope.cachedFigureUID = NULL;
sco->scope.cachedAxeUID = (char **)CALLOC(block->nin, sizeof(char *));
- sco->scope.cachedPolylinesUIDs = (char ***)CALLOC(block->nin, sizeof(char **));
+ sco->scope.cachedBufferPolylinesUIDs = (char ***)CALLOC(block->nin, sizeof(char **));
+ sco->scope.cachedHistoryPolylinesUIDs = (char ***)CALLOC(block->nin, sizeof(char **));
for (i = 0; i < block->nin; i++)
{
- sco->scope.cachedPolylinesUIDs[i] = (char **)CALLOC(block->insz[i], sizeof(char *));
+ sco->scope.cachedBufferPolylinesUIDs[i] = (char **)CALLOC(block->insz[i], sizeof(char *));
+ sco->scope.cachedHistoryPolylinesUIDs[i] = (char **)CALLOC(block->insz[i], sizeof(char *));
}
*(block->work) = sco;
/*
* Error management (out of normal flow)
*/
+
+error_handler_historyUpdateCounter:
+ FREE(sco->scope.disableBufferUpdate);
+error_handler_disableBufferUpdate:
+ FREE(sco->scope.periodCounter);
error_handler_periodCounter:
+ i = block->nin;
+error_handler_historyCoordinates_i:
+ for (j = 0; j < i; j++)
+ {
+ FREE(sco->internal.historyCoordinates[i]);
+ }
+ FREE(sco->internal.historyCoordinates);
+error_handler_historyCoordinates:
i = block->nin - 1;
- j = 2 ^ 31;
-error_handler_coordinates_ij:
+ j = block->insz[i] - 1;
+error_handler_bufferCoordinates_ij:
for (k = 0; k < i; k++)
{
- for (l = 0; l < j && l < block->insz[i]; l++)
+ for (l = 0; l < j; l++)
{
- FREE(sco->internal.coordinates[k][l]);
+ FREE(sco->internal.bufferCoordinates[k][l]);
}
}
i = block->nin - 1;
-error_handler_coordinates_i:
+error_handler_bufferCoordinates_i:
for (j = 0; j < i; j++)
{
- FREE(sco->internal.coordinates[i]);
+ FREE(sco->internal.bufferCoordinates[i]);
}
- FREE(sco->internal.coordinates);
-error_handler_coordinates:
+ FREE(sco->internal.bufferCoordinates);
+error_handler_bufferCoordinates:
FREE(sco->internal.maxNumberOfPoints);
error_handler_maxNumberOfPoints:
FREE(sco->internal.numberOfPoints);
{
for (j = 0; j < block->insz[i]; j++)
{
- FREE(sco->internal.coordinates[i][j]);
+ if (sco->internal.historyCoordinates[i][j] != NULL)
+ {
+ FREE(sco->internal.historyCoordinates[i][j]);
+ }
+ FREE(sco->internal.bufferCoordinates[i][j]);
}
- FREE(sco->internal.coordinates[i]);
+ FREE(sco->internal.historyCoordinates[i]);
+ FREE(sco->internal.bufferCoordinates[i]);
}
- FREE(sco->internal.coordinates);
+ FREE(sco->internal.historyCoordinates);
+ FREE(sco->internal.bufferCoordinates);
- for (i = 0; i < block->nin; i++)
+ FREE(sco->scope.periodCounter);
+
+ FREE(sco->scope.disableBufferUpdate);
+ FREE(sco->scope.historyUpdateCounter);
+
+ for (i = 0; i < block->insz[0]; i++)
{
- for (j = 0; j < block->insz[i]; j++)
- {
- FREE(sco->scope.cachedPolylinesUIDs[i][j]);
- }
- FREE(sco->scope.cachedAxeUID[i]);
+ FREE(sco->scope.cachedHistoryPolylinesUIDs[i]);
+ FREE(sco->scope.cachedBufferPolylinesUIDs[i]);
}
+ FREE(sco->scope.cachedAxeUID);
FREE(sco);
*(block->work) = NULL;
}
}
-static sco_data *reallocScoData(scicos_block * block, int input, int numberOfPoints)
+static sco_data *reallocHistoryBuffer(scicos_block * block, int input, int numberOfPoints)
{
sco_data *sco = (sco_data *) * (block->work);
int i;
double *ptr;
- int setLen;
+ int allocatedNumberOfPoints;
+
int previousNumberOfPoints = sco->internal.maxNumberOfPoints[input];
- int newPoints = numberOfPoints - previousNumberOfPoints;
+ int numberOfCopiedPoints = numberOfPoints - sco->internal.maxNumberOfPoints[input];
- LOG("%s: %s at %d to %d\n", "cmscope", "reallocScoData", input, numberOfPoints);
+ double *buffer;
+ int bufferNumberOfPoints = block->ipar[2];
+ int bufferNewPointInc;
+
+ if (previousNumberOfPoints == 0)
+ {
+ allocatedNumberOfPoints = numberOfPoints;
+ bufferNewPointInc = 0;
+ }
+ else
+ {
+ allocatedNumberOfPoints = numberOfPoints - 1;
+ bufferNewPointInc = 1;
+ }
+
+ if (sco->scope.historyUpdateCounter[input] <= 0)
+ {
+ if (numberOfPoints > HISTORY_POINTS_THRESHOLD)
+ {
+ sco->scope.disableBufferUpdate[input] = TRUE;
+ sco->scope.historyUpdateCounter[input] = numberOfPoints / HISTORY_POINTS_THRESHOLD;
+ }
+ else
+ {
+ sco->scope.disableBufferUpdate[input] = FALSE;
+ sco->scope.historyUpdateCounter[input] = 0;
+ }
+ }
for (i = 0; i < block->insz[input]; i++)
{
- ptr = (double *)REALLOC(sco->internal.coordinates[input][i], 3 * numberOfPoints * sizeof(double));
+ ptr = (double *)MALLOC(3 * allocatedNumberOfPoints * sizeof(double));
if (ptr == NULL)
{
goto error_handler;
}
+ // memcpy existing X-axis values from the history
+ memcpy(ptr, sco->internal.historyCoordinates[input][i], previousNumberOfPoints * sizeof(double));
+ // memcpy existing Y-axis values from the history
+ memcpy(ptr + allocatedNumberOfPoints, sco->internal.historyCoordinates[input][i] + previousNumberOfPoints, previousNumberOfPoints * sizeof(double));
// clear the last points, the Z-axis values
- memset(ptr + 2 * numberOfPoints, 0, numberOfPoints * sizeof(double));
-
- // memcpy existing Y-axis values (use memmove to handle memory overlapping)
- memmove(ptr + numberOfPoints, ptr + previousNumberOfPoints, previousNumberOfPoints * sizeof(double));
+ memset(ptr + 2 * allocatedNumberOfPoints, 0, allocatedNumberOfPoints * sizeof(double));
- // then set the last points to the last values for Y-axis and X-axis values
- for (setLen = newPoints - 1; setLen >= 0; setLen--)
- {
- ptr[numberOfPoints + previousNumberOfPoints + setLen] = ptr[numberOfPoints + previousNumberOfPoints - 1];
- }
- for (setLen = newPoints - 1; setLen >= 0; setLen--)
- {
- ptr[previousNumberOfPoints + setLen] = ptr[previousNumberOfPoints - 1];
- }
+ // then set the last points to the last values for X-axis and Y-axis values from the buffer points
+ buffer = sco->internal.bufferCoordinates[input][i];
+ memcpy(ptr + previousNumberOfPoints, buffer + bufferNewPointInc, (numberOfCopiedPoints - bufferNewPointInc) * sizeof(double));
+ memcpy(ptr + allocatedNumberOfPoints + previousNumberOfPoints, buffer + bufferNumberOfPoints + bufferNewPointInc, (numberOfCopiedPoints - bufferNewPointInc) * sizeof(double));
- sco->internal.coordinates[input][i] = ptr;
+ FREE(sco->internal.historyCoordinates[input][i]);
+ sco->internal.historyCoordinates[input][i] = ptr;
}
- sco->internal.maxNumberOfPoints[input] = numberOfPoints;
+ sco->internal.maxNumberOfPoints[input] = allocatedNumberOfPoints;
return sco;
error_handler:
return NULL;
}
+static void setBuffersCoordinates(scicos_block * block, int input, double* coordinates, const int numberOfPoints,
+ const int bufferPoints, const double t, const double value)
+{
+ int setLen;
+ sco_data *sco = (sco_data *) * (block->work);
+
+ if (sco->scope.disableBufferUpdate[input] == TRUE)
+ {
+ coordinates[numberOfPoints] = t;
+ coordinates[bufferPoints + numberOfPoints] = value;
+ return;
+ }
+
+ // X-axis values first
+ for (setLen = numberOfPoints; setLen < bufferPoints; setLen++)
+ {
+ coordinates[setLen] = t;
+ }
+ // then Y-axis values
+ for (setLen = numberOfPoints; setLen < bufferPoints; setLen++)
+ {
+ coordinates[bufferPoints + setLen] = value;
+ }
+ // then Z-axis values (always clear'ed)
+}
+
static void appendData(scicos_block * block, int input, double t, double *data)
{
int i;
sco_data *sco = (sco_data *) * (block->work);
- int maxNumberOfPoints = sco->internal.maxNumberOfPoints[input];
- int numberOfPoints = sco->internal.numberOfPoints[input];
-
/*
* Handle the case where the t is greater than the data_bounds
{
sco->scope.periodCounter[input]++;
- numberOfPoints = 0;
- sco->internal.numberOfPoints[input] = 0;
+ // set the buffer coordinates to the last point
+ for (i = 0; i < block->insz[input]; i++)
+ {
+ sco->internal.bufferCoordinates[input][i][0] = sco->internal.bufferCoordinates[input][i][sco->internal.numberOfPoints[input] - 1];
+ sco->internal.bufferCoordinates[input][i][block->ipar[2]] = sco->internal.bufferCoordinates[input][i][block->ipar[2] + sco->internal.numberOfPoints[input] - 1];
+ }
+ sco->internal.numberOfPoints[input] = 1;
+
+ // clear the history coordinates
+ sco->internal.maxNumberOfPoints[input] = 0;
+ for (i = 0; i < block->insz[input]; i++)
+ {
+ if (sco->internal.historyCoordinates[input][i] != NULL)
+ {
+ FREE(sco->internal.historyCoordinates[input][i]);
+ sco->internal.historyCoordinates[input][i] = NULL;
+ }
+ }
+
+ // configure scope setting
if (setPolylinesBounds(block, input, sco->scope.periodCounter[input]) == FALSE)
{
set_block_error(-5);
/*
* Handle the case where the scope has more points than maxNumberOfPoints
*/
- if (sco != NULL && numberOfPoints >= maxNumberOfPoints)
+ if (sco != NULL && sco->internal.numberOfPoints[input] >= block->ipar[2])
{
- // on a full scope, re-alloc
+ int maxNumberOfPoints = sco->internal.maxNumberOfPoints[input];
+
+ // on a full scope, re-alloc history coordinates
maxNumberOfPoints = maxNumberOfPoints + block->ipar[2];
- sco = reallocScoData(block, input, maxNumberOfPoints);
+ sco = reallocHistoryBuffer(block, input, maxNumberOfPoints);
+
+ // set the buffer coordinates to the last point
+ for (i = 0; i < block->insz[input]; i++)
+ {
+ sco->internal.bufferCoordinates[input][i][0] = sco->internal.bufferCoordinates[input][i][block->ipar[2] - 1];
+ sco->internal.bufferCoordinates[input][i][block->ipar[2]] = sco->internal.bufferCoordinates[input][i][2 * block->ipar[2] - 1];
+ }
+ sco->internal.numberOfPoints[input] = 1;
// reconfigure related graphic objects
- if (setPolylinesBuffers(block, input, maxNumberOfPoints) == FALSE)
+ if (pushHistory(block, input, sco->internal.maxNumberOfPoints[input]) == FALSE)
{
set_block_error(-5);
freeScoData(block);
*/
if (sco != NULL)
{
- int setLen;
-
for (i = 0; i < block->insz[input]; i++)
{
- // X-axis values first
- for (setLen = maxNumberOfPoints - numberOfPoints - 1; setLen >= 0; setLen--)
- {
- sco->internal.coordinates[input][i][numberOfPoints + setLen] = t;
- }
-
- // then Y-axis values
- for (setLen = maxNumberOfPoints - numberOfPoints - 1; setLen >= 0; setLen--)
- {
- sco->internal.coordinates[input][i][maxNumberOfPoints + numberOfPoints + setLen] = data[i];
- }
-
- // do not update Z-axis values, always cleared
+ const double value = data[i];
+ setBuffersCoordinates(block, input, sco->internal.bufferCoordinates[input][i], sco->internal.numberOfPoints[input], block->ipar[2], t, value);
}
sco->internal.numberOfPoints[input]++;
pFigureUID = getFigure(block);
pAxeUID = getAxe(pFigureUID, block, input);
- pPolylineUID = getPolyline(pAxeUID, block, input, row);
+ pPolylineUID = getPolyline(pAxeUID, block, input, row, FALSE);
sco = getScoData(block);
if (sco == NULL)
return FALSE;
}
+ // do not push any data if disabled
+ if (sco->scope.disableBufferUpdate[input] == TRUE)
+ {
+ return TRUE;
+ }
+
// select the right input and row
- data = sco->internal.coordinates[input][row];
+ data = sco->internal.bufferCoordinates[input][row];
- return setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_COORDINATES__, data, jni_double_vector, sco->internal.maxNumberOfPoints[input]);
+ return setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_COORDINATES__, data, jni_double_vector, block->ipar[2]);
}
/*****************************************************************************
{
int win_pos[2];
int win_dim[2];
+ char* label;
int *ipar = block->ipar;
{
setGraphicObjectProperty(pFigureUID, __GO_SIZE__, &win_dim, jni_int_vector, 2);
}
-};
+
+ label = GetLabelPtrs(block);
+ if (label != NULL)
+ {
+ if (strlen(label) > 0)
+ {
+ setGraphicObjectProperty(pFigureUID, __GO_NAME__, label, jni_string, 1);
+ }
+ }
+}
/**
* Set properties on the axes.
// allocate the polylines through the getter
for (i = 0; i < block->insz[input]; i++)
{
- getPolyline(pAxe, block, input, i);
+ getPolyline(pAxe, block, input, i, TRUE);
+ }
+ for (i = 0; i < block->insz[input]; i++)
+ {
+ getPolyline(pAxe, block, input, i, FALSE);
}
setAxesSettings(pAxe, block, input);
return sco->scope.cachedAxeUID[input];
}
-static char *getPolyline(char *pAxeUID, scicos_block * block, int input, int row)
+static char *getPolyline(char *pAxeUID, scicos_block * block, int input, int row, BOOL history)
{
char *pPolyline;
BOOL b__true = TRUE;
int color;
+ char*** polylinesUIDs;
+ int polylineIndex;
+ int polylineDefaultNumElement;
+
sco_data *sco = (sco_data *) * (block->work);
// assert the sco is not NULL
return NULL;
}
+ if (!history)
+ {
+ polylinesUIDs = sco->scope.cachedBufferPolylinesUIDs;
+ polylineIndex = block->insz[input] + row;
+ polylineDefaultNumElement = block->ipar[2];
+ }
+ else
+ {
+ polylinesUIDs = sco->scope.cachedHistoryPolylinesUIDs;
+ polylineIndex = row;
+ polylineDefaultNumElement = 0;
+ }
+
// fast path for an existing object
- if (sco->scope.cachedPolylinesUIDs != NULL && sco->scope.cachedPolylinesUIDs[input] != NULL && sco->scope.cachedPolylinesUIDs[input][row] != NULL)
+ if (polylinesUIDs != NULL && polylinesUIDs[input] != NULL && polylinesUIDs[input][row] != NULL)
{
- return sco->scope.cachedPolylinesUIDs[input][row];
+ return polylinesUIDs[input][row];
}
- pPolyline = findChildWithKindAt(pAxeUID, __GO_POLYLINE__, row);
+ pPolyline = findChildWithKindAt(pAxeUID, __GO_POLYLINE__, polylineIndex);
/*
* Allocate if necessary
* Default setup (will crash if removed)
*/
{
- int polylineSize[2] = { 1, block->ipar[2] };
+ int polylineSize[2] = { 1, polylineDefaultNumElement };
setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
}
/*
* then cache with local storage
*/
- if (sco->scope.cachedPolylinesUIDs != NULL && sco->scope.cachedPolylinesUIDs[input] != NULL)
+ if (pPolyline != NULL && polylinesUIDs != NULL && polylinesUIDs[input] != NULL)
{
- sco->scope.cachedPolylinesUIDs[input][row] = strdup(pPolyline);
+ polylinesUIDs[input][row] = strdup(pPolyline);
releaseGraphicObjectProperty(__GO_PARENT__, pPolyline, jni_string, 1);
}
- return sco->scope.cachedPolylinesUIDs[input][row];
+ return polylinesUIDs[input][row];
}
-static BOOL setPolylinesBuffers(scicos_block * block, int input, int maxNumberOfPoints)
+static void deleteBufferPolylines(scicos_block * block)
+{
+ int i, j;
+
+ char *pPolylineUID;
+
+ sco_data *sco;
+
+ sco = getScoData(block);
+ for (i = 0; i < block->nin; i++)
+ {
+ for (j = 0; j < block->insz[i]; j++)
+ {
+ pPolylineUID = sco->scope.cachedBufferPolylinesUIDs[i][j];
+ deleteGraphicObject(pPolylineUID);
+ }
+ }
+}
+
+static BOOL pushHistory(scicos_block * block, int input, int maxNumberOfPoints)
{
int i;
char *pAxeUID;
char *pPolylineUID;
+ double *data;
+ sco_data *sco;
+
BOOL result = TRUE;
int polylineSize[2] = { 1, maxNumberOfPoints };
- LOG("%s: %s at %d to %d\n", "cmscope", "setPolylinesBuffers", input, maxNumberOfPoints);
-
+ sco = getScoData(block);
pFigureUID = getFigure(block);
pAxeUID = getAxe(pFigureUID, block, input);
+ // push the data only if the counter == 0, decrement the counter if positive
+ if (sco->scope.historyUpdateCounter[input] > 0)
+ {
+ sco->scope.historyUpdateCounter[input]--;
+ }
+ if (sco->scope.historyUpdateCounter[input] > 0)
+ {
+ return result;
+ }
+
for (i = 0; i < block->insz[input]; i++)
{
- pPolylineUID = getPolyline(pAxeUID, block, input, i);
+ pPolylineUID = getPolyline(pAxeUID, block, input, i, TRUE);
result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
+
+ data = sco->internal.historyCoordinates[input][i];
+ result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_COORDINATES__, data, jni_double_vector, maxNumberOfPoints);
}
return result;
/*
* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) 2011 - Scilab Enterprises - Clement DAVID
+ * Copyright (C) 2011-2012 - Scilab Enterprises - Clement DAVID
*
* This file must be used under the terms of the CeCILL.
* This source file is licensed as described in the file COPYING, which
#include "setGraphicObjectProperty.h"
#include "graphicObjectProperties.h"
#include "createGraphicObject.h"
+#include "deleteGraphicObject.h"
#include "CurrentFigure.h"
#include "CurrentObject.h"
#include "BuildObjects.h"
#include "AxesModel.h"
+#define HISTORY_POINTS_THRESHOLD 4096
+
/*****************************************************************************
* Internal container structure
****************************************************************************/
struct
{
int numberOfPoints;
+ double ***bufferCoordinates;
int maxNumberOfPoints;
- double ***coordinates;
+ double ***historyCoordinates;
} internal;
struct
{
int periodCounter;
+ BOOL disableBufferUpdate;
+ int historyUpdateCounter;
+
char const* cachedFigureUID;
char *cachedAxeUID;
- char **cachedPolylinesUIDs;
+ char **cachedBufferPolylinesUIDs;
+ char **cachedHistoryPolylinesUIDs;
} scope;
} sco_data;
static void freeScoData(scicos_block * block);
/**
- * Realloc any internal data
+ * Realloc the history buffer data
*
* \param block the block
- * \param input the selected input
* \param numberOfPoints realloc to store this number of points
*/
-static sco_data *reallocScoData(scicos_block * block, int numberOfPoints);
+static sco_data *reallocHistoryBuffer(scicos_block * block, int numberOfPoints);
+
+/**
+ * Set values into the coordinates buffer.
+ *
+ * \param block the block
+ * \param coordinates the buffer
+ * \param numberOfPoints the number of points to set (actual)
+ * \param bufferPoints the buffer size (max)
+ * \param t the time to set
+ * \param value the value to set
+ */
+static void setBuffersCoordinates(scicos_block * block, double* coordinates, const int numberOfPoints,
+ const int bufferPoints, const double t, const double value);
/**
* Append the data to the current data
* \param pAxeUID the parent axe UID
* \param block the block
* \param row the current row index (0-indexed)
+ * \param history get the history polyline
* \return a valid polyline UID or NULL on error
*/
-static char *getPolyline(char *pAxeUID, scicos_block * block, int row);
+static char *getPolyline(char *pAxeUID, scicos_block * block, int row, BOOL history);
/**
- * Set the polylines buffer size
+ * Delete all the buffer polylines.
+ *
+ * \param block the block
+ */
+static void deleteBufferPolylines(scicos_block * block);
+
+/**
+ * Set the polylines history size and push the history buffer
*
* \param block the block
* \param input the input port index
* \param maxNumberOfPoints the size of the buffer
*/
-static BOOL setPolylinesBuffers(scicos_block * block, int input, int maxNumberOfPoints);
+static BOOL pushHistory(scicos_block * block, int input, int maxNumberOfPoints);
/**
* Set the polylines bounds
break;
case Ending:
+ sco = getScoData(block);
+ sco = reallocHistoryBuffer(block, sco->internal.maxNumberOfPoints + sco->internal.numberOfPoints);
+ sco->scope.disableBufferUpdate = FALSE;
+ sco->scope.historyUpdateCounter = 0;
+ pushHistory(block, 0, sco->internal.maxNumberOfPoints);
+ deleteBufferPolylines(block);
freeScoData(block);
break;
goto error_handler_sco;
}
+ // 0 points out of a block->ipar[2] points buffer
sco->internal.numberOfPoints = 0;
- sco->internal.maxNumberOfPoints = block->ipar[2];
- sco->internal.coordinates = (double ***)CALLOC(block->nin, sizeof(double **));
- if (sco->internal.coordinates == NULL)
+ sco->internal.bufferCoordinates = (double ***)CALLOC(block->nin, sizeof(double **));
+ if (sco->internal.bufferCoordinates == NULL)
{
- goto error_handler_coordinates;
+ goto error_handler_bufferCoordinates;
}
for (i = 0; i < block->nin; i++)
{
- sco->internal.coordinates[i] = (double **)CALLOC(block->insz[i], sizeof(double *));
- if (sco->internal.coordinates[i] == NULL)
+ sco->internal.bufferCoordinates[i] = (double **)CALLOC(block->insz[i], sizeof(double *));
+ if (sco->internal.bufferCoordinates[i] == NULL)
{
- goto error_handler_coordinates_i;
+ goto error_handler_bufferCoordinates_i;
}
}
for (i = 0; i < block->nin; i++)
{
for (j = 0; j < block->insz[i]; j++)
{
- sco->internal.coordinates[i][j] = (double *)CALLOC(3 * block->ipar[2], sizeof(double));
+ sco->internal.bufferCoordinates[i][j] = (double *)CALLOC(3 * block->ipar[2], sizeof(double));
- if (sco->internal.coordinates[i][j] == NULL)
+ if (sco->internal.bufferCoordinates[i][j] == NULL)
{
- goto error_handler_coordinates_ij;
+ goto error_handler_bufferCoordinates_ij;
}
}
}
+ // 0 points out of a 0 points history
+ sco->internal.maxNumberOfPoints = 0;
+
+ sco->internal.historyCoordinates = (double ***)CALLOC(block->nin, sizeof(double **));
+ if (sco->internal.historyCoordinates == NULL)
+ {
+ goto error_handler_historyCoordinates;
+ }
+
+ for (i = 0; i < block->nin; i++)
+ {
+ sco->internal.historyCoordinates[i] = (double **)CALLOC(block->insz[i], sizeof(double *));
+ if (sco->internal.historyCoordinates[i] == NULL)
+ {
+ goto error_handler_historyCoordinates_i;
+ }
+ }
+
sco->scope.periodCounter = 0;
+
+ // flag to avoid pushing the buffer each time
+ sco->scope.disableBufferUpdate = FALSE;
+ // counter use to delay the history push
+ sco->scope.historyUpdateCounter = 0;
+
sco->scope.cachedFigureUID = NULL;
sco->scope.cachedAxeUID = NULL;
- sco->scope.cachedPolylinesUIDs = (char **)CALLOC(block->insz[0], sizeof(char *));
+ sco->scope.cachedBufferPolylinesUIDs = (char **)CALLOC(block->insz[0], sizeof(char *));
+ sco->scope.cachedHistoryPolylinesUIDs = (char **)CALLOC(block->insz[0], sizeof(char *));
*(block->work) = sco;
}
* Error management (out of normal flow)
*/
-error_handler_coordinates_ij:
+error_handler_historyCoordinates_i:
+ for (j = 0; j < i; j++)
+ {
+ FREE(sco->internal.historyCoordinates[i]);
+ }
+ FREE(sco->internal.historyCoordinates);
+error_handler_historyCoordinates:
+ i = block->nin - 1;
+ j = block->insz[i] - 1;
+error_handler_bufferCoordinates_ij:
for (k = 0; k < i; k++)
{
for (l = 0; l < j; l++)
{
- FREE(sco->internal.coordinates[k][l]);
+ FREE(sco->internal.bufferCoordinates[k][l]);
}
}
i = block->nin - 1;
-error_handler_coordinates_i:
+error_handler_bufferCoordinates_i:
for (j = 0; j < i; j++)
{
- FREE(sco->internal.coordinates[i]);
+ FREE(sco->internal.bufferCoordinates[i]);
}
- FREE(sco->internal.coordinates);
-error_handler_coordinates:
+ FREE(sco->internal.bufferCoordinates);
+error_handler_bufferCoordinates:
FREE(sco);
error_handler_sco:
// allocation error
{
for (j = 0; j < block->insz[i]; j++)
{
- FREE(sco->internal.coordinates[i][j]);
+ if (sco->internal.historyCoordinates[i][j] != NULL)
+ {
+ FREE(sco->internal.historyCoordinates[i][j]);
+ }
+ FREE(sco->internal.bufferCoordinates[i][j]);
}
- FREE(sco->internal.coordinates[i]);
+ FREE(sco->internal.historyCoordinates[i]);
+ FREE(sco->internal.bufferCoordinates[i]);
}
- FREE(sco->internal.coordinates);
+ FREE(sco->internal.historyCoordinates);
+ FREE(sco->internal.bufferCoordinates);
for (i = 0; i < block->insz[0]; i++)
{
- FREE(sco->scope.cachedPolylinesUIDs[i]);
+ FREE(sco->scope.cachedHistoryPolylinesUIDs[i]);
+ FREE(sco->scope.cachedBufferPolylinesUIDs[i]);
}
FREE(sco->scope.cachedAxeUID);
}
}
-static sco_data *reallocScoData(scicos_block * block, int numberOfPoints)
+static sco_data *reallocHistoryBuffer(scicos_block * block, int numberOfPoints)
{
sco_data *sco = (sco_data *) * (block->work);
- int i, j;
+ int i;
double *ptr;
- int setLen;
+ int allocatedNumberOfPoints;
+
int previousNumberOfPoints = sco->internal.maxNumberOfPoints;
- int newPoints = numberOfPoints - previousNumberOfPoints;
+ int numberOfCopiedPoints = numberOfPoints - sco->internal.maxNumberOfPoints;
- for (i = 0; i < block->nin; i++)
+ double *buffer;
+ int bufferNumberOfPoints = block->ipar[2];
+ int bufferNewPointInc;
+
+ if (previousNumberOfPoints == 0)
{
- for (j = 0; j < block->insz[i]; j++)
+ allocatedNumberOfPoints = numberOfPoints;
+ bufferNewPointInc = 0;
+ }
+ else
+ {
+ allocatedNumberOfPoints = numberOfPoints - 1;
+ bufferNewPointInc = 1;
+ }
+
+ if (sco->scope.historyUpdateCounter <= 0)
+ {
+ if (numberOfPoints > HISTORY_POINTS_THRESHOLD)
{
- ptr = (double *)REALLOC(sco->internal.coordinates[i][j], 3 * numberOfPoints * sizeof(double));
- if (ptr == NULL)
- {
- goto error_handler;
- }
+ sco->scope.disableBufferUpdate = TRUE;
+ sco->scope.historyUpdateCounter = numberOfPoints / HISTORY_POINTS_THRESHOLD;
+ }
+ else
+ {
+ sco->scope.disableBufferUpdate = FALSE;
+ sco->scope.historyUpdateCounter = 0;
+ }
+ }
- // clear the last points, the Z-axis values
- memset(ptr + 2 * numberOfPoints, 0, numberOfPoints * sizeof(double));
+ for (i = 0; i < block->insz[0]; i++)
+ {
+ ptr = (double *)MALLOC(3 * allocatedNumberOfPoints * sizeof(double));
+ if (ptr == NULL)
+ {
+ goto error_handler;
+ }
- // memcpy existing Y-axis values (use memmove to handle memory overlapping)
- memmove(ptr + numberOfPoints, ptr + previousNumberOfPoints, previousNumberOfPoints * sizeof(double));
+ // memcpy existing X-axis values from the history
+ memcpy(ptr, sco->internal.historyCoordinates[0][i], previousNumberOfPoints * sizeof(double));
+ // memcpy existing Y-axis values from the history
+ memcpy(ptr + allocatedNumberOfPoints, sco->internal.historyCoordinates[0][i] + previousNumberOfPoints, previousNumberOfPoints * sizeof(double));
+ // clear the last points, the Z-axis values
+ memset(ptr + 2 * allocatedNumberOfPoints, 0, allocatedNumberOfPoints * sizeof(double));
- // then set the last points to the last values for Y-axis and X-axis values
- for (setLen = newPoints - 1; setLen >= 0; setLen--)
- {
- ptr[numberOfPoints + previousNumberOfPoints + setLen] = ptr[numberOfPoints + previousNumberOfPoints - 1];
- }
- for (setLen = newPoints - 1; setLen >= 0; setLen--)
- {
- ptr[previousNumberOfPoints + setLen] = ptr[previousNumberOfPoints - 1];
- }
+ // then set the last points to the last values for X-axis and Y-axis values from the buffer points
+ buffer = sco->internal.bufferCoordinates[0][i];
+ memcpy(ptr + previousNumberOfPoints, buffer + bufferNewPointInc, (numberOfCopiedPoints - bufferNewPointInc) * sizeof(double));
+ memcpy(ptr + allocatedNumberOfPoints + previousNumberOfPoints, buffer + bufferNumberOfPoints + bufferNewPointInc, (numberOfCopiedPoints - bufferNewPointInc) * sizeof(double));
- sco->internal.coordinates[i][j] = ptr;
- }
+ FREE(sco->internal.historyCoordinates[0][i]);
+ sco->internal.historyCoordinates[0][i] = ptr;
}
- sco->internal.maxNumberOfPoints = numberOfPoints;
+ sco->internal.maxNumberOfPoints = allocatedNumberOfPoints;
return sco;
error_handler:
return NULL;
}
+static void setBuffersCoordinates(scicos_block* block, double* coordinates, const int numberOfPoints,
+ const int bufferPoints, const double t, const double value)
+{
+ int setLen;
+ sco_data *sco = (sco_data *) * (block->work);
+
+ if (sco->scope.disableBufferUpdate == TRUE)
+ {
+ coordinates[numberOfPoints] = t;
+ coordinates[bufferPoints + numberOfPoints] = value;
+ return;
+ }
+
+ // X-axis values first
+ for (setLen = numberOfPoints; setLen < bufferPoints; setLen++)
+ {
+ coordinates[setLen] = t;
+ }
+ // then Y-axis values
+ for (setLen = numberOfPoints; setLen < bufferPoints; setLen++)
+ {
+ coordinates[bufferPoints + setLen] = value;
+ }
+ // then Z-axis values (always clear'ed)
+}
+
static void appendData(scicos_block * block, int input, double t, double *data)
{
int i;
sco_data *sco = (sco_data *) * (block->work);
- int maxNumberOfPoints = sco->internal.maxNumberOfPoints;
- int numberOfPoints = sco->internal.numberOfPoints;
/*
* Handle the case where the t is greater than the data_bounds
{
sco->scope.periodCounter++;
- numberOfPoints = 0;
- sco->internal.numberOfPoints = 0;
+ // set the buffer coordinates to the last point
+ for (i = 0; i < block->insz[input]; i++)
+ {
+ sco->internal.bufferCoordinates[input][i][0] = sco->internal.bufferCoordinates[input][i][sco->internal.numberOfPoints - 1];
+ sco->internal.bufferCoordinates[input][i][block->ipar[2]] = sco->internal.bufferCoordinates[input][i][block->ipar[2] + sco->internal.numberOfPoints - 1];
+ }
+ sco->internal.numberOfPoints = 1;
+
+ // clear the history coordinates
+ sco->internal.maxNumberOfPoints = 0;
+ for (i = 0; i < block->insz[input]; i++)
+ {
+ if (sco->internal.historyCoordinates[input][i] != NULL)
+ {
+ FREE(sco->internal.historyCoordinates[input][i]);
+ sco->internal.historyCoordinates[input][i] = NULL;
+ }
+ }
+
+ // configure scope setting
if (setPolylinesBounds(block, input, sco->scope.periodCounter) == FALSE)
{
set_block_error(-5);
/*
* Handle the case where the scope has more points than maxNumberOfPoints
*/
- if (sco != NULL && numberOfPoints >= maxNumberOfPoints)
+ if (sco != NULL && sco->internal.numberOfPoints >= block->ipar[2])
{
- // on a full scope, re-alloc
+ int maxNumberOfPoints = sco->internal.maxNumberOfPoints;
+
+ // on a full scope, re-alloc history coordinates
maxNumberOfPoints = maxNumberOfPoints + block->ipar[2];
- sco = reallocScoData(block, maxNumberOfPoints);
+ sco = reallocHistoryBuffer(block, maxNumberOfPoints);
+
+ // set the buffer coordinates to the last point
+ for (i = 0; i < block->insz[input]; i++)
+ {
+ sco->internal.bufferCoordinates[input][i][0] = sco->internal.bufferCoordinates[input][i][block->ipar[2] - 1];
+ sco->internal.bufferCoordinates[input][i][block->ipar[2]] = sco->internal.bufferCoordinates[input][i][2 * block->ipar[2] - 1];
+ }
+ sco->internal.numberOfPoints = 1;
// reconfigure related graphic objects
- if (setPolylinesBuffers(block, input, maxNumberOfPoints) == FALSE)
+ if (pushHistory(block, input, sco->internal.maxNumberOfPoints) == FALSE)
{
set_block_error(-5);
freeScoData(block);
*/
if (sco != NULL)
{
- int setLen;
-
for (i = 0; i < block->insz[input]; i++)
{
- // X-axis values first
- for (setLen = maxNumberOfPoints - numberOfPoints - 1; setLen >= 0; setLen--)
- {
- sco->internal.coordinates[input][i][numberOfPoints + setLen] = t;
- }
-
- // then Y-axis values
- for (setLen = maxNumberOfPoints - numberOfPoints - 1; setLen >= 0; setLen--)
- {
- sco->internal.coordinates[input][i][maxNumberOfPoints + numberOfPoints + setLen] = data[i];
- }
-
- // do not update Z-axis values, always cleared
+ const double value = data[i];
+ setBuffersCoordinates(block, sco->internal.bufferCoordinates[input][i], sco->internal.numberOfPoints, block->ipar[2], t, value);
}
sco->internal.numberOfPoints++;
pFigureUID = getFigure(block);
pAxeUID = getAxe(pFigureUID, block, input);
- pPolylineUID = getPolyline(pAxeUID, block, row);
+ pPolylineUID = getPolyline(pAxeUID, block, row, FALSE);
sco = getScoData(block);
if (sco == NULL)
return FALSE;
}
+ // do not push any data if disabled
+ if (sco->scope.disableBufferUpdate == TRUE)
+ {
+ return TRUE;
+ }
+
// select the right input and row
- data = sco->internal.coordinates[input][row];
+ data = sco->internal.bufferCoordinates[input][row];
- return setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_COORDINATES__, data, jni_double_vector, sco->internal.maxNumberOfPoints);
+ return setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_COORDINATES__, data, jni_double_vector, block->ipar[2]);
}
/*****************************************************************************
// allocate the polylines through the getter
for (i = 0; i < block->insz[input]; i++)
{
- getPolyline(pAxe, block, i);
+ getPolyline(pAxe, block, i, TRUE);
+ }
+ for (i = 0; i < block->insz[input]; i++)
+ {
+ getPolyline(pAxe, block, i, FALSE);
}
}
return sco->scope.cachedAxeUID;
}
-static char *getPolyline(char *pAxeUID, scicos_block * block, int row)
+static char *getPolyline(char *pAxeUID, scicos_block * block, int row, BOOL history)
{
char *pPolyline;
BOOL b__true = TRUE;
int color;
+ char** polylinesUIDs;
+ int polylineIndex;
+ int polylineDefaultNumElement;
+
sco_data *sco = (sco_data *) * (block->work);
// assert the sco is not NULL
return NULL;
}
+ if (!history)
+ {
+ polylinesUIDs = sco->scope.cachedBufferPolylinesUIDs;
+ polylineIndex = block->insz[0] + row;
+ polylineDefaultNumElement = block->ipar[2];
+ }
+ else
+ {
+ polylinesUIDs = sco->scope.cachedHistoryPolylinesUIDs;
+ polylineIndex = row;
+ polylineDefaultNumElement = 0;
+ }
+
// fast path for an existing object
- if (sco->scope.cachedPolylinesUIDs != NULL && sco->scope.cachedPolylinesUIDs[row] != NULL)
+ if (polylinesUIDs != NULL && polylinesUIDs[row] != NULL)
{
- return sco->scope.cachedPolylinesUIDs[row];
+ return polylinesUIDs[row];
}
- pPolyline = findChildWithKindAt(pAxeUID, __GO_POLYLINE__, row);
+ pPolyline = findChildWithKindAt(pAxeUID, __GO_POLYLINE__, polylineIndex);
/*
* Allocate if necessary
* Default setup (will crash if removed)
*/
{
- int polylineSize[2] = { 1, block->ipar[2] };
+ int polylineSize[2] = { 1, polylineDefaultNumElement };
setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
}
/*
* then cache with local storage
*/
- if (pPolyline != NULL && sco->scope.cachedPolylinesUIDs != NULL && sco->scope.cachedPolylinesUIDs[row] == NULL)
+ if (pPolyline != NULL && polylinesUIDs != NULL && polylinesUIDs[row] == NULL)
{
- sco->scope.cachedPolylinesUIDs[row] = strdup(pPolyline);
+ polylinesUIDs[row] = strdup(pPolyline);
releaseGraphicObjectProperty(__GO_PARENT__, pPolyline, jni_string, 1);
}
- return sco->scope.cachedPolylinesUIDs[row];
+ return polylinesUIDs[row];
}
-static BOOL setPolylinesBuffers(scicos_block * block, int input, int maxNumberOfPoints)
+static void deleteBufferPolylines(scicos_block * block)
+{
+ int i, j;
+
+ char *pPolylineUID;
+
+ sco_data *sco;
+
+ sco = getScoData(block);
+ for (i = 0; i < block->nin; i++)
+ {
+ for (j = 0; j < block->insz[i]; j++)
+ {
+ pPolylineUID = sco->scope.cachedBufferPolylinesUIDs[j];
+ deleteGraphicObject(pPolylineUID);
+ }
+ }
+}
+
+static BOOL pushHistory(scicos_block * block, int input, int maxNumberOfPoints)
{
int i;
char *pAxeUID;
char *pPolylineUID;
+ double *data;
+ sco_data *sco;
+
BOOL result = TRUE;
int polylineSize[2] = { 1, maxNumberOfPoints };
+ sco = getScoData(block);
pFigureUID = getFigure(block);
pAxeUID = getAxe(pFigureUID, block, input);
+ // push the data only if the counter == 0, decrement the counter if positive
+ if (sco->scope.historyUpdateCounter > 0)
+ {
+ sco->scope.historyUpdateCounter--;
+ }
+ if (sco->scope.historyUpdateCounter > 0)
+ {
+ return result;
+ }
+
for (i = 0; i < block->insz[input]; i++)
{
- pPolylineUID = getPolyline(pAxeUID, block, i);
+ pPolylineUID = getPolyline(pAxeUID, block, i, TRUE);
result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
+
+ data = sco->internal.historyCoordinates[input][i];
+ result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_COORDINATES__, data, jni_double_vector, maxNumberOfPoints);
}
return result;
--- /dev/null
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Clément DAVID
+//
+// This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- XCOS TEST -->
+//
+// <-- Non-regression test for bug 12057 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=12057
+//
+// <-- Short Description -->
+// Scopes with big scope buffer size simulation was much more slower.
+//
+// This test check cscope and cmscope huge-buffer (more than 4k points)
+// optimization.
+assert_checktrue(importXcosDiagram(SCI + "/modules/xcos/tests/nonreg_tests/bug_12057_cscope.xcos"));
+timer();
+xcos_simulate(scs_m, 4);
+t = timer();
+assert_checktrue(t < 60);
+assert_checktrue(importXcosDiagram(SCI + "/modules/xcos/tests/nonreg_tests/bug_12057_cmscope.xcos"));
+timer();
+xcos_simulate(scs_m, 4);
+t = timer();
+assert_checktrue(t < 60);
--- /dev/null
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Clément DAVID
+//
+// This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- XCOS TEST -->
+//
+// <-- Non-regression test for bug 12057 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=12057
+//
+// <-- Short Description -->
+// Scopes with big scope buffer size simulation was much more slower.
+//
+// This test check cscope and cmscope huge-buffer (more than 4k points)
+// optimization.
+
+assert_checktrue(importXcosDiagram(SCI + "/modules/xcos/tests/nonreg_tests/bug_12057_cscope.xcos"));
+timer();
+xcos_simulate(scs_m, 4);
+t = timer();
+
+assert_checktrue(t < 60);
+
+assert_checktrue(importXcosDiagram(SCI + "/modules/xcos/tests/nonreg_tests/bug_12057_cmscope.xcos"));
+timer();
+xcos_simulate(scs_m, 4);
+t = timer();
+
+assert_checktrue(t < 60);
// =============================================================================
// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Clément DAVID
// Copyright (C) 2011 - DIGITEO - Clément DAVID
//
// This file is distributed under the same license as the Scilab package.
assert_checkequal(a1.y_label.text, "y");
assert_checkequal(a2.y_label.text, "y");
assert_checkequal(a3.y_label.text, "y");
- // check removed due to junk data at the end
- // assert_checkequal(size(p11.data), [299 2]);
- // assert_checkequal(size(p12.data), [299 2]);
- // assert_checkequal(size(p21.data), [299 2]);
- // assert_checkequal(size(p31.data), [299 2]);
+ assert_checkequal(size(p11.data), [299 2]);
+ assert_checkequal(size(p12.data), [299 2]);
+ assert_checkequal(size(p21.data), [299 2]);
+ assert_checkequal(size(p31.data), [299 2]);
endfunction
assert_checkcmscope();
// Simulate again to check multi-simulations cases
// =============================================================================
// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Clément DAVID
// Copyright (C) 2011 - DIGITEO - Clément DAVID
//
// This file is distributed under the same license as the Scilab package.
assert_checkequal(a2.y_label.text, "y");
assert_checkequal(a3.y_label.text, "y");
- // check removed due to junk data at the end
- // assert_checkequal(size(p11.data), [299 2]);
- // assert_checkequal(size(p12.data), [299 2]);
- // assert_checkequal(size(p21.data), [299 2]);
- // assert_checkequal(size(p31.data), [299 2]);
+ assert_checkequal(size(p11.data), [299 2]);
+ assert_checkequal(size(p12.data), [299 2]);
+ assert_checkequal(size(p21.data), [299 2]);
+ assert_checkequal(size(p31.data), [299 2]);
endfunction
assert_checkcmscope();
// =============================================================================
// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Clément DAVID
// Copyright (C) 2011 - DIGITEO - Clément DAVID
//
// This file is distributed under the same license as the Scilab package.
assert_checkequal(a.data_bounds, [30 -2 ; 60 3]);
assert_checkequal(a.x_label.text, "t");
assert_checkequal(a.y_label.text, "y");
- // check removed due to junk data at the end
- // assert_checkequal(size(p1.data), [315 2]);
- // assert_checkequal(size(p2.data), [315 2]);
- // assert_checkequal(size(p3.data), [315 2]);
- // assert_checkequal(size(p4.data), [315 2]);
+ assert_checkequal(size(p1.data), [301 2]);
+ assert_checkequal(size(p2.data), [301 2]);
+ assert_checkequal(size(p3.data), [301 2]);
+ assert_checkequal(size(p4.data), [301 2]);
assert_checkequal(p1.polyline_style, 1);
assert_checkequal(p2.polyline_style, 1);
assert_checkequal(p3.polyline_style, 1);
// =============================================================================
// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Clément DAVID
// Copyright (C) 2011 - DIGITEO - Clément DAVID
//
// This file is distributed under the same license as the Scilab package.
assert_checkequal(a.x_label.text, "t");
assert_checkequal(a.y_label.text, "y");
- // check removed due to junk data at the end
- // assert_checkequal(size(p1.data), [315 2]);
- // assert_checkequal(size(p2.data), [315 2]);
- // assert_checkequal(size(p3.data), [315 2]);
- // assert_checkequal(size(p4.data), [315 2]);
+ assert_checkequal(size(p1.data), [301 2]);
+ assert_checkequal(size(p2.data), [301 2]);
+ assert_checkequal(size(p3.data), [301 2]);
+ assert_checkequal(size(p4.data), [301 2]);
assert_checkequal(p1.polyline_style, 1);
assert_checkequal(p2.polyline_style, 1);