Scicos blocks: use the new MVC graphic for scopes 47/4547/22
Clément DAVID [Tue, 12 Jul 2011 08:02:24 +0000 (10:02 +0200)]
 * Use cached UIDs if possible
 * Use multiple of buffer size to store data.
 * Remove not used files (scoBase scoSetProperty scoGetProperty ...)

To check please run :
test_run("xcos", ["canimxy" "canimxy3d" "cevscpe" "cfscope" "cmatview" "cmatview3d" "cmscope" "cscope" "cscopxy" "cscopxy3d"])

Change-Id: Ie2724632c8594856033fcfbf2ca1cafb1b410dbd

40 files changed:
scilab/modules/graphics/src/nographics/nographics.c
scilab/modules/scicos_blocks/Makefile.am
scilab/modules/scicos_blocks/Makefile.in
scilab/modules/scicos_blocks/includes/scoBase.h [deleted file]
scilab/modules/scicos_blocks/includes/scoGetProperty.h [deleted file]
scilab/modules/scicos_blocks/includes/scoMemoryScope.h [deleted file]
scilab/modules/scicos_blocks/includes/scoMisc.h [deleted file]
scilab/modules/scicos_blocks/includes/scoSetProperty.h [deleted file]
scilab/modules/scicos_blocks/includes/scoWindowScope.h [deleted file]
scilab/modules/scicos_blocks/src/c/bouncexy.c
scilab/modules/scicos_blocks/src/c/canimxy.c
scilab/modules/scicos_blocks/src/c/canimxy3d.c
scilab/modules/scicos_blocks/src/c/cevscpe.c
scilab/modules/scicos_blocks/src/c/cfscope.c
scilab/modules/scicos_blocks/src/c/cmat3d.c
scilab/modules/scicos_blocks/src/c/cmatview.c
scilab/modules/scicos_blocks/src/c/cmscope.c
scilab/modules/scicos_blocks/src/c/cscope.c
scilab/modules/scicos_blocks/src/c/cscopxy.c
scilab/modules/scicos_blocks/src/c/cscopxy3d.c
scilab/modules/scicos_blocks/src/c/graphics_Import.def
scilab/modules/scicos_blocks/src/c/scicos_blocks.vcxproj
scilab/modules/scicos_blocks/src/c/scicos_blocks.vcxproj.filters
scilab/modules/scicos_blocks/src/c/scoGetProperty.c [deleted file]
scilab/modules/scicos_blocks/src/c/scoMemoryScope.c [deleted file]
scilab/modules/scicos_blocks/src/c/scoMisc.c [deleted file]
scilab/modules/scicos_blocks/src/c/scoSetProperty.c [deleted file]
scilab/modules/scicos_blocks/src/c/scoUtils.c [new file with mode: 0644]
scilab/modules/scicos_blocks/src/c/scoUtils.h [new file with mode: 0644]
scilab/modules/scicos_blocks/src/c/scoWindowScope.c [deleted file]
scilab/modules/xcos/tests/unit_tests/cevscpe.dia.ref
scilab/modules/xcos/tests/unit_tests/cevscpe.tst
scilab/modules/xcos/tests/unit_tests/cmatview3d.dia.ref
scilab/modules/xcos/tests/unit_tests/cmatview3d.tst
scilab/modules/xcos/tests/unit_tests/cmscope.dia.ref
scilab/modules/xcos/tests/unit_tests/cmscope.tst
scilab/modules/xcos/tests/unit_tests/cscope.dia.ref
scilab/modules/xcos/tests/unit_tests/cscope.tst
scilab/modules/xcos/tests/unit_tests/cscopxy3d.dia.ref
scilab/modules/xcos/tests/unit_tests/cscopxy3d.tst

index 4cb3c22..11de281 100644 (file)
@@ -236,7 +236,7 @@ double getDoubleFromStack( size_t stackPointer )
        return 0.;
 }
 /*--------------------------------------------------------------------------*/
-sciPointObj * getFigureFromIndex(int figNum)
+char * getFigureFromIndex(int figNum)
 {
        return NULL;
 }
index 5c7dd74..de8f088 100644 (file)
@@ -336,11 +336,7 @@ src/c/zcross2.c
 SCICOS_BLOCKS_CPP_SOURCES = \
 src/cpp/affich2.cpp
 
-NON_BLOCK_C_SOURCES =  src/c/scoGetProperty.c \
-src/c/scoSetProperty.c \
-src/c/scoMisc.c \
-src/c/scoMemoryScope.c\
-src/c/scoWindowScope.c \
+NON_BLOCK_C_SOURCES =  src/c/scoUtils.c \
 src/c/scicos_evalhermite.c \
 src/c/scicos_indexfinder.c
 
index 25aceb9..977f63e 100644 (file)
@@ -253,9 +253,7 @@ am__libsciscicos_blocks_la_SOURCES_DIST = src/c/absblk.c \
        src/fortran/sinblk.f src/fortran/sqrblk.f src/fortran/sum2.f \
        src/fortran/sum3.f src/fortran/tanblk.f src/fortran/tcslti.f \
        src/fortran/tcsltj.f src/fortran/timblk.f src/fortran/trash.f \
-       src/fortran/writef.f src/fortran/zcross.f \
-       src/c/scoGetProperty.c src/c/scoSetProperty.c src/c/scoMisc.c \
-       src/c/scoMemoryScope.c src/c/scoWindowScope.c \
+       src/fortran/writef.f src/fortran/zcross.f src/c/scoUtils.c \
        src/c/scicos_evalhermite.c src/c/scicos_indexfinder.c \
        src/jni/AfficheBlock.cpp src/cpp/affich2.cpp
 @XCOS_TRUE@am__objects_1 = libsciscicos_blocks_la-absblk.lo \
@@ -581,11 +579,7 @@ am__libsciscicos_blocks_la_SOURCES_DIST = src/c/absblk.c \
 @XCOS_TRUE@    sciblk.lo selblk.lo sinblk.lo sqrblk.lo sum2.lo \
 @XCOS_TRUE@    sum3.lo tanblk.lo tcslti.lo tcsltj.lo timblk.lo \
 @XCOS_TRUE@    trash.lo writef.lo zcross.lo
-@XCOS_TRUE@am__objects_3 = libsciscicos_blocks_la-scoGetProperty.lo \
-@XCOS_TRUE@    libsciscicos_blocks_la-scoSetProperty.lo \
-@XCOS_TRUE@    libsciscicos_blocks_la-scoMisc.lo \
-@XCOS_TRUE@    libsciscicos_blocks_la-scoMemoryScope.lo \
-@XCOS_TRUE@    libsciscicos_blocks_la-scoWindowScope.lo \
+@XCOS_TRUE@am__objects_3 = libsciscicos_blocks_la-scoUtils.lo \
 @XCOS_TRUE@    libsciscicos_blocks_la-scicos_evalhermite.lo \
 @XCOS_TRUE@    libsciscicos_blocks_la-scicos_indexfinder.lo
 @XCOS_TRUE@am__objects_4 = libsciscicos_blocks_la-AfficheBlock.lo
@@ -1274,11 +1268,7 @@ HELP_CHAPTERLANG = en_US fr_FR pt_BR
 @XCOS_TRUE@SCICOS_BLOCKS_CPP_SOURCES = \
 @XCOS_TRUE@src/cpp/affich2.cpp
 
-@XCOS_TRUE@NON_BLOCK_C_SOURCES = src/c/scoGetProperty.c \
-@XCOS_TRUE@src/c/scoSetProperty.c \
-@XCOS_TRUE@src/c/scoMisc.c \
-@XCOS_TRUE@src/c/scoMemoryScope.c\
-@XCOS_TRUE@src/c/scoWindowScope.c \
+@XCOS_TRUE@NON_BLOCK_C_SOURCES = src/c/scoUtils.c \
 @XCOS_TRUE@src/c/scicos_evalhermite.c \
 @XCOS_TRUE@src/c/scicos_indexfinder.c
 
@@ -1977,11 +1967,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciscicos_blocks_la-scicos_evalhermite.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciscicos_blocks_la-scicos_indexfinder.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciscicos_blocks_la-scicosexit.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciscicos_blocks_la-scoGetProperty.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciscicos_blocks_la-scoMemoryScope.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciscicos_blocks_la-scoMisc.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciscicos_blocks_la-scoSetProperty.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciscicos_blocks_la-scoWindowScope.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciscicos_blocks_la-scoUtils.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciscicos_blocks_la-selector.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciscicos_blocks_la-selector_m.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciscicos_blocks_la-shift_16_LA.Plo@am__quote@
@@ -4240,40 +4226,12 @@ libsciscicos_blocks_la-zcross2.lo: src/c/zcross2.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_blocks_la_CPPFLAGS) $(CPPFLAGS) $(libsciscicos_blocks_la_CFLAGS) $(CFLAGS) -c -o libsciscicos_blocks_la-zcross2.lo `test -f 'src/c/zcross2.c' || echo '$(srcdir)/'`src/c/zcross2.c
 
-libsciscicos_blocks_la-scoGetProperty.lo: src/c/scoGetProperty.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_blocks_la_CPPFLAGS) $(CPPFLAGS) $(libsciscicos_blocks_la_CFLAGS) $(CFLAGS) -MT libsciscicos_blocks_la-scoGetProperty.lo -MD -MP -MF $(DEPDIR)/libsciscicos_blocks_la-scoGetProperty.Tpo -c -o libsciscicos_blocks_la-scoGetProperty.lo `test -f 'src/c/scoGetProperty.c' || echo '$(srcdir)/'`src/c/scoGetProperty.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libsciscicos_blocks_la-scoGetProperty.Tpo $(DEPDIR)/libsciscicos_blocks_la-scoGetProperty.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/c/scoGetProperty.c' object='libsciscicos_blocks_la-scoGetProperty.lo' libtool=yes @AMDEPBACKSLASH@
+libsciscicos_blocks_la-scoUtils.lo: src/c/scoUtils.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_blocks_la_CPPFLAGS) $(CPPFLAGS) $(libsciscicos_blocks_la_CFLAGS) $(CFLAGS) -MT libsciscicos_blocks_la-scoUtils.lo -MD -MP -MF $(DEPDIR)/libsciscicos_blocks_la-scoUtils.Tpo -c -o libsciscicos_blocks_la-scoUtils.lo `test -f 'src/c/scoUtils.c' || echo '$(srcdir)/'`src/c/scoUtils.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libsciscicos_blocks_la-scoUtils.Tpo $(DEPDIR)/libsciscicos_blocks_la-scoUtils.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/c/scoUtils.c' object='libsciscicos_blocks_la-scoUtils.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_blocks_la_CPPFLAGS) $(CPPFLAGS) $(libsciscicos_blocks_la_CFLAGS) $(CFLAGS) -c -o libsciscicos_blocks_la-scoGetProperty.lo `test -f 'src/c/scoGetProperty.c' || echo '$(srcdir)/'`src/c/scoGetProperty.c
-
-libsciscicos_blocks_la-scoSetProperty.lo: src/c/scoSetProperty.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_blocks_la_CPPFLAGS) $(CPPFLAGS) $(libsciscicos_blocks_la_CFLAGS) $(CFLAGS) -MT libsciscicos_blocks_la-scoSetProperty.lo -MD -MP -MF $(DEPDIR)/libsciscicos_blocks_la-scoSetProperty.Tpo -c -o libsciscicos_blocks_la-scoSetProperty.lo `test -f 'src/c/scoSetProperty.c' || echo '$(srcdir)/'`src/c/scoSetProperty.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libsciscicos_blocks_la-scoSetProperty.Tpo $(DEPDIR)/libsciscicos_blocks_la-scoSetProperty.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/c/scoSetProperty.c' object='libsciscicos_blocks_la-scoSetProperty.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_blocks_la_CPPFLAGS) $(CPPFLAGS) $(libsciscicos_blocks_la_CFLAGS) $(CFLAGS) -c -o libsciscicos_blocks_la-scoSetProperty.lo `test -f 'src/c/scoSetProperty.c' || echo '$(srcdir)/'`src/c/scoSetProperty.c
-
-libsciscicos_blocks_la-scoMisc.lo: src/c/scoMisc.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_blocks_la_CPPFLAGS) $(CPPFLAGS) $(libsciscicos_blocks_la_CFLAGS) $(CFLAGS) -MT libsciscicos_blocks_la-scoMisc.lo -MD -MP -MF $(DEPDIR)/libsciscicos_blocks_la-scoMisc.Tpo -c -o libsciscicos_blocks_la-scoMisc.lo `test -f 'src/c/scoMisc.c' || echo '$(srcdir)/'`src/c/scoMisc.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libsciscicos_blocks_la-scoMisc.Tpo $(DEPDIR)/libsciscicos_blocks_la-scoMisc.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/c/scoMisc.c' object='libsciscicos_blocks_la-scoMisc.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_blocks_la_CPPFLAGS) $(CPPFLAGS) $(libsciscicos_blocks_la_CFLAGS) $(CFLAGS) -c -o libsciscicos_blocks_la-scoMisc.lo `test -f 'src/c/scoMisc.c' || echo '$(srcdir)/'`src/c/scoMisc.c
-
-libsciscicos_blocks_la-scoMemoryScope.lo: src/c/scoMemoryScope.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_blocks_la_CPPFLAGS) $(CPPFLAGS) $(libsciscicos_blocks_la_CFLAGS) $(CFLAGS) -MT libsciscicos_blocks_la-scoMemoryScope.lo -MD -MP -MF $(DEPDIR)/libsciscicos_blocks_la-scoMemoryScope.Tpo -c -o libsciscicos_blocks_la-scoMemoryScope.lo `test -f 'src/c/scoMemoryScope.c' || echo '$(srcdir)/'`src/c/scoMemoryScope.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libsciscicos_blocks_la-scoMemoryScope.Tpo $(DEPDIR)/libsciscicos_blocks_la-scoMemoryScope.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/c/scoMemoryScope.c' object='libsciscicos_blocks_la-scoMemoryScope.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_blocks_la_CPPFLAGS) $(CPPFLAGS) $(libsciscicos_blocks_la_CFLAGS) $(CFLAGS) -c -o libsciscicos_blocks_la-scoMemoryScope.lo `test -f 'src/c/scoMemoryScope.c' || echo '$(srcdir)/'`src/c/scoMemoryScope.c
-
-libsciscicos_blocks_la-scoWindowScope.lo: src/c/scoWindowScope.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_blocks_la_CPPFLAGS) $(CPPFLAGS) $(libsciscicos_blocks_la_CFLAGS) $(CFLAGS) -MT libsciscicos_blocks_la-scoWindowScope.lo -MD -MP -MF $(DEPDIR)/libsciscicos_blocks_la-scoWindowScope.Tpo -c -o libsciscicos_blocks_la-scoWindowScope.lo `test -f 'src/c/scoWindowScope.c' || echo '$(srcdir)/'`src/c/scoWindowScope.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libsciscicos_blocks_la-scoWindowScope.Tpo $(DEPDIR)/libsciscicos_blocks_la-scoWindowScope.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/c/scoWindowScope.c' object='libsciscicos_blocks_la-scoWindowScope.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_blocks_la_CPPFLAGS) $(CPPFLAGS) $(libsciscicos_blocks_la_CFLAGS) $(CFLAGS) -c -o libsciscicos_blocks_la-scoWindowScope.lo `test -f 'src/c/scoWindowScope.c' || echo '$(srcdir)/'`src/c/scoWindowScope.c
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_blocks_la_CPPFLAGS) $(CPPFLAGS) $(libsciscicos_blocks_la_CFLAGS) $(CFLAGS) -c -o libsciscicos_blocks_la-scoUtils.lo `test -f 'src/c/scoUtils.c' || echo '$(srcdir)/'`src/c/scoUtils.c
 
 libsciscicos_blocks_la-scicos_evalhermite.lo: src/c/scicos_evalhermite.c
 @am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciscicos_blocks_la_CPPFLAGS) $(CPPFLAGS) $(libsciscicos_blocks_la_CFLAGS) $(CFLAGS) -MT libsciscicos_blocks_la-scicos_evalhermite.lo -MD -MP -MF $(DEPDIR)/libsciscicos_blocks_la-scicos_evalhermite.Tpo -c -o libsciscicos_blocks_la-scicos_evalhermite.lo `test -f 'src/c/scicos_evalhermite.c' || echo '$(srcdir)/'`src/c/scicos_evalhermite.c
diff --git a/scilab/modules/scicos_blocks/includes/scoBase.h b/scilab/modules/scicos_blocks/includes/scoBase.h
deleted file mode 100755 (executable)
index 39ca11b..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*  Scicos
-*
-*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
-/**
-\file scoBase.h
-\author Benoit Bayol
-\version 1.0
-\date September 2006 - January 2007
-\brief Base file of the SCO Library
-*/
-
-
-#ifndef __SCO_BASE_H__
-#define __SCO_BASE_H__
-
-/*----------------------------------INCLUDES-----------------------*/
-
-#include "machine.h"
-
-#include "dynlib_scicos_blocks.h"
-
-/*Graphic Library*/
-#include "SetProperty.h"
-#include "GetProperty.h"
-#include "InitObjects.h"
-#include "DrawObjects.h"
-#include "BuildObjects.h"
-#include "ObjectStructure.h"
-#include "DestroyObjects.h"
-#include "ObjectStructure.h"
-
-#include "MALLOC.h"
-
-/*--------------------------------TYPEDEF---------------------*/
-
-/**
-\brief scoGraphicalObject is an equivalent of sciPointObj * 
-*/
-typedef sciPointObj * scoGraphicalObject;
-
-/**
-\brief scoLineOfGraphicalObjects is a table of scoGraphicalObject
-\attention No plural here for GraphicalObject 
-*/
-typedef scoGraphicalObject * scoLineOfGraphicalObject;
-
-/**
-\brief scoMatrixOfGraphicalObjects is a table of scoLineOfGraphicalObjects or a matrix of scoGraphicalObject
-\attention No plural here for GraphicalObject
-*/
-typedef scoLineOfGraphicalObject * scoMatrixOfGraphicalObject;
-
-/**
-\brief scoInteger is an equivalent of int 
-*/
-typedef int scoInteger;
-
-/**
-\brief scoLineOfInteger is a table of scoInteger 
-*/
-typedef scoInteger * scoLineOfInteger;
-
-/**
-\brief scoLongInteger is an equivalent of long
-*/
-typedef long scoLongInteger;
-
-/**
-\brief scoLineOfLongInteger is a table of scoLongInteger
-*/
-typedef scoLongInteger * scoLineOfLongInteger;
-
-/**
-\brief scoMatrixOfLongInteger is a table of scoLineOfLongInteger or a matrix of scoLongInteger 
-*/
-typedef scoLineOfLongInteger * scoMatrixOfLongInteger;
-
-/**
-\brief scoDouble is an equivalent of double 
-*/
-typedef double scoDouble;
-
-/**
-\brief scoLineOfDouble is a table of scoDouble 
-*/
-typedef scoDouble * scoLineOfDouble;
-
-/** \brief ScopeMemory is useful to stock in the block->work the whole information we need to proceed the draw of the scope. Attention we are using the block->work because we cannot use a static structure (without a huge modification of the behavior) because there will be problems if we have two blocks of the same nature in the diagram
-\param number_of_subwin Number of Subwin (Axes) in the whole Window
-\param win_id Windows ID
-\param shortdraw_size Size of the Buffer of an axes i i.e. shortdraw_size[i]
-\param new_draw Determines if we have to do a new draw of an axes i i.e. new_draw[i]
-\param period_counter When we are using a timed scope it allows to calculate the X scale
-\param longdraw_size When we have a non direct scope we have to know the length of the trace to be stocked
-\param number_of_curves_by_subwin The number of curve by subwin (axes) i i.e. number_of_curves_by_subwin[i]
-\param hScopeWindow the Handle on the Scope Window
-\param hAxes the Handles of an axes i i.e. hAxes[i]
-\param hShortDraw the Handle of a ShortDraw j on an axes i i.e. hShortDraw[i][j]
-\param hLongDraw the Handle of a LongDraw j on an axes i i.e. hLongDraw[i][j]
-\param period the period of the axes i i.e. period[i]
-*/
-typedef struct
-{
-       scoInteger number_of_subwin;
-       scoInteger win_id;
-
-       scoLineOfInteger   shortdraw_size;
-       scoLineOfInteger   new_draw;
-       scoLineOfInteger   period_counter;
-       scoLineOfInteger   longdraw_size;
-       scoLineOfInteger   number_of_curves_by_subwin;
-
-       scoLongInteger hScopeWindow;
-
-       scoLineOfLongInteger   hAxes;
-
-       scoMatrixOfLongInteger hShortDraw;
-       scoMatrixOfLongInteger hLongDraw;
-
-       scoLineOfDouble   period;
-
-       scoInteger activated;
-
-       double     d_last_scope_update_time ; 
-
-} ScopeMemory;
-
-/*External function of malloc/free - Don't forget to use these and not malloc or MALLOC*/
-
-#endif
-
diff --git a/scilab/modules/scicos_blocks/includes/scoGetProperty.h b/scilab/modules/scicos_blocks/includes/scoGetProperty.h
deleted file mode 100755 (executable)
index 3e6c74b..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/*  Scicos
-*
-*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
-/**
-\file scoGetProperty.h
-\author Benoit Bayol
-\version 1.0
-\date September 2006 - January 2007
-\brief Header File of the scoGetProperty.c file 
-*/
-
-#ifndef __SCO_GET_PROPERTY_H__
-#define __SCO_GET_PROPERTY_H__
-
-#include "dynlib_scicos_blocks.h"
-#include "scoBase.h"
-
-/**
-\brief Get the internal time in seconds (micro or nano second max resolution)
-\return double
-*/
-SCICOS_BLOCKS_IMPEXP double scoGetRealTime(void);
-
-
-/**
-\brief Get the Handle of the Scope Window in the ScopeMemory
-\param pScopeMemory a pointer on a ScopeMemory
-\return hScopeWindow
-*/
-SCICOS_BLOCKS_IMPEXP scoLongInteger scoGetHandleScopeWindow(ScopeMemory * pScopeMemory);
-
-/**
-\brief Get the Handle of Axes i in the ScopeMemory where i is the index of the axes
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an Axes
-\return hAxes[i]
-*/
-SCICOS_BLOCKS_IMPEXP scoLongInteger scoGetHandleAxes(ScopeMemory * pScopeMemory, int i);
-
-/**
-\brief Get the Handle of the ShortDraw i,j in the ScopeMemory where i is the index of the axes and j is the index of the curve in the axes
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an Axes
-\param j index of a curve
-\return hShortDraw[i][j]
-*/
-SCICOS_BLOCKS_IMPEXP scoLongInteger scoGetHandleShortDraw(ScopeMemory * pScopeMemory, int i, int j);
-
-/**
-\brief Get the Handle of the LongDraw i,j in the ScopeMemory where i is the index of the axes and j is the index of the curve in the axes
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an Axes
-\param j index of a curve
-\return hLongDraw[i][j]
-*/
-SCICOS_BLOCKS_IMPEXP scoLongInteger scoGetHandleLongDraw(ScopeMemory * pScopeMemory, int i, int j);
-
-/**
-\brief Get the NewDraw value of Axes i in the ScopeMemory
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\return new_draw[i]
-*/
-SCICOS_BLOCKS_IMPEXP scoInteger scoGetNewDraw(ScopeMemory * pScopeMemory, int i);
-
-/**
-\brief Get the PeriodCounter of Axes i in the ScopeMemory
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\return period_counter[i]
-*/
-SCICOS_BLOCKS_IMPEXP scoInteger scoGetPeriodCounter(ScopeMemory * pScopeMemory, int i);
-
-/**
-\brief Get the TraceLength of the Axes i in the ScopeMemory
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\return trace_length[i]
-*/
-SCICOS_BLOCKS_IMPEXP scoInteger scoGetLongDrawSize(ScopeMemory * pScopeMemory, int i);
-
-/**
-\brief Get the NumberOfSubwin in the ScopeMemory
-\param pScopeMemory a pointer on a ScopeMemory
-\return number_of_subwin[i]
-*/
-SCICOS_BLOCKS_IMPEXP scoInteger scoGetNumberOfSubwin(ScopeMemory * pScopeMemory);
-
-/**
-\brief Get the NumberOfCurvesBySubwin of Axes i in the ScopeMemory
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\return number_of_curves_by_subwin[i]
-*/
-SCICOS_BLOCKS_IMPEXP scoInteger scoGetNumberOfCurvesBySubwin(ScopeMemory * pScopeMemory,int i);
-
-/**
-\brief Get the WindowID of the Scope Graphic Window in the ScopeMemory
-\param pScopeMemory a pointer on a ScopeMemory
-\return win_id
-*/
-SCICOS_BLOCKS_IMPEXP scoInteger scoGetWindowID(ScopeMemory * pScopeMemory);
-
-/**
-\brief Get the BufferSize of the Axes i in the ScopeMemory
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\return buffer_sze[i]
-*/
-SCICOS_BLOCKS_IMPEXP scoInteger scoGetShortDrawSize(ScopeMemory * pScopeMemory,int i);
-
-/**
-\brief Get the Period of the Axes i in the ScopeMemory
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\return period[i]
-*/
-SCICOS_BLOCKS_IMPEXP scoDouble scoGetPeriod(ScopeMemory * pScopeMemory, int i);
-
-
-/**
-\brief Get the Pointer on the ScopeWindow
-\param pScopeMemory a pointer on a ScopeMemory
-\return an scoGraphicalObject which is the pointer on the Scope Window
-*/
-SCICOS_BLOCKS_IMPEXP scoGraphicalObject scoGetPointerScopeWindow(ScopeMemory * pScopeMemory);
-
-/**
-\brief Get the Pointer on Axes[i]
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axe
-\return an scoGraphicalObject which is the pointer on the Axes[i]
-*/
-SCICOS_BLOCKS_IMPEXP scoGraphicalObject scoGetPointerAxes(ScopeMemory * pScopeMemory, int i);
-
-/**
-\brief Get the Pointer on ShortDraw[i][j]
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axe
-\param j index of a curve in the Axes[i]
-\return an scoGraphicalObject which is the pointer on the ShortDraw[i][j]
-*/
-SCICOS_BLOCKS_IMPEXP scoGraphicalObject scoGetPointerShortDraw(ScopeMemory * pScopeMemory, int i, int j);
-
-/**
-\brief Get the Pointer on LongDraw[i][j]
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axe
-\param j index of a curve in the Axes[i]
-\return an scoGraphicalObject which is the pointer on the LongDraw[i][j]
-*/
-SCICOS_BLOCKS_IMPEXP scoGraphicalObject scoGetPointerLongDraw(ScopeMemory * pScopeMemory, int i, int j);
-
-/**
-\brief Get status of activation of the block
-\return 1 activated or 0 deactivated (by default)
-
-*/
-SCICOS_BLOCKS_IMPEXP scoInteger scoGetScopeActivation(ScopeMemory * pScopeMemory);
-
-#endif
diff --git a/scilab/modules/scicos_blocks/includes/scoMemoryScope.h b/scilab/modules/scicos_blocks/includes/scoMemoryScope.h
deleted file mode 100644 (file)
index 4db45df..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*  Scicos
-*
-*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
-/**
-\file scoMemoryScope.h
-\author Benoit Bayol
-\version 1.0
-\date September 2006 - January 2007
-\brief Header file of the scoMemoryScope.c file
-*/
-
-#ifndef __SCO_MEMORYSCOPE_H__
-#define __SCO_MEMORYSCOPE_H__
-
-#include "dynlib_scicos_blocks.h"
-#include"scoBase.h"
-
-/**
-\brief Initialization with scicos_malloc on the ScopeMemory and put in ScopeMemory the number_of_subwin and the number_of_curves_by_subwin
-\param block a pointer on a scicos_block, typically the bloc in agument of the computational function
-\param pScopeMemory a pointer on a pointer of a ScopeMemory, typically &pScopeMemory where pScopeMemory is a ScopeMemory *
-\param number_of_subwin Number of Subwin in the whole Scope
-\param number_of_curves_by_subwin Number of Curves for the subwin[i]
-*/
-SCICOS_BLOCKS_IMPEXP void scoInitScopeMemory(void ** block_work, ScopeMemory ** pScopeMemory, int number_of_subwin, int * number_of_curves_by_subwin);
-
-/**
-\brief Retrieve the whole ScopeMemory and put in the pScopeMemory
-\param block a pointer on a scicos_block, typically the bloc in agument of the computational function
-\param pScopeMemory a pointer on a pointer of a ScopeMemory, typically &pScopeMemory where pScopeMemory is a ScopeMemory *
-*/
-SCICOS_BLOCKS_IMPEXP void scoRetrieveScopeMemory(void ** block_work, ScopeMemory ** pScopeMemory);
-
-/**
-\brief Free the ScopeMemory which has been allocated by scicos_malloc in the scoInitScopeMemory
-\param block a pointer on a scicos_block, typically the bloc in agument of the computational function
-\param pScopeMemory a pointer on a pointer of a ScopeMemory, typically &pScopeMemory where pScopeMemory is a ScopeMemory *
-*/
-SCICOS_BLOCKS_IMPEXP void scoFreeScopeMemory(void ** block_work, ScopeMemory ** pScopeMemory);
-
-/**
-\brief Realloc to extend the size of the longdraw in the memory
-\param pLongDraw A pointer on the longdraw which needs to be reallocated
-\param NbrPtsLong Current size of the longdraw
-\param buffer_size Buffer size which would be added to the longdraw
-\param plus An other buffer size which is a security
-*/
-SCICOS_BLOCKS_IMPEXP void scoReallocLongDraw(scoGraphicalObject pLongDraw, int NbrPtsLong, int buffer_size, int plus);
-
-#endif
diff --git a/scilab/modules/scicos_blocks/includes/scoMisc.h b/scilab/modules/scicos_blocks/includes/scoMisc.h
deleted file mode 100755 (executable)
index f7d79fe..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*  Scicos
-*
-*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
-/**
-\file scoMisc.h
-\author Benoit Bayol
-\version 1.0
-\date September 2006 - January 2007
-\brief Header File of the scoMisc.c file
-*/
-
-#ifndef __SCO_MISC_H__
-#define __SCO_MISC_H__
-
-#include "dynlib_scicos_blocks.h"
-#include"scoBase.h"
-
-/**
-\brief Stop simulation and return an indication of the bug
-\param pScopeMemory a pointer on a ScopeMemory
-\param code_error a code error (see in the function to determine the right number for the moment)
-*/
-SCICOS_BLOCKS_IMPEXP void scoScopeError(ScopeMemory * pScopeMemory, int code_error);
-
-#endif
diff --git a/scilab/modules/scicos_blocks/includes/scoSetProperty.h b/scilab/modules/scicos_blocks/includes/scoSetProperty.h
deleted file mode 100755 (executable)
index d04174e..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*  Scicos
-*
-*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
-/**
-\file scoSetProperty.h
-\author Benoit Bayol
-\version 1.0
-\date September 2006 - January 2007
-\brief Header file of the scoSetProperty.c file
-*/
-
-#ifndef __SCO_SET_PROPERTY_H__
-#define __SCO_SET_PROPERTY_H__
-
-#include "dynlib_scicos_blocks.h"
-#include "scoBase.h"
-
-/**
-\brief Set value in the hScopeWindow
-\param pScopeMemory a pointer on a ScopeMemory
-\param value the new value of the handle
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetHandleScopeWindow(ScopeMemory * pScopeMemory, long value);
-
-/**
-\brief Set value in the hAxes
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\param value the new value of the handle hAxes[i]
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetHandleAxes(ScopeMemory * pScopeMemory, int i, long value);
-
-/**
-\brief Set value in the hShortDraw[i][j] 
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\param j index of a curve
-\param value the new value of the hShortDraw[i][j]
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetHandleShortDraw(ScopeMemory * pScopeMemory, int i,int j, long value);
-
-/**
-\brief Set value in the hLongDraw[i][j]
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\param j index of a curve
-\param value the new value of the hLongDraw[i][j]
-*/ 
-SCICOS_BLOCKS_IMPEXP void scoSetHandleLongDraw(ScopeMemory * pScopeMemory, int i,int j, long value);
-
-/**
-\brief Set value in the new_draw[i]
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\param value the new value of new_draw[i]
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetNewDraw(ScopeMemory * pScopeMemory, int i, int value);
-
-/**
-\brief Set value in the period_counter[i]
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\param value the new value of period_counter[i]
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetPeriodCounter(ScopeMemory * pScopeMemory, int i, int value);
-
-/**
-\brief Set value in the trace_length[i]
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\param value the new value of trace_length[i]
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetLongDrawSize(ScopeMemory * pScopeMemory, int i, int value);
-
-/**
-\brief Set value in the number_of_subwin
-\param pScopeMemory a pointer on a ScopeMemory
-\param value the new value of number_of_subwin
-
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetNumberOfSubwin(ScopeMemory * pScopeMemory, int value);
-
-/**
-\brief Set value in the number_of_curves_by_subwin[i]
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\param value the new value of number_of_curves_by_subwin[i]
-*/ 
-SCICOS_BLOCKS_IMPEXP void scoSetNumberOfCurvesBySubwin(ScopeMemory * pScopeMemory, int i, int value);
-
-/**
-\brief Set value in the win_id
-\param pScopeMemory a pointer on a ScopeMemory
-\param value the new value of the win_id
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetWindowID(ScopeMemory * pScopeMemory, int value);
-
-/**
-\brief Set value in the buffer_size[i]
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\param value the new value of buffer_size[i]
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetShortDrawSize(ScopeMemory * pScopeMemory, int i, int value);
-
-/**
-\brief Set value in the period[i]
-\param pScopeMemory a pointer on a ScopeMemory
-\param i index of an axes
-\param value the new value of period[i]
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetPeriod(ScopeMemory * pScopeMemory, int i, double value);
-
-/**
-\brief Set value of handle axes in the structure by passing a pointer on argument
-\param pScopeMemory a pointer on a ScopeMemory
-\param i the position i of the axes
-\param value a scoGraphicalObject (i.e. sciPointObj *) of an axes
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetHandleFromPointerAxes(ScopeMemory * pScopeMemory, int i, scoGraphicalObject value);
-
-/**
-\brief Set value of handle shortdraw in the structure by passing a pointer on argument
-\param pScopeMemory a pointer on a ScopeMemory
-\param i the position i of the axes
-\param j the position j of the shortdraw in the axes
-\param value a scoGraphicalObject (i.e. sciPointObj *) of a shortdraw
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetHandleFromPointerShortDraw(ScopeMemory * pScopeMemory, int i,int j, scoGraphicalObject value);
-
-/**
-\brief Set value of handle longdraw in the structure by passing a pointer on argument
-\param pScopeMemory a pointer on a ScopeMemory
-\param i the position i of the axes
-\param j the position j of the longdraw in the axes
-\param value a scoGraphicalObject (i.e. sciPointObj *) of a longdraw
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetHandleFromPointerLongDraw(ScopeMemory * pScopeMemory, int i,int j, scoGraphicalObject value);
-
-/**
-\brief Set value of handle scopewindow in the structure by passing a pointer on argument
-\param pScopeMemory a pointer on a ScopeMemory
-\param value a scoGraphicalObject (i.e. sciPointObj *) of a window
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetHandleFromPointerScopeWindow(ScopeMemory * pScopeMemory, scoGraphicalObject value);
-
-
-/**
-\brief Set value for activation (1 activate 0 else (by default))
-\param pScopeMemory a pointer on a ScopeMemory
-\param status : 1 activate 0 deactivate
-*/
-SCICOS_BLOCKS_IMPEXP void scoSetScopeActivation(ScopeMemory * pScopeMemory, int status);
-
-
-#endif
diff --git a/scilab/modules/scicos_blocks/includes/scoWindowScope.h b/scilab/modules/scicos_blocks/includes/scoWindowScope.h
deleted file mode 100644 (file)
index b6ae36c..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/*  Scicos
-*
-*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
-/**
-\file scoWindowScope.h
-\author Benoit Bayol
-\version 1.0
-\date September 2006 - January 2007
-\brief Header File of the scoWindowScope.c file
-*/
-
-#ifndef __SCO_WINDOWSCOPE_H__
-#define __SCO_WINDOWSCOPE_H__
-
-#include "dynlib_scicos_blocks.h"
-#include"scoBase.h"
-
-/**
-\brief Initialization of the Window and its apparence
-\param pScopeMemory a pointer on a ScopeMemory
-\param dimension the dimension of the axes 2 or 3
-\param win_id the windows ID
-\param win_pos a table of 2 numbers which determines the position of the window on the screen
-\param win_dim a table of 2 numbers which determines the dimension of the window on the screen
-\param xmin a table of (number_of_subwin) size
-\param xmax a table of (number_of_subwin) size
-\param ymin a table of (number_of_subwin) size 
-\param ymax a table of (number_of_subwin) size
-\param zmin a table of (number_of_subwin) size
-\param zmax a table of (number_of_subwin) size
-*/
-SCICOS_BLOCKS_IMPEXP void scoInitOfWindow(ScopeMemory * pScopeMemory, int dimension, int win_id, int * win_pos, int * win_dim, double * xmin, double * xmax, double * ymin, double * ymax, double * zmin, double * zmax);
-
-/**
-\brief Allocate space and set block_number in the user_data of the window associated in the pScopeMemory
-**/
-SCICOS_BLOCKS_IMPEXP void scoSetInUserData(ScopeMemory * pScopeMemory,int block_number);
-
-/**
-\brief Retrive UserData[0] (i.e. the block_number we have stocked)
-\param pTemp is a pointer on the figure
-**/
-SCICOS_BLOCKS_IMPEXP scoInteger scoGetUserData(scoGraphicalObject pTemp);
-
-/*--------------------------CREATIONS FUNCTIONS-----------------------------*/
-/*
-All these functions create pointer of special objects. We could use directly the sci graphic library function but in Scicos we have some behaviors which doesn't need to be really tuned for our usage. For this reason we have redefined them by putting some default values for some parameters.
-*/
-
-/**
-\brief Create a polyline and return a pointer on it
-\param pAxes A pointer on the designated axe
-\param polyline_size Size of the polyline for pvx, pvy or pvz
-\param color The color of the polyline. If <= 0 it will be a mark else it will be a line.
-\attention There is a polyline_size to allocate the table but dont forget that the n1 value of pPOLYLINE_FEATURE is set to 0
-*/
-SCICOS_BLOCKS_IMPEXP scoGraphicalObject scoCreatePolyline(scoGraphicalObject pAxes, scoInteger polyline_size,int color);
-
-/**
-\brief Create a Filled Circle  by using the constructArc method of sgl and return a pointer on it
-\param pAxes A pointer on the designated axe
-\param radius the radius of the filled circle
-\param color the color of the filled circle
-*/
-SCICOS_BLOCKS_IMPEXP scoGraphicalObject scoCreateSphere(scoGraphicalObject pAxes, double radius, int color);
-
-/**
-\brief Create a Rectangle by using constructRectangle and return a pointer on it
-\param pAxes a pointer on the designated axe
-\param x the abscisse of the left bottom corner of the rectangle
-\param y the ordonate of the left bottom corner of the rectangle
-\param width width of the rectangle
-\param height height of the rectangle
-*/
-SCICOS_BLOCKS_IMPEXP scoGraphicalObject scoCreateRectangle(scoGraphicalObject pAxes, double x, double y, double width, double height);
-
-/**
-\brief Create a Grayplot using constructGrayplot and return a pointer on it
-\param pAxes a pointer on the designated axes
-\param size_x size of the grayplot for abscisses
-\param size_y size of the grayplot for ordinates
-*/
-SCICOS_BLOCKS_IMPEXP scoGraphicalObject scoCreateGrayplot(scoGraphicalObject pAxes, int size_x, int size_y);
-
-/**
-\brief Create a Plot3d using constructSurface (a param is for plot3d) and return a pointer on it
-\param pAxes a pointer on the designated axes
-\param size_x size of the plot3d for abscisses
-\param size_y size of the plot3d for ordinates
-*/
-SCICOS_BLOCKS_IMPEXP scoGraphicalObject scoCreatePlot3d(scoGraphicalObject pAxes, int size_x, int size_y);
-
-/*---------------------------ADDING FUNCTIONS------------------------------*/
-/*
-All these functions take a pointer of a graphical object and place it on axes i at position j. There is one for ShortDraw and one for LongDraw.
-*/
-
-/**
-\brief Add a polyline for a shortdraw
-\param pScopeMemory a pointer on the ScopeMemory
-\param i the number of the axes
-\param j the number of the designated shortdraw in the axes i
-\param color color of the polyline. <=0 is a mark >0 is a line
-*/
-SCICOS_BLOCKS_IMPEXP void scoAddPolylineForShortDraw(ScopeMemory * pScopeMemory, int i, int j, int color);
-
-/**
-\brief Add a polyline for a longdraw
-\param pScopeMemory  a pointer on the ScopeMemory
-\param i the number of the axes
-\param j the number of the designated longdraw in the axes i
-\param color color of the polyline. <=0 is a mark >0 is a line
-
-*/
-SCICOS_BLOCKS_IMPEXP void scoAddPolylineForLongDraw(ScopeMemory * pScopeMemory, int i, int j, int color);
-
-/**
-\brief Add a sphere to the axis as a shortdraw
-\param pScopeMemory  a pointer on the ScopeMemory
-\param i the number of the axes
-\param j the number of the designated shortdraw in the axes i
-\param radius the radius of the sphere
-\param color the color of the filled sphere
-*/
-SCICOS_BLOCKS_IMPEXP void scoAddSphereForShortDraw(ScopeMemory * pScopeMemory, int i, int j, double radius, int color);
-
-/**
-\brief Add a sphere to the axis as a longdraw
-\param pScopeMemory  a pointer on the ScopeMemory
-\param i the number of the axes
-\param j the number of the designated longdraw in the axes i
-\param radius the radius of the sphere
-\param color the color of the filled sphere
-*/
-SCICOS_BLOCKS_IMPEXP void scoAddSphereForLongDraw(ScopeMemory * pScopeMemory, int i, int j, double radius, int color);
-
-/**
-\brief Add a rectangle for a longdraw
-\param pScopeMemory  a pointer on the ScopeMemory
-\param i the number of the axes
-\param j the number of the designated longdraw in the axes i
-\param x the abscisse of the left bottom corner of the rectangle
-\param y the ordonate of the left bottom corner of the rectangle
-\param width width of the rectangle
-\param height height of the rectangle
-
-*/
-SCICOS_BLOCKS_IMPEXP void scoAddRectangleForLongDraw(ScopeMemory * pScopeMemory, int i, int j, double x, double y, double width, double height);
-
-/**
-\brief Add a grayplot for a shortdraw
-\param pScopeMemory  a pointer on the ScopeMemory
-\param i the number of the axes
-\param j the number of the designated shortdraw in the axes i
-\param size_x size of the grayplot for abscisses
-\param size_y size of the grayplot for ordinates
-*/
-SCICOS_BLOCKS_IMPEXP void scoAddGrayplotForShortDraw(ScopeMemory * pScopeMemory, int i, int j, int size_x, int size_y);
-
-/**
-\brief Add a plot3d for a ShortDraw
-\param pScopeMemory  a pointer on the ScopeMemory
-\param i the number of the axes
-\param j the number of the designated shortdraw in the axes i
-\param size_x size of the plot3d for abscisses
-\param size_y size of the plot3d for ordinates
-*/
-SCICOS_BLOCKS_IMPEXP void scoAddPlot3dForShortDraw(ScopeMemory * pScopeMemory, int i, int j, int size_x, int size_y);
-
-/*-------------------------------ADDING COUPLE FUNCTIONS-----------------------------------*/
-
-/**
-\brief Add a couple of polylines one for shortdraw and one for longdraw
-\param pScopeMemory  a pointer on the ScopeMemory
-\param colors a table of colors of all curves in the ScopeMemory
-\attention this function use the value of number_of_subwin and number_of_curves_by_subwin to fill all allocated space with shortdraw and longdraw typed with polylines
-*/
-SCICOS_BLOCKS_IMPEXP void scoAddCoupleOfPolylines(ScopeMemory * pScopeMemory, int * colors);
-
-/**
-\brief Add a couple of polyline one for the ShortDraw and one for the LongDraw they are lined
-\param pScopeMemory a pointer on a ScopeMemory
-\param color a table of (number_of_curves_by_subwin[0]) size to colorize segments
-\attention this function use the value of number_of_subwin and number_of_curves_by_subwin to fill all allocated space with shortdraw and longdraw typed with segments
-*/
-SCICOS_BLOCKS_IMPEXP void scoAddCoupleOfSegments(ScopeMemory * pScopeMemory, int * color);
-
-/**
-\brief Add a couple of spheres to the axis
-\param pScopeMemory a pointer on a ScopeMemory
-\param radius a table of radii for all spheres
-\param colors a table of colors
-\attention this function use the value of number_of_subwin and number_of_curves_by_subwin to fill all allocated space with shortdraw and longdraw typed with segment
-*/
-SCICOS_BLOCKS_IMPEXP void scoAddCoupleOfSpheres(ScopeMemory * pScopeMemory, double * radius, int * colors);
-
-/*-------------------------------DELETING FUNCTIONS---------------------------*/
-/**
-\brief Del a couple of polyline one for the ShortDraw and one for the LongDraw they are linked
-\param pScopeMemory a pointer on a ScopeMemory
-*/
-SCICOS_BLOCKS_IMPEXP void scoDelCoupleOfPolylines(ScopeMemory * pScopeMemory);
-
-/**
-\brief Del a couple of polyline one for the ShortDraw and one for the LongDraw they are linked
-\param pScopeMemory a pointer on a ScopeMemory
-*/
-SCICOS_BLOCKS_IMPEXP void scoDelCoupleOfSegments(ScopeMemory * pScopeMemory);
-
-/* ----------------------DRAWING FUNCTIONS --------------------------------*/
-/*
-These functions modify the view of the scope. They all have at a moment an instruction to redraw a graphical objet or the whole window.
-*/
-/**
-\brief Draw a Scope like CSCOPE : Amplitude + Time Based
-\param pScopeMemory a pointer on a ScopeMemory
-\param t the scicos time (get_scicos_time())
-*/
-SCICOS_BLOCKS_IMPEXP void scoDrawScopeAmplitudeTimeStyle(ScopeMemory * pScopeMemory, double t);
-
-/**
-\brief Draw a Scope like CSCOPXY or CSCOPXY3D
-\param pScopeMemory a pointer on a ScopeMemory
-*/
-SCICOS_BLOCKS_IMPEXP void scoDrawScopeXYStyle(ScopeMemory * pScopeMemory);
-/**
-\brief Add Titles and Backgound on the scope
-\param pScopeMemory a pointer on a ScopeMemory
-\param label a string to be printed on the title of the graphic window
-\param x a string to be printed on x
-\param y a string to be printed on y
-\param z a string to be printed on z (can be NULL)
-*/
-SCICOS_BLOCKS_IMPEXP void scoAddTitlesScope(ScopeMemory * pScopeMemory, char * label, char * x, char * y, char * z);
-
-/**
-\brief Draw a Scope libe ANIMXY or ANIMXY3D
-\param pScopeMemory a pointer on a ScopeMemory
-\param u1 values on first entry 
-\param u2 values on second entry
-\param u3 values on third entry (can be NULL)
-*/
-SCICOS_BLOCKS_IMPEXP void scoDrawScopeAnimXYStyle(ScopeMemory * pScopeMemory, double * u1, double * u2, double * u3);
-
-/**
-\brief Refresh the DataBounds of X if we have touched the end of the x-axes
-\param pScopeMemory a pointer on a ScopeMemory
-\param t the scicos time (get_scicos_time())
-*/
-SCICOS_BLOCKS_IMPEXP void scoRefreshDataBoundsX(ScopeMemory * pScopeMemory,double t);
-
-#endif
index d2107ee..61f9251 100644 (file)
-/*  Scicos
-*
-*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
-/*--------------------------------------------------------------------------*/
-/**
-   \file bouncexy.c
-   \author Benoit Bayol
-   \version 1.0
-   \date September 2006 - January 2007
-   \brief BOUNCEXY has to be used with bounce_ball block
-   \see BOUNCEXY.sci in macros/scicos_blocks/Misc/
-*/
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2011 - DIGITEO - Clément DAVID
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
 #include <math.h>
-#include "scoMemoryScope.h"
-#include "scoWindowScope.h"
-#include "scoMisc.h"
-#include "scoGetProperty.h"
-#include "scoSetProperty.h"
+#ifndef M_PI
+#define M_PI           3.14159265358979323846
+#endif
+
+#include "dynlib_scicos_blocks.h"
+#include "scoUtils.h"
+
+#include "MALLOC.h"
+#include "elementary_functions.h"
+
+#include "getGraphicObjectProperty.h"
+#include "setGraphicObjectProperty.h"
+#include "graphicObjectProperties.h"
+#include "createGraphicObject.h"
+
+#include "CurrentFigure.h"
+
 #include "scicos_block4.h"
-#include "ObjectStructure.h"
-#include "DrawingBridge.h"
 #include "scicos.h"
-#include "scicos_malloc.h"
-#include "scicos_free.h"
-#include "MALLOC.h"
-#include "dynlib_scicos_blocks.h"
-#include "HandleManagement.h"
-/*--------------------------------------------------------------------------*/
-/** \fn bouncexy_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
-    \brief Function to draw or redraw the window
+
+#include "localization.h"
+#include "FigureList.h"
+#include "BuildObjects.h"
+#include "AxesModel.h"
+
+/*****************************************************************************
+ * Internal container structure
+ ****************************************************************************/
+
+/**
+ * Container structure
+ */
+typedef struct
+{
+    struct
+    {
+        double *ballsSize;
+        double **data;
+    } internal;
+
+    struct
+    {
+        char *cachedFigureUID;
+        char *cachedAxeUID;
+        char **cachedArcsUIDs;
+    } scope;
+} sco_data;
+
+/**
+ * Get (and allocate on demand) the internal data used on this scope
+ * \param block the block
+ * \return the scope data
+ */
+static sco_data *getScoData(scicos_block * block);
+
+/**
+ * Release any internal data
+ *
+ * \param block the block
+ */
+static void freeScoData(scicos_block * block);
+
+/**
+ * Append the data to the current data
+ *
+ * \param block the block
+ * \param x x data
+ * \param y y data
+ */
+static void appendData(scicos_block * block, double *x, double *y);
+
+/**
+ * Push the block data to the polyline
+ *
+ * \param block the block
+ * \param row the selected row
+ *
+ */
+static BOOL pushData(scicos_block * block, int row);
+
+/*****************************************************************************
+ * Graphics utils
+ ****************************************************************************/
+
+/**
+ * Get (and allocate on demand) the figure associated with the block
+ * \param block the block
+ * \return a valid figure UID or NULL on error
+ */
+static char *getFigure(scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the axe associated with the input
+ *
+ * \param pFigureUID the parent figure UID
+ * \param block the block
+ * \param input the current input index (0-indexed)
+ * \return a valid axe UID or NULL on error
+ */
+static char *getAxe(char *pFigureUID, scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the arc associated with the row
+ *
+ * \param pAxeUID the parent axe UID
+ * \param block the block
+ * \param row the current row index (0-indexed)
+ * \return a valid polyline UID or NULL on error
+ */
+static char *getArc(char *pAxeUID, scicos_block * block, int row);
+
+/**
+ * Set the bounds
+ *
+ * \param block the block
+ */
+static BOOL setBounds(scicos_block * block);
+
+/*****************************************************************************
+ * Simulation function
+ ****************************************************************************/
+
+/** \fn void bouncexy(scicos_block * block,int flag)
+    \brief the computational function
+    \param block A pointer to a scicos_block
+    \param flag An int which indicates the state of the block (init, update, ending)
 */
-SCICOS_BLOCKS_IMPEXP void bouncexy_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
+SCICOS_BLOCKS_IMPEXP void bouncexy(scicos_block * block, scicos_flag flag)
+{
+    char *pFigureUID;
+
+    sco_data *sco;
+
+    int j;
+    BOOL result;
+
+    switch (flag)
+    {
+
+    case Initialization:
+        sco = getScoData(block);
+        if (sco == NULL)
+        {
+            set_block_error(-5);
+        }
+        pFigureUID = getFigure(block);
+        if (pFigureUID == NULL)
+        {
+            // allocation error
+            set_block_error(-5);
+        }
+        break;
+
+    case StateUpdate:
+        pFigureUID = getFigure(block);
+
+        appendData(block, (double *)block->inptr[0], (double *)block->inptr[1]);
+        for (j = 0; j < block->insz[0]; j++)
+        {
+            result = pushData(block, j);
+            if (result == FALSE)
+            {
+                Coserror("%s: unable to push some data.", "bouncexy");
+                break;
+            }
+        }
+        break;
+
+    case Ending:
+        freeScoData(block);
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*****************************************************************************
+ *
+ * Container management
+ *
+ ****************************************************************************/
+
+static sco_data *getScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+
+    if (sco == NULL)
+    {
+        /*
+         * Data allocation
+         */
+
+        sco = (sco_data *) MALLOC(sizeof(sco_data));
+        if (sco == NULL)
+            goto error_handler_sco;
+
+        sco->internal.ballsSize = (double *)CALLOC(block->nin, sizeof(double));
+        if (sco->internal.ballsSize == NULL)
+            goto error_handler_ballsSize;
+        for (i = 0; i < block->insz[0]; i++)
+        {
+            sco->internal.ballsSize[i] = block->z[6 * i + 2];
+        }
+
+        sco->internal.data = (double **)CALLOC(block->insz[0], sizeof(double *));
+        if (sco->internal.data == NULL)
+            goto error_handler_data;
+
+        for (i = 0; i < block->insz[0]; i++)
+        {
+            sco->internal.data[i] = (double *)CALLOC(3, sizeof(double));
+            if (sco->internal.data[i] == NULL)
+                goto error_handler_data_i;
+        }
+
+        sco->scope.cachedFigureUID = NULL;
+        sco->scope.cachedAxeUID = NULL;
+
+        sco->scope.cachedArcsUIDs = (char **)CALLOC(block->insz[0], sizeof(char *));
+
+        *(block->work) = sco;
+    }
+
+    return sco;
+
+    /*
+     * Error management (out of normal flow)
+     */
+
+error_handler_data_i:
+    for (j = 0; j < i; j++)
+    {
+        FREE(sco->internal.data[i]);
+    }
+    FREE(sco->internal.data);
+error_handler_data:
+    FREE(sco->internal.ballsSize);
+error_handler_ballsSize:
+    FREE(sco);
+error_handler_sco:
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
+
+static void freeScoData(scicos_block * block)
 {
-  scoGraphicalObject pAxes;
-  scoGraphicalObject pTemp;
-  double * z = NULL;
-  double *rpar = NULL;
-  int *ipar = NULL, nipar = 0;
-  int i = 0,j = 0;
-  int dimension = 0;
-  double ymin = 0., ymax = 0., xmin = 0., xmax = 0.;
-  int win = 0;
-  int number_of_subwin = 0;
-  int number_of_curves_by_subwin = 0;
-  int * colors = NULL;
-  int imode = 0;
-  double * size_balls = NULL;
-  double radius_max;
-
-  /*Retrieving Parameters*/
-  rpar = GetRparPtrs(block);
-  ipar = GetIparPtrs(block);
-  nipar = GetNipar(block);
-  win = ipar[0];
-  if (win == -1)
-    {
-      win = 20000 + get_block_number() ;
+    sco_data *sco = (sco_data *) * (block->work);
+    int i;
+
+    if (sco != NULL)
+    {
+        for (i = 0; i < block->insz[0]; i++)
+        {
+            FREE(sco->internal.data[i]);
+        }
+
+        FREE(sco->internal.data);
+        FREE(sco->internal.ballsSize);
+
+//      Commented due to the C++ allocation
+//      see http://bugzilla.scilab.org/show_bug.cgi?id=9747
+//      FREE(sco->scope.cachedFigureUID);
+//      sco->scope.cachedFigureUID = NULL;
+//      for (i=0; i<block->nin; i++) {
+//          for (j=0; j<block->insz[i]; j++) {
+//              FREE(sco->scope.cachedArcsUIDs[i][j]);
+//              sco->scope.cachedArcsUIDs[i][j] = NULL;
+//          }
+//          FREE(sco->scope.cachedAxeUID[i]);
+//          sco->scope.cachedAxeUID[i] = NULL;
+//      }
+
+        FREE(sco);
     }
-  dimension = 2;
-  imode = ipar[1];
-  number_of_curves_by_subwin = GetInPortRows(block,1);
-  radius_max = 0;
-  size_balls = (double*)scicos_malloc(number_of_curves_by_subwin*sizeof(double));
-  z = GetDstate(block);
-  for(i = 0 ; i < number_of_curves_by_subwin ; i++)
-    {
-      size_balls[i] = z[6*i+2];
-      if(radius_max < size_balls[i])
-       {
-         radius_max = size_balls[i];
-       }
+}
+
+static void appendData(scicos_block * block, double *x, double *y)
+{
+    int i;
+    double *upperLeftPoint;
+    double ballSize;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    /*
+     * Update data
+     */
+    if (sco != NULL)
+    {
+        for (i = 0; i < block->insz[0]; i++)
+        {
+            upperLeftPoint = sco->internal.data[i];
+            ballSize = sco->internal.ballsSize[i];
+
+            upperLeftPoint[0] = x[i] - (ballSize / 2);  // x
+            upperLeftPoint[1] = y[i] + (ballSize / 2);  // y
+            upperLeftPoint[2] = 0;  // z
+        }
     }
-  number_of_subwin = 1;
-  xmin = rpar[0];
-  xmax = rpar[1];
-  ymin = rpar[2];
-  ymax = rpar[3];
-  colors = (int*)scicos_malloc(number_of_curves_by_subwin*sizeof(int));
-  for(i = 0 ; i < number_of_curves_by_subwin ; i++)
-    {
-      colors[i] = ipar[i+2];
+}
+
+static BOOL pushData(scicos_block * block, int row)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pArcUID;
+
+    double *upperLeftPoint;
+    sco_data *sco;
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+    pArcUID = getArc(pAxeUID, block, row);
+
+    sco = getScoData(block);
+    if (sco == NULL)
+        return FALSE;
+
+    upperLeftPoint = sco->internal.data[row];
+    return setGraphicObjectProperty(pArcUID, __GO_UPPER_LEFT_POINT__, upperLeftPoint, jni_double_vector, 3);
+}
+
+/*****************************************************************************
+ *
+ * Graphic utils
+ *
+ ****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Graphic
+ *
+ ****************************************************************************/
+
+static char *getFigure(scicos_block * block)
+{
+    signed int figNum;
+    char *pFigureUID = NULL;
+    char *pAxe = NULL;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedFigureUID != NULL)
+    {
+        return sco->scope.cachedFigureUID;
     }
-  if(firstdraw == 1)
+
+    figNum = block->ipar[0];
+
+    // with a negative id, use the block number indexed from a constant.
+    if (figNum < 0)
     {
-      /*Allocating memory*/
-      scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
+        figNum = 20000 + get_block_number();
     }
-  /*Creating the Scope*/
-  scoInitOfWindow(*pScopeMemory, dimension, win, NULL, NULL, &xmin, &xmax, &ymin, &ymax, NULL, NULL);
-  if(scoGetScopeActivation(*pScopeMemory) == 1)
+
+    pFigureUID = getFigureFromIndex(figNum);
+    // create on demand
+    if (pFigureUID == NULL)
     {
-  pTemp = scoGetPointerScopeWindow(*pScopeMemory);
-  pAxes = scoGetPointerAxes(*pScopeMemory,0);
+        pFigureUID = createNewFigureWithAxes();
+        setGraphicObjectProperty(pFigureUID, __GO_ID__, &figNum, jni_int, 1);
 
-  pSUBWIN_FEATURE(pAxes)->isoview = TRUE;
+        sco->scope.cachedFigureUID = pFigureUID;
 
-  (pSUBWIN_FEATURE(pAxes)->axes).axes_visible[0] = FALSE;
-  (pSUBWIN_FEATURE(pAxes)->axes).axes_visible[1] = FALSE;
+        // allocate the axes through the getter
+        pAxe = getAxe(pFigureUID, block);
 
-  //** sciSetIsBoxed(pAxes, FALSE); //** obsolete in Scilab 5
-  sciSetBoxType(pAxes,BT_ON);
+        /*
+         * Setup according to block settings
+         */
+        setLabel(pAxe, __GO_X_AXIS_LABEL__, "x");
+        setLabel(pAxe, __GO_Y_AXIS_LABEL__, "y");
 
+        setBounds(block);
+    }
 
-  for(j = 0 ; j < number_of_curves_by_subwin ; j++)
+    if (sco->scope.cachedFigureUID == NULL)
     {
-      scoAddSphereForShortDraw(*pScopeMemory, 0, j, size_balls[j], colors[j]);
+        sco->scope.cachedFigureUID = pFigureUID;
     }
-  scoAddRectangleForLongDraw(*pScopeMemory,0,0,xmin,(ymax-fabs(ymin)),fabs(xmax-xmin),fabs(ymax-ymin));
-  sciDrawObj(scoGetPointerLongDraw(*pScopeMemory,0,0));
+    return pFigureUID;
+}
+
+static char *getAxe(char *pFigureUID, scicos_block * block)
+{
+    char *pAxe;
+    int i;
+
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedAxeUID != NULL)
+    {
+        return sco->scope.cachedAxeUID;
+    }
+
+    pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, 0);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pAxe == NULL)
+    {
+        pAxe = cloneGraphicObject(getAxesModel());
+
+        if (pAxe != NULL)
+        {
+            setGraphicObjectRelationship(pFigureUID, pAxe);
+
+            // allocate the polylines through the getter
+            for (i = 0; i < block->insz[0]; i++)
+            {
+                getArc(pAxe, block, i);
+            }
+        }
     }
-  scicos_free(colors);
-  scicos_free(size_balls);
 
+    sco->scope.cachedAxeUID = pAxe;
+    return pAxe;
 }
-/*--------------------------------------------------------------------------*/
-/** \fn void bouncexy(scicos_block * block,int flag)
-    \brief the computational function
-    \param block A pointer to a scicos_block
-    \param flag An int which indicates the state of the block (init, update, ending)
-*/
-SCICOS_BLOCKS_IMPEXP void bouncexy(scicos_block * block,int flag)
+
+static char *getArc(char *pAxeUID, scicos_block * block, int row)
 {
-  ScopeMemory * pScopeMemory = NULL;
-  scoGraphicalObject pShortDraw;
-  double * z = NULL;
-  double t = 0.;
-  int i = 0;
-  double * u1 = NULL, *u2 = NULL;
-  double * size_balls = NULL;
-  switch(flag)
+    static double d__0 = 0.0;
+    static double d__2PI = 2 * M_PI;
+
+    char *pArc;
+    int color;
+
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedArcsUIDs != NULL && sco->scope.cachedArcsUIDs[row] != NULL)
     {
-    case Initialization:
-      {
-       bouncexy_draw(block,&pScopeMemory,1);
-       break;
-      }
-    case StateUpdate:
-      {
-       /*Retreiving Scope in the block->work*/
-       scoRetrieveScopeMemory(block->work,&pScopeMemory);
-       if(scoGetScopeActivation(pScopeMemory) == 1)
-         {
-           t = get_scicos_time();
-       /*If window has been destroyed we recreate it*/
-       if(scoGetPointerScopeWindow(pScopeMemory) == NULL)
-         {
-           bouncexy_draw(block,&pScopeMemory,0);
-         }
-
-       //Cannot be factorized depends of the scope
-       size_balls = (double*)scicos_malloc(scoGetNumberOfCurvesBySubwin(pScopeMemory,0)*sizeof(double));
-       z = GetDstate(block);
-       for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0) ; i++)
-         {
-           size_balls[i] = z[6*i+2];
-         }
-       u1 = GetRealInPortPtrs(block,1);
-       u2 = GetRealInPortPtrs(block,2);
-       for (i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0) ; i++)
-         {
-           pShortDraw  = scoGetPointerShortDraw(pScopeMemory,0,i);
-           //** pLongDraw  = scoGetPointerLongDraw(pScopeMemory,0,i);
-           pARC_FEATURE(pShortDraw)->x = u1[i]-size_balls[i]/2;
-           pARC_FEATURE(pShortDraw)->y = u2[i]+size_balls[i]/2;
-            forceRedraw(pShortDraw); //** force the redraw of each ball
-         }
-
-       sciSetUsedWindow(scoGetWindowID(pScopeMemory));
-       sciDrawObj(scoGetPointerScopeWindow(pScopeMemory));
-        scicos_free(size_balls);
-         }
-       break;
-      }
+        return sco->scope.cachedArcsUIDs[row];
+    }
 
-    case Ending:
-      {
-       scoRetrieveScopeMemory(block->work, &pScopeMemory);
-       if(scoGetScopeActivation(pScopeMemory) == 1)
-         {
-           sciSetUsedWindow(scoGetWindowID(pScopeMemory));
-           pShortDraw = sciGetCurrentFigure();
-           pFIGURE_FEATURE(pShortDraw)->user_data = NULL;
-           pFIGURE_FEATURE(pShortDraw)->size_of_user_data = 0;
-         }
-       scoFreeScopeMemory(block->work, &pScopeMemory);
-       break;
-      }
+    pArc = findChildWithKindAt(pAxeUID, __GO_ARC__, row);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pArc == NULL)
+    {
+        pArc = createGraphicObject(__GO_ARC__);
+
+        if (pArc != NULL)
+        {
+            createDataObject(pArc, __GO_ARC__);
+            setGraphicObjectRelationship(pAxeUID, pArc);
+
+            /*
+             * Default setup
+             */
+            setGraphicObjectProperty(pArc, __GO_START_ANGLE__, &d__0, jni_double, 1);
+            setGraphicObjectProperty(pArc, __GO_END_ANGLE__, &d__2PI, jni_double, 1);
+
+            color = block->ipar[2 + row];
+            setGraphicObjectProperty(pArc, __GO_BACKGROUND__, &color, jni_int, 1);
+
+            setGraphicObjectProperty(pArc, __GO_WIDTH__, &sco->internal.ballsSize[row], jni_double, 1);
+            setGraphicObjectProperty(pArc, __GO_HEIGHT__, &sco->internal.ballsSize[row], jni_double, 1);
+        }
+    }
+
+    if (sco->scope.cachedArcsUIDs != NULL)
+    {
+        sco->scope.cachedArcsUIDs[row] = pArc;
     }
+    return pArc;
+}
+
+static BOOL setBounds(scicos_block * block)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+
+    double dataBounds[6];
+
+    dataBounds[0] = block->rpar[0]; // xMin
+    dataBounds[1] = block->rpar[1]; // xMax
+    dataBounds[2] = block->rpar[2]; // yMin
+    dataBounds[3] = block->rpar[3]; // yMax
+    dataBounds[4] = -1.0;       // zMin
+    dataBounds[5] = 1.0;        // zMax
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+
+    return setGraphicObjectProperty(pAxeUID, __GO_DATA_BOUNDS__, dataBounds, jni_double_vector, 6);
 }
-/*--------------------------------------------------------------------------*/
index c15ee2b..664afc9 100755 (executable)
-/*  Scicos
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2011 - Scilab Enterprises - Clément DAVID
  *
- *  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ */
+
+#include "dynlib_scicos_blocks.h"
+#include "scoUtils.h"
+
+#include "MALLOC.h"
+#include "elementary_functions.h"
+
+#include "getGraphicObjectProperty.h"
+#include "setGraphicObjectProperty.h"
+#include "graphicObjectProperties.h"
+#include "createGraphicObject.h"
+
+#include "CurrentFigure.h"
+
+#include "scicos_block4.h"
+#include "scicos.h"
+
+#include "localization.h"
+
+#include "FigureList.h"
+#include "BuildObjects.h"
+#include "AxesModel.h"
+
+#include <string.h>
+
+/*****************************************************************************
+ * Internal container structure
+ ****************************************************************************/
+
+/**
+ * Container structure
+ */
+typedef struct
+{
+    struct
+    {
+        int numberOfPoints;
+        int maxNumberOfPoints;
+        double ***data;
+    } internal;
+
+    struct
+    {
+        char *cachedFigureUID;
+        char *cachedAxeUID;
+        char **cachedPolylinesUIDs;
+    } scope;
+} sco_data;
+
+/**
+ * Get (and allocate on demand) the internal data used on this scope
+ * \param block the block
+ * \return the scope data
+ */
+static sco_data *getScoData(scicos_block * block);
+
+/**
+ * Release any internal data
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * \param block the block
+ */
+static void freeScoData(scicos_block * block);
+
+/**
+ * Append the data to the current data
+ *
+ * \param block the block
+ * \param x x data
+ * \param y y data
+ */
+static void appendData(scicos_block * block, double *x, double *y);
+
+/**
+ * Push the block data to the polyline
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * \param block the block
+ * \param row the selected row
  *
- * See the file ./license.txt
  */
-/*--------------------------------------------------------------------------*/
+static BOOL pushData(scicos_block * block, int row);
+
+/*****************************************************************************
+ * Graphics utils
+ ****************************************************************************/
+
 /**
-   \file canimxy.c
-   \author Benoit Bayol
-   \version 1.0
-   \date September 2006 - January 2007
-   \brief CANIMXY is a scope in 2D which draw its input as a XY scope, there is animation.
-   \see CANIMXY.sci in macros/scicos_blocks/Sinks/
-*/
-/*--------------------------------------------------------------------------*/
-#include "scoMemoryScope.h"
-#include "scoWindowScope.h"
-#include "scoMisc.h"
-#include "scoGetProperty.h"
-#include "scoSetProperty.h"
-#include "scicos_block4.h"
-#include "DrawingBridge.h"
-#include "MALLOC.h"
-#include "dynlib_scicos_blocks.h"
-/*--------------------------------------------------------------------------*/
-/** \fn canimxy_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
-    \brief Function to draw or redraw the window
+ * Get (and allocate on demand) the figure associated with the block
+ * \param block the block
+ * \return a valid figure UID or NULL on error
+ */
+static char *getFigure(scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the axe associated with the input
+ *
+ * \param pFigureUID the parent figure UID
+ * \param block the block
+ * \param input the current input index (0-indexed)
+ * \return a valid axe UID or NULL on error
+ */
+static char *getAxe(char *pFigureUID, scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the polyline associated with the row
+ *
+ * \param pAxeUID the parent axe UID
+ * \param block the block
+ * \param row the current row index (0-indexed)
+ * \return a valid polyline UID or NULL on error
+ */
+static char *getPolyline(char *pAxeUID, scicos_block * block, int row);
+
+/**
+ * Set the polylines bounds
+ *
+ * \param block the block
+ */
+static BOOL setPolylinesBounds(scicos_block * block);
+
+/*****************************************************************************
+ * Simulation function
+ ****************************************************************************/
+
+/** \fn void cmscope(scicos_block * block,int flag)
+    \brief the computational function
+    \param block A pointer to a scicos_block
+    \param flag An int which indicates the state of the block (init, update, ending)
 */
-SCICOS_BLOCKS_IMPEXP void canimxy_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
+SCICOS_BLOCKS_IMPEXP void canimxy(scicos_block * block, scicos_flag flag)
+{
+    char *pFigureUID;
+    sco_data *sco;
+
+    int j;
+    BOOL result;
+
+    switch (flag)
+    {
+
+    case Initialization:
+        sco = getScoData(block);
+        if (sco == NULL)
+        {
+            set_block_error(-5);
+        }
+        pFigureUID = getFigure(block);
+        if (pFigureUID == NULL)
+        {
+            // allocation error
+            set_block_error(-5);
+        }
+        break;
+
+    case StateUpdate:
+        pFigureUID = getFigure(block);
+
+        appendData(block, (double *)block->inptr[0], (double *)block->inptr[1]);
+        for (j = 0; j < block->insz[0]; j++)
+        {
+            result = pushData(block, j);
+            if (result == FALSE)
+            {
+                Coserror("%s: unable to push some data.", "cscopxy");
+                break;
+            }
+        }
+        break;
+
+    case Ending:
+        freeScoData(block);
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*****************************************************************************
+ *
+ * Container management
+ *
+ ****************************************************************************/
+
+static sco_data *getScoData(scicos_block * block)
 {
-  /* Declarations*/
-  int i = 0;
-  int gomme_color = 0; //As usual
-  int * ipar = NULL; //Integer Parameters
-  int color_flag = 0; //Flag on Color
-  int color[2];
-  int line_size = 0;
-  int animed = 0;
-  int win = 0; //Windows ID : To give a name to the window
-  int buffer_size = 0; //Buffer Size
-  int win_pos[2]; //Position of the Window
-  int win_dim[2]; //Dimension of the Window
-  int nipar = 0;
-  double * rpar = NULL; //Reals parameters
-  double xmin = 0., xmax = 0., ymin = 0., ymax = 0.; //Ymin and Ymax are vectors here
-  scoGraphicalObject Pinceau; //Pointer to each polyline of each axes
-  scoGraphicalObject Gomme; //Pointer to each polyline of each axes
-  scoGraphicalObject Trait; //Pointer to each trache of each axes
-  int number_of_subwin = 0;
-  int number_of_curves_by_subwin = 0;
-  int dimension = 2;
-  int nbr_curves = 0;
-  char *label = NULL;
-
-  /*Retrieving Parameters*/
-  ipar = GetIparPtrs(block);
-  nipar = GetNipar(block);
-  rpar = GetRparPtrs(block);
-  win = ipar[0];
-  color_flag = ipar[1];
-  buffer_size = ipar[2];
-  color[0] = ipar[3];
-  color[1] = ipar[3];
-  line_size = ipar[4];
-  animed = ipar[5];
-  win_pos[0] = ipar[6];
-  win_pos[1] = ipar[7];
-  win_dim[0] = ipar[8];
-  win_dim[1] = ipar[9];
-  nbr_curves = ipar[10];
-  xmin = rpar[0];
-  xmax = rpar[1];
-  ymin = rpar[2];
-  ymax = rpar[3];
-  label = GetLabelPtrs(block);
-  number_of_subwin = 1;
-  /* If only one element to draw*/
-  if (buffer_size == 1)
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j, k, l;
+
+    if (sco == NULL)
     {
-      number_of_curves_by_subwin = nbr_curves;
-      if(firstdraw == 1)
-       {
-         scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
-         scoSetShortDrawSize(*pScopeMemory,0,1);
-         scoSetLongDrawSize(*pScopeMemory,0,0);
-       }
-      scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, NULL, NULL);
-      if(scoGetScopeActivation(*pScopeMemory) == 1)
-       {
-
-         //sciSetPixmapMode(scoGetPointerScopeWindow(*pScopeMemory),TRUE);
-
-         for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(*pScopeMemory, 0) ; i++)
-           {
-             scoAddPolylineForShortDraw(*pScopeMemory,0,i,color[0]);
-             Pinceau = scoGetPointerShortDraw(*pScopeMemory,0,i);
-             pPOLYLINE_FEATURE(Pinceau)->n1 = 1;
-             sciSetMarkSize(Pinceau, line_size);
-
-           }
-       }
+        /*
+         * Data allocation
+         */
+
+        sco = (sco_data *) MALLOC(sizeof(sco_data));
+        if (sco == NULL)
+            goto error_handler_sco;
+
+        sco->internal.numberOfPoints = 0;
+        sco->internal.maxNumberOfPoints = block->ipar[2];
+
+        sco->internal.data = (double ***)CALLOC(block->nin, sizeof(double **));
+        if (sco->internal.data == NULL)
+            goto error_handler_data;
+
+        for (i = 0; i < block->nin; i++)
+        {
+            sco->internal.data[i] = (double **)CALLOC(block->insz[i], sizeof(double *));
+            if (sco->internal.data[i] == NULL)
+                goto error_handler_data_i;
+        }
+        for (i = 0; i < block->nin; i++)
+        {
+            for (j = 0; j < block->insz[i]; j++)
+            {
+                sco->internal.data[i][j] = (double *)CALLOC(block->ipar[2], sizeof(double));
+
+                if (sco->internal.data[i][j] == NULL)
+                    goto error_handler_data_ij;
+            }
+        }
+
+        sco->scope.cachedFigureUID = NULL;
+        sco->scope.cachedAxeUID = NULL;
+
+        sco->scope.cachedPolylinesUIDs = (char **)CALLOC(block->insz[0], sizeof(char **));
+
+        *(block->work) = sco;
     }
-  /*else if 2 or more elements*/
-  else
+
+    return sco;
+
+    /*
+     * Error management (out of normal flow)
+     */
+
+error_handler_data_ij:
+    for (k = 0; k < i; k++)
     {
-      number_of_curves_by_subwin = 2*nbr_curves; //it is a trick to recognize the type of scope, not sure it is a good way because normally a curve is the combination of a short and a longdraw
-      if(firstdraw == 1)
-       {
-         scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
-       }
-
-      scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, NULL, NULL);
-      if(scoGetScopeActivation(*pScopeMemory) == 1)
-       {
-         gomme_color = sciGetBackground(scoGetPointerAxes(*pScopeMemory,0));
-
-
-         if(color[0] <= 0)  /*if mark style*/
-           {
-             if(firstdraw == 1)
-               {
-                 scoSetShortDrawSize(*pScopeMemory,0,1);
-                 scoSetLongDrawSize(*pScopeMemory,0,buffer_size-1);
-               }
-             for(i = 0 ; i < nbr_curves ; i++)
-               {
-                 //because of color[0] is negative it will add a black mark with style number color[0]
-                 scoAddPolylineForShortDraw(*pScopeMemory,0,i,color[0]);
-                 scoAddPolylineForShortDraw(*pScopeMemory,0,i+nbr_curves,color[0]); //same type of mark and black for the rubber
-                 scoAddPolylineForLongDraw(*pScopeMemory,0,i,color[0]);
-
-                 Pinceau = scoGetPointerShortDraw(*pScopeMemory,0,i);
-                 Gomme = scoGetPointerShortDraw(*pScopeMemory,0,i+nbr_curves);
-                 Trait = scoGetPointerLongDraw(*pScopeMemory,0,i);
-
-                 pPOLYLINE_FEATURE(Pinceau)->n1 = 1;
-                 pPOLYLINE_FEATURE(Gomme)->n1 = 1;
-                 sciSetMarkForeground(Gomme, gomme_color); //here the rubber becomes colored like the background of the axes
-                 pPOLYLINE_FEATURE(Trait)->n1 = buffer_size-1;
-
-                 sciSetMarkSize(Pinceau, line_size);
-                 sciSetMarkSize(Gomme, line_size);
-                 sciSetMarkSize(Trait, line_size);
-               }
-           }
-         /*if line style*/
-         else
-           {
-             if(firstdraw == 1)
-               {
-                 scoSetShortDrawSize(*pScopeMemory,0,2);
-                 scoSetLongDrawSize(*pScopeMemory,0,buffer_size-1);
-               }
-             for(i = 0 ; i < nbr_curves ; i++)
-               {
-                 scoAddPolylineForShortDraw(*pScopeMemory,0,i,color[0]);
-                 scoAddPolylineForShortDraw(*pScopeMemory,0,i+nbr_curves,gomme_color);
-                 scoAddPolylineForLongDraw(*pScopeMemory,0,i,color[0]);
-
-                 Pinceau = scoGetPointerShortDraw(*pScopeMemory,0,i);
-                 Gomme = scoGetPointerShortDraw(*pScopeMemory,0,i+nbr_curves);
-                 Trait = scoGetPointerLongDraw(*pScopeMemory,0,i);
-
-                 pPOLYLINE_FEATURE(Pinceau)->n1 = 2;
-                 pPOLYLINE_FEATURE(Gomme)->n1 = 2;
-                 pPOLYLINE_FEATURE(Trait)->n1 = buffer_size-1;
-
-                 sciSetLineWidth(Pinceau, line_size);
-                 sciSetLineWidth(Gomme, line_size);
-                 sciSetLineWidth(Trait, line_size);
-               }
-           }
-       }
+        for (l = 0; l < j; l++)
+        {
+            FREE(sco->internal.data[k][l]);
+        }
     }
-  if(scoGetScopeActivation(*pScopeMemory) == 1)
+    i = block->nin - 1;
+error_handler_data_i:
+    for (j = 0; j < i; j++)
     {
-      scoAddTitlesScope(*pScopeMemory,label,"x","y",NULL);
+        FREE(sco->internal.data[i]);
     }
+    FREE(sco->internal.data);
+error_handler_data:
+    FREE(sco);
+error_handler_sco:
+    // allocation error
+    set_block_error(-5);
+    return NULL;
 }
-/*--------------------------------------------------------------------------*/
-/** \fn void canimxy(scicos_block * block, int flag)
-    \brief the computational function
-    \param block A pointer to a scicos_block
-    \param flag An int which indicates the state of the block (init, update, ending)
-*/
-SCICOS_BLOCKS_IMPEXP void canimxy(scicos_block * block, int flag)
+
+static void freeScoData(scicos_block * block)
 {
-  /*Declarations*/
-  ScopeMemory * pScopeMemory = NULL;
-  double *u1 = NULL,*u2 = NULL;
-  scoGraphicalObject pLongDraw;
-  int i = 0;
-  /* State Machine Control */
-  switch(flag)
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+
+    if (sco != NULL)
     {
-    case Initialization:
-      {
-       canimxy_draw(block,&pScopeMemory,1);
-       break; //Break of the switch condition don t forget it
-      } //End of Initialization
+        for (i = 0; i < block->nin; i++)
+        {
+            for (j = 0; j < block->insz[i]; j++)
+            {
+                FREE(sco->internal.data[i][j]);
+            }
+            FREE(sco->internal.data[i]);
+        }
 
-    case StateUpdate:
-      {
-       scoRetrieveScopeMemory(block->work,&pScopeMemory);
-       if(scoGetScopeActivation(pScopeMemory) == 1)
-         {
-
-           /* Charging Elements */
-           if (scoGetPointerScopeWindow(pScopeMemory) == NULL) // If the window has been destroyed we recreate it
-             {
-               canimxy_draw(block,&pScopeMemory,0);
-             }
-
-           /*Retrieve Elements*/
-           u1 = GetRealInPortPtrs(block,1);
-           u2 = GetRealInPortPtrs(block,2);
-
-           scoDrawScopeAnimXYStyle(pScopeMemory,u1,u2,NULL);
-         }
-       break; //Break of the switch don t forget it !
-      }//End of stateupdate
-
-      //This case is activated when the simulation is done or when we close scicos
-    case Ending:
-      {
-       scoRetrieveScopeMemory(block->work, &pScopeMemory);
-       if(scoGetScopeActivation(pScopeMemory) == 1)
-         {
-           /* Check if figure is still opened, otherwise, don't try to destroy it again. */
-           scoGraphicalObject figure = scoGetPointerScopeWindow(pScopeMemory);
-           if (figure != NULL)
-             {
-               if(scoGetLongDrawSize(pScopeMemory,0) == 0)
-                 {
-                   for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0) ; i++)
-                     {
-                       pLongDraw = scoGetPointerLongDraw(pScopeMemory,0,i);
-                       forceRedraw(pLongDraw);
-                     }
-                 }
-               else
-                 {
-                   for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0)/2 ; i++)
-                     {
-                       pLongDraw = scoGetPointerLongDraw(pScopeMemory,0,i);
-                       forceRedraw(pLongDraw);
-                     }
-                 }
-               clearUserData(figure);
-             }
-         }
-       scoFreeScopeMemory(block->work, &pScopeMemory);
-       break; //Break of the switch
-      }
-      //free the memory which is allocated at each turn by some variables
+        FREE(sco->internal.data);
+
+//      Commented due to the C++ allocation
+//      see http://bugzilla.scilab.org/show_bug.cgi?id=9747
+//      FREE(sco->scope.cachedFigureUID);
+//      sco->scope.cachedFigureUID = NULL;
+//      for (i=0; i<block->nin; i++) {
+//          for (j=0; j<block->insz[i]; j++) {
+//              FREE(sco->scope.cachedPolylinesUIDs[i][j]);
+//              sco->scope.cachedPolylinesUIDs[i][j] = NULL;
+//          }
+//          FREE(sco->scope.cachedAxeUID[i]);
+//          sco->scope.cachedAxeUID[i] = NULL;
+//      }
+
+        FREE(sco);
+    }
+}
 
+static void appendData(scicos_block * block, double *x, double *y)
+{
+    int i;
+
+    sco_data *sco = (sco_data *) * (block->work);
+    int maxNumberOfPoints = sco->internal.maxNumberOfPoints;
+    int numberOfPoints = sco->internal.numberOfPoints;
+
+    /*
+     * Handle the case where the scope has more points than maxNumberOfPoints
+     */
+    if (sco != NULL && numberOfPoints >= maxNumberOfPoints)
+    {
+        unsigned int setLen = (unsigned int)maxNumberOfPoints - 1;
+
+        // on a full scope, push data
+        for (i = 0; i < block->insz[0]; i++)
+        {
+            sco->internal.data[0][i][setLen] = x[i];
+            memmove(sco->internal.data[0][i], &sco->internal.data[0][i][1], setLen * sizeof(double));
+
+            sco->internal.data[1][i][setLen] = y[i];
+            memmove(sco->internal.data[1][i], &sco->internal.data[1][i][1], setLen * sizeof(double));
+        }
+
+        // then return
+        return;
+    }
+
+    /*
+     * Update data
+     */
+    if (sco != NULL)
+    {
+        int setLen;
+
+        for (i = 0; i < block->insz[0]; i++)
+        {
+            for (setLen = maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+            {
+                sco->internal.data[0][i][numberOfPoints + setLen] = x[i];
+                sco->internal.data[1][i][numberOfPoints + setLen] = y[i];
+            }
+        }
+
+        sco->internal.numberOfPoints++;
+    }
+}
+
+static BOOL pushData(scicos_block * block, int row)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pPolylineUID;
+
+    double *x;
+    double *y;
+    sco_data *sco;
+
+    BOOL result = TRUE;
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+    pPolylineUID = getPolyline(pAxeUID, block, row);
+
+    sco = getScoData(block);
+    if (sco == NULL)
+        return FALSE;
+
+    // select the right input and row
+    x = sco->internal.data[0][row];
+    y = sco->internal.data[1][row];
+
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_X__, x, jni_double_vector, sco->internal.maxNumberOfPoints);
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_Y__, y, jni_double_vector, sco->internal.maxNumberOfPoints);
+
+    return result;
+}
+
+/*****************************************************************************
+ *
+ * Graphic utils
+ *
+ ****************************************************************************/
+
+/**
+ * Set properties on the figure.
+ *
+ * \param pFigureUID the figure uid
+ * \param block the current block
+ */
+static void setFigureSettings(char *pFigureUID, scicos_block * block)
+{
+    int win_pos[2];
+    int win_dim[2];
+
+    int *ipar = block->ipar;
+
+    win_pos[0] = ipar[6];
+    win_pos[1] = ipar[7];
+    win_dim[0] = ipar[8];
+    win_dim[1] = ipar[9];
+
+    setGraphicObjectProperty(pFigureUID, __GO_POSITION__, &win_pos, jni_int_vector, 2);
+    setGraphicObjectProperty(pFigureUID, __GO_SIZE__, &win_dim, jni_int_vector, 2);
+};
+
+/*****************************************************************************
+ *
+ * Graphic
+ *
+ ****************************************************************************/
+
+static char *getFigure(scicos_block * block)
+{
+    signed int figNum;
+    char *pFigureUID = NULL;
+    char *pAxe = NULL;
+    static const int i__1 = 1;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedFigureUID != NULL)
+    {
+        return sco->scope.cachedFigureUID;
+    }
+
+    figNum = block->ipar[0];
+
+    // with a negative id, use the block number indexed from a constant.
+    if (figNum < 0)
+    {
+        figNum = 20000 + get_block_number();
+    }
+
+    pFigureUID = getFigureFromIndex(figNum);
+    // create on demand
+    if (pFigureUID == NULL)
+    {
+        pFigureUID = createNewFigureWithAxes();
+        setGraphicObjectProperty(pFigureUID, __GO_ID__, &figNum, jni_int, 1);
+
+        // set configured parameters
+        setFigureSettings(pFigureUID, block);
+        sco->scope.cachedFigureUID = pFigureUID;
+
+        // allocate the axes through the getter
+        pAxe = getAxe(pFigureUID, block);
+
+        /*
+         * Setup according to block settings
+         */
+        setLabel(pAxe, __GO_X_AXIS_LABEL__, "x");
+        setLabel(pAxe, __GO_Y_AXIS_LABEL__, "y");
+
+        setGraphicObjectProperty(pAxe, __GO_X_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+        setGraphicObjectProperty(pAxe, __GO_Y_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+
+        setPolylinesBounds(block);
+    }
+
+    if (sco->scope.cachedFigureUID == NULL)
+    {
+        sco->scope.cachedFigureUID = pFigureUID;
+    }
+    return pFigureUID;
+}
+
+static char *getAxe(char *pFigureUID, scicos_block * block)
+{
+    char *pAxe;
+    int i;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedAxeUID != NULL)
+    {
+        return sco->scope.cachedAxeUID;
+    }
+
+    pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, 0);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pAxe == NULL)
+    {
+        pAxe = cloneGraphicObject(getAxesModel());
+
+        if (pAxe != NULL)
+        {
+            setGraphicObjectRelationship(pFigureUID, pAxe);
+
+            // allocate the polylines through the getter
+            for (i = 0; i < block->insz[0]; i++)
+            {
+                getPolyline(pAxe, block, i);
+            }
+        }
+    }
+
+    if (sco->scope.cachedAxeUID == NULL)
+    {
+        sco->scope.cachedAxeUID = pAxe;
+    }
+    return pAxe;
+}
+
+static char *getPolyline(char *pAxeUID, scicos_block * block, int row)
+{
+    char *pPolyline;
+    static double d__0 = 0.0;
+    static BOOL b__true = TRUE;
+
+    int color;
+    int markSize;
+    double lineThickness;
+
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedPolylinesUIDs != NULL && sco->scope.cachedPolylinesUIDs[row] != NULL)
+    {
+        return sco->scope.cachedPolylinesUIDs[row];
     }
+
+    pPolyline = findChildWithKindAt(pAxeUID, __GO_POLYLINE__, row);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pPolyline == NULL)
+    {
+        pPolyline = createGraphicObject(__GO_POLYLINE__);
+
+        if (pPolyline != NULL)
+        {
+            createDataObject(pPolyline, __GO_POLYLINE__);
+            setGraphicObjectRelationship(pAxeUID, pPolyline);
+
+            /*
+             * Default setup (will crash if removed)
+             */
+            {
+                int polylineSize[2] = { 1, block->ipar[2] };
+                setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
+            }
+
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_X__, &d__0, jni_double_vector, 1);
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_Y__, &d__0, jni_double_vector, 1);
+
+            color = block->ipar[3];
+            markSize = block->ipar[4];
+            lineThickness = (double)markSize;
+            if (color > 0)
+            {
+                setGraphicObjectProperty(pPolyline, __GO_LINE_MODE__, &b__true, jni_bool, 1);
+
+                setGraphicObjectProperty(pPolyline, __GO_LINE_COLOR__, &color, jni_int, 1);
+                setGraphicObjectProperty(pPolyline, __GO_LINE_THICKNESS__, &lineThickness, jni_double, 1);
+            }
+            else
+            {
+                color = -color;
+                setGraphicObjectProperty(pPolyline, __GO_MARK_MODE__, &b__true, jni_bool, 1);
+
+                setGraphicObjectProperty(pPolyline, __GO_MARK_STYLE__, &color, jni_int, 1);
+                setGraphicObjectProperty(pPolyline, __GO_MARK_SIZE__, &markSize, jni_int, 1);
+            }
+        }
+    }
+
+    if (sco->scope.cachedPolylinesUIDs != NULL)
+    {
+        sco->scope.cachedPolylinesUIDs[row] = pPolyline;
+    }
+    return pPolyline;
+}
+
+static BOOL setPolylinesBounds(scicos_block * block)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+
+    double dataBounds[6];
+
+    dataBounds[0] = block->rpar[0]; // xMin
+    dataBounds[1] = block->rpar[1]; // xMax
+    dataBounds[2] = block->rpar[2]; // yMin
+    dataBounds[3] = block->rpar[3]; // yMax
+    dataBounds[4] = -1.0;       // zMin
+    dataBounds[5] = 1.0;        // zMax
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+
+    return setGraphicObjectProperty(pAxeUID, __GO_DATA_BOUNDS__, dataBounds, jni_double_vector, 6);
 }
-/*--------------------------------------------------------------------------*/
index c9339f2..f1f4588 100644 (file)
-/*  Scicos
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2011 - DIGITEO - Clément DAVID
  *
- *  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ */
+
+#include "dynlib_scicos_blocks.h"
+#include "scoUtils.h"
+
+#include "MALLOC.h"
+#include "elementary_functions.h"
+
+#include "getGraphicObjectProperty.h"
+#include "setGraphicObjectProperty.h"
+#include "graphicObjectProperties.h"
+#include "createGraphicObject.h"
+
+#include "CurrentFigure.h"
+
+#include "scicos_block4.h"
+#include "scicos.h"
+
+#include "localization.h"
+
+#include "FigureList.h"
+#include "BuildObjects.h"
+#include "AxesModel.h"
+
+#include <string.h>
+
+/*****************************************************************************
+ * Internal container structure
+ ****************************************************************************/
+
+/**
+ * Container structure
+ */
+typedef struct
+{
+    struct
+    {
+        int numberOfPoints;
+        int maxNumberOfPoints;
+        double ***data;
+    } internal;
+
+    struct
+    {
+        char *cachedFigureUID;
+        char *cachedAxeUID;
+        char **cachedPolylinesUIDs;
+    } scope;
+} sco_data;
+
+/**
+ * Get (and allocate on demand) the internal data used on this scope
+ * \param block the block
+ * \return the scope data
+ */
+static sco_data *getScoData(scicos_block * block);
+
+/**
+ * Release any internal data
+ *
+ * \param block the block
+ */
+static void freeScoData(scicos_block * block);
+
+/**
+ * Append the data to the current data
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * \param block the block
+ * \param x x data
+ * \param y y data
+ * \param z z data
+ */
+static void appendData(scicos_block * block, double *x, double *y, double *z);
+
+/**
+ * Push the block data to the polyline
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * \param block the block
+ * \param row the selected row
  *
- * See the file ./license.txt
  */
-/*--------------------------------------------------------------------------*/
+static BOOL pushData(scicos_block * block, int row);
+
+/*****************************************************************************
+ * Graphics utils
+ ****************************************************************************/
+
 /**
-   \file canimxy3d.c
-   \author Benoit Bayol
-   \version 1.0
-   \date September 2006 - January 2007
-   \brief CANIMXY3D is a scope in 3D which draw its input as a XY scope, there is animation.
-   \see CANIMXY3D.sci in macros/scicos_blocks/Sinks/
-*/
-/*--------------------------------------------------------------------------*/
-#include "scoMemoryScope.h"
-#include "scoWindowScope.h"
-#include "scoMisc.h"
-#include "scoGetProperty.h"
-#include "scoSetProperty.h"
-#include "scicos_block4.h"
-#include "DrawingBridge.h"
-#include "scicos_malloc.h"
-#include "scicos_free.h"
-#include "MALLOC.h"
-#include "dynlib_scicos_blocks.h"
-/*--------------------------------------------------------------------------*/
-/** \fn canimxy3d_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
-    \brief Function to draw or redraw the window
+ * Get (and allocate on demand) the figure associated with the block
+ * \param block the block
+ * \return a valid figure UID or NULL on error
+ */
+static char *getFigure(scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the axe associated with the input
+ *
+ * \param pFigureUID the parent figure UID
+ * \param block the block
+ * \param input the current input index (0-indexed)
+ * \return a valid axe UID or NULL on error
+ */
+static char *getAxe(char *pFigureUID, scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the polyline associated with the row
+ *
+ * \param pAxeUID the parent axe UID
+ * \param block the block
+ * \param row the current row index (0-indexed)
+ * \return a valid polyline UID or NULL on error
+ */
+static char *getPolyline(char *pAxeUID, scicos_block * block, int row);
+
+/**
+ * Set the polylines bounds
+ *
+ * \param block the block
+ */
+static BOOL setPolylinesBounds(scicos_block * block);
+
+/*****************************************************************************
+ * Simulation function
+ ****************************************************************************/
+
+/** \fn void cmscope(scicos_block * block,int flag)
+    \brief the computational function
+    \param block A pointer to a scicos_block
+    \param flag An int which indicates the state of the block (init, update, ending)
 */
-SCICOS_BLOCKS_IMPEXP void canimxy3d_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
+SCICOS_BLOCKS_IMPEXP void canimxy3d(scicos_block * block, scicos_flag flag)
 {
-  int i = 0; //As usual
-  int * ipar = NULL; //Integer Parameters
-  int color_number = 0; //Flag on Color
-  int * color = NULL;
-  int * line_size = NULL;
-  int nbr_curves = 0;
-  int animed = 0;
-  int win = 0; //Windows ID : To give a name to the window
-  int buffer_size = 0; //Buffer Size
-  int win_pos[2]; //Position of the Window
-  int win_dim[2]; //Dimension of the Window
-  int nipar = 0;
-  double * rpar = NULL; //Reals parameters
-  double xmin = 0., xmax = 0., ymin = 0., ymax = 0., zmin = 0., zmax = 0.,alpha = 0.,theta = 0.; //Ymin and Ymax are vectors here
-  scoGraphicalObject Pinceau; //Pointer to each polyline of each axes
-  scoGraphicalObject Gomme; //Pointer to each polyline of each axes
-  scoGraphicalObject Trait; //Pointer to each trache of each axes
-  int number_of_subwin = 0;
-  int number_of_curves_by_subwin = 0;
-  int dimension = 3;
-  int gomme_color = 0;
-  int size=0;
-  char *label = NULL;
-
-  ipar = GetIparPtrs(block);
-  nipar = GetNipar(block);
-  rpar = GetRparPtrs(block);
-  win = ipar[0];
-  color_number = ipar[1];
-  buffer_size = ipar[2];
-  label = GetLabelPtrs(block);
-
-  color = (int*)scicos_malloc(color_number*sizeof(int));
-  line_size = (int*)scicos_malloc(color_number*sizeof(int));
-  for(i = 0 ; i < color_number ; i++)
+    char *pFigureUID;
+
+    sco_data *sco;
+
+    int j;
+    BOOL result;
+
+    switch (flag)
     {
-      color[i] = ipar[i+3];
-      line_size[i] = ipar[i+3+color_number];
+
+    case Initialization:
+        sco = getScoData(block);
+        if (sco == NULL)
+        {
+            set_block_error(-5);
+        }
+        pFigureUID = getFigure(block);
+        if (pFigureUID == NULL)
+        {
+            // allocation error
+            set_block_error(-5);
+        }
+        break;
+
+    case StateUpdate:
+        pFigureUID = getFigure(block);
+
+        appendData(block, (double *)block->inptr[0], (double *)block->inptr[1], (double *)block->inptr[2]);
+        for (j = 0; j < block->insz[0]; j++)
+        {
+            result = pushData(block, j);
+            if (result == FALSE)
+            {
+                Coserror("%s: unable to push some data.", "cscopxy3d");
+                break;
+            }
+        }
+        break;
+
+    case Ending:
+        freeScoData(block);
+        break;
+
+    default:
+        break;
     }
-  size = 2*color_number;
-  animed = ipar[size+3];
-  win_pos[0] = ipar[size+4];
-  win_pos[1] = ipar[size+5];
-  win_dim[0] = ipar[size+6];
-  win_dim[1] = ipar[size+7];
-  xmin = rpar[0];
-  xmax = rpar[1];
-  ymin = rpar[2];
-  ymax = rpar[3];
-  zmin = rpar[4];
-  zmax = rpar[5];
-  alpha = rpar[6];
-  theta = rpar[7];
-  number_of_subwin = 1;
-  nbr_curves = ipar[size+8];
-
-
-  /* If only one element to draw*/
-  if (buffer_size == 1)
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*****************************************************************************
+ *
+ * Container management
+ *
+ ****************************************************************************/
+
+static sco_data *getScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j, k, l;
+
+    if (sco == NULL)
     {
-      number_of_curves_by_subwin = nbr_curves;
-      if(firstdraw == 1)
-       {
-         scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
-         scoSetShortDrawSize(*pScopeMemory,0,1);
-         scoSetLongDrawSize(*pScopeMemory,0,0);
-       }
-
-      scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, &zmin, &zmax);
-      if(scoGetScopeActivation(*pScopeMemory) == 1)
-       {
-         sciSetPixmapMode(scoGetPointerScopeWindow(*pScopeMemory),TRUE);
-         pFIGURE_FEATURE(scoGetPointerScopeWindow(*pScopeMemory))->pixmapMode = 1;
-
-         for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(*pScopeMemory, 0) ; i++)
-           {
-             scoAddPolylineForShortDraw(*pScopeMemory,0,i,color[i]);
-             Pinceau = scoGetPointerShortDraw(*pScopeMemory,0,i);
-
-             sciSetMarkSize(Pinceau, line_size[i]);
-
-             pPOLYLINE_FEATURE(Pinceau)->n1 = 1;
-           }
-       }
+        /*
+         * Data allocation
+         */
+
+        sco = (sco_data *) MALLOC(sizeof(sco_data));
+        if (sco == NULL)
+            goto error_handler_sco;
+
+        sco->internal.numberOfPoints = 0;
+        sco->internal.maxNumberOfPoints = block->ipar[2];
+
+        sco->internal.data = (double ***)CALLOC(block->nin, sizeof(double **));
+        if (sco->internal.data == NULL)
+            goto error_handler_data;
+
+        for (i = 0; i < block->nin; i++)
+        {
+            sco->internal.data[i] = (double **)CALLOC(block->insz[i], sizeof(double *));
+            if (sco->internal.data[i] == NULL)
+                goto error_handler_data_i;
+        }
+        for (i = 0; i < block->nin; i++)
+        {
+            for (j = 0; j < block->insz[i]; j++)
+            {
+                sco->internal.data[i][j] = (double *)CALLOC(block->ipar[2], sizeof(double));
+
+                if (sco->internal.data[i][j] == NULL)
+                    goto error_handler_data_ij;
+            }
+        }
+
+        sco->scope.cachedFigureUID = NULL;
+        sco->scope.cachedAxeUID = NULL;
+
+        sco->scope.cachedPolylinesUIDs = (char **)CALLOC(block->insz[0], sizeof(char **));
+
+        *(block->work) = sco;
     }
-  /*else if 2 or more elements*/
-  else
+
+    return sco;
+
+    /*
+     * Error management (out of normal flow)
+     */
+
+error_handler_data_ij:
+    for (k = 0; k < i; k++)
     {
-      number_of_curves_by_subwin = 2*nbr_curves; //it is a trick to recognize the type of scope, not sure it is a good way because normally a curve is the combination of a short and a longdraw
-      if(firstdraw == 1)
-       {
-         scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
-       }
-      scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, &zmin, &zmax);
-      if(scoGetScopeActivation(*pScopeMemory) == 1)
-       {
-         gomme_color = sciGetBackground(scoGetPointerAxes(*pScopeMemory,0));
-
-          if(firstdraw == 1) {
-            scoSetShortDrawSize(*pScopeMemory,0,2);
-            scoSetLongDrawSize(*pScopeMemory,0,buffer_size);
-          }
-
-          for(i = 0 ; i < nbr_curves ; i++) {
-            /*if mark style*/
-            if (color[i]<=0) {
-              //because of color[0] is negative it will add a black mark with style number color[0]
-              scoAddPolylineForShortDraw(*pScopeMemory,0,i,color[i]);
-              scoAddPolylineForShortDraw(*pScopeMemory,0,i+nbr_curves,color[i]); //same type of mark and black for the rubber
-              scoAddPolylineForLongDraw(*pScopeMemory,0,i,color[i]);
-
-              Pinceau = scoGetPointerShortDraw(*pScopeMemory,0,i);
-              Gomme = scoGetPointerShortDraw(*pScopeMemory,0,i+nbr_curves);
-              Trait = scoGetPointerLongDraw(*pScopeMemory,0,i);
-
-              sciSetMarkSize(Pinceau, line_size[i]);
-              sciSetMarkSize(Gomme, line_size[i]);
-              sciSetMarkSize(Trait, line_size[i]);
-
-              pPOLYLINE_FEATURE(Pinceau)->n1 = 1;
-              pPOLYLINE_FEATURE(Gomme)->n1 = 1;
-              sciSetMarkForeground(Gomme, gomme_color); //here the rubber becomes colored like the background of the axes
-              pPOLYLINE_FEATURE(Trait)->n1 = buffer_size-1;
+        for (l = 0; l < j; l++)
+        {
+            FREE(sco->internal.data[k][l]);
+        }
+    }
+    i = block->nin - 1;
+error_handler_data_i:
+    for (j = 0; j < i; j++)
+    {
+        FREE(sco->internal.data[i]);
+    }
+    FREE(sco->internal.data);
+error_handler_data:
+    FREE(sco);
+error_handler_sco:
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
+
+static void freeScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+
+    if (sco != NULL)
+    {
+        for (i = 0; i < block->nin; i++)
+        {
+            for (j = 0; j < block->insz[i]; j++)
+            {
+                FREE(sco->internal.data[i][j]);
             }
-            /*if line style*/
-            else {
-              scoAddPolylineForShortDraw(*pScopeMemory,0,i,color[i]);
-              scoAddPolylineForShortDraw(*pScopeMemory,0,i+nbr_curves,gomme_color);
-              scoAddPolylineForLongDraw(*pScopeMemory,0,i,color[i]);
-
-              Pinceau = scoGetPointerShortDraw(*pScopeMemory,0,i);
-              Gomme = scoGetPointerShortDraw(*pScopeMemory,0,i+nbr_curves);
-              Trait = scoGetPointerLongDraw(*pScopeMemory,0,i);
-
-              sciSetLineWidth(Pinceau, line_size[i]);
-              sciSetLineWidth(Gomme, line_size[i]);
-              sciSetLineWidth(Trait, line_size[i]);
-
-              pPOLYLINE_FEATURE(Pinceau)->n1 = 2;
-              pPOLYLINE_FEATURE(Gomme)->n1 = 2;
-              pPOLYLINE_FEATURE(Trait)->n1 = buffer_size;
+            FREE(sco->internal.data[i]);
+        }
+
+        FREE(sco->internal.data);
+
+//      Commented due to the C++ allocation
+//      see http://bugzilla.scilab.org/show_bug.cgi?id=9747
+//      FREE(sco->scope.cachedFigureUID);
+//      sco->scope.cachedFigureUID = NULL;
+//      for (i=0; i<block->nin; i++) {
+//          for (j=0; j<block->insz[i]; j++) {
+//              FREE(sco->scope.cachedPolylinesUIDs[i][j]);
+//              sco->scope.cachedPolylinesUIDs[i][j] = NULL;
+//          }
+//          FREE(sco->scope.cachedAxeUID[i]);
+//          sco->scope.cachedAxeUID[i] = NULL;
+//      }
+
+        FREE(sco);
+    }
+}
+
+static void appendData(scicos_block * block, double *x, double *y, double *z)
+{
+    int i;
+
+    sco_data *sco = (sco_data *) * (block->work);
+    int maxNumberOfPoints = sco->internal.maxNumberOfPoints;
+    int numberOfPoints = sco->internal.numberOfPoints;
+
+    /*
+     * Handle the case where the scope has more points than maxNumberOfPoints
+     */
+    if (sco != NULL && numberOfPoints >= maxNumberOfPoints)
+    {
+        unsigned int setLen = (unsigned int)maxNumberOfPoints - 1;
+
+        // on a full scope, push data
+        for (i = 0; i < block->insz[0]; i++)
+        {
+            sco->internal.data[0][i][setLen] = x[i];
+            memmove(sco->internal.data[0][i], &sco->internal.data[0][i][1], setLen * sizeof(double));
+
+            sco->internal.data[1][i][setLen] = y[i];
+            memmove(sco->internal.data[1][i], &sco->internal.data[1][i][1], setLen * sizeof(double));
+
+            sco->internal.data[2][i][setLen] = z[i];
+            memmove(sco->internal.data[2][i], &sco->internal.data[2][i][1], setLen * sizeof(double));
+        }
+
+        // then return
+        return;
+    }
+
+    /*
+     * Update data
+     */
+    if (sco != NULL)
+    {
+        int setLen;
+
+        for (i = 0; i < block->insz[0]; i++)
+        {
+            for (setLen = maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+            {
+                sco->internal.data[0][i][numberOfPoints + setLen] = x[i];
+                sco->internal.data[1][i][numberOfPoints + setLen] = y[i];
+                sco->internal.data[2][i][numberOfPoints + setLen] = z[i];
             }
-          }
+        }
+
+        sco->internal.numberOfPoints++;
+    }
+}
+
+static BOOL pushData(scicos_block * block, int row)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pPolylineUID;
+
+    double *x;
+    double *y;
+    double *z;
+    sco_data *sco;
+
+    BOOL result = TRUE;
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+    pPolylineUID = getPolyline(pAxeUID, block, row);
+
+    sco = getScoData(block);
+    if (sco == NULL)
+        return FALSE;
+
+    // select the right input and row
+    x = sco->internal.data[0][row];
+    y = sco->internal.data[1][row];
+    z = sco->internal.data[2][row];
+
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_X__, x, jni_double_vector, sco->internal.maxNumberOfPoints);
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_Y__, y, jni_double_vector, sco->internal.maxNumberOfPoints);
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_Z__, z, jni_double_vector, sco->internal.maxNumberOfPoints);
+
+    return result;
+}
+
+/*****************************************************************************
+ *
+ * Graphic utils
+ *
+ ****************************************************************************/
+
+/**
+ * Set properties on the figure.
+ *
+ * \param pFigureUID the figure uid
+ * \param block the current block
+ */
+static void setFigureSettings(char *pFigureUID, scicos_block * block)
+{
+    int win_pos[2];
+    int win_dim[2];
+
+    int *ipar = block->ipar;
+    int nipar = block->nipar;
+
+    win_pos[0] = ipar[nipar - 5];
+    win_pos[1] = ipar[nipar - 4];
+    win_dim[0] = ipar[nipar - 3];
+    win_dim[1] = ipar[nipar - 2];
+
+    setGraphicObjectProperty(pFigureUID, __GO_POSITION__, &win_pos, jni_int_vector, 2);
+    setGraphicObjectProperty(pFigureUID, __GO_SIZE__, &win_dim, jni_int_vector, 2);
+};
+
+/*****************************************************************************
+ *
+ * Graphic
+ *
+ ****************************************************************************/
+
+static char *getFigure(scicos_block * block)
+{
+    signed int figNum;
+    char *pFigureUID = NULL;
+    char *pAxe = NULL;
+    static const int i__1 = 1;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedFigureUID != NULL)
+    {
+        return sco->scope.cachedFigureUID;
+    }
+
+    figNum = block->ipar[0];
+
+    // with a negative id, use the block number indexed from a constant.
+    if (figNum < 0)
+    {
+        figNum = 20000 + get_block_number();
+    }
+
+    pFigureUID = getFigureFromIndex(figNum);
+    // create on demand
+    if (pFigureUID == NULL)
+    {
+        pFigureUID = createNewFigureWithAxes();
+        setGraphicObjectProperty(pFigureUID, __GO_ID__, &figNum, jni_int, 1);
+
+        // set configured parameters
+        setFigureSettings(pFigureUID, block);
+        sco->scope.cachedFigureUID = pFigureUID;
+
+        // allocate the axes through the getter
+        pAxe = getAxe(pFigureUID, block);
 
-       }
+        /*
+         * Setup according to block settings
+         */
+        setLabel(pAxe, __GO_X_AXIS_LABEL__, "x");
+        setLabel(pAxe, __GO_Y_AXIS_LABEL__, "y");
+        setLabel(pAxe, __GO_Z_AXIS_LABEL__, "z");
+
+        setGraphicObjectProperty(pAxe, __GO_X_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+        setGraphicObjectProperty(pAxe, __GO_Y_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+        setGraphicObjectProperty(pAxe, __GO_Z_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+
+        setPolylinesBounds(block);
     }
-  if(scoGetScopeActivation(*pScopeMemory) == 1)
+
+    if (sco->scope.cachedFigureUID == NULL)
+    {
+        sco->scope.cachedFigureUID = pFigureUID;
+    }
+    return pFigureUID;
+}
+
+static char *getAxe(char *pFigureUID, scicos_block * block)
+{
+    char *pAxe;
+    int i;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedAxeUID != NULL)
+    {
+        return sco->scope.cachedAxeUID;
+    }
+
+    pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, 0);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pAxe == NULL)
     {
-      pSUBWIN_FEATURE(scoGetPointerAxes(*pScopeMemory,0))->alpha = alpha;
-      pSUBWIN_FEATURE(scoGetPointerAxes(*pScopeMemory,0))->theta = theta;
+        pAxe = cloneGraphicObject(getAxesModel());
 
-      scoAddTitlesScope(*pScopeMemory,label,"x","y","z");
+        if (pAxe != NULL)
+        {
+            setGraphicObjectRelationship(pFigureUID, pAxe);
+
+            // allocate the polylines through the getter
+            for (i = 0; i < block->insz[0]; i++)
+            {
+                getPolyline(pAxe, block, i);
+            }
+        }
     }
-  scicos_free(color);
-  scicos_free(line_size);
+
+    if (sco->scope.cachedAxeUID == NULL)
+    {
+        sco->scope.cachedAxeUID = pAxe;
+    }
+    return pAxe;
 }
-/*--------------------------------------------------------------------------*/
-/** \fn void canimxy3d(scicos_block * block, int flag)
-    \brief the computational function
-    \param block A pointer to a scicos_block
-    \param flag An int which indicates the state of the block (init, update, ending)
-*/
-SCICOS_BLOCKS_IMPEXP void canimxy3d(scicos_block * block, int flag)
+
+static char *getPolyline(char *pAxeUID, scicos_block * block, int row)
 {
-  /* Declarations*/
-  double *u1 = NULL,*u2 = NULL,*u3 = NULL;
-  int i = 0;
-  ScopeMemory * pScopeMemory = NULL;
-  scoGraphicalObject pLongDraw;
-  /* State Machine Control */
-  switch(flag)
+    char *pPolyline;
+    static double d__0 = 0.0;
+    static int i__1 = 1;
+    static BOOL b__true = TRUE;
+
+    int color;
+    int markSize;
+    double lineThickness;
+
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedPolylinesUIDs != NULL && sco->scope.cachedPolylinesUIDs[row] != NULL)
     {
-    case Initialization:
-      {
+        return sco->scope.cachedPolylinesUIDs[row];
+    }
 
-       canimxy3d_draw(block,&pScopeMemory,1);
-       break; //Break of the switch condition don t forget it
-      } //End of Initialization
+    pPolyline = findChildWithKindAt(pAxeUID, __GO_POLYLINE__, row);
 
-    case StateUpdate:
-      {
-       scoRetrieveScopeMemory(block->work,&pScopeMemory);
-       if(scoGetScopeActivation(pScopeMemory) == 1)
-         {
-           /* Charging Elements */
-           if (scoGetPointerScopeWindow(pScopeMemory) == NULL) // If the window has been destroyed we recreate it
-             {
-               canimxy3d_draw(block,&pScopeMemory,0);
-             }
-
-           /*Retrieve Elements*/
-           u1 = GetRealInPortPtrs(block,1);
-           u2 = GetRealInPortPtrs(block,2);
-           u3 = GetRealInPortPtrs(block,3);
-
-           scoDrawScopeAnimXYStyle(pScopeMemory,u1,u2,u3);
-         }
-       break; //Break of the switch don t forget it !
-      }//End of stateupdate
-
-      //This case is activated when the simulation is done or when we close scicos
-    case Ending:
-      {
-                               scoRetrieveScopeMemory(block->work, &pScopeMemory);
-                               if(scoGetScopeActivation(pScopeMemory) == 1)
-                               {
-                                       /* sciSetUsedWindow(scoGetWindowID(pScopeMemory)); */
-                                       /* Check if figure is still opened, otherwise, don't try to destroy it again. */
-                                       scoGraphicalObject figure = scoGetPointerScopeWindow(pScopeMemory);
-                                       if (figure != NULL)
-                                       {
-                                               if(scoGetLongDrawSize(pScopeMemory,0) == 0)
-                                               {
-                                                       for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0) ; i++)
-                                                       {
-                                                               pLongDraw = scoGetPointerLongDraw(pScopeMemory,0,i);
-                                                               forceRedraw(pLongDraw);
-                                                       }
-                                               }
-                                               else
-                                               {
-                                                       for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0)/2 ; i++)
-                                                       {
-                                                               pLongDraw = scoGetPointerLongDraw(pScopeMemory,0,i);
-                                                               forceRedraw(pLongDraw);
-                                                       }
-                                               }
-
-                                               /* pShortDraw = sciGetCurrentFigure(); */
-                                               /*pShortDraw = scoGetPointerScopeWindow(pScopeMemory);*/
-                                               /*pFIGURE_FEATURE(pShortDraw)->user_data = NULL;*/
-                                               /*pFIGURE_FEATURE(pShortDraw)->size_of_user_data = 0;*/
-                                               clearUserData(figure);
-                                       }
-                               }
-                               scoFreeScopeMemory(block->work, &pScopeMemory);
-                               break; //Break of the switch
-      }
-      //free the memory which is allocated at each turn by some variables
+    /*
+     * Allocate if necessary
+     */
+    if (pPolyline == NULL)
+    {
+        pPolyline = createGraphicObject(__GO_POLYLINE__);
+
+        if (pPolyline != NULL)
+        {
+            createDataObject(pPolyline, __GO_POLYLINE__);
+            setGraphicObjectRelationship(pAxeUID, pPolyline);
 
+            /*
+             * Default setup (will crash if removed)
+             */
+            {
+                int polylineSize[2] = { 1, block->ipar[2] };
+                setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
+            }
+
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_X__, &d__0, jni_double_vector, 1);
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_Y__, &d__0, jni_double_vector, 1);
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_Z__, &d__0, jni_double_vector, 1);
+
+            color = block->ipar[3 + row];
+            markSize = block->ipar[3 + block->ipar[1] + row];
+            lineThickness = (double)markSize;
+            if (color > 0)
+            {
+                setGraphicObjectProperty(pPolyline, __GO_LINE_MODE__, &b__true, jni_bool, 1);
+
+                setGraphicObjectProperty(pPolyline, __GO_LINE_COLOR__, &color, jni_int, 1);
+                setGraphicObjectProperty(pPolyline, __GO_LINE_THICKNESS__, &lineThickness, jni_double, 1);
+            }
+            else
+            {
+                color = -color;
+                setGraphicObjectProperty(pPolyline, __GO_MARK_MODE__, &b__true, jni_bool, 1);
+
+                setGraphicObjectProperty(pPolyline, __GO_MARK_STYLE__, &color, jni_int, 1);
+                setGraphicObjectProperty(pPolyline, __GO_MARK_SIZE__, &markSize, jni_int, 1);
+            }
+        }
     }
+
+    if (sco->scope.cachedPolylinesUIDs != NULL)
+    {
+        sco->scope.cachedPolylinesUIDs[row] = pPolyline;
+    }
+    return pPolyline;
+}
+
+static BOOL setPolylinesBounds(scicos_block * block)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+
+    BOOL result;
+    double dataBounds[6];
+    double rotationAngle[2];
+
+    dataBounds[0] = block->rpar[0]; // xMin
+    dataBounds[1] = block->rpar[1]; // xMax
+    dataBounds[2] = block->rpar[2]; // yMin
+    dataBounds[3] = block->rpar[3]; // yMax
+    dataBounds[4] = block->rpar[4]; // zMin
+    dataBounds[5] = block->rpar[5]; // zMax
+
+    rotationAngle[0] = block->rpar[6];  // alpha
+    rotationAngle[1] = block->rpar[7];  // theta
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+
+    result = setGraphicObjectProperty(pAxeUID, __GO_DATA_BOUNDS__, dataBounds, jni_double_vector, 6);
+    result &= setGraphicObjectProperty(pAxeUID, __GO_ROTATION_ANGLES__, rotationAngle, jni_double_vector, 2);
+
+    return result;
 }
-/*--------------------------------------------------------------------------*/
index 2ab114d..00313e9 100755 (executable)
-/*  Scicos
-*
-*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
-/*--------------------------------------------------------------------------*/
-/**
-   \file cevscpe.c
-   \author Benoit Bayol
-   \version 1.0
-   \date September 2006 - January 2007
-   \brief CEVSCPE is a scope that indicates when the clocks is activated
-   \see CEVENTSCOPE.sci in macros/scicos_blocks/Sinks/
-*/
-/*--------------------------------------------------------------------------*/
-#include "scicos.h"
-#include "scoMemoryScope.h"
-#include "scoWindowScope.h"
-#include "scoMisc.h"
-#include "scoGetProperty.h"
-#include "scoSetProperty.h"
-#include "scicos_block4.h"
-#include "DrawingBridge.h"
-#include "SetJavaProperty.h"
-#include "scicos_malloc.h"
-#include "scicos_free.h"
-#include "MALLOC.h"
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2011 - Scilab Enterprises - Clément DAVID
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
 #include "dynlib_scicos_blocks.h"
-/*--------------------------------------------------------------------------*/
-/** \fn cscopxy_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
-    \brief Function to draw or redraw the window
+#include "scoUtils.h"
+
+#include "MALLOC.h"
+#include "elementary_functions.h"
+#include "string.h"
+
+#include "getGraphicObjectProperty.h"
+#include "setGraphicObjectProperty.h"
+#include "graphicObjectProperties.h"
+#include "createGraphicObject.h"
+
+#include "CurrentFigure.h"
+
+#include "scicos_block4.h"
+#include "scicos.h"
+
+#include "localization.h"
+
+#include "FigureList.h"
+#include "BuildObjects.h"
+#include "AxesModel.h"
+
+/*****************************************************************************
+ * Internal container structure
+ ****************************************************************************/
+
+#define DEFAULT_MAX_NUMBER_OF_POINTS 8
+
+/**
+ * Container structure
+ */
+typedef struct
+{
+    struct
+    {
+        int *numberOfPoints;
+        int *maxNumberOfPoints;
+        double **data;
+    } internal;
+
+    struct
+    {
+        int periodCounter;
+
+        char *cachedFigureUID;
+        char *cachedAxeUID;
+        char **cachedSegsUIDs;
+    } scope;
+} sco_data;
+
+/**
+ * Get (and allocate on demand) the internal data used on this scope
+ * \param block the block
+ * \return the scope data
+ */
+static sco_data *getScoData(scicos_block * block);
+
+/**
+ * Release any internal data
+ *
+ * \param block the block
+ */
+static void freeScoData(scicos_block * block);
+
+/**
+ * Append the data to the current data
+ *
+ * \param block the block
+ * \param input the input (0-indexed)
+ * \param t the current time
+ */
+static void appendData(scicos_block * block, int input, double t);
+
+/**
+ * Push the block data to the segs
+ *
+ * \param block the block
+ * \param input the selected input
+ *
+ */
+static BOOL pushData(scicos_block * block, int input);
+
+/*****************************************************************************
+ * Graphics utils
+ ****************************************************************************/
+
+/**
+ * Get (and allocate on demand) the figure associated with the block
+ * \param block the block
+ * \return a valid figure UID or NULL on error
+ */
+static char *getFigure(scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the axe associated with the input
+ *
+ * \param pFigureUID the parent figure UID
+ * \param block the block
+ * \return a valid axe UID or NULL on error
+ */
+static char *getAxe(char *pFigureUID, scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the segs associated with the input
+ *
+ * \param pAxeUID the parent axe UID
+ * \param block the block
+ * \param input the current row index (0-indexed)
+ * \return a valid polyline UID or NULL on error
+ */
+static char *getSegs(char *pAxeUID, scicos_block * block, int input);
+
+/**
+ * Set the segs buffer size
+ *
+ * \param block the block
+ * \param maxNumberOfPoints the size of the buffer
+ */
+static BOOL setSegsBuffers(scicos_block * block, int maxNumberOfPoints);
+
+/**
+ * Set the axes bounds
+ *
+ * \param block the block
+ * \param periodCounter number of past periods since startup
+ */
+static BOOL setBounds(scicos_block * block, int periodCounter);
+
+/*****************************************************************************
+ * Simulation function
+ ****************************************************************************/
+
+/** \fn void cscope(scicos_block * block,int flag)
+    \brief the computational function
+    \param block A pointer to a scicos_block
+    \param flag An int which indicates the state of the block (init, update, ending)
 */
-SCICOS_BLOCKS_IMPEXP void cevscpe_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
+SCICOS_BLOCKS_IMPEXP void cevscpe(scicos_block * block, scicos_flag flag)
 {
-  /* Declarations */
+    char *pFigureUID;
+
+    double t;
+    int i;
+    int mask;
+    int nclk = block->nipar - 6;
+    sco_data *sco;
 
-  int nipar = 0; //Number of elements in ipar vector
-  int i; //As usual
-  int * ipar = NULL;
-  double * rpar = NULL; //Integer Parameter
-  int nbr_colors = 0; //Number of colors and lines IS ALSO number of channels
-  int win = 0; //To give a name to the window
-  int color_flag = 0; //0/1 color flag -- NOT USED
-  int  * colors = NULL; //Begin at ipar[2] and has a measure of 8 max
-  int dimension = 2;
-  double period = 0.; //Refresh Period of the scope is a vector here
-  int number_of_subwin = 0;
-  int number_of_curves_by_subwin = 0;
-  double xmin = 0., xmax = 0., ymin = 0., ymax = 0;
-  int win_pos[2], win_dim[2];
-  char *label = NULL;
+    BOOL result;
 
-  /* Initialization */
-  ipar =  GetIparPtrs(block);
-  win = ipar[0];
-  color_flag = ipar[1]; /*not used*/
-  rpar = GetRparPtrs(block);
-  period = rpar[0];
-  nipar = GetNipar(block);
-  label = GetLabelPtrs(block);
-  nbr_colors = nipar-6;
-  colors=(int*)scicos_malloc(nbr_colors*sizeof(int));
-  for( i = 2 ; i < nbr_colors+2 ; i++)
+    switch (flag)
     {
-      colors[i-2] = ipar[i];
+
+    case Initialization:
+        sco = getScoData(block);
+        if (sco == NULL)
+        {
+            set_block_error(-5);
+        }
+        pFigureUID = getFigure(block);
+        if (pFigureUID == NULL)
+        {
+            // allocation error
+            set_block_error(-5);
+            break;
+        }
+
+        setSegsBuffers(block, DEFAULT_MAX_NUMBER_OF_POINTS);
+        break;
+
+    case StateUpdate:
+        pFigureUID = getFigure(block);
+
+        t = get_scicos_time();
+
+        // select only the masked indexes
+        for (i = 0; i < nclk; i++)
+        {
+            mask = 1 << i;
+            if ((block->nevprt & mask) == mask)
+            {
+                appendData(block, i, t);
+
+                result = pushData(block, i);
+                if (result == FALSE)
+                {
+                    Coserror("%s: unable to push some data.", "cevscpe");
+                    break;
+                }
+            }
+        }
+        break;
+
+    case Ending:
+        freeScoData(block);
+        break;
+
+    default:
+        break;
     }
+}
 
-  number_of_subwin = 1;
-  number_of_curves_by_subwin = nbr_colors;
+/*-------------------------------------------------------------------------*/
 
-  ymin = 0;
-  ymax = 1;
+/*****************************************************************************
+ *
+ * Container management
+ *
+ ****************************************************************************/
 
-  win_pos[0] = ipar[(nipar-1) - 3];
-  win_pos[1] = ipar[(nipar-1) - 2];
-  win_dim[0] = ipar[(nipar-1) - 1];
-  win_dim[1] = ipar[nipar-1];
+static sco_data *getScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+
+    int nclk = block->nipar - 6;
 
-  if(firstdraw == 1)
+    if (sco == NULL)
     {
-      scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
-      scoSetLongDrawSize(*pScopeMemory,0,5000);
-      scoSetShortDrawSize(*pScopeMemory,0,1);
-      scoSetPeriod(*pScopeMemory,0,period);
+        /*
+         * Data allocation
+         */
+
+        sco = (sco_data *) MALLOC(sizeof(sco_data));
+        if (sco == NULL)
+            goto error_handler_sco;
+
+        sco->internal.numberOfPoints = (int *)CALLOC(nclk, sizeof(int));
+        if (sco->internal.numberOfPoints == NULL)
+        {
+            goto error_handler_numberOfPoints;
+        }
+        sco->internal.maxNumberOfPoints = (int *)MALLOC(nclk * sizeof(int));
+        if (sco->internal.numberOfPoints == NULL)
+        {
+            goto error_handler_maxNumberOfPoints;
+        }
+        for (i = 0; i < nclk; i++)
+        {
+            sco->internal.maxNumberOfPoints[i] = DEFAULT_MAX_NUMBER_OF_POINTS;
+        }
+
+        sco->internal.data = (double **)CALLOC(2 * nclk, sizeof(double *));
+        if (sco->internal.data == NULL)
+            goto error_handler_data;
+
+        for (i = 0; i < nclk; i++)
+        {
+            /*
+             * Alloc base pointer
+             */
+            sco->internal.data[2 * i + 0] = (double *)CALLOC(3 * DEFAULT_MAX_NUMBER_OF_POINTS, sizeof(double));
+            if (sco->internal.data[2 * i + 0] == NULL)
+                goto error_handler_data_i;
+
+            /*
+             * Alloc direction pointer
+             */
+            sco->internal.data[2 * i + 1] = (double *)CALLOC(3 * DEFAULT_MAX_NUMBER_OF_POINTS, sizeof(double));
+            if (sco->internal.data[2 * i + 1] == NULL)
+            {
+                FREE(sco->internal.data[2 * i + 0]);
+                goto error_handler_data_i;
+            }
+        }
+
+        sco->scope.periodCounter = 0;
+        sco->scope.cachedFigureUID = NULL;
+        sco->scope.cachedAxeUID = NULL;
+        sco->scope.cachedSegsUIDs = (char **)CALLOC(nclk, sizeof(char *));
+        if (sco->scope.cachedSegsUIDs == NULL)
+        {
+            goto error_handler_data_i;
+        }
+
+        *(block->work) = sco;
     }
 
-  xmin = period*scoGetPeriodCounter(*pScopeMemory,0);
-  xmax = period*(scoGetPeriodCounter(*pScopeMemory,0)+1);
+    return sco;
 
-  scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, NULL, NULL);
-  if(scoGetScopeActivation(*pScopeMemory) == 1)
+    /*
+     * Error management (out of normal flow)
+     */
+
+error_handler_data_i:
+    for (j = 0; j < i; j++)
     {
-      scoAddTitlesScope(*pScopeMemory,label,"t","y",NULL);
-      scoAddCoupleOfSegments(*pScopeMemory,colors);
+        FREE(sco->internal.data[2 * j + 0]);
+        FREE(sco->internal.data[2 * j + 1]);
     }
-  scicos_free(colors);
+    FREE(sco->internal.data);
+error_handler_data:
+    FREE(sco->internal.maxNumberOfPoints);
+error_handler_maxNumberOfPoints:
+    FREE(sco->internal.numberOfPoints);
+error_handler_numberOfPoints:
+    FREE(sco);
+error_handler_sco:
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
+
+static void freeScoData(scicos_block * block)
+{
+    sco_data *sco = getScoData(block);
+    int i;
+
+    int nclk = block->nipar - 6;
+
+    if (sco != NULL)
+    {
+        for (i = 0; i < nclk; i++)
+        {
+            FREE(sco->internal.data[i]);
+        }
+        FREE(sco->internal.data);
+        FREE(sco->internal.maxNumberOfPoints);
+        FREE(sco->internal.numberOfPoints);
 
-    /* use only single buffering to be sure to draw on the screen */
-    if (scoGetPointerScopeWindow(*pScopeMemory) != NULL) {
-        sciSetJavaUseSingleBuffer(scoGetPointerScopeWindow(*pScopeMemory), TRUE);
+//      Commented due to the C++ allocation
+//      see http://bugzilla.scilab.org/show_bug.cgi?id=9747
+//      FREE(sco->scope.cachedFigureUID);
+//      FREE(sco->scope.cachedAxeUID);
+//      sco->scope.cachedFigureUID = NULL;
+//      for (i=0; i<nclk; i++) {
+//              FREE(sco->scope.cachedPolylinesUIDs[i]);
+//              sco->scope.cachedPolylinesUIDs[i] = NULL;
+//      }
+//      sco->scope.cachedAxeUID = NULL;
+
+        FREE(sco->scope.cachedSegsUIDs);
+
+        FREE(sco);
     }
 }
-/*--------------------------------------------------------------------------*/
-/** \fn void cevscpe(scicos_block * block, int flag)
-    \brief the computational function
-    \param block A pointer to a scicos_block
-    \param flag An int which indicates the state of the block (init, update, ending)
-*/
-SCICOS_BLOCKS_IMPEXP void cevscpe(scicos_block * block, int flag)
+
+static sco_data *reallocScoData(scicos_block * block, int input, int numberOfPoints)
 {
+    sco_data *sco = getScoData(block);
+    double *ptr;
+    int maxNumberOfPoints = sco->internal.maxNumberOfPoints[input];
+    int setLen;
 
-  ScopeMemory * pScopeMemory = NULL;
-  int nbseg = 0;
-  int tab[20];
-  scoGraphicalObject pShortDraw, pLongDraw;
-  int i = 0;
-  double t = 0;
+    /*
+     * Realloc base pointer
+     */
+    ptr = (double *)REALLOC(sco->internal.data[2 * input], 3 * numberOfPoints * sizeof(double));
+    if (ptr == NULL)
+        goto error_handler;
 
-  switch(flag)
+    for (setLen = numberOfPoints - maxNumberOfPoints; setLen >= 0; setLen--)
     {
-    case Initialization:
-      {
-    cevscpe_draw(block,&pScopeMemory,1);
-    break;
-      }
+        ptr[3 * (maxNumberOfPoints + setLen) + 0] = ptr[3 * (maxNumberOfPoints - 1) + 0];
+        ptr[3 * (maxNumberOfPoints + setLen) + 1] = ptr[3 * (maxNumberOfPoints - 1) + 1];
+        ptr[3 * (maxNumberOfPoints + setLen) + 2] = ptr[3 * (maxNumberOfPoints - 1) + 2];
+    }
+    sco->internal.data[2 * input] = ptr;
 
-    case StateUpdate:
-      {
+    /*
+     * Realloc direction pointer
+     */
+    ptr = (double *)REALLOC(sco->internal.data[2 * input + 1], 3 * numberOfPoints * sizeof(double));
+    if (ptr == NULL)
+        goto error_handler;
 
-    /* Charging elements */
+    for (setLen = numberOfPoints - maxNumberOfPoints; setLen >= 0; setLen--)
+    {
+        ptr[3 * (maxNumberOfPoints + setLen) + 0] = ptr[3 * (maxNumberOfPoints - 1) + 0];
+        ptr[3 * (maxNumberOfPoints + setLen) + 1] = ptr[3 * (maxNumberOfPoints - 1) + 1];
+        ptr[3 * (maxNumberOfPoints + setLen) + 2] = ptr[3 * (maxNumberOfPoints - 1) + 2];
+    }
+    sco->internal.data[2 * input + 1] = ptr;
 
-    scoRetrieveScopeMemory(block->work,&pScopeMemory);
+    sco->internal.maxNumberOfPoints[input] = numberOfPoints;
+    return sco;
 
-    if(scoGetScopeActivation(pScopeMemory) == 1)
-      {
+error_handler:
+    freeScoData(block);
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
 
-        t = get_scicos_time();
-        if(scoGetPointerScopeWindow(pScopeMemory) == NULL)
-          {
-        cevscpe_draw(block,&pScopeMemory,0);
-          }
-
-        scoRefreshDataBoundsX(pScopeMemory,t);
-
-        /*Not Factorize*/
-
-        for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0) ; i++)
-          {
-        if((GetNevIn(block)&(1<<i))==(1<<i))
-          {
-            tab[nbseg]=i;
-            nbseg++;
-          }
-          }
-
-        for(i = 0 ; i < nbseg ; i++)
-          {
-        pShortDraw = scoGetPointerShortDraw(pScopeMemory,0,tab[i]);
-        pSEGS_FEATURE(pShortDraw)->vx[0] = t;
-        pSEGS_FEATURE(pShortDraw)->vx[1] = t;
-        pSEGS_FEATURE(pShortDraw)->vy[0] = i*0.8/nbseg;
-        pSEGS_FEATURE(pShortDraw)->vy[1] = (i+1)*0.8/nbseg;
-        pSEGS_FEATURE(pShortDraw)->Nbr1 = 2;
-        pSEGS_FEATURE(pShortDraw)->Nbr2 = 2;
-          }
-        /*End of Not Factorize*/
-        scoDrawScopeAmplitudeTimeStyle(pScopeMemory,t);
-      }
-    break;
-      }
+static void appendData(scicos_block * block, int input, double t)
+{
+    sco_data *sco = getScoData(block);
+    int maxNumberOfPoints = sco->internal.maxNumberOfPoints[input];
+    int numberOfPoints = sco->internal.numberOfPoints[input];
 
-    case Ending:
-      {
+    /*
+     * Handle the case where the t is greater than the data_bounds
+     */
+    if (t > ((sco->scope.periodCounter + 1) * block->rpar[0]))
+    {
+        sco->scope.periodCounter++;
 
-                scoRetrieveScopeMemory(block->work, &pScopeMemory);
-                if(scoGetScopeActivation(pScopeMemory) == 1)
-                {
-                    /* sciSetUsedWindow(scoGetWindowID(pScopeMemory)); */
-                    /* Check if figure is still opened, otherwise, don't try to destroy it again. */
-                    if(scoGetPointerScopeWindow(pScopeMemory) != NULL)
-                    {
-                        for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0) ; i++)
-                        {
-                            /* maybe a bug here in the last argument of the following instruction (see tab[i]) */
-                            pLongDraw = scoGetPointerLongDraw(pScopeMemory,0,i);
-                            forceRedraw(pLongDraw);
-                        }
-
-
-                        /* pShortDraw = sciGetCurrentFigure(); */
-                        pShortDraw = scoGetPointerScopeWindow(pScopeMemory);
-                        clearUserData(pShortDraw);
-                        /* pFIGURE_FEATURE(pShortDraw)->user_data = NULL; */
-                        /* pFIGURE_FEATURE(pShortDraw)->size_of_user_data = 0; */
-                        /* restore double buffering */
-                        if (pShortDraw) {
-                            sciSetJavaUseSingleBuffer(pShortDraw, FALSE);
-                        }
-                        scoDelCoupleOfSegments(pScopeMemory);
-                    }
-                }
-                scoFreeScopeMemory(block->work,&pScopeMemory);
-                break;
+        numberOfPoints = 0;
+        sco->internal.numberOfPoints[input] = 0;
+        if (setBounds(block, sco->scope.periodCounter) == FALSE)
+        {
+            set_block_error(-5);
+            freeScoData(block);
+            sco = NULL;
+        }
+    }
+
+    /*
+     * Handle the case where the scope has more points than maxNumberOfPoints
+     */
+    if (sco != NULL && numberOfPoints >= maxNumberOfPoints)
+    {
+        // on a full scope, re-alloc
+        maxNumberOfPoints = maxNumberOfPoints + DEFAULT_MAX_NUMBER_OF_POINTS;
+        sco = reallocScoData(block, input, maxNumberOfPoints);
+
+        // reconfigure related graphic objects
+        if (setSegsBuffers(block, maxNumberOfPoints) == FALSE)
+        {
+            set_block_error(-5);
+            freeScoData(block);
+            sco = NULL;
+        }
+    }
+
+    /*
+     * Update data
+     */
+    if (sco != NULL)
+    {
+        int setLen;
+
+        /*
+         * Base pointer
+         */
+        for (setLen = maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+        {
+            sco->internal.data[2 * input][3 * (numberOfPoints + setLen) + 0] = t;   // x
+            sco->internal.data[2 * input][3 * (numberOfPoints + setLen) + 1] = 0;   // y
+            sco->internal.data[2 * input][3 * (numberOfPoints + setLen) + 2] = (double)input;   // z
+        }
+
+        /*
+         * Direction pointer
+         */
+        for (setLen = maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+        {
+            sco->internal.data[2 * input][3 * (numberOfPoints + setLen) + 0] = t;   // x
+            sco->internal.data[2 * input][3 * (numberOfPoints + setLen) + 1] = 0.8; // y
+            sco->internal.data[2 * input][3 * (numberOfPoints + setLen) + 2] = (double)input;   // z
+        }
+
+        sco->internal.numberOfPoints[input]++;
+    }
+}
+
+static BOOL pushData(scicos_block * block, int input)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pSegsUID;
+
+    int dataLen;
+    double *base;
+    double *direction;
+    sco_data *sco;
+
+    BOOL result = TRUE;
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+    pSegsUID = getSegs(pAxeUID, block, input);
+
+    sco = getScoData(block);
+    if (sco == NULL)
+        return FALSE;
+
+    // select the right input and row
+    base = sco->internal.data[2 * input];
+    direction = sco->internal.data[2 * input + 1];
+
+    dataLen = 3 * sco->internal.maxNumberOfPoints[input];
+
+    result &= setGraphicObjectProperty(pSegsUID, __GO_BASE__, base, jni_double_vector, dataLen);
+    result &= setGraphicObjectProperty(pSegsUID, __GO_DIRECTION__, direction, jni_double_vector, dataLen);
+
+    return result;
+}
+
+/*****************************************************************************
+ *
+ * Graphic utils
+ *
+ ****************************************************************************/
+
+/**
+ * Set properties on the figure.
+ *
+ * \param pFigureUID the figure uid
+ * \param block the current block
+ */
+static void setFigureSettings(char *pFigureUID, scicos_block * block)
+{
+    int nipar = GetNipar(block);
+    int *ipar = GetIparPtrs(block);
+
+    int win_pos[2];
+    int win_dim[2];
+
+    win_pos[0] = ipar[(nipar - 1) - 3];
+    win_pos[1] = ipar[(nipar - 1) - 2];
+    win_dim[0] = ipar[(nipar - 1) - 1];
+    win_dim[1] = ipar[nipar - 1];
+
+    setGraphicObjectProperty(pFigureUID, __GO_POSITION__, &win_pos, jni_int_vector, 2);
+    setGraphicObjectProperty(pFigureUID, __GO_SIZE__, &win_dim, jni_int_vector, 2);
+};
+
+/*****************************************************************************
+ *
+ * Graphic
+ *
+ ****************************************************************************/
+
+static char *getFigure(scicos_block * block)
+{
+    signed int figNum;
+    char *pFigureUID = NULL;
+    char *pAxe = NULL;
+    static const int i__1 = 1;
+    sco_data *sco = getScoData(block);
+
+    // fast path for an existing object
+    if (sco->scope.cachedFigureUID != NULL)
+    {
+        return sco->scope.cachedFigureUID;
+    }
+
+    figNum = block->ipar[0];
+
+    // with a negative id, use the block number indexed from a constant.
+    if (figNum < 0)
+    {
+        figNum = 20000 + get_block_number();
+    }
+
+    pFigureUID = getFigureFromIndex(figNum);
+    // create on demand
+    if (pFigureUID == NULL)
+    {
+        pFigureUID = createNewFigureWithAxes();
+        setGraphicObjectProperty(pFigureUID, __GO_ID__, &figNum, jni_int, 1);
+
+        // set configured parameters
+        setFigureSettings(pFigureUID, block);
+
+        // allocate the axes through the getter
+        pAxe = getAxe(pFigureUID, block);
+
+        /*
+         * Setup according to block settings
+         */
+        setLabel(pAxe, __GO_X_AXIS_LABEL__, "t");
+        setLabel(pAxe, __GO_Y_AXIS_LABEL__, "y");
+
+        setGraphicObjectProperty(pAxe, __GO_X_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+        setGraphicObjectProperty(pAxe, __GO_Y_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+
+        setBounds(block, 0);
+
+        sco->scope.cachedFigureUID = pFigureUID;
+    }
+
+    if (sco->scope.cachedFigureUID == NULL)
+    {
+        sco->scope.cachedFigureUID = pFigureUID;
+    }
+    return pFigureUID;
+}
+
+static char *getAxe(char *pFigureUID, scicos_block * block)
+{
+    char *pAxe;
+    int i;
+
+    int nclk = block->nipar - 6;
+    sco_data *sco = getScoData(block);
+
+    // fast path for an existing object
+    if (sco->scope.cachedAxeUID != NULL)
+    {
+        return sco->scope.cachedAxeUID;
+    }
+
+    pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, 0);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pAxe == NULL)
+    {
+        pAxe = cloneGraphicObject(getAxesModel());
+
+        if (pAxe != NULL)
+        {
+            setGraphicObjectRelationship(pFigureUID, pAxe);
+
+            // allocate the segs through the getter
+            for (i = 0; i < nclk; i++)
+            {
+                getSegs(pAxe, block, i);
+            }
+
+            sco->scope.cachedAxeUID = pAxe;
+        }
+    }
+
+    if (sco->scope.cachedAxeUID == NULL)
+    {
+        sco->scope.cachedAxeUID = pAxe;
+    }
+    return pAxe;
+}
+
+static char *getSegs(char *pAxeUID, scicos_block * block, int input)
+{
+    char *pSegs;
+    static const BOOL b__true = TRUE;
+    static const double d__1 = 1.0;
+
+    int color;
+
+    sco_data *sco = getScoData(block);
+
+    // fast path for an existing object
+    if (sco->scope.cachedSegsUIDs != NULL && sco->scope.cachedSegsUIDs[input] != NULL)
+    {
+        return sco->scope.cachedSegsUIDs[input];
+    }
+
+    pSegs = findChildWithKindAt(pAxeUID, __GO_SEGS__, input);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pSegs == NULL)
+    {
+        pSegs = createGraphicObject(__GO_SEGS__);
+
+        if (pSegs != NULL)
+        {
+            createDataObject(pSegs, __GO_SEGS__);
+            setGraphicObjectRelationship(pAxeUID, pSegs);
+
+            setGraphicObjectProperty(pSegs, __GO_NUMBER_ARROWS__, &sco->internal.maxNumberOfPoints[input], jni_int, 1);
+
+            // Setup properties
+            setGraphicObjectProperty(pSegs, __GO_LINE_THICKNESS__, &d__1, jni_double, 1);
+
+            color = block->ipar[2 + input];
+            if (color > 0)
+            {
+                setGraphicObjectProperty(pSegs, __GO_LINE_MODE__, &b__true, jni_bool, 1);
+                setGraphicObjectProperty(pSegs, __GO_SEGS_COLORS__, &color, jni_int_vector, 1);
             }
+            else
+            {
+                color = -color;
+                setGraphicObjectProperty(pSegs, __GO_MARK_MODE__, &b__true, jni_bool, 1);
+                setGraphicObjectProperty(pSegs, __GO_MARK_STYLE__, &color, jni_int, 1);
+            }
+
+            sco->scope.cachedSegsUIDs[input] = pSegs;
+        }
+    }
+
+    if (sco->scope.cachedSegsUIDs != NULL && sco->scope.cachedSegsUIDs[input] == NULL)
+    {
+        sco->scope.cachedSegsUIDs[input] = pSegs;
+    }
+    return pSegs;
+}
+
+static BOOL setSegsBuffers(scicos_block * block, int maxNumberOfPoints)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pSegsUID;
+
+    int i;
+    int nclk = block->nipar - 6;
+    BOOL result = TRUE;
+
+    int color;
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+    for (i = 0; i < nclk; i++)
+    {
+        pSegsUID = getSegs(pAxeUID, block, i);
+        result &= setGraphicObjectProperty(pSegsUID, __GO_NUMBER_ARROWS__, &maxNumberOfPoints, jni_int, 1);
+
+        /*
+         * Update color due to bug #9902
+         * http://bugzilla.scilab.org/show_bug.cgi?id=9902
+         */
+        color = block->ipar[2 + i];
+        if (color > 0)
+        {
+            setGraphicObjectProperty(pSegsUID, __GO_SEGS_COLORS__, &color, jni_int_vector, 1);
+        }
+
     }
+
+    return result;
+}
+
+static BOOL setBounds(scicos_block * block, int periodCounter)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+
+    double dataBounds[6];
+    double period = block->rpar[0];
+
+    dataBounds[0] = periodCounter * period; // xMin
+    dataBounds[1] = (periodCounter + 1) * period;   // xMax
+    dataBounds[2] = 0;          // yMin
+    dataBounds[3] = 1;          // yMax
+    dataBounds[4] = -1.0;       // zMin
+    dataBounds[5] = 1.0;        // zMax
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+    return setGraphicObjectProperty(pAxeUID, __GO_DATA_BOUNDS__, dataBounds, jni_double_vector, 6);
 }
-/*--------------------------------------------------------------------------*/
index 328ae7c..4b655aa 100755 (executable)
-/*  Scicos
-*
-*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
-/*--------------------------------------------------------------------------*/
-/**
-   \file cfscope.c
-   \author Benoit Bayol
-   \version 1.0
-   \date September 2006 - January 2007
-   \brief CFSCOPE This scope has no input port because it displays the values on the designated link
-   \see CFSCOPE.sci in macros/scicos_blocks/Sinks/
-*/
-/*--------------------------------------------------------------------------*/
-#include "scicos.h"
-#include "scoMemoryScope.h"
-#include "scoWindowScope.h"
-#include "scoMisc.h"
-#include "scoGetProperty.h"
-#include "scoSetProperty.h"
-#include "scicos_block4.h"
-#include "scicos_malloc.h"
-#include "scicos_free.h"
-#include "MALLOC.h"
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2011 - Scilab Enterprises - Clément DAVID
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
 #include "dynlib_scicos_blocks.h"
-/*--------------------------------------------------------------------------*/
-extern int C2F(getouttb)();
-/*--------------------------------------------------------------------------*/
-/** \fn cfscope_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
-    \brief Function to draw or redraw the window
-*/
-SCICOS_BLOCKS_IMPEXP void cfscope_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
+#include "scoUtils.h"
+
+#include "MALLOC.h"
+#include "elementary_functions.h"
+
+#include "getGraphicObjectProperty.h"
+#include "setGraphicObjectProperty.h"
+#include "graphicObjectProperties.h"
+#include "createGraphicObject.h"
+
+#include "CurrentFigure.h"
+
+#include "scicos_block4.h"
+#include "scicos.h"
+
+#include "localization.h"
+
+#include "FigureList.h"
+#include "BuildObjects.h"
+#include "AxesModel.h"
+
+extern int C2F(getouttb) ();
+
+/*****************************************************************************
+ * Internal container structure
+ ****************************************************************************/
+
+/**
+ * Container structure
+ */
+typedef struct
 {
+    struct
+    {
+        int numberOfPoints;
+        int maxNumberOfPoints;
+        double *time;
+        double ***data;
+    } internal;
 
-  double *rpar = NULL;
-  int *ipar = NULL, nipar = 0;
-
-  double period = 0.;
-  int i = 0;
-  int dimension = 0;
-  double ymin = 0., ymax = 0., xmin = 0., xmax = 0.;
-  int buffer_size = 0;
-  int win_pos[2];
-  int win_dim[2];
-  int win = 0;
-  int number_of_subwin = 0;
-  int number_of_curves_by_subwin = 0;
-  double dt = 0.;
-  int nbr_of_curves = 0;
-  int color_flag = 0;
-  int * colors = NULL;
-  char *label = NULL;
-
-  rpar = GetRparPtrs(block);
-  ipar = GetIparPtrs(block);
-  nipar = GetNipar(block);
-  win = ipar[0];
-  color_flag = ipar[1];
-  buffer_size = ipar[2];
-  dt = rpar[0];
-  period = rpar[3];
-  ymin  = rpar[1];
-  ymax = rpar[2];
-  label = GetLabelPtrs(block);
-
-  dimension = 2;
-  win_pos[0] = ipar[11];
-  win_pos[1] = ipar[12];
-  win_dim[0] = ipar[13];
-  win_dim[1] = ipar[14];
-  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.
-  nbr_of_curves = number_of_curves_by_subwin;
-  number_of_subwin = 1;
-
-  colors=(int*)scicos_malloc(8*sizeof(int));
-  for( i = 3 ; i < 10 ; i++)
-    {
-      colors[i-3] = ipar[i];
-    }
-
-  /*Allocating memory*/
-  if(firstdraw == 1)
-    {
-      scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
-      /*Must be placed before adding polyline or other elements*/
-      scoSetLongDrawSize(*pScopeMemory, 0, 5000);
-      scoSetShortDrawSize(*pScopeMemory,0,buffer_size);
-      scoSetPeriod(*pScopeMemory,0,period);
-    }
-
-  xmin = period*scoGetPeriodCounter(*pScopeMemory,0);
-  xmax = period*(scoGetPeriodCounter(*pScopeMemory,0)+1);
-
-  /*Creating the Scope*/
-  scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, NULL, NULL);
-  if(scoGetScopeActivation(*pScopeMemory) == 1)
-    {
-      scoAddTitlesScope(*pScopeMemory,label,"t","y",NULL);
-
-  /*Add a couple of polyline : one for the shortdraw and one for the longdraw*/
-      scoAddCoupleOfPolylines(*pScopeMemory,colors);
-      scicos_free(colors);
-    }
-}
-/*--------------------------------------------------------------------------*/
+    struct
+    {
+        int periodCounter;
+
+        char *cachedFigureUID;
+        char *cachedAxeUID;
+        char **cachedPolylinesUIDs;
+    } scope;
+} sco_data;
 
-/** \fn void cfscope(scicos_block * block,int flag)
+/**
+ * Get (and allocate on demand) the internal data used on this scope
+ * \param block the block
+ * \return the scope data
+ */
+static sco_data *getScoData(scicos_block * block);
+
+/**
+ * Release any internal data
+ *
+ * \param block the block
+ */
+static void freeScoData(scicos_block * block);
+
+/**
+ * Append the data to the current data
+ *
+ * \param block the block
+ * \param input the input (0-indexed)
+ * \param t the current time
+ * \param data the data to append
+ */
+static void appendData(scicos_block * block, int input, double t, double *data);
+
+/**
+ * Push the block data to the polyline
+ *
+ * \param block the block
+ * \param input the selected input
+ * \param row the selected row
+ * \param pPolylineUID the polyline uid
+ *
+ */
+static BOOL pushData(scicos_block * block, int input, int row);
+
+/*****************************************************************************
+ * Graphics utils
+ ****************************************************************************/
+
+/**
+ * Get (and allocate on demand) the figure associated with the block
+ * \param block the block
+ * \return a valid figure UID or NULL on error
+ */
+static char *getFigure(scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the axe associated with the input
+ *
+ * \param pFigureUID the parent figure UID
+ * \param block the block
+ * \param input the current input index (0-indexed)
+ * \return a valid axe UID or NULL on error
+ */
+static char *getAxe(char *pFigureUID, scicos_block * block, int input);
+
+/**
+ * Get (and allocate on demand) the polyline associated with the row
+ *
+ * \param pAxeUID the parent axe UID
+ * \param block the block
+ * \param row the current row index (0-indexed)
+ * \return a valid polyline UID or NULL on error
+ */
+static char *getPolyline(char *pAxeUID, scicos_block * block, int row);
+
+/**
+ * Set the polylines buffer size
+ *
+ * \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);
+
+/**
+ * Set the polylines bounds
+ *
+ * \param block the block
+ * \param input the input port index
+ * \param periodCounter number of past periods since startup
+ */
+static BOOL setPolylinesBounds(scicos_block * block, int input, int periodCounter);
+
+/*****************************************************************************
+ * Simulation function
+ ****************************************************************************/
+
+/** \fn void cscope(scicos_block * block,int flag)
     \brief the computational function
     \param block A pointer to a scicos_block
     \param flag An int which indicates the state of the block (init, update, ending)
 */
-SCICOS_BLOCKS_IMPEXP void cfscope(scicos_block * block,int flag)
+SCICOS_BLOCKS_IMPEXP void cfscope(scicos_block * block, scicos_flag flag)
 {
-  ScopeMemory * pScopeMemory = NULL;
-  scoGraphicalObject pShortDraw;
-  double * sortie = NULL;
-  int  *  index_of_view = NULL;
-  double t  = 0.;
-  int nbr_of_curves = 0;
-  int *ipar = NULL;
-  int i = 0,j = 0;
-  int NbrPtsShort = 0;
-
-  switch(flag)
+    char *pFigureUID;
+
+    double t;
+    double *u;
+    int links_count;
+    int *links_indexes;
+
+    sco_data *sco;
+
+    int i;
+    BOOL result;
+
+    switch (flag)
     {
+
     case Initialization:
-      {
-       /*Retrieving Parameters*/
-       cfscope_draw(block,&pScopeMemory,1);
-       break;
-      }
+        sco = getScoData(block);
+        if (sco == NULL)
+        {
+            set_block_error(-5);
+        }
+        pFigureUID = getFigure(block);
+        if (pFigureUID == NULL)
+        {
+            // allocation error
+            set_block_error(-5);
+        }
+        break;
+
     case StateUpdate:
-      {
-
-
-       /*Retreiving Scope in the block->work*/
-       scoRetrieveScopeMemory(block->work,&pScopeMemory);
-       if(scoGetScopeActivation(pScopeMemory) == 1)
-         {
-           t = get_scicos_time();
-           /* If window has been destroyed we recreate it */
-       if(scoGetPointerScopeWindow(pScopeMemory) == NULL)
-         {
-           cfscope_draw(block,&pScopeMemory,0);
-         }
-       /*Maybe we are in the end of axes so we have to draw new ones */
-       scoRefreshDataBoundsX(pScopeMemory,t);
-
-       //Cannot be factorized depends of the scope
-       nbr_of_curves = scoGetNumberOfCurvesBySubwin(pScopeMemory,0);
-
-       ipar = GetIparPtrs(block);
-       sortie = (double*)scicos_malloc(nbr_of_curves*sizeof(double));
-       index_of_view =(int*)scicos_malloc(nbr_of_curves*sizeof(int));
-       for(i = 16 ; i < 16+nbr_of_curves ; i++)
-         {
-           index_of_view[i-16] = ipar[i];
-         }
-
-       C2F(getouttb)(&nbr_of_curves,index_of_view,sortie);
-       for(i = 0; i < scoGetNumberOfSubwin(pScopeMemory) ; i++)
-         {
-           for (j = 0; j < nbr_of_curves ; j++)
-             {
-               pShortDraw = scoGetPointerShortDraw(pScopeMemory,i,j);
-               NbrPtsShort = pPOLYLINE_FEATURE(pShortDraw)->n1;
-               pPOLYLINE_FEATURE(pShortDraw)->pvx[NbrPtsShort] = t;         // get time
-               pPOLYLINE_FEATURE(pShortDraw)->pvy[NbrPtsShort] = sortie[j]; // get value
-               pPOLYLINE_FEATURE(pShortDraw)->n1++;
-             }
-         }
-       //End of cannot
-       /*Main drawing function*/
-       scoDrawScopeAmplitudeTimeStyle(pScopeMemory, t);
-
-       scicos_free(sortie);
-       scicos_free(index_of_view);
-         }
-       break;
-      }
+        pFigureUID = getFigure(block);
+
+        t = get_scicos_time();
+
+        /*
+         * Get the data through the scicos_import structure
+         */
+        links_count = block->ipar[15];
+        links_indexes = &block->ipar[16];
+
+        u = (double *)CALLOC(links_count, sizeof(double));
+        if (u == NULL)
+        {
+            Coserror("%s: unable to allocate some data.", "cfscope");
+            return;
+        }
+
+        C2F(getouttb) (&links_count, links_indexes, u);
+
+        /*
+         * Append then free them
+         */
+        appendData(block, 0, t, u);
+        FREE(u);
+
+        for (i = 0; i < links_count; i++)
+        {
+            result = pushData(block, 0, i);
+            if (result == FALSE)
+            {
+                Coserror("%s: unable to push some data.", "cfscope");
+                break;
+            }
+        }
+        break;
+
     case Ending:
-      {
-       scoRetrieveScopeMemory(block->work, &pScopeMemory);
-       if(scoGetScopeActivation(pScopeMemory) == 1)
-         {
-           /*sciSetUsedWindow(scoGetWindowID(pScopeMemory));
-           pShortDraw = sciGetCurrentFigure();
-           pFIGURE_FEATURE(pShortDraw)->user_data = NULL;
-           pFIGURE_FEATURE(pShortDraw)->size_of_user_data = 0;
-
-           scoDelCoupleOfPolylines(pScopeMemory);*/
-
-                       /* Check if figure is still opened, otherwise, don't try to destroy it again. */
-                       scoGraphicalObject figure = scoGetPointerScopeWindow(pScopeMemory);
-                       if (figure != NULL)
-                       {
-                               /*pShortDraw = scoGetPointerScopeWindow(pScopeMemory);*/
-                               clearUserData(figure);
-
-                               scoDelCoupleOfPolylines(pScopeMemory);
-                       }
-         }
-       scoFreeScopeMemory(block->work, &pScopeMemory);
-       break;
-      }
+        freeScoData(block);
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*****************************************************************************
+ *
+ * Container management
+ *
+ ****************************************************************************/
+
+static sco_data *getScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j, k, l;
+    BOOL result;
+    int links_count = block->ipar[15];
+
+    if (sco == NULL)
+    {
+        /*
+         * Data allocation
+         */
+
+        sco = (sco_data *) MALLOC(sizeof(sco_data));
+        if (sco == NULL)
+            goto error_handler_sco;
+
+        sco->internal.numberOfPoints = 0;
+        sco->internal.maxNumberOfPoints = block->ipar[2];
+
+        sco->internal.data = (double ***)CALLOC(1, sizeof(double **));
+        if (sco->internal.data == NULL)
+            goto error_handler_data;
+
+        for (i = 0; i < 1; i++)
+        {
+            sco->internal.data[i] = (double **)CALLOC(links_count, sizeof(double *));
+            if (sco->internal.data[i] == NULL)
+                goto error_handler_data_i;
+        }
+        for (i = 0; i < 1; i++)
+        {
+            for (j = 0; j < links_count; j++)
+            {
+                sco->internal.data[i][j] = (double *)CALLOC(block->ipar[2], sizeof(double));
+
+                if (sco->internal.data[i][j] == NULL)
+                    goto error_handler_data_ij;
+            }
+        }
+
+        sco->internal.time = (double *)CALLOC(block->ipar[2], sizeof(double));
+        if (sco->internal.time == NULL)
+        {
+            goto error_handler_time;
+        }
+
+        sco->scope.periodCounter = 0;
+        sco->scope.cachedFigureUID = NULL;
+        sco->scope.cachedAxeUID = NULL;
+        sco->scope.cachedPolylinesUIDs = (char **)CALLOC(links_count, sizeof(char *));
+
+        *(block->work) = sco;
+    }
+
+    return sco;
+
+    /*
+     * Error management (out of normal flow)
+     */
+
+error_handler_time:
+error_handler_data_ij:
+    for (k = 0; k < i; k++)
+    {
+        for (l = 0; l < j; l++)
+        {
+            FREE(sco->internal.data[k][l]);
+        }
+    }
+    i = 1;
+error_handler_data_i:
+    for (j = 0; j < i; j++)
+    {
+        FREE(sco->internal.data[i]);
+    }
+    FREE(sco->internal.data);
+error_handler_data:
+    FREE(sco);
+error_handler_sco:
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
+
+static void freeScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+    int links_count = block->ipar[15];
+
+    if (sco != NULL)
+    {
+        for (i = 0; i < 1; i++)
+        {
+            for (j = 0; j < links_count; j++)
+            {
+                FREE(sco->internal.data[i][j]);
+            }
+            FREE(sco->internal.data[i]);
+        }
+
+        FREE(sco->internal.data);
+        FREE(sco->internal.time);
+
+//      Commented due to the C++ allocation
+//      see http://bugzilla.scilab.org/show_bug.cgi?id=9747
+//      FREE(sco->scope.cachedFigureUID);
+//      sco->scope.cachedFigureUID = NULL;
+//      for (i=0; i<1; i++) {
+//          for (j=0; j<links_count; j++) {
+//              FREE(sco->scope.cachedPolylinesUIDs[i][j]);
+//              sco->scope.cachedPolylinesUIDs[i][j] = NULL;
+//          }
+//          FREE(sco->scope.cachedAxeUID[i]);
+//          sco->scope.cachedAxeUID[i] = NULL;
+//      }
+
+        FREE(sco);
+    }
+}
+
+static sco_data *reallocScoData(scicos_block * block, int numberOfPoints)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+    double *ptr;
+    int setLen;
+    int links_count = block->ipar[15];
+
+    for (i = 0; i < 1; i++)
+    {
+        for (j = 0; j < links_count; j++)
+        {
+            ptr = (double *)REALLOC(sco->internal.data[i][j], numberOfPoints * sizeof(double));
+            if (ptr == NULL)
+                goto error_handler;
+
+            for (setLen = sco->internal.maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+                ptr[sco->internal.maxNumberOfPoints + setLen] = ptr[sco->internal.maxNumberOfPoints - 1];
+            sco->internal.data[i][j] = ptr;
+        }
+    }
+
+    ptr = (double *)REALLOC(sco->internal.time, numberOfPoints * sizeof(double));
+    if (ptr == NULL)
+        goto error_handler;
+
+    for (setLen = sco->internal.maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+        ptr[sco->internal.maxNumberOfPoints + setLen] = ptr[sco->internal.maxNumberOfPoints - 1];
+    sco->internal.time = ptr;
+
+    sco->internal.maxNumberOfPoints = numberOfPoints;
+    return sco;
+
+error_handler:
+    freeScoData(block);
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
+
+static void appendData(scicos_block * block, int input, double t, double *data)
+{
+    int i;
+    static const int i__1 = 1;
+
+    sco_data *sco = (sco_data *) * (block->work);
+    int maxNumberOfPoints = sco->internal.maxNumberOfPoints;
+    int numberOfPoints = sco->internal.numberOfPoints;
+    int links_count = block->ipar[15];
+
+    /*
+     * Handle the case where the t is greater than the data_bounds
+     */
+    if (t > ((sco->scope.periodCounter + 1) * block->rpar[3]))
+    {
+        sco->scope.periodCounter++;
+
+        numberOfPoints = 0;
+        sco->internal.numberOfPoints = 0;
+        if (setPolylinesBounds(block, input, sco->scope.periodCounter) == FALSE)
+        {
+            set_block_error(-5);
+            freeScoData(block);
+            sco = NULL;
+        }
+    }
+
+    /*
+     * Handle the case where the scope has more points than maxNumberOfPoints
+     */
+    if (sco != NULL && numberOfPoints >= maxNumberOfPoints)
+    {
+        // on a full scope, re-alloc
+        maxNumberOfPoints = maxNumberOfPoints + block->ipar[2];
+        sco = reallocScoData(block, maxNumberOfPoints);
+
+        // reconfigure related graphic objects
+        if (setPolylinesBuffers(block, input, maxNumberOfPoints) == FALSE)
+        {
+            set_block_error(-5);
+            freeScoData(block);
+            sco = NULL;
+        }
     }
+
+    /*
+     * Update data
+     */
+    if (sco != NULL)
+    {
+        int setLen;
+
+        for (i = 0; i < links_count; i++)
+        {
+            for (setLen = maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+                sco->internal.data[input][i][numberOfPoints + setLen] = data[i];
+        }
+
+        for (setLen = maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+            sco->internal.time[numberOfPoints + setLen] = t;
+
+        sco->internal.numberOfPoints++;
+    }
+}
+
+static BOOL pushData(scicos_block * block, int input, int row)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pPolylineUID;
+
+    static const int i__0 = 0;
+
+    double *data;
+    sco_data *sco;
+
+    BOOL result = TRUE;
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block, input);
+    pPolylineUID = getPolyline(pAxeUID, block, row);
+
+    sco = getScoData(block);
+    if (sco == NULL)
+        return FALSE;
+
+    // select the right input and row
+    data = sco->internal.data[input][row];
+
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_X__, sco->internal.time, jni_double_vector, sco->internal.maxNumberOfPoints);
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_Y__, data, jni_double_vector, sco->internal.maxNumberOfPoints);
+
+    return result;
+}
+
+/*****************************************************************************
+ *
+ * Graphic utils
+ *
+ ****************************************************************************/
+
+/**
+ * Set properties on the figure.
+ *
+ * \param pFigureUID the figure uid
+ * \param block the current block
+ */
+static void setFigureSettings(char *pFigureUID, scicos_block * block)
+{
+    int nipar = GetNipar(block);
+    int *ipar = GetIparPtrs(block);
+
+    int win_pos[2];
+    int win_dim[2];
+
+    win_pos[0] = ipar[11];
+    win_pos[1] = ipar[12];
+    win_dim[0] = ipar[13];
+    win_dim[1] = ipar[14];
+
+    setGraphicObjectProperty(pFigureUID, __GO_POSITION__, &win_pos, jni_int_vector, 2);
+    setGraphicObjectProperty(pFigureUID, __GO_SIZE__, &win_dim, jni_int_vector, 2);
+};
+
+/*****************************************************************************
+ *
+ * Graphic
+ *
+ ****************************************************************************/
+
+static char *getFigure(scicos_block * block)
+{
+    signed int figNum;
+    char *pFigureUID = NULL;
+    char *pAxe = NULL;
+    static const int i__1 = 1;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    int i, j;
+
+    // fast path for an existing object
+    if (sco->scope.cachedFigureUID != NULL)
+    {
+        return sco->scope.cachedFigureUID;
+    }
+
+    figNum = block->ipar[0];
+
+    // with a negative id, use the block number indexed from a constant.
+    if (figNum < 0)
+    {
+        figNum = 20000 + get_block_number();
+    }
+
+    pFigureUID = getFigureFromIndex(figNum);
+    // create on demand
+    if (pFigureUID == NULL)
+    {
+        pFigureUID = createNewFigureWithAxes();
+        setGraphicObjectProperty(pFigureUID, __GO_ID__, &figNum, jni_int, 1);
+
+        // set configured parameters
+        setFigureSettings(pFigureUID, block);
+
+        // allocate the axes through the getter
+        for (i = 0; i < 1; i++)
+        {
+            pAxe = getAxe(pFigureUID, block, i);
+
+            /*
+             * Setup according to block settings
+             */
+            setLabel(pAxe, __GO_X_AXIS_LABEL__, "t");
+            setLabel(pAxe, __GO_Y_AXIS_LABEL__, "y");
+
+            setGraphicObjectProperty(pAxe, __GO_X_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+            setGraphicObjectProperty(pAxe, __GO_Y_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+
+            setPolylinesBounds(block, i, 0);
+        }
+
+        sco->scope.cachedFigureUID = pFigureUID;
+    }
+
+    return pFigureUID;
+}
+
+static char *getAxe(char *pFigureUID, scicos_block * block, int input)
+{
+    char *pAxe;
+    int i;
+    sco_data *sco = (sco_data *) * (block->work);
+    int links_count = block->ipar[15];
+
+    // fast path for an existing object
+    if (sco->scope.cachedAxeUID != NULL)
+    {
+        return sco->scope.cachedAxeUID;
+    }
+
+    pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, input);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pAxe == NULL)
+    {
+        pAxe = cloneGraphicObject(getAxesModel());
+
+        if (pAxe != NULL)
+        {
+            setGraphicObjectRelationship(pFigureUID, pAxe);
+
+            // allocate the polylines through the getter
+            for (i = 0; i < links_count; i++)
+            {
+                getPolyline(pAxe, block, i);
+            }
+        }
+    }
+
+    if (sco->scope.cachedAxeUID == NULL)
+    {
+        sco->scope.cachedAxeUID = pAxe;
+    }
+    return pAxe;
+}
+
+static char *getPolyline(char *pAxeUID, scicos_block * block, int row)
+{
+    char *pPolyline;
+    static const double d__0 = 0.0;
+    static const int i__1 = 1;
+    static const BOOL b__true = TRUE;
+
+    int color;
+
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedPolylinesUIDs != NULL && sco->scope.cachedPolylinesUIDs[row] != NULL)
+    {
+        return sco->scope.cachedPolylinesUIDs[row];
+    }
+
+    pPolyline = findChildWithKindAt(pAxeUID, __GO_POLYLINE__, row);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pPolyline == NULL)
+    {
+        pPolyline = createGraphicObject(__GO_POLYLINE__);
+
+        if (pPolyline != NULL)
+        {
+            createDataObject(pPolyline, __GO_POLYLINE__);
+            setGraphicObjectRelationship(pAxeUID, pPolyline);
+
+            /*
+             * Default setup (will crash if removed)
+             */
+            {
+                int polylineSize[2] = { 1, block->ipar[2] };
+                setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
+            }
+
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_X__, &d__0, jni_double_vector, 1);
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_Y__, &d__0, jni_double_vector, 1);
+
+            color = block->ipar[3 + row];
+            if (color > 0)
+            {
+                setGraphicObjectProperty(pPolyline, __GO_LINE_MODE__, &b__true, jni_bool, 1);
+                setGraphicObjectProperty(pPolyline, __GO_LINE_COLOR__, &color, jni_int, 1);
+            }
+            else
+            {
+                color = -color;
+                setGraphicObjectProperty(pPolyline, __GO_MARK_MODE__, &b__true, jni_bool, 1);
+                setGraphicObjectProperty(pPolyline, __GO_MARK_STYLE__, &color, jni_int, 1);
+            }
+
+            sco->scope.cachedPolylinesUIDs[row] = pPolyline;
+        }
+    }
+
+    return pPolyline;
+}
+
+static BOOL setPolylinesBuffers(scicos_block * block, int input, int maxNumberOfPoints)
+{
+    int i;
+
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pPolylineUID;
+
+    BOOL result = TRUE;
+    int polylineSize[2] = { 1, maxNumberOfPoints };
+    int links_count = block->ipar[15];
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block, input);
+
+    for (i = 0; i < links_count; i++)
+    {
+        pPolylineUID = getPolyline(pAxeUID, block, i);
+        result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
+    }
+
+    return result;
+}
+
+static BOOL setPolylinesBounds(scicos_block * block, int input, int periodCounter)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+
+    BOOL result;
+    double dataBounds[6];
+    double period = block->rpar[3];
+
+    dataBounds[0] = periodCounter * period; // xMin
+    dataBounds[1] = (periodCounter + 1) * period;   // xMax
+    dataBounds[2] = block->rpar[1]; // yMin
+    dataBounds[3] = block->rpar[2]; // yMax
+    dataBounds[4] = -1.0;       // zMin
+    dataBounds[5] = 1.0;        // zMax
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block, input);
+    return setGraphicObjectProperty(pAxeUID, __GO_DATA_BOUNDS__, dataBounds, jni_double_vector, 6);
 }
-/*--------------------------------------------------------------------------*/
index ccfbfcf..00818dc 100644 (file)
-/*  Scicos
-*
-*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
-/*--------------------------------------------------------------------------*/
-/**
-   \file cmat3d.c
-   \author Benoit Bayol
-   \version 1.0
-   \date September 2006 - January 2007
-   \brief CMAT3D is a scope which connect a matrix to a plot3d. Values of the matrix are the values at the nodes.
-   \see CMAT3D.sci in macros/scicos_blocks/Sinks/
-*/
-/*--------------------------------------------------------------------------*/
-#include <math.h>
-#include "DrawingBridge.h"
-#include "scoMemoryScope.h"
-#include "scoWindowScope.h"
-#include "scoMisc.h"
-#include "scoGetProperty.h"
-#include "scoSetProperty.h"
-#include "scicos_block4.h"
-#include "scicos_malloc.h"
-#include "scicos_free.h"
-#include "MALLOC.h"
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2011 - Scilab Enterprises - Clément DAVID
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
 #include "dynlib_scicos_blocks.h"
-/*--------------------------------------------------------------------------*/
-/** \fn cmat3d_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
-    \brief Function to draw or redraw the window
-*/
-SCICOS_BLOCKS_IMPEXP void cmat3d_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
+#include "scoUtils.h"
+
+#include "MALLOC.h"
+#include "elementary_functions.h"
+
+#include "getGraphicObjectProperty.h"
+#include "setGraphicObjectProperty.h"
+#include "graphicObjectProperties.h"
+#include "createGraphicObject.h"
+
+#include "CurrentFigure.h"
+
+#include "scicos_block4.h"
+#include "scicos.h"
+#include "math.h"
+
+#include "localization.h"
+
+#include "FigureList.h"
+#include "BuildObjects.h"
+#include "AxesModel.h"
+/*****************************************************************************
+ * Internal container structure
+ ****************************************************************************/
+
+/**
+ * Container structure
+ */
+typedef struct
 {
-  /*Declarations*/
-  int i = 0; //As usual
-  int * ipar = NULL; //Integer Parameters
-  int win_pos[2]; //Position of the Window
-  int win_dim[2]; //Dimension of the Window
-  int dimension = 3;
-  double * rpar = NULL; //Reals parameters
-  double  ymin = 0., ymax = 0.; //Ymin and Ymax are vectors here
-  double  xmin = 0., xmax = 0.;
-  double zmin = 0., zmax = 0.;
-  int number_of_curves_by_subwin = 0;
-  int number_of_subwin = 0;
-  double * mat = NULL;
-  int size_mat = 0;
-  int size_in_x = 0;
-  int size_in_y = 0;
-  char *label = NULL;
-  scoGraphicalObject pShortDraw;
-
-  /*Retrieve parameters from the scicos_model() which has been created thanks to the interfacing function*/
-  rpar = GetRparPtrs(block);
-  ipar = GetIparPtrs(block);
-
-  number_of_subwin = 1;
-
-  win_pos[0] = -1;
-  win_pos[1] = -1;
-  win_dim[0] = -1;
-  win_dim[1] = -1;
-
-  size_mat = ipar[2];
-  mat = (double*)scicos_malloc(size_mat*sizeof(double));
-  for(i = 0 ; i < size_mat ; i++)
-    {
-      mat[i] = rpar[i];
-    }
-  size_in_x = GetInPortSize(block,1,1);
-  size_in_y = GetInPortSize(block,1,2);
-  if(ipar[3] == 1)
-    {
-      xmax = size_in_x;
-      xmin = 0;
-      ymax = size_in_y;
-      ymin = 0;
-    }
-  else
-    {
-      xmin = rpar[size_mat];
-      xmax = rpar[size_mat+1];
-      ymin = rpar[size_mat+2];
-      ymax = rpar[size_mat+3];
-    }
-
-  zmin = ipar[0];
-  zmax = ipar[1];
-  number_of_curves_by_subwin = 1;
-  label = GetLabelPtrs(block);
-
-  /*Allocating memory for scope only if the window has to be created and not redraw*/
-  if(firstdraw == 1)
-    {
-      scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
-    }
-
-  /*Creating the Scope with axes*/
-  scoInitOfWindow(*pScopeMemory, dimension, -1, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, &zmin, &zmax);
-  if(scoGetScopeActivation(*pScopeMemory) == 1)
-    {
-      /*Here we put the special window feature like pixmap or text title
-       Dont forget that the function scoAddTitleScope redraws the window at end so it would be a good idea to put it at the end*/
-      //sciSetPixmapMode(scoGetPointerScopeWindow(*pScopeMemory),TRUE);
-      //pFIGURE_FEATURE(scoGetPointerScopeWindow(*pScopeMemory))->pixmapMode = 1;
-
-      sciSetColormap(scoGetPointerScopeWindow(*pScopeMemory), mat , size_mat/3, 3);
-
-      pSUBWIN_FEATURE(scoGetPointerAxes(*pScopeMemory,0))->alpha = 50;
-      pSUBWIN_FEATURE(scoGetPointerAxes(*pScopeMemory,0))->theta = 280;
-
-      /*Adding graphic elements like plot3d or polyline and so*/
-      if(ipar[3] == 1)
-       {
-         scoAddPlot3dForShortDraw(*pScopeMemory,0,0,GetInPortSize(block,1,1),GetInPortSize(block,1,2));
-       }
-      else
-       {
-         double h_x,h_y;
-         scoAddPlot3dForShortDraw(*pScopeMemory,0,0,GetInPortSize(block,1,1),GetInPortSize(block,1,2));
-         pShortDraw = scoGetPointerShortDraw(*pScopeMemory,0,0);
-         h_x = fabs((xmax-xmin)/(GetInPortSize(block,1,1)-1));
-         h_y = fabs((ymax-ymin)/(GetInPortSize(block,1,2)-1));
-
-         for(i = 0 ; i < size_in_x ; i++)
-           {
-             pSURFACE_FEATURE(pShortDraw)->pvecx[i] = xmin + i*h_x;
-           }
-         for(i = 0 ; i < size_in_y ; i++)
-           {
-             pSURFACE_FEATURE(pShortDraw)->pvecy[i] = ymin + i*h_y;
-           }
-       }
-      scoAddTitlesScope(*pScopeMemory,label,"x","y","z");
-    }
-  /*Dont forget to free your scicos_malloc or MALLOC*/
-  scicos_free(mat);
+    struct
+    {
+        char *cachedFigureUID;
+        char *cachedAxeUID;
+        char *cachedPlot3dUID;
+    } scope;
+} sco_data;
 
-}
-/*--------------------------------------------------------------------------*/
-/** \fn void cmat3d(scicos_block * block, int flag)
+/**
+ * Get (and allocate on demand) the internal data used on this scope
+ * \param block the block
+ * \return the scope data
+ */
+static sco_data *getScoData(scicos_block * block);
+
+/**
+ * Release any internal data
+ *
+ * \param block the block
+ */
+static void freeScoData(scicos_block * block);
+
+/**
+ * Push the block data to the polyline
+ *
+ * \param data the data to push
+ *
+ */
+static BOOL pushData(scicos_block * block, double *data);
+
+/*****************************************************************************
+ * Graphics utils
+ ****************************************************************************/
+
+/**
+ * Get (and allocate on demand) the figure associated with the block
+ * \param block the block
+ * \return a valid figure UID or NULL on error
+ */
+static char *getFigure(scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the axe associated with the input
+ *
+ * \param pFigureUID the parent figure UID
+ * \param block the block
+ * \return a valid axe UID or NULL on error
+ */
+static char *getAxe(char *pFigureUID, scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the plot3d
+ *
+ * \param pAxeUID the parent axe UID
+ * \param block the block
+ * \return a valid plot3d UID or NULL on error
+ */
+static char *getPlot3d(char *pAxeUID, scicos_block * block);
+
+/**
+ * Set the plot3d and axes bounds
+ *
+ * \param block the block
+ * \param pAxeUID the axe
+ * \param pPlot3dUID the plot3d
+ */
+static BOOL setBounds(scicos_block * block, char *pAxeUID, char *pPlot3dUID);
+
+/**
+ * Set the plot3d settings
+ *
+ * \param block the block
+ * \param pPlot3dUID the plot3d
+ */
+static BOOL setPlot3dSettings(scicos_block * block, char *pPlot3dUID);
+
+/**
+ * Set the plot3d default values
+ *
+ * \param block the block
+ * \param pPlot3dUID the plot3d
+ */
+static BOOL setDefaultValues(scicos_block * block, char *pPlot3dUID);
+
+/*****************************************************************************
+ * Simulation function
+ ****************************************************************************/
+
+/** \fn void cmatview(scicos_block * block,int flag)
     \brief the computational function
     \param block A pointer to a scicos_block
     \param flag An int which indicates the state of the block (init, update, ending)
 */
-SCICOS_BLOCKS_IMPEXP void cmat3d(scicos_block * block, int flag)
+SCICOS_BLOCKS_IMPEXP void cmat3d(scicos_block * block, scicos_flag flag)
 {
-  /* Declarations */
-  ScopeMemory * pScopeMemory = NULL;
-  scoGraphicalObject pShortDraw;
-  double * u1 = NULL;
-  int i = 0, j = 0;
-  int dim_i = 0, dim_j = 0;
+    char *pFigureUID;
+
+    double *u;
+    sco_data *sco;
 
-  /* State Machine Control */
-  switch(flag)
+    int i;
+    BOOL result;
+
+    switch (flag)
     {
-      /*Flag 4*/
+
     case Initialization:
-      {
-        /*We create the window for the first time, so 1 is in parameters*/
-       cmat3d_draw(block,&pScopeMemory,1);
-       break; //dont forget the break
-      }
-      /*Flag 2*/
+        sco = getScoData(block);
+        if (sco == NULL)
+        {
+            set_block_error(-5);
+        }
+        pFigureUID = getFigure(block);
+        if (pFigureUID == NULL)
+        {
+            // allocation error
+            set_block_error(-5);
+        }
+        break;
+
     case StateUpdate:
-      {
-       /*Retreiving Scope in the block->work*/
-       scoRetrieveScopeMemory(block->work,&pScopeMemory);
-       if(scoGetScopeActivation(pScopeMemory) == 1)
-         {
-
-           /* If window has been destroyed we recreate it */
-           if(scoGetPointerScopeWindow(pScopeMemory) == NULL)
-             {
-               //0 here because of the recreation
-               cmat3d_draw(block,&pScopeMemory,0);
-             }
-           /*Here some allocations and calcul wich are necessary*/
-           pShortDraw = scoGetPointerShortDraw(pScopeMemory,0,0);
-
-           u1 = GetInPortPtrs(block,1);
-           dim_i = GetInPortRows(block,1);
-           dim_j = GetInPortCols(block,1);
-
-           for(i = 0 ; i < dim_i ; i++)
-             {
-
-               for(j = 0; j < dim_j ; j++)
-                 {
-                   pSURFACE_FEATURE(pShortDraw)->pvecz[j+i*dim_j] = u1[j+dim_j*i];
-                 }
-             }
-
-           /*Here is the draw instructions*/
-           sciSetUsedWindow(scoGetWindowID(pScopeMemory));
-           if(sciGetPixmapMode(scoGetPointerScopeWindow(pScopeMemory)))
-             {
-                         /* TODO : not implemented */
-                         /*C2F(dr)("xset","wshow",PI0,PI0,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);*/
-             }
-           forceRedraw(pShortDraw);
-           sciDrawObj(scoGetPointerScopeWindow(pScopeMemory));
-         }
-       break; //dont forget the break
-      }
-      /*Flag 5*/
+        pFigureUID = getFigure(block);
+
+        u = GetRealInPortPtrs(block, 1);
+
+        result = pushData(block, u);
+        if (result == FALSE)
+        {
+            Coserror("%s: unable to push some data.", "cmatview");
+            break;
+        }
+        break;
+
     case Ending:
-      {
-        /*Retrieve Memory*/
-       scoRetrieveScopeMemory(block->work, &pScopeMemory);
-        /*Here we can add specific instructions to be sure that we have stick short and longdraw if we need it. Cscope for example stick the last short to the long to have one curve to move*/
-        /*Free Memory*/
-       if(scoGetScopeActivation(pScopeMemory) == 1)
-         {
-           /*sciSetUsedWindow(scoGetWindowID(pScopeMemory));
-           pShortDraw = sciGetCurrentFigure();
-           pFIGURE_FEATURE(pShortDraw)->user_data = NULL;
-           pFIGURE_FEATURE(pShortDraw)->size_of_user_data = 0;*/
-                       /* Check if figure is still opened, otherwise, don't try to destroy it again. */
-                       scoGraphicalObject figure = scoGetPointerScopeWindow(pScopeMemory);
-                       if (figure != NULL)
-                       {
-                               /*pShortDraw = scoGetPointerScopeWindow(pScopeMemory);*/
-                               clearUserData(figure);
-                       }
-         }
-       scoFreeScopeMemory(block->work, &pScopeMemory);
-       break;
-      }
+        freeScoData(block);
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*****************************************************************************
+ *
+ * Container management
+ *
+ ****************************************************************************/
+
+static sco_data *getScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    BOOL result;
+
+    if (sco == NULL)
+    {
+        /*
+         * Data allocation
+         */
+
+        sco = (sco_data *) MALLOC(sizeof(sco_data));
+        if (sco == NULL)
+            goto error_handler_sco;
+
+        sco->scope.cachedFigureUID = NULL;
+        sco->scope.cachedAxeUID = NULL;
+        sco->scope.cachedPlot3dUID = NULL;
+
+        *(block->work) = sco;
+    }
+
+    return sco;
+
+    /*
+     * Error management (out of normal flow)
+     */
+
+error_handler_sco:
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
+
+static void freeScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+
+    if (sco != NULL)
+    {
+        FREE(sco);
+    }
+}
+
+static BOOL pushData(scicos_block * block, double *data)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pPlot3dUID;
+
+    BOOL result;
+    int i;
+
+    int m, n;
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+    pPlot3dUID = getPlot3d(pAxeUID, block);
+
+    m = GetInPortSize(block, 1, 1);
+    n = GetInPortSize(block, 1, 2);
+
+    result = setGraphicObjectProperty(pPlot3dUID, __GO_DATA_MODEL_Z__, data, jni_double_vector, m * n);
+
+    return result;
+}
+
+/*****************************************************************************
+ *
+ * Graphic utils
+ *
+ ****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Graphic
+ *
+ ****************************************************************************/
+
+static char *getFigure(scicos_block * block)
+{
+    signed int figNum;
+    char *pFigureUID = NULL;
+    char *pAxe = NULL;
+    static const int i__1 = 1;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    int i, j;
+
+    // fast path for an existing object
+    if (sco->scope.cachedFigureUID != NULL)
+    {
+        return sco->scope.cachedFigureUID;
+    }
+
+    figNum = block->ipar[0];
+
+    // with a negative id, use the block number indexed from a constant.
+    if (figNum < 0)
+    {
+        figNum = 20000 + get_block_number();
+    }
+
+    pFigureUID = getFigureFromIndex(figNum);
+    // create on demand
+    if (pFigureUID == NULL)
+    {
+        pFigureUID = createNewFigureWithAxes();
+        setGraphicObjectProperty(pFigureUID, __GO_ID__, &figNum, jni_int, 1);
+
+        setGraphicObjectProperty(pFigureUID, __GO_COLORMAP__, block->rpar, jni_double_vector, block->ipar[2]);
+
+        // allocate the axes through the getter
+        pAxe = getAxe(pFigureUID, block);
+
+        /*
+         * Setup according to block settings
+         */
+        setLabel(pAxe, __GO_X_AXIS_LABEL__, "x");
+        setLabel(pAxe, __GO_Y_AXIS_LABEL__, "y");
+        setLabel(pAxe, __GO_Z_AXIS_LABEL__, "z");
+
+        setGraphicObjectProperty(pAxe, __GO_X_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+        setGraphicObjectProperty(pAxe, __GO_Y_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+        setGraphicObjectProperty(pAxe, __GO_Z_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+
+        sco->scope.cachedFigureUID = pFigureUID;
+    }
+
+    if (sco->scope.cachedFigureUID == NULL)
+    {
+        sco->scope.cachedFigureUID = pFigureUID;
+    }
+    return pFigureUID;
+}
+
+static char *getAxe(char *pFigureUID, scicos_block * block)
+{
+    char *pAxe;
+    int i;
+    static const int i__1 = 1;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedAxeUID != NULL)
+    {
+        return sco->scope.cachedAxeUID;
+    }
+
+    pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, 0);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pAxe == NULL)
+    {
+        pAxe = cloneGraphicObject(getAxesModel());
+
+        if (pAxe != NULL)
+        {
+            setGraphicObjectRelationship(pFigureUID, pAxe);
+
+            getPlot3d(pAxe, block);
+        }
+    }
+
+    if (sco->scope.cachedAxeUID == NULL)
+    {
+        sco->scope.cachedAxeUID = pAxe;
+    }
+    return pAxe;
+}
+
+static char *getPlot3d(char *pAxeUID, scicos_block * block)
+{
+    char *pPlot3d;
+    static const double d__0 = 0.0;
+    static const int i__0 = 0;
+    static const BOOL b__true = TRUE;
+
+    int color;
+
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedPlot3dUID != NULL)
+    {
+        return sco->scope.cachedPlot3dUID;
+    }
+
+    pPlot3d = findChildWithKindAt(pAxeUID, __GO_PLOT3D__, 0);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pPlot3d == NULL)
+    {
+        pPlot3d = createGraphicObject(__GO_PLOT3D__);
+
+        if (pPlot3d != NULL)
+        {
+            createDataObject(pPlot3d, __GO_PLOT3D__);
+            setGraphicObjectRelationship(pAxeUID, pPlot3d);
+
+            setBounds(block, pAxeUID, pPlot3d);
+            setPlot3dSettings(block, pPlot3d);
+            setDefaultValues(block, pPlot3d);
+        }
+    }
+
+    if (sco->scope.cachedPlot3dUID == NULL)
+    {
+        sco->scope.cachedPlot3dUID = pPlot3d;
+    }
+    return pPlot3d;
+}
+
+static BOOL setBounds(scicos_block * block, char *pAxeUID, char *pPlot3dUID)
+{
+    BOOL result;
+
+    int gridSize[4];
+    double dataBounds[6];
+    double rotationAngle[2];
+
+    int m, n;
+    int colormapLen;
+
+    m = GetInPortSize(block, 1, 1);
+    n = GetInPortSize(block, 1, 2);
+
+    gridSize[0] = 1;
+    gridSize[1] = n;
+    gridSize[2] = 1;
+    gridSize[3] = m;
+
+    colormapLen = block->ipar[3];
+    if (colormapLen == 1)
+    {
+        dataBounds[0] = 0;      // xMin
+        dataBounds[1] = (double)n;  // xMax
+        dataBounds[2] = 0;      // yMin
+        dataBounds[3] = (double)m;  // yMax
+    }
+    else
+    {
+        dataBounds[0] = block->rpar[colormapLen + 0];   // xMin
+        dataBounds[1] = block->rpar[colormapLen + 1];   // xMax
+        dataBounds[2] = block->rpar[colormapLen + 2];   // yMin
+        dataBounds[3] = block->rpar[colormapLen + 3];   // yMax
+    }
+
+    dataBounds[4] = (double)block->ipar[0]; // zMin
+    dataBounds[5] = (double)block->ipar[1]; // zMax
+
+    rotationAngle[0] = 80;      // alpha
+    rotationAngle[1] = 250;     // theta
+
+    result = setGraphicObjectProperty(pPlot3dUID, __GO_DATA_MODEL_GRID_SIZE__, gridSize, jni_int_vector, 4);
+    result &= setGraphicObjectProperty(pAxeUID, __GO_DATA_BOUNDS__, dataBounds, jni_double_vector, 6);
+    result &= setGraphicObjectProperty(pAxeUID, __GO_ROTATION_ANGLES__, rotationAngle, jni_double_vector, 2);
+
+    return result;
+}
+
+static BOOL setPlot3dSettings(scicos_block * block, char *pPlot3dUID)
+{
+    static const int i__1 = 1;
+    static const double d__1 = 1.0;
+    static const int i__2 = 2;
+    static const int i__4 = 4;
+
+    BOOL result = TRUE;
+
+    result &= setGraphicObjectProperty(pPlot3dUID, __GO_SURFACE_MODE__, &i__1, jni_bool, 1);
+    result &= setGraphicObjectProperty(pPlot3dUID, __GO_LINE_THICKNESS__, &d__1, jni_double, 1);
+
+    result &= setGraphicObjectProperty(pPlot3dUID, __GO_COLOR_MODE__, &i__2, jni_int, 1);
+    result &= setGraphicObjectProperty(pPlot3dUID, __GO_COLOR_FLAG__, &i__1, jni_int, 1);
+    result &= setGraphicObjectProperty(pPlot3dUID, __GO_HIDDEN_COLOR__, &i__4, jni_int, 1);
+
+    return result;
+}
+
+static BOOL setDefaultValues(scicos_block * block, char *pPlot3dUID)
+{
+    int m, n, len;
+    int i;
+    double *values;
+
+    BOOL result;
+
+    m = GetInPortSize(block, 1, 1);
+    n = GetInPortSize(block, 1, 2);
+
+    /*
+     * Share the same memory for 0 allocation (z) and incremented index (x and y)
+     */
+    values = (double *)CALLOC(n * m, sizeof(double));
+    if (values == NULL)
+    {
+        return FALSE;
     }
+    result = setGraphicObjectProperty(pPlot3dUID, __GO_DATA_MODEL_Z__, values, jni_double_vector, m * n);
+
+    len = max(m, n);
+    for (i = 1; i <= len; i++)
+    {
+        values[i] = (double)i;
+    }
+
+    result &= setGraphicObjectProperty(pPlot3dUID, __GO_DATA_MODEL_X__, values, jni_double_vector, n);
+    result &= setGraphicObjectProperty(pPlot3dUID, __GO_DATA_MODEL_Y__, values, jni_double_vector, m);
+
+    FREE(values);
+    return result;
 }
-/*--------------------------------------------------------------------------*/
index 0ab67d7..5186f9c 100644 (file)
-/*  Scicos
-*
-*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
-/*--------------------------------------------------------------------------*/
-/**
-   \file cmatview.c
-   \author Benoit Bayol
-   \version 1.0
-   \date September 2006 - January 2007
-   \brief CMATVIEW is a scope that connects a matrix to a grayplot. The values of the matrix are the values at the nodes
-  \see CMATVIEW.sci in macros/scicos_blocks/Sinks/
-*/
-/*--------------------------------------------------------------------------*/
-#include <math.h>
-#include <stdlib.h>
-#include "DrawingBridge.h"
-#include "scoMemoryScope.h"
-#include "scoWindowScope.h"
-#include "scoMisc.h"
-#include "scoGetProperty.h"
-#include "scoSetProperty.h"
-#include "scicos_block4.h"
-#include "scicos_malloc.h"
-#include "scicos_free.h"
-#include "MALLOC.h"
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2011 - Scilab Enterprises - Clément DAVID
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
 #include "dynlib_scicos_blocks.h"
-/*--------------------------------------------------------------------------*/
-/** \fn cmatview_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
-    \brief Function to draw or redraw the window
+#include "scoUtils.h"
+
+#include "MALLOC.h"
+#include "elementary_functions.h"
+
+#include "getGraphicObjectProperty.h"
+#include "setGraphicObjectProperty.h"
+#include "graphicObjectProperties.h"
+#include "createGraphicObject.h"
+
+#include "CurrentFigure.h"
+
+#include "scicos_block4.h"
+#include "scicos.h"
+#include "math.h"
+
+#include "localization.h"
+
+#include "FigureList.h"
+#include "BuildObjects.h"
+#include "AxesModel.h"
+
+/*****************************************************************************
+ * Internal container structure
+ ****************************************************************************/
+
+/**
+ * Container structure
+ */
+typedef struct
+{
+    struct
+    {
+        char *cachedFigureUID;
+        char *cachedAxeUID;
+        char *cachedGrayplotUID;
+    } scope;
+} sco_data;
+
+/**
+ * Get (and allocate on demand) the internal data used on this scope
+ * \param block the block
+ * \return the scope data
+ */
+static sco_data *getScoData(scicos_block * block);
+
+/**
+ * Release any internal data
+ *
+ * \param block the block
+ */
+static void freeScoData(scicos_block * block);
+
+/**
+ * Push the block data to the polyline
+ *
+ * \param data the data to push
+ *
+ */
+static BOOL pushData(scicos_block * block, double *data);
+
+/*****************************************************************************
+ * Graphics utils
+ ****************************************************************************/
+
+/**
+ * Get (and allocate on demand) the figure associated with the block
+ * \param block the block
+ * \return a valid figure UID or NULL on error
+ */
+static char *getFigure(scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the axe associated with the input
+ *
+ * \param pFigureUID the parent figure UID
+ * \param block the block
+ * \return a valid axe UID or NULL on error
+ */
+static char *getAxe(char *pFigureUID, scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the grayplot
+ *
+ * \param pAxeUID the parent axe UID
+ * \param block the block
+ * \return a valid grayplot UID or NULL on error
+ */
+static char *getGrayplot(char *pAxeUID, scicos_block * block);
+
+/**
+ * Set the grayplot and axes bounds
+ *
+ * \param block the block
+ * \param pAxeUID the axe
+ * \param pGrayplotUID the grayplot
+ */
+static BOOL setBounds(scicos_block * block, char *pAxeUID, char *pGrayplotUID);
+
+/**
+ * Set the grayplot default values
+ *
+ * \param block the block
+ * \param pGrayplotUID the grayplot
+ */
+static BOOL setDefaultValues(scicos_block * block, char *pGrayplotUID);
+
+/*****************************************************************************
+ * Simulation function
+ ****************************************************************************/
+
+/** \fn void cmatview(scicos_block * block,int flag)
+    \brief the computational function
+    \param block A pointer to a scicos_block
+    \param flag An int which indicates the state of the block (init, update, ending)
 */
-SCICOS_BLOCKS_IMPEXP void cmatview_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
+SCICOS_BLOCKS_IMPEXP void cmatview(scicos_block * block, scicos_flag flag)
 {
-  int i = 0; //As usual
-  int * ipar = NULL; //Integer Parameters
-  int win_pos[2]; //Position of the Window
-  int win_dim[2]; //Dimension of the Window
-  int dimension = 2;
-  double * rpar = NULL; //Reals parameters
-  double  ymin = 0., ymax = 0.; //Ymin and Ymax are vectors here
-  double  xmin = 0., xmax = 0.;
-  int number_of_curves_by_subwin = 0;
-  int number_of_subwin = 0;
-  double * mat = NULL;
-  int size_mat = 0;
-  char *label = NULL;
+    char *pFigureUID;
 
-  rpar = GetRparPtrs(block);
-  ipar = GetIparPtrs(block);
-  number_of_subwin = 1;
-  win_pos[0] = -1;
-  win_pos[1] = -1;
-  win_dim[0] = -1;
-  win_dim[1] = -1;
+    double *u;
+    sco_data *sco;
 
-  size_mat = ipar[2];
-  mat = (double*)scicos_malloc(size_mat*sizeof(double));
-  for(i = 0 ; i < size_mat ; i++)
+    int i;
+    BOOL result;
+
+    switch (flag)
+    {
+
+    case Initialization:
+        sco = getScoData(block);
+        if (sco == NULL)
+        {
+            set_block_error(-5);
+        }
+        pFigureUID = getFigure(block);
+        if (pFigureUID == NULL)
+        {
+            // allocation error
+            set_block_error(-5);
+        }
+        break;
+
+    case StateUpdate:
+        pFigureUID = getFigure(block);
+
+        u = GetRealInPortPtrs(block, 1);
+
+        result = pushData(block, u);
+        if (result == FALSE)
+        {
+            Coserror("%s: unable to push some data.", "cmatview");
+            break;
+        }
+        break;
+
+    case Ending:
+        freeScoData(block);
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*****************************************************************************
+ *
+ * Container management
+ *
+ ****************************************************************************/
+
+static sco_data *getScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    BOOL result;
+
+    if (sco == NULL)
+    {
+        /*
+         * Data allocation
+         */
+
+        sco = (sco_data *) MALLOC(sizeof(sco_data));
+        if (sco == NULL)
+            goto error_handler_sco;
+
+        sco->scope.cachedFigureUID = NULL;
+        sco->scope.cachedAxeUID = NULL;
+        sco->scope.cachedGrayplotUID = NULL;
+
+        *(block->work) = sco;
+    }
+
+    return sco;
+
+    /*
+     * Error management (out of normal flow)
+     */
+
+error_handler_sco:
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
+
+static void freeScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+
+    if (sco != NULL)
     {
-      mat[i] = rpar[i+2];
+        FREE(sco);
     }
-  xmax = GetInPortSize(block,1,1);
-  xmin = 0;
-  ymax = GetInPortSize(block,1,2);
-  ymin = 0;
+}
+
+static BOOL pushData(scicos_block * block, double *data)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pGrayplotUID;
+
+    BOOL result;
+    int i;
+
+    int m, n;
+    double alpha, beta;
+    double *scaledData;
 
-  number_of_curves_by_subwin = 1;
-  label = GetLabelPtrs(block);
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+    pGrayplotUID = getGrayplot(pAxeUID, block);
 
-  /*Allocating memory*/
+    m = GetInPortSize(block, 1, 1);
+    n = GetInPortSize(block, 1, 2);
 
-  if(firstdraw == 1)
+    /*
+     * Scale the data
+     */
+    alpha = block->rpar[0];
+    beta = block->rpar[1];
+
+    scaledData = (double *)MALLOC(m * n * sizeof(double));
+    if (scaledData == NULL)
     {
-      scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
+        return FALSE;
     }
 
-  /*Creating the Scope*/
-  scoInitOfWindow(*pScopeMemory, dimension, -1, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, NULL, NULL);
-  if(scoGetScopeActivation(*pScopeMemory) == 1)
+    for (i = 0; i < m * n; i++)
     {
-      sciSetColormap(scoGetPointerScopeWindow(*pScopeMemory), mat , size_mat/3, 3);
-      scoAddTitlesScope(*pScopeMemory,label,"x","y",NULL);
-      scoAddGrayplotForShortDraw(*pScopeMemory,0,0,GetInPortSize(block,1,1),GetInPortSize(block,1,2));
+        scaledData[i] = floor(alpha * data[i] + beta);
     }
-  scicos_free(mat);
 
+    result = setGraphicObjectProperty(pGrayplotUID, __GO_DATA_MODEL_Z__, scaledData, jni_double_vector, m * n);
+    FREE(scaledData);
+
+    return result;
 }
-/*--------------------------------------------------------------------------*/
-/** \fn void cmatview(scicos_block * block, int flag)
-    \brief the computational function
-    \param block A pointer to a scicos_block
-    \param flag An int which indicates the state of the block (init, update, ending)
-*/
-SCICOS_BLOCKS_IMPEXP void cmatview(scicos_block * block, int flag)
+
+/*****************************************************************************
+ *
+ * Graphic utils
+ *
+ ****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Graphic
+ *
+ ****************************************************************************/
+
+static char *getFigure(scicos_block * block)
 {
-  /* Declarations */
-  ScopeMemory * pScopeMemory = NULL;
-  scoGraphicalObject pShortDraw;
-  double * u1 = NULL;
-  double alpha = 0.,beta = 0.;
-  int i = 0, j = 0;
-  double * rpar = NULL;
-  int dim_i = 0, dim_j = 0;
-  /* Initializations and Allocations*/
-  //Allocations are done here because there are dependent of some values presents below
-
-  /* State Machine Control */
-  switch(flag)
+    signed int figNum;
+    char *pFigureUID = NULL;
+    char *pAxe = NULL;
+    static const int i__1 = 1;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    int i, j;
+
+    // fast path for an existing object
+    if (sco->scope.cachedFigureUID != NULL)
     {
-    case Initialization:
-      {
-       cmatview_draw(block,&pScopeMemory,1);
-       break;
-      }
-    case StateUpdate:
-      {
-       /*Retreiving Scope in the block->work*/
-       scoRetrieveScopeMemory(block->work,&pScopeMemory);
-       if(scoGetScopeActivation(pScopeMemory) == 1)
-         {
-           /* If window has been destroyed we recreate it */
-           if(scoGetPointerScopeWindow(pScopeMemory) == NULL)
-             {
-               cmatview_draw(block,&pScopeMemory,0);
-             }
-
-           pShortDraw = scoGetPointerShortDraw(pScopeMemory,0,0);
-           rpar = GetRparPtrs(block);
-           alpha = rpar[0];
-           beta = rpar[1];
-           u1 = GetInPortPtrs(block,1);
-
-           dim_i = GetInPortRows(block,1);
-           dim_j = GetInPortCols(block,1);
-
-           for(i = 0 ; i < dim_i ; i++)
-             {
-               for(j = 0; j < dim_j ; j++)
-                 {
-                   pGRAYPLOT_FEATURE(pShortDraw)->pvecz[i*dim_j+j] = floor(alpha*u1[j+i*dim_j]+beta);
-                 }
-             }
-           sciSetUsedWindow(scoGetWindowID(pScopeMemory));
-           if(sciGetPixmapMode(scoGetPointerScopeWindow(pScopeMemory)))
-             {
-                         /* TODO : not implemented */
-                         /*C2F(dr)("xset","wshow",PI0,PI0,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);*/
-             }
-           sciDrawObj(scoGetPointerShortDraw(pScopeMemory,0,0));
-         }
-       break;
-      }//End of stateupdate
-    case Ending:
-      {
-                               scoRetrieveScopeMemory(block->work, &pScopeMemory);
-                               if(scoGetScopeActivation(pScopeMemory) == 1)
-                               {
-                                       /* sciSetUsedWindow(scoGetWindowID(pScopeMemory)); */
-                                       /*pShortDraw = sciGetCurrentFigure(); */
-                                       /*pFIGURE_FEATURE(pShortDraw)->user_data = NULL; */
-                                       /*pFIGURE_FEATURE(pShortDraw)->size_of_user_data = 0; */
-                                       /* Check if figure is still opened, otherwise, don't try to destroy it again. */
-                                       scoGraphicalObject figure = scoGetPointerScopeWindow(pScopeMemory);
-                                       if (figure != NULL)
-                                       {
-                                               /*pShortDraw = scoGetPointerScopeWindow(pScopeMemory);*/
-                                               clearUserData(figure);
-                                       }
-                               }
-                               scoFreeScopeMemory(block->work, &pScopeMemory);
-                               break;
-      }
+        return sco->scope.cachedFigureUID;
+    }
+
+    figNum = block->ipar[0];
+
+    // with a negative id, use the block number indexed from a constant.
+    if (figNum < 0)
+    {
+        figNum = 20000 + get_block_number();
+    }
+
+    pFigureUID = getFigureFromIndex(figNum);
+    // create on demand
+    if (pFigureUID == NULL)
+    {
+        pFigureUID = createNewFigureWithAxes();
+        setGraphicObjectProperty(pFigureUID, __GO_ID__, &figNum, jni_int, 1);
+
+        setGraphicObjectProperty(pFigureUID, __GO_COLORMAP__, &block->rpar[2], jni_double_vector, block->ipar[2]);
+
+        // allocate the axes through the getter
+        pAxe = getAxe(pFigureUID, block);
+
+        /*
+         * Setup according to block settings
+         */
+        setLabel(pAxe, __GO_X_AXIS_LABEL__, "x");
+        setLabel(pAxe, __GO_Y_AXIS_LABEL__, "y");
+
+        setGraphicObjectProperty(pAxe, __GO_X_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+        setGraphicObjectProperty(pAxe, __GO_Y_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+
+        sco->scope.cachedFigureUID = pFigureUID;
+    }
+
+    if (sco->scope.cachedFigureUID == NULL)
+    {
+        sco->scope.cachedFigureUID = pFigureUID;
+    }
+    return pFigureUID;
+}
+
+static char *getAxe(char *pFigureUID, scicos_block * block)
+{
+    char *pAxe;
+    int i;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedAxeUID != NULL)
+    {
+        return sco->scope.cachedAxeUID;
+    }
+
+    pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, 0);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pAxe == NULL)
+    {
+        pAxe = cloneGraphicObject(getAxesModel());
+
+        if (pAxe != NULL)
+        {
+            setGraphicObjectRelationship(pFigureUID, pAxe);
+
+            getGrayplot(pAxe, block);
+        }
+    }
+
+    if (sco->scope.cachedAxeUID == NULL)
+    {
+        sco->scope.cachedAxeUID = pAxe;
+    }
+    return pAxe;
+}
+
+static char *getGrayplot(char *pAxeUID, scicos_block * block)
+{
+    char *pGrayplot;
+    static const double d__0 = 0.0;
+    static const int i__0 = 0;
+    static const BOOL b__true = TRUE;
+
+    int color;
+
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedGrayplotUID != NULL)
+    {
+        return sco->scope.cachedGrayplotUID;
+    }
+
+    pGrayplot = findChildWithKindAt(pAxeUID, __GO_GRAYPLOT__, 1);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pGrayplot == NULL)
+    {
+        pGrayplot = createGraphicObject(__GO_GRAYPLOT__);
+
+        if (pGrayplot != NULL)
+        {
+            createDataObject(pGrayplot, __GO_GRAYPLOT__);
+            setGraphicObjectRelationship(pAxeUID, pGrayplot);
+
+            setGraphicObjectProperty(pGrayplot, __GO_DATA_MAPPING__, &i__0, jni_int, 1);
+            setBounds(block, pAxeUID, pGrayplot);
+            setDefaultValues(block, pGrayplot);
+        }
+    }
+
+    if (sco->scope.cachedGrayplotUID == NULL)
+    {
+        sco->scope.cachedGrayplotUID = pGrayplot;
+    }
+    return pGrayplot;
+}
+
+static BOOL setBounds(scicos_block * block, char *pAxeUID, char *pGrayplotUID)
+{
+    BOOL result;
+
+    int gridSize[4];
+    double dataBounds[6];
+
+    int m, n;
+
+    m = GetInPortSize(block, 1, 1);
+    n = GetInPortSize(block, 1, 2);
+
+    gridSize[0] = m;
+    gridSize[1] = 1;
+    gridSize[2] = n;
+    gridSize[3] = 1;
+
+    dataBounds[0] = 0;          // xMin
+    dataBounds[1] = (double)m;  // xMax
+    dataBounds[2] = 0;          // yMin
+    dataBounds[3] = (double)n;  // yMax
+    dataBounds[4] = -1.0;       // zMin
+    dataBounds[5] = 1.0;        // zMax
+
+    result = setGraphicObjectProperty(pGrayplotUID, __GO_DATA_MODEL_GRID_SIZE__, gridSize, jni_int_vector, 4);
+    result &= setGraphicObjectProperty(pAxeUID, __GO_DATA_BOUNDS__, dataBounds, jni_double_vector, 6);
+
+    return result;
+}
+
+static BOOL setDefaultValues(scicos_block * block, char *pGrayplotUID)
+{
+    int m, n, len;
+    int i;
+    double *values;
+
+    BOOL result;
+
+    m = GetInPortSize(block, 1, 1);
+    n = GetInPortSize(block, 1, 2);
+
+    len = max(m, n);
+
+    values = (double *)CALLOC(n * m, sizeof(double));
+    if (values == NULL)
+    {
+        return FALSE;
     }
+
+    result = setGraphicObjectProperty(pGrayplotUID, __GO_DATA_MODEL_Z__, values, jni_double_vector, m * n);
+
+    for (i = 1; i <= len; i++)
+    {
+        values[i] = (double)i;
+    }
+    result &= setGraphicObjectProperty(pGrayplotUID, __GO_DATA_MODEL_X__, values, jni_double_vector, m);
+    result &= setGraphicObjectProperty(pGrayplotUID, __GO_DATA_MODEL_Y__, values, jni_double_vector, n);
+
+    FREE(values);
+    return result;
 }
-/*--------------------------------------------------------------------------*/
index ea60a6c..8d14beb 100644 (file)
-/*  Scicos
-*
-*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
-/*--------------------------------------------------------------------------*/
-/**
-   \file cmscope.c
-   \author Benoit Bayol
-   \version 1.0
-   \date September 2006 - January 2007
-   \brief CMSCOPE is a typical scope which links its input to the simulation time
-   \see CMSCOPE.sci in macros/scicos_blocks/Sinks/
-*/
-/*--------------------------------------------------------------------------*/
-#include "scicos.h"
-#include "scoMemoryScope.h"
-#include "scoWindowScope.h"
-#include "scoMisc.h"
-#include "scoGetProperty.h"
-#include "scoSetProperty.h"
-#include "scicos_block4.h"
-#include "SetJavaProperty.h"
-#include "scicos_malloc.h"
-#include "scicos_free.h"
-#include "MALLOC.h"
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2011 - Scilab Enterprises - Clément DAVID
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
 #include "dynlib_scicos_blocks.h"
-/*--------------------------------------------------------------------------*/
-/** \fn cmscope_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
-    \brief Function to draw or redraw the window
+#include "scoUtils.h"
+
+#include "MALLOC.h"
+#include "elementary_functions.h"
+
+#include "getGraphicObjectProperty.h"
+#include "setGraphicObjectProperty.h"
+#include "graphicObjectProperties.h"
+#include "createGraphicObject.h"
+
+#include "CurrentFigure.h"
+
+#include "scicos_block4.h"
+#include "scicos.h"
+
+#include "localization.h"
+
+#include "FigureList.h"
+#include "BuildObjects.h"
+#include "AxesModel.h"
+
+/*****************************************************************************
+ * Internal container structure
+ ****************************************************************************/
+
+/**
+ * Container structure
+ */
+typedef struct
+{
+    struct
+    {
+        int numberOfPoints;
+        int maxNumberOfPoints;
+        double *time;
+        double ***data;
+    } internal;
+
+    struct
+    {
+        int periodCounter;
+
+        char *cachedFigureUID;
+        char **cachedAxeUID;
+        char ***cachedPolylinesUIDs;
+    } scope;
+} sco_data;
+
+/**
+ * Get (and allocate on demand) the internal data used on this scope
+ * \param block the block
+ * \return the scope data
+ */
+static sco_data *getScoData(scicos_block * block);
+
+/**
+ * Release any internal data
+ *
+ * \param block the block
+ */
+static void freeScoData(scicos_block * block);
+
+/**
+ * Append the data to the current data
+ *
+ * \param block the block
+ * \param input the input (0-indexed)
+ * \param t the current time
+ * \param data the data to append
+ */
+static void appendData(scicos_block * block, int input, double t, double *data);
+
+/**
+ * Push the block data to the polyline
+ *
+ * \param block the block
+ * \param input the selected input
+ * \param row the selected row
+ * \param pPolylineUID the polyline uid
+ *
+ */
+static BOOL pushData(scicos_block * block, int input, int row);
+
+/*****************************************************************************
+ * Graphics utils
+ ****************************************************************************/
+
+/**
+ * Get (and allocate on demand) the figure associated with the block
+ * \param block the block
+ * \return a valid figure UID or NULL on error
+ */
+static char *getFigure(scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the axe associated with the input
+ *
+ * \param pFigureUID the parent figure UID
+ * \param block the block
+ * \param input the current input index (0-indexed)
+ * \return a valid axe UID or NULL on error
+ */
+static char *getAxe(char *pFigureUID, scicos_block * block, int input);
+
+/**
+ * Get (and allocate on demand) the polyline associated with the row
+ *
+ * \param pAxeUID the parent axe UID
+ * \param block the block
+ * \param input the current input index (0-indexed)
+ * \param row the current row index (0-indexed)
+ * \return a valid polyline UID or NULL on error
+ */
+static char *getPolyline(char *pAxeUID, scicos_block * block, int input, int row);
+
+/**
+ * Set the polylines buffer size
+ *
+ * \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);
+
+/**
+ * Set the polylines bounds
+ *
+ * \param block the block
+ * \param input the input port index
+ * \param periodCounter number of past periods since startup
+ */
+static BOOL setPolylinesBounds(scicos_block * block, int input, int periodCounter);
+
+/*****************************************************************************
+ * Simulation function
+ ****************************************************************************/
+
+/** \fn void cmscope(scicos_block * block,int flag)
+    \brief the computational function
+    \param block A pointer to a scicos_block
+    \param flag An int which indicates the state of the block (init, update, ending)
 */
-SCICOS_BLOCKS_IMPEXP void cmscope_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
+SCICOS_BLOCKS_IMPEXP void cmscope(scicos_block * block, scicos_flag flag)
+{
+    char *pFigureUID;
+
+    double t;
+    double *u;
+    sco_data *sco;
+
+    int i, j;
+    BOOL result;
+
+    switch (flag)
+    {
+
+    case Initialization:
+        sco = getScoData(block);
+        if (sco == NULL)
+        {
+            set_block_error(-5);
+        }
+        pFigureUID = getFigure(block);
+        if (pFigureUID == NULL)
+        {
+            // allocation error
+            set_block_error(-5);
+        }
+        break;
+
+    case StateUpdate:
+        pFigureUID = getFigure(block);
+
+        t = get_scicos_time();
+        for (i = 0; i < block->nin; i++)
+        {
+            u = (double *)block->inptr[i];
+
+            appendData(block, i, t, u);
+            for (j = 0; j < block->insz[i]; j++)
+            {
+                result = pushData(block, i, j);
+                if (result == FALSE)
+                {
+                    Coserror("%s: unable to push some data.", "cmscope");
+                    break;
+                }
+            }
+        }
+        break;
+
+    case Ending:
+        freeScoData(block);
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*****************************************************************************
+ *
+ * Container management
+ *
+ ****************************************************************************/
+
+static sco_data *getScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j, k, l;
+    BOOL result;
+
+    if (sco == NULL)
+    {
+        /*
+         * Data allocation
+         */
+
+        sco = (sco_data *) MALLOC(sizeof(sco_data));
+        if (sco == NULL)
+            goto error_handler_sco;
+
+        sco->internal.numberOfPoints = 0;
+        sco->internal.maxNumberOfPoints = block->ipar[2];
+
+        sco->internal.data = (double ***)CALLOC(block->nin, sizeof(double **));
+        if (sco->internal.data == NULL)
+            goto error_handler_data;
+
+        for (i = 0; i < block->nin; i++)
+        {
+            sco->internal.data[i] = (double **)CALLOC(block->insz[i], sizeof(double *));
+            if (sco->internal.data[i] == NULL)
+                goto error_handler_data_i;
+        }
+        for (i = 0; i < block->nin; i++)
+        {
+            for (j = 0; j < block->insz[i]; j++)
+            {
+                sco->internal.data[i][j] = (double *)CALLOC(block->ipar[2], sizeof(double));
+
+                if (sco->internal.data[i][j] == NULL)
+                    goto error_handler_data_ij;
+            }
+        }
+
+        sco->internal.time = (double *)CALLOC(block->ipar[2], sizeof(double));
+        if (sco->internal.time == NULL)
+        {
+            goto error_handler_time;
+        }
+
+        sco->scope.periodCounter = 0;
+        sco->scope.cachedFigureUID = NULL;
+        sco->scope.cachedAxeUID = (char **)CALLOC(block->nin, sizeof(char *));
+
+        sco->scope.cachedPolylinesUIDs = (char ***)CALLOC(block->nin, sizeof(char **));
+        for (i = 0; i < block->nin; i++)
+        {
+            sco->scope.cachedPolylinesUIDs[i] = (char **)CALLOC(block->insz[i], sizeof(char *));
+        }
+
+        *(block->work) = sco;
+    }
+
+    return sco;
+
+    /*
+     * Error management (out of normal flow)
+     */
+
+error_handler_time:
+error_handler_data_ij:
+    for (k = 0; k < i; k++)
+    {
+        for (l = 0; l < j; l++)
+        {
+            FREE(sco->internal.data[k][l]);
+        }
+    }
+    i = block->nin - 1;
+error_handler_data_i:
+    for (j = 0; j < i; j++)
+    {
+        FREE(sco->internal.data[i]);
+    }
+    FREE(sco->internal.data);
+error_handler_data:
+    FREE(sco);
+error_handler_sco:
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
+
+static void freeScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+
+    if (sco != NULL)
+    {
+        for (i = 0; i < block->nin; i++)
+        {
+            for (j = 0; j < block->insz[i]; j++)
+            {
+                FREE(sco->internal.data[i][j]);
+            }
+            FREE(sco->internal.data[i]);
+        }
+
+        FREE(sco->internal.data);
+        FREE(sco->internal.time);
+
+//      Commented due to the C++ allocation
+//      see http://bugzilla.scilab.org/show_bug.cgi?id=9747
+//      FREE(sco->scope.cachedFigureUID);
+//      sco->scope.cachedFigureUID = NULL;
+//      for (i=0; i<block->nin; i++) {
+//          for (j=0; j<block->insz[i]; j++) {
+//              FREE(sco->scope.cachedPolylinesUIDs[i][j]);
+//              sco->scope.cachedPolylinesUIDs[i][j] = NULL;
+//          }
+//          FREE(sco->scope.cachedAxeUID[i]);
+//          sco->scope.cachedAxeUID[i] = NULL;
+//      }
+
+        FREE(sco);
+    }
+}
+
+static sco_data *reallocScoData(scicos_block * block, int numberOfPoints)
 {
-  int i = 0; //As usual
-  int * ipar = NULL; //Integer Parameters
-  int * colors = NULL; //Colors
-  int win = 0; //Windows ID : To give a name to the window
-  int buffer_size = 0; //Buffer Size
-  int win_pos[2]; //Position of the Window
-  int win_dim[2]; //Dimension of the Window
-  int inherited_events = 0;
-  int nipar = 0;
-  int dimension = 2;
-  double * rpar = NULL; //Reals parameters
-  double dt = 0.; //Time++
-  double * period = NULL; //Refresh Period of the scope is a vector here
-  double * ymin = NULL,* ymax = NULL; //Ymin and Ymax are vectors here
-  double * xmin = NULL, *xmax = NULL;
-  int nbr_period = 0;
-  int * number_of_curves_by_subwin = NULL;
-  int number_of_subwin = 0;
-  int nbr_total_curves = 0;
-  char *label = NULL;
-
-
-  rpar = GetRparPtrs(block);
-  ipar = GetIparPtrs(block);
-  nipar = GetNipar(block);
-  win = ipar[0];
-  number_of_subwin = ipar[1];
-  buffer_size = ipar[2];
-  win_pos[0] = ipar[3];
-  win_pos[1] = ipar[4];
-  win_dim[0] = ipar[5];
-  win_dim[1] = ipar[6];
-  label = GetLabelPtrs(block);
-  nbr_total_curves = 0;
-  //Don't forget malloc for 'type *'
-  number_of_curves_by_subwin = (int*)scicos_malloc(number_of_subwin*sizeof(int));
-  for (i = 7; i < 7+number_of_subwin ; i++)
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+    double *ptr;
+    int setLen;
+
+    for (i = 0; i < block->nin; i++)
     {
-      number_of_curves_by_subwin[i-7] = ipar[i];
-      nbr_total_curves = nbr_total_curves + ipar[i];
+        for (j = 0; j < block->insz[i]; j++)
+        {
+            ptr = (double *)REALLOC(sco->internal.data[i][j], numberOfPoints * sizeof(double));
+            if (ptr == NULL)
+                goto error_handler;
+
+            for (setLen = sco->internal.maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+                ptr[sco->internal.maxNumberOfPoints + setLen] = ptr[sco->internal.maxNumberOfPoints - 1];
+            sco->internal.data[i][j] = ptr;
+        }
     }
-  colors = (int*)scicos_malloc(nbr_total_curves*sizeof(int));
-  for(i = 0; i < nbr_total_curves ; i++)
+
+    ptr = (double *)REALLOC(sco->internal.time, numberOfPoints * sizeof(double));
+    if (ptr == NULL)
+        goto error_handler;
+
+    for (setLen = sco->internal.maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+        ptr[sco->internal.maxNumberOfPoints + setLen] = ptr[sco->internal.maxNumberOfPoints - 1];
+    sco->internal.time = ptr;
+
+    sco->internal.maxNumberOfPoints = numberOfPoints;
+    return sco;
+
+error_handler:
+    freeScoData(block);
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
+
+static void appendData(scicos_block * block, int input, double t, double *data)
+{
+    int i;
+    static const int i__1 = 1;
+
+    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
+     */
+    if (t > ((sco->scope.periodCounter + 1) * block->rpar[1 + input]))
     {
-      colors[i] = ipar[i+7+number_of_subwin];
+        sco->scope.periodCounter++;
+
+        numberOfPoints = 0;
+        sco->internal.numberOfPoints = 0;
+        if (setPolylinesBounds(block, input, sco->scope.periodCounter) == FALSE)
+        {
+            set_block_error(-5);
+            freeScoData(block);
+            sco = NULL;
+        }
     }
-  inherited_events = ipar[7+number_of_subwin+number_of_subwin];
 
-  dt = rpar[0];
+    /*
+     * Handle the case where the scope has more points than maxNumberOfPoints
+     */
+    if (sco != NULL && numberOfPoints >= maxNumberOfPoints)
+    {
+        // on a full scope, re-alloc
+        maxNumberOfPoints = maxNumberOfPoints + block->ipar[2];
+        sco = reallocScoData(block, maxNumberOfPoints);
+
+        // reconfigure related graphic objects
+        if (setPolylinesBuffers(block, input, maxNumberOfPoints) == FALSE)
+        {
+            set_block_error(-5);
+            freeScoData(block);
+            sco = NULL;
+        }
+    }
 
-  nbr_period = 0;
-  period = (double*)scicos_malloc(number_of_subwin*sizeof(double));
-  for (i = 0 ; i < number_of_subwin ; i++)
+    /*
+     * Update data
+     */
+    if (sco != NULL)
     {
-      period[i] = rpar[i+1];
-      nbr_period++;
+        int setLen;
+
+        for (i = 0; i < block->insz[input]; i++)
+        {
+            for (setLen = maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+                sco->internal.data[input][i][numberOfPoints + setLen] = data[i];
+        }
+
+        for (setLen = maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+            sco->internal.time[numberOfPoints + setLen] = t;
+
+        sco->internal.numberOfPoints++;
     }
-  ymin = (double*)scicos_malloc(number_of_subwin*sizeof(double));
-  ymax = (double*)scicos_malloc(number_of_subwin*sizeof(double));
-  for (i = 0 ; i < number_of_subwin ; i++)
+}
+
+static BOOL pushData(scicos_block * block, int input, int row)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pPolylineUID;
+
+    static const int i__0 = 0;
+
+    double *data;
+    sco_data *sco;
+
+    BOOL result = TRUE;
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block, input);
+    pPolylineUID = getPolyline(pAxeUID, block, input, row);
+
+    sco = getScoData(block);
+    if (sco == NULL)
+        return FALSE;
+
+    // select the right input and row
+    data = sco->internal.data[input][row];
+
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_X__, sco->internal.time, jni_double_vector, sco->internal.maxNumberOfPoints);
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_Y__, data, jni_double_vector, sco->internal.maxNumberOfPoints);
+
+    return result;
+}
+
+/*****************************************************************************
+ *
+ * Graphic utils
+ *
+ ****************************************************************************/
+
+/**
+ * Set properties on the figure.
+ *
+ * \param pFigureUID the figure uid
+ * \param block the current block
+ */
+static void setFigureSettings(char *pFigureUID, scicos_block * block)
+{
+    int win_pos[2];
+    int win_dim[2];
+
+    int *ipar = block->ipar;
+
+    win_pos[0] = ipar[3];
+    win_pos[1] = ipar[4];
+    win_dim[0] = ipar[5];
+    win_dim[1] = ipar[6];
+
+    setGraphicObjectProperty(pFigureUID, __GO_POSITION__, &win_pos, jni_int_vector, 2);
+    setGraphicObjectProperty(pFigureUID, __GO_SIZE__, &win_dim, jni_int_vector, 2);
+};
+
+/**
+ * Set properties on the axes.
+ *
+ * \param pAxeUID the axe uid
+ * \param block the current block
+ * \param index axe index (0-indexed)
+ */
+static void setAxesSettings(char *pAxeUID, scicos_block * block, int index)
+{
+    double axesBounds[4];
+    double margins[4];
+
+    double nin = (double)block->nin;
+
+    axesBounds[0] = 0;          // x
+    axesBounds[1] = index / nin;    // y
+    axesBounds[2] = 1.0;        // w
+    axesBounds[3] = 1 / nin;    // h
+    setGraphicObjectProperty(pAxeUID, __GO_AXES_BOUNDS__, axesBounds, jni_double_vector, 4);
+
+    margins[0] = 0.125;
+    margins[1] = 0.125;
+    margins[2] = 0.125;
+    margins[3] = 0.125;
+    setGraphicObjectProperty(pAxeUID, __GO_MARGINS__, margins, jni_double_vector, 4);
+
+};
+
+/*****************************************************************************
+ *
+ * Graphic
+ *
+ ****************************************************************************/
+
+static char *getFigure(scicos_block * block)
+{
+    signed int figNum;
+    char *pFigureUID = NULL;
+    char *pAxe = NULL;
+    static const int i__1 = 1;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    int i, j;
+
+    // fast path for an existing object
+    if (sco->scope.cachedFigureUID != NULL)
     {
-      ymin[i] = rpar[2*i+nbr_period+1];
-      ymax[i] = rpar[2*i+nbr_period+2];
+        return sco->scope.cachedFigureUID;
     }
 
-  /*Allocating memory*/
-  if(firstdraw == 1)
+    figNum = block->ipar[0];
+
+    // with a negative id, use the block number indexed from a constant.
+    if (figNum < 0)
     {
+        figNum = 20000 + get_block_number();
+    }
 
-      scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, number_of_curves_by_subwin);
-      for(i = 0 ; i < number_of_subwin ; i++)
+    pFigureUID = getFigureFromIndex(figNum);
+    // create on demand
+    if (pFigureUID == NULL)
     {
-      scoSetLongDrawSize(*pScopeMemory, i, 5000);
-      scoSetShortDrawSize(*pScopeMemory,i,buffer_size);
-      scoSetPeriod(*pScopeMemory,i,period[i]);
+        pFigureUID = createNewFigureWithAxes();
+        setGraphicObjectProperty(pFigureUID, __GO_ID__, &figNum, jni_int, 1);
+
+        // set configured parameters
+        setFigureSettings(pFigureUID, block);
+        sco->scope.cachedFigureUID = pFigureUID;
+
+        // allocate the axes through the getter
+        for (i = 0; i < GetNin(block); i++)
+        {
+            pAxe = getAxe(pFigureUID, block, i);
+
+            /*
+             * Setup according to block settings
+             */
+            setLabel(pAxe, __GO_X_AXIS_LABEL__, "t");
+            setLabel(pAxe, __GO_Y_AXIS_LABEL__, "y");
+
+            setGraphicObjectProperty(pAxe, __GO_X_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+            setGraphicObjectProperty(pAxe, __GO_Y_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+
+            setPolylinesBounds(block, i, 0);
+        }
     }
+
+    if (sco->scope.cachedFigureUID == NULL)
+    {
+        sco->scope.cachedFigureUID = pFigureUID;
     }
+    return pFigureUID;
+}
+
+static char *getAxe(char *pFigureUID, scicos_block * block, int input)
+{
+    char *pAxe;
+    int i;
+    sco_data *sco = (sco_data *) * (block->work);
 
-  /* 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*/
-  xmin = (double*)scicos_malloc(number_of_subwin*sizeof(double));
-  xmax = (double*)scicos_malloc(number_of_subwin*sizeof(double));
-  for (i = 0 ; i < number_of_subwin ; i++)
+    // fast path for an existing object
+    if (sco->scope.cachedAxeUID != NULL && sco->scope.cachedAxeUID[input] != NULL)
     {
-      xmin[i] = period[i]*(scoGetPeriodCounter(*pScopeMemory,i));
-      xmax[i] = period[i]*(scoGetPeriodCounter(*pScopeMemory,i)+1);
+        return sco->scope.cachedAxeUID[input];
     }
 
-  /*Creating the Scope*/
-  scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, xmin, xmax, ymin, ymax, NULL, NULL);
-  if(scoGetScopeActivation(*pScopeMemory) == 1)
+    pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, input);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pAxe == NULL)
     {
-      scoAddTitlesScope(*pScopeMemory,label,"t","y",NULL);
+        pAxe = cloneGraphicObject(getAxesModel());
 
-  /*Add a couple of polyline : one for the shortdraw and one for the longdraw*/
-  /*     scoAddPolylineLineStyle(*pScopeMemory,colors); */
-      scoAddCoupleOfPolylines(*pScopeMemory,colors);
+        if (pAxe != NULL)
+        {
+            setGraphicObjectRelationship(pFigureUID, pAxe);
+
+            // allocate the polylines through the getter
+            for (i = 0; i < block->insz[input]; i++)
+            {
+                getPolyline(pAxe, block, input, i);
+            }
+        }
     }
-  scicos_free(number_of_curves_by_subwin);
-  scicos_free(colors);
-  scicos_free(period);
-  scicos_free(ymin);
-  scicos_free(ymax);
-  scicos_free(xmin);
-  scicos_free(xmax);
-
-  /* use only single buffering to be sure to draw on the screen */
-  if (scoGetPointerScopeWindow(*pScopeMemory) != NULL) {
-    sciSetJavaUseSingleBuffer(scoGetPointerScopeWindow(*pScopeMemory), TRUE);
-  }
+
+    if (sco->scope.cachedAxeUID != NULL)
+    {
+        setAxesSettings(pAxe, block, input);
+        sco->scope.cachedAxeUID[input] = pAxe;
+    }
+    return pAxe;
 }
-/*--------------------------------------------------------------------------*/
-/** \fn void cmscope(scicos_block * block, int flag)
-    \brief the computational function
-    \param block A pointer to a scicos_block
-    \param flag An int which indicates the state of the block (init, update, ending)
-*/
-SCICOS_BLOCKS_IMPEXP void cmscope(scicos_block * block, int flag)
+
+static char *getPolyline(char *pAxeUID, scicos_block * block, int input, int row)
 {
-  /* Declarations */
-  ScopeMemory * pScopeMemory = NULL;
-  int NbrPtsShort = 0;
-  double * u1 = NULL;
-  double t = 0.; //get_scicos_time()
-  scoGraphicalObject pShortDraw;
-  int i = 0,j = 0;
+    char *pPolyline;
+    static const double d__0 = 0.0;
+    static const int i__1 = 1;
+    static const BOOL b__true = TRUE;
 
-  double d_current_real_time = 0. ;
+    int color;
 
-  /* Initializations and Allocations*/
-  //Allocations are done here because there are dependent of some values presents below
+    sco_data *sco = (sco_data *) * (block->work);
 
-  /* State Machine Control */
-  switch(flag)
+    // fast path for an existing object
+    if (sco->scope.cachedPolylinesUIDs != NULL && sco->scope.cachedPolylinesUIDs[input] != NULL && sco->scope.cachedPolylinesUIDs[input][row] != NULL)
     {
-    case Initialization:
-      {
-    cmscope_draw(block,&pScopeMemory,1);
+        return sco->scope.cachedPolylinesUIDs[input][row];
+    }
 
-        //** Init the real time section
-          //** current real time as double [second]
-          d_current_real_time = scoGetRealTime();
-          pScopeMemory->d_last_scope_update_time = d_current_real_time ; //** update the ds for the next step
+    pPolyline = findChildWithKindAt(pAxeUID, __GO_POLYLINE__, row);
 
-    break; //Break of the switch condition: dont forget it
-      } //End of Initialization
+    /*
+     * Allocate if necessary
+     */
+    if (pPolyline == NULL)
+    {
+        pPolyline = createGraphicObject(__GO_POLYLINE__);
 
-    case StateUpdate:
-      {
-    /*Retreiving Scope in the block->work*/
-    scoRetrieveScopeMemory(block->work,&pScopeMemory);
-    if(scoGetScopeActivation(pScopeMemory) == 1)
-      {
-        /* Charging Elements */
-        t = get_scicos_time();
-        /* If window has been destroyed we recreate it */
-        if(scoGetPointerScopeWindow(pScopeMemory) == NULL)
-          {
-        cmscope_draw(block,&pScopeMemory,0);
-          }
-
-        scoRefreshDataBoundsX(pScopeMemory,t);
-
-        //Here we are calculating the points in the polylines
-        for (i = 0 ; i < scoGetNumberOfSubwin(pScopeMemory) ; i++)
-          {
-        u1 = GetRealInPortPtrs(block,i+1);
-        pShortDraw = scoGetPointerShortDraw(pScopeMemory,i,0);
-        NbrPtsShort = pPOLYLINE_FEATURE(pShortDraw)->n1;
-        for (j = 0; j < scoGetNumberOfCurvesBySubwin(pScopeMemory,i) ; j++)
-          {
-            pShortDraw = scoGetPointerShortDraw(pScopeMemory,i,j);
-            pPOLYLINE_FEATURE(pShortDraw)->pvx[NbrPtsShort] = t;
-            pPOLYLINE_FEATURE(pShortDraw)->pvy[NbrPtsShort] = u1[j];
-            pPOLYLINE_FEATURE(pShortDraw)->n1++;
-          }
-          }
-
-            // Draw the Scope
-        scoDrawScopeAmplitudeTimeStyle(pScopeMemory, t); //** the scope update condition
-                                                             //** is hidden here
-
-      }
-    break;
-
-      } //**End of stateupdate
-
-   //** Ending is activated when the simulation is done or when we close Scicos
-    case Ending:
-      {
-    scoRetrieveScopeMemory(block->work, &pScopeMemory);
-    if(scoGetScopeActivation(pScopeMemory) == 1)
-      {
-      //  sciSetUsedWindow(scoGetWindowID(pScopeMemory));
-      //  pShortDraw = sciGetCurrentFigure();
-      //  pFIGURE_FEATURE(pShortDraw)->user_data = NULL;
-      //  pFIGURE_FEATURE(pShortDraw)->size_of_user_data = 0;
-            ///* restore double buffering */
-            //sciSetJavaUseSingleBuffer(pShortDraw, FALSE);
-      //  scoDelCoupleOfPolylines(pScopeMemory);
-
-
-            /* Check if figure is still opened, otherwise, don't try to destroy it again. */
-            scoGraphicalObject figure = scoGetPointerScopeWindow(pScopeMemory);
-            if (figure != NULL)
+        if (pPolyline != NULL)
+        {
+            createDataObject(pPolyline, __GO_POLYLINE__);
+            setGraphicObjectRelationship(pAxeUID, pPolyline);
+
+            /*
+             * Default setup (will crash if removed)
+             */
             {
-                /*pShortDraw = scoGetPointerScopeWindow(pScopeMemory);*/
-                clearUserData(figure);
+                int polylineSize[2] = { 1, block->ipar[2] };
+                setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
+            }
 
-                /* restore double buffering */
-                if (figure) {
-                    sciSetJavaUseSingleBuffer(figure, FALSE);
-                }
-                scoDelCoupleOfPolylines(pScopeMemory);
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_X__, &d__0, jni_double_vector, 1);
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_Y__, &d__0, jni_double_vector, 1);
+
+            color = block->ipar[6 + block->nin + input + row];
+            if (color > 0)
+            {
+                setGraphicObjectProperty(pPolyline, __GO_LINE_MODE__, &b__true, jni_bool, 1);
+                setGraphicObjectProperty(pPolyline, __GO_LINE_COLOR__, &color, jni_int, 1);
             }
+            else
+            {
+                color = -color;
+                setGraphicObjectProperty(pPolyline, __GO_MARK_MODE__, &b__true, jni_bool, 1);
+                setGraphicObjectProperty(pPolyline, __GO_MARK_STYLE__, &color, jni_int, 1);
+            }
+        }
+    }
+
+    if (sco->scope.cachedPolylinesUIDs != NULL && sco->scope.cachedPolylinesUIDs[input] != NULL)
+    {
+        sco->scope.cachedPolylinesUIDs[input][row] = pPolyline;
+    }
+    return pPolyline;
+}
 
-      }
+static BOOL setPolylinesBuffers(scicos_block * block, int input, int maxNumberOfPoints)
+{
+    int i;
 
-        scoFreeScopeMemory(block->work, &pScopeMemory);
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pPolylineUID;
 
-        break;
-      }
+    BOOL result = TRUE;
+    int polylineSize[2] = { 1, maxNumberOfPoints };
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block, input);
+
+    for (i = 0; i < block->insz[input]; i++)
+    {
+        pPolylineUID = getPolyline(pAxeUID, block, input, i);
+        result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
     }
+
+    return result;
+}
+
+static BOOL setPolylinesBounds(scicos_block * block, int input, int periodCounter)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+
+    BOOL result;
+    double dataBounds[6];
+    int nin = block->nin;
+    double period = block->rpar[block->nrpar - 3 * nin + input];
+
+    dataBounds[0] = periodCounter * period; // xMin
+    dataBounds[1] = (periodCounter + 1) * period;   // xMax
+    dataBounds[2] = block->rpar[block->nrpar - 2 * nin + 2 * input];    // yMin
+    dataBounds[3] = block->rpar[block->nrpar - 2 * nin + 2 * input + 1];    // yMax
+    dataBounds[4] = -1.0;       // zMin
+    dataBounds[5] = 1.0;        // zMax
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block, input);
+
+    return setGraphicObjectProperty(pAxeUID, __GO_DATA_BOUNDS__, dataBounds, jni_double_vector, 6);
 }
-/*--------------------------------------------------------------------------*/
index 1eba2b8..05551fc 100644 (file)
-/*  Scicos
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2011 - Scilab Enterprises - Clément DAVID
  *
- *  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ */
+
+#include "dynlib_scicos_blocks.h"
+#include "scoUtils.h"
+
+#include "MALLOC.h"
+#include "elementary_functions.h"
+
+#include "getGraphicObjectProperty.h"
+#include "setGraphicObjectProperty.h"
+#include "graphicObjectProperties.h"
+#include "createGraphicObject.h"
+
+#include "CurrentFigure.h"
+
+#include "scicos_block4.h"
+#include "scicos.h"
+
+#include "localization.h"
+
+#include "FigureList.h"
+#include "BuildObjects.h"
+#include "AxesModel.h"
+
+/*****************************************************************************
+ * Internal container structure
+ ****************************************************************************/
+
+/**
+ * Container structure
+ */
+typedef struct
+{
+    struct
+    {
+        int numberOfPoints;
+        int maxNumberOfPoints;
+        double *time;
+        double ***data;
+    } internal;
+
+    struct
+    {
+        int periodCounter;
+
+        char *cachedFigureUID;
+        char *cachedAxeUID;
+        char **cachedPolylinesUIDs;
+    } scope;
+} sco_data;
+
+/**
+ * Get (and allocate on demand) the internal data used on this scope
+ * \param block the block
+ * \return the scope data
+ */
+static sco_data *getScoData(scicos_block * block);
+
+/**
+ * Release any internal data
+ *
+ * \param block the block
+ */
+static void freeScoData(scicos_block * block);
+
+/**
+ * Append the data to the current data
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * \param block the block
+ * \param input the input (0-indexed)
+ * \param t the current time
+ * \param data the data to append
+ */
+static void appendData(scicos_block * block, int input, double t, double *data);
+
+/**
+ * Push the block data to the polyline
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * \param block the block
+ * \param input the selected input
+ * \param row the selected row
+ * \param pPolylineUID the polyline uid
  *
- * See the file ./license.txt
  */
-/*--------------------------------------------------------------------------*/
+static BOOL pushData(scicos_block * block, int input, int row);
+
+/*****************************************************************************
+ * Graphics utils
+ ****************************************************************************/
+
 /**
-   \file cscope.c
-   \author Benoit Bayol
-   \version 1.0
-   \date September 2006 - January 2007
-   \brief CSCOPE is a typical scope which links its input to the simulation time but there is only one input instead of CMSCOPE
-   \see CSCOPE.sci in macros/scicos_blocks/Sinks/
-*/
-/*--------------------------------------------------------------------------*/
-#include <stdio.h>
-#include "scicos.h"
-#include "scoMemoryScope.h"
-#include "scoWindowScope.h"
-#include "scoMisc.h"
-#include "scoGetProperty.h"
-#include "scoSetProperty.h"
-#include "scicos_block4.h"
-#include "SetJavaProperty.h"
-#include "scicos_malloc.h"
-#include "scicos_free.h"
-#include "MALLOC.h"
-#include "dynlib_scicos_blocks.h"
-/*--------------------------------------------------------------------------*/
-/** \fn cscope_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
-    \brief Function to draw or redraw the window
+ * Get (and allocate on demand) the figure associated with the block
+ * \param block the block
+ * \return a valid figure UID or NULL on error
+ */
+static char *getFigure(scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the axe associated with the input
+ *
+ * \param pFigureUID the parent figure UID
+ * \param block the block
+ * \param input the current input index (0-indexed)
+ * \return a valid axe UID or NULL on error
+ */
+static char *getAxe(char *pFigureUID, scicos_block * block, int input);
+
+/**
+ * Get (and allocate on demand) the polyline associated with the row
+ *
+ * \param pAxeUID the parent axe UID
+ * \param block the block
+ * \param row the current row index (0-indexed)
+ * \return a valid polyline UID or NULL on error
+ */
+static char *getPolyline(char *pAxeUID, scicos_block * block, int row);
+
+/**
+ * Set the polylines buffer size
+ *
+ * \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);
+
+/**
+ * Set the polylines bounds
+ *
+ * \param block the block
+ * \param input the input port index
+ * \param periodCounter number of past periods since startup
+ */
+static BOOL setPolylinesBounds(scicos_block * block, int input, int periodCounter);
+
+/*****************************************************************************
+ * Simulation function
+ ****************************************************************************/
+
+/** \fn void cscope(scicos_block * block,int flag)
+    \brief the computational function
+    \param block A pointer to a scicos_block
+    \param flag An int which indicates the state of the block (init, update, ending)
 */
-SCICOS_BLOCKS_IMPEXP void cscope_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
+SCICOS_BLOCKS_IMPEXP void cscope(scicos_block * block, scicos_flag flag)
 {
-    int i = 0;
-    double *rpar = NULL;
-    int *ipar = NULL, nipar = 0;
-    double period = 0.;
-    int dimension = 0;
-    double ymin = 0., ymax = 0., xmin = 0., xmax = 0.;
-    int buffer_size = 0;
-    int win_pos[2];
-    int win_dim[2];
-    int win = 0;
-    int number_of_subwin = 0;
-    int number_of_curves_by_subwin[1];
-    int * colors = NULL;
-    char *label = NULL;
+    char *pFigureUID;
 
-    /*Retrieving Parameters*/
-    rpar = GetRparPtrs(block);
-    ipar = GetIparPtrs(block);
-    nipar = GetNipar(block);
+    double t;
+    double *u;
+    sco_data *sco;
 
-    buffer_size = ipar[2]; //** this is the "standard" buffer size
+    int i;
+    BOOL result;
 
-    win = ipar[0];
-    period  = rpar[3];
-    win_pos[0] = ipar[(nipar-1) - 3];
-    win_pos[1] = ipar[(nipar-1) - 2];
-    win_dim[0] = ipar[(nipar-1) - 1];
-    win_dim[1] = ipar[nipar-1];
-    dimension = 2;
-    number_of_curves_by_subwin[0] = GetInPortRows(block,1);
+    switch (flag)
+    {
 
-    number_of_subwin = 1;
-    ymin = rpar[1];
-    ymax = rpar[2];
-    label = GetLabelPtrs(block);
+    case Initialization:
+        sco = getScoData(block);
+        if (sco == NULL)
+        {
+            set_block_error(-5);
+        }
+        pFigureUID = getFigure(block);
+        if (pFigureUID == NULL)
+        {
+            // allocation error
+            set_block_error(-5);
+        }
+        break;
 
-    colors = (int*)scicos_malloc(number_of_curves_by_subwin[0]*sizeof(int));
-    for(i = 0 ; i < number_of_curves_by_subwin[0] ; i++)
-    {
-        colors[i] = ipar[3+i];
+    case StateUpdate:
+        pFigureUID = getFigure(block);
+
+        t = get_scicos_time();
+        u = GetRealInPortPtrs(block, 1);
+
+        appendData(block, 0, t, u);
+
+        for (i = 0; i < block->insz[0]; i++)
+        {
+            result = pushData(block, 0, i);
+            if (result == FALSE)
+            {
+                Coserror("%s: unable to push some data.", "cscope");
+                break;
+            }
+        }
+        break;
+
+    case Ending:
+        freeScoData(block);
+        break;
+
+    default:
+        break;
     }
+}
+
+/*-------------------------------------------------------------------------*/
 
-    /*Allocating memory*/
-    if(firstdraw == 1)
+/*****************************************************************************
+ *
+ * Container management
+ *
+ ****************************************************************************/
+
+static sco_data *getScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j, k, l;
+    BOOL result;
+
+    if (sco == NULL)
     {
-        scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, number_of_curves_by_subwin);
-        /*Must be placed before adding polyline or other elements*/
-        scoSetLongDrawSize(*pScopeMemory, 0, 50);
+        /*
+         * Data allocation
+         */
+
+        sco = (sco_data *) MALLOC(sizeof(sco_data));
+        if (sco == NULL)
+            goto error_handler_sco;
+
+        sco->internal.numberOfPoints = 0;
+        sco->internal.maxNumberOfPoints = block->ipar[2];
+
+        sco->internal.data = (double ***)CALLOC(block->nin, sizeof(double **));
+        if (sco->internal.data == NULL)
+            goto error_handler_data;
 
-        scoSetShortDrawSize(*pScopeMemory,0,buffer_size); //** set the short draw size
+        for (i = 0; i < block->nin; i++)
+        {
+            sco->internal.data[i] = (double **)CALLOC(block->insz[i], sizeof(double *));
+            if (sco->internal.data[i] == NULL)
+                goto error_handler_data_i;
+        }
+        for (i = 0; i < block->nin; i++)
+        {
+            for (j = 0; j < block->insz[i]; j++)
+            {
+                sco->internal.data[i][j] = (double *)CALLOC(block->ipar[2], sizeof(double));
+
+                if (sco->internal.data[i][j] == NULL)
+                    goto error_handler_data_ij;
+            }
+        }
+
+        sco->internal.time = (double *)CALLOC(block->ipar[2], sizeof(double));
+        if (sco->internal.time == NULL)
+        {
+            goto error_handler_time;
+        }
 
-        scoSetPeriod(*pScopeMemory,0,period);
+        sco->scope.periodCounter = 0;
+        sco->scope.cachedFigureUID = NULL;
+        sco->scope.cachedAxeUID = NULL;
+        sco->scope.cachedPolylinesUIDs = (char **)CALLOC(block->insz[0], sizeof(char *));
+
+        *(block->work) = sco;
     }
 
-    xmin = period*scoGetPeriodCounter(*pScopeMemory,0);
-    xmax = period*(scoGetPeriodCounter(*pScopeMemory,0)+1);
+    return sco;
+
+    /*
+     * Error management (out of normal flow)
+     */
 
-    /*Creating the Scope*/
-    scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, NULL, NULL);
-    if(scoGetScopeActivation(*pScopeMemory) == 1)
+error_handler_time:
+error_handler_data_ij:
+    for (k = 0; k < i; k++)
+    {
+        for (l = 0; l < j; l++)
+        {
+            FREE(sco->internal.data[k][l]);
+        }
+    }
+    i = block->nin - 1;
+error_handler_data_i:
+    for (j = 0; j < i; j++)
     {
-        scoAddTitlesScope(*pScopeMemory,label,"t","y",NULL);
-        /*Add a couple of polyline : one for the shortdraw and one for the longdraw*/
-        scoAddCoupleOfPolylines(*pScopeMemory,colors);
-        /* scoAddPolylineLineStyle(*pScopeMemory,colors); */
+        FREE(sco->internal.data[i]);
     }
-    scicos_free(colors);
+    FREE(sco->internal.data);
+error_handler_data:
+    FREE(sco);
+error_handler_sco:
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
+
+static void freeScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
 
-    /* use only single buffering to be sure to draw on the screen */
-    if (scoGetPointerScopeWindow(*pScopeMemory) != NULL)
+    if (sco != NULL)
     {
-        sciSetJavaUseSingleBuffer(scoGetPointerScopeWindow(*pScopeMemory), TRUE);
+        for (i = 0; i < block->nin; i++)
+        {
+            for (j = 0; j < block->insz[i]; j++)
+            {
+                FREE(sco->internal.data[i][j]);
+            }
+            FREE(sco->internal.data[i]);
+        }
+
+        FREE(sco->internal.data);
+        FREE(sco->internal.time);
+
+//      Commented due to the C++ allocation
+//      see http://bugzilla.scilab.org/show_bug.cgi?id=9747
+//      FREE(sco->scope.cachedFigureUID);
+//      sco->scope.cachedFigureUID = NULL;
+//      for (i=0; i<block->nin; i++) {
+//          for (j=0; j<block->insz[i]; j++) {
+//              FREE(sco->scope.cachedPolylinesUIDs[i][j]);
+//              sco->scope.cachedPolylinesUIDs[i][j] = NULL;
+//          }
+//          FREE(sco->scope.cachedAxeUID[i]);
+//          sco->scope.cachedAxeUID[i] = NULL;
+//      }
+
+        FREE(sco);
     }
+}
+
+static sco_data *reallocScoData(scicos_block * block, int numberOfPoints)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+    double *ptr;
+    int setLen;
+
+    for (i = 0; i < block->nin; i++)
+    {
+        for (j = 0; j < block->insz[i]; j++)
+        {
+            ptr = (double *)REALLOC(sco->internal.data[i][j], numberOfPoints * sizeof(double));
+            if (ptr == NULL)
+                goto error_handler;
 
+            for (setLen = sco->internal.maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+                ptr[sco->internal.maxNumberOfPoints + setLen] = ptr[sco->internal.maxNumberOfPoints - 1];
+            sco->internal.data[i][j] = ptr;
+        }
+    }
+
+    ptr = (double *)REALLOC(sco->internal.time, numberOfPoints * sizeof(double));
+    if (ptr == NULL)
+        goto error_handler;
+
+    for (setLen = sco->internal.maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+        ptr[sco->internal.maxNumberOfPoints + setLen] = ptr[sco->internal.maxNumberOfPoints - 1];
+    sco->internal.time = ptr;
+
+    sco->internal.maxNumberOfPoints = numberOfPoints;
+    return sco;
+
+error_handler:
+    freeScoData(block);
+    // allocation error
+    set_block_error(-5);
+    return NULL;
 }
-/*--------------------------------------------------------------------------*/
-/** \fn void cscope(scicos_block * block,int flag)
-    \brief the computational function
-    \param block A pointer to a scicos_block
-    \param flag An int which indicates the state of the block (init, update, ending)
-*/
-SCICOS_BLOCKS_IMPEXP void cscope(scicos_block * block,int flag)
+
+static void appendData(scicos_block * block, int input, double t, double *data)
 {
-    ScopeMemory * pScopeMemory = NULL;
-    int i = 0;
-    double t = 0.;
-    int NbrPtsShort = 0;
-    double * u1 = NULL;
-    scoGraphicalObject pShortDraw;
+    int i;
+    static const int i__1 = 1;
 
-    double d_current_real_time = 0.;
+    sco_data *sco = (sco_data *) * (block->work);
+    int maxNumberOfPoints = sco->internal.maxNumberOfPoints;
+    int numberOfPoints = sco->internal.numberOfPoints;
 
-    switch(flag)
+    /*
+     * Handle the case where the t is greater than the data_bounds
+     */
+    if (t > ((sco->scope.periodCounter + 1) * block->rpar[3]))
     {
+        sco->scope.periodCounter++;
 
-    case Initialization:
+        numberOfPoints = 0;
+        sco->internal.numberOfPoints = 0;
+        if (setPolylinesBounds(block, input, sco->scope.periodCounter) == FALSE)
+        {
+            set_block_error(-5);
+            freeScoData(block);
+            sco = NULL;
+        }
+    }
+
+    /*
+     * Handle the case where the scope has more points than maxNumberOfPoints
+     */
+    if (sco != NULL && numberOfPoints >= maxNumberOfPoints)
     {
-        cscope_draw(block,&pScopeMemory,1);
+        // on a full scope, re-alloc
+        maxNumberOfPoints = maxNumberOfPoints + block->ipar[2];
+        sco = reallocScoData(block, maxNumberOfPoints);
+
+        // reconfigure related graphic objects
+        if (setPolylinesBuffers(block, input, maxNumberOfPoints) == FALSE)
+        {
+            set_block_error(-5);
+            freeScoData(block);
+            sco = NULL;
+        }
+    }
 
-        //** Init the real time section
-        //** current real time as double [second]
-        d_current_real_time = scoGetRealTime();
-        pScopeMemory->d_last_scope_update_time = d_current_real_time ; //** update the ds for the next step
-        //** printf("Init:Start! \n\n"); //** DEBUG ONLY !
+    /*
+     * Update data
+     */
+    if (sco != NULL)
+    {
+        int setLen;
 
-        break;
+        for (i = 0; i < block->insz[input]; i++)
+        {
+            for (setLen = maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+                sco->internal.data[input][i][numberOfPoints + setLen] = data[i];
+        }
+
+        for (setLen = maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+            sco->internal.time[numberOfPoints + setLen] = t;
+
+        sco->internal.numberOfPoints++;
     }
+}
 
-    case StateUpdate:
+static BOOL pushData(scicos_block * block, int input, int row)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pPolylineUID;
+
+    static const int i__0 = 0;
+
+    double *data;
+    sco_data *sco;
+
+    BOOL result = TRUE;
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block, input);
+    pPolylineUID = getPolyline(pAxeUID, block, row);
+
+    sco = getScoData(block);
+    if (sco == NULL)
+        return FALSE;
+
+    // select the right input and row
+    data = sco->internal.data[input][row];
+
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_X__, sco->internal.time, jni_double_vector, sco->internal.maxNumberOfPoints);
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_Y__, data, jni_double_vector, sco->internal.maxNumberOfPoints);
+
+    return result;
+}
+
+/*****************************************************************************
+ *
+ * Graphic utils
+ *
+ ****************************************************************************/
+
+/**
+ * Set properties on the figure.
+ *
+ * \param pFigureUID the figure uid
+ * \param block the current block
+ */
+static void setFigureSettings(char *pFigureUID, scicos_block * block)
+{
+    int nipar = GetNipar(block);
+    int *ipar = GetIparPtrs(block);
+
+    int win_pos[2];
+    int win_dim[2];
+
+    win_pos[0] = ipar[(nipar - 1) - 3];
+    win_pos[1] = ipar[(nipar - 1) - 2];
+    win_dim[0] = ipar[(nipar - 1) - 1];
+    win_dim[1] = ipar[nipar - 1];
+
+    setGraphicObjectProperty(pFigureUID, __GO_POSITION__, &win_pos, jni_int_vector, 2);
+    setGraphicObjectProperty(pFigureUID, __GO_SIZE__, &win_dim, jni_int_vector, 2);
+};
+
+/*****************************************************************************
+ *
+ * Graphic
+ *
+ ****************************************************************************/
+
+static char *getFigure(scicos_block * block)
+{
+    signed int figNum;
+    char *pFigureUID = NULL;
+    char *pAxe = NULL;
+    static const int i__1 = 1;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    int i, j;
+
+    // fast path for an existing object
+    if (sco->scope.cachedFigureUID != NULL)
+    {
+        return sco->scope.cachedFigureUID;
+    }
+
+    figNum = block->ipar[0];
+
+    // with a negative id, use the block number indexed from a constant.
+    if (figNum < 0)
+    {
+        figNum = 20000 + get_block_number();
+    }
+
+    pFigureUID = getFigureFromIndex(figNum);
+    // create on demand
+    if (pFigureUID == NULL)
     {
-        scoRetrieveScopeMemory(block->work,&pScopeMemory);
-        if(scoGetScopeActivation(pScopeMemory) == 1)
+        pFigureUID = createNewFigureWithAxes();
+        setGraphicObjectProperty(pFigureUID, __GO_ID__, &figNum, jni_int, 1);
+
+        // set configured parameters
+        setFigureSettings(pFigureUID, block);
+
+        // allocate the axes through the getter
+        for (i = 0; i < GetNin(block); i++)
         {
-            t = get_scicos_time();
-            /*Retreiving Scope in the block->work*/
+            pAxe = getAxe(pFigureUID, block, i);
 
-            /*If window has been destroyed we recreate it*/
-            if (scoGetPointerScopeWindow(pScopeMemory) == NULL)
-            {
-                cscope_draw(block,&pScopeMemory,0);
-            }
+            /*
+             * Setup according to block settings
+             */
+            setLabel(pAxe, __GO_X_AXIS_LABEL__, "t");
+            setLabel(pAxe, __GO_Y_AXIS_LABEL__, "y");
+
+            setGraphicObjectProperty(pAxe, __GO_X_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+            setGraphicObjectProperty(pAxe, __GO_Y_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+
+            setPolylinesBounds(block, i, 0);
+        }
+
+        sco->scope.cachedFigureUID = pFigureUID;
+    }
+
+    if (sco->scope.cachedFigureUID == NULL)
+    {
+        sco->scope.cachedFigureUID = pFigureUID;
+    }
+    return pFigureUID;
+}
+
+static char *getAxe(char *pFigureUID, scicos_block * block, int input)
+{
+    char *pAxe;
+    int i;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedAxeUID != NULL)
+    {
+        return sco->scope.cachedAxeUID;
+    }
 
-            /*Maybe we are in the end of axes so we have to draw new ones */
-            scoRefreshDataBoundsX(pScopeMemory,t);
+    pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, input);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pAxe == NULL)
+    {
+        pAxe = cloneGraphicObject(getAxesModel());
+
+        if (pAxe != NULL)
+        {
+            setGraphicObjectRelationship(pFigureUID, pAxe);
 
-            // Cannot be factorized depends of the scope
-            u1 = GetRealInPortPtrs(block,1);
-            for (i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0) ; i++)
+            // allocate the polylines through the getter
+            for (i = 0; i < block->insz[input]; i++)
             {
-                pShortDraw  = scoGetPointerShortDraw(pScopeMemory,0,i);
-                if (pShortDraw)
-                {
-                    NbrPtsShort = pPOLYLINE_FEATURE(pShortDraw)->n1;
-                    pPOLYLINE_FEATURE(pShortDraw)->pvx[NbrPtsShort] = t;
-                    pPOLYLINE_FEATURE(pShortDraw)->pvy[NbrPtsShort] = u1[i];
-                    pPOLYLINE_FEATURE(pShortDraw)->n1++;
-                }
+                getPolyline(pAxe, block, i);
             }
-            // End of Cannot
 
-            // Draw the Scope
-            scoDrawScopeAmplitudeTimeStyle(pScopeMemory, t); //** the scope update condition
-                                                             //** is hidden here
+            sco->scope.cachedAxeUID = pAxe;
         }
+    }
 
-        break;
-    } //**-----------------------------------------------------------
+    if (sco->scope.cachedAxeUID == NULL)
+    {
+        sco->scope.cachedAxeUID = pAxe;
+    }
+    return pAxe;
+}
 
-    case Ending:
+static char *getPolyline(char *pAxeUID, scicos_block * block, int row)
+{
+    char *pPolyline;
+    static const double d__0 = 0.0;
+    static const int i__1 = 1;
+    static const BOOL b__true = TRUE;
+
+    int color;
+
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedPolylinesUIDs != NULL && sco->scope.cachedPolylinesUIDs[row] != NULL)
+    {
+        return sco->scope.cachedPolylinesUIDs[row];
+    }
+
+    pPolyline = findChildWithKindAt(pAxeUID, __GO_POLYLINE__, row);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pPolyline == NULL)
     {
-        scoRetrieveScopeMemory(block->work, &pScopeMemory);
-        if(scoGetScopeActivation(pScopeMemory) == 1)
+        pPolyline = createGraphicObject(__GO_POLYLINE__);
+
+        if (pPolyline != NULL)
         {
-            //  sciSetUsedWindow(scoGetWindowID(pScopeMemory));
-            //  pShortDraw = sciGetCurrentFigure();
-            //  pFIGURE_FEATURE(pShortDraw)->user_data = NULL;
-            //  pFIGURE_FEATURE(pShortDraw)->size_of_user_data = 0;
-            ///* restore double buffering */
-            //sciSetJavaUseSingleBuffer(pShortDraw, FALSE);
-            //  scoDelCoupleOfPolylines(pScopeMemory);
-
-            /* Check if figure is still opened, otherwise, don't try to destroy it again. */
-            scoGraphicalObject figure = scoGetPointerScopeWindow(pScopeMemory);
-            if (figure != NULL)
+            createDataObject(pPolyline, __GO_POLYLINE__);
+            setGraphicObjectRelationship(pAxeUID, pPolyline);
+
+            /*
+             * Default setup (will crash if removed)
+             */
             {
-                clearUserData(figure);
+                int polylineSize[2] = { 1, block->ipar[2] };
+                setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
+            }
+
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_X__, &d__0, jni_double_vector, 1);
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_Y__, &d__0, jni_double_vector, 1);
 
-                /* restore double buffering */
-                if (figure) {
-                    sciSetJavaUseSingleBuffer(figure, FALSE);
-                }
-                scoDelCoupleOfPolylines(pScopeMemory);
+            color = block->ipar[3 + row];
+            if (color > 0)
+            {
+                setGraphicObjectProperty(pPolyline, __GO_LINE_MODE__, &b__true, jni_bool, 1);
+                setGraphicObjectProperty(pPolyline, __GO_LINE_COLOR__, &color, jni_int, 1);
+            }
+            else
+            {
+                color = -color;
+                setGraphicObjectProperty(pPolyline, __GO_MARK_MODE__, &b__true, jni_bool, 1);
+                setGraphicObjectProperty(pPolyline, __GO_MARK_STYLE__, &color, jni_int, 1);
             }
 
+            sco->scope.cachedPolylinesUIDs[row] = pPolyline;
         }
-        scoFreeScopeMemory(block->work, &pScopeMemory);
-        break;
     }
+
+    if (sco->scope.cachedPolylinesUIDs != NULL && sco->scope.cachedPolylinesUIDs[row] == NULL)
+    {
+        sco->scope.cachedPolylinesUIDs[row] = pPolyline;
+    }
+    return pPolyline;
+}
+
+static BOOL setPolylinesBuffers(scicos_block * block, int input, int maxNumberOfPoints)
+{
+    int i;
+
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pPolylineUID;
+
+    BOOL result = TRUE;
+    int polylineSize[2] = { 1, maxNumberOfPoints };
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block, input);
+
+    for (i = 0; i < block->insz[input]; i++)
+    {
+        pPolylineUID = getPolyline(pAxeUID, block, i);
+        result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
     }
+
+    return result;
+}
+
+static BOOL setPolylinesBounds(scicos_block * block, int input, int periodCounter)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+
+    BOOL result;
+    double dataBounds[6];
+    double period = block->rpar[3];
+
+    dataBounds[0] = periodCounter * period; // xMin
+    dataBounds[1] = (periodCounter + 1) * period;   // xMax
+    dataBounds[2] = block->rpar[1]; // yMin
+    dataBounds[3] = block->rpar[2]; // yMax
+    dataBounds[4] = -1.0;       // zMin
+    dataBounds[5] = 1.0;        // zMax
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block, input);
+    return setGraphicObjectProperty(pAxeUID, __GO_DATA_BOUNDS__, dataBounds, jni_double_vector, 6);
 }
-/*--------------------------------------------------------------------------*/
index 2cc2adc..02cee77 100755 (executable)
-/*  Scicos
-*
-*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
-/*--------------------------------------------------------------------------*/
-/**
-   \file cscopxy.c
-   \author Benoit Bayol
-   \version 1.0
-   \date September 2006 - January 2007
-   \brief CSCOPXY is a scope in 2D which draw its input as a XY scope, there is no animation, everything is keep in memory instead of CANIMXY
-   \see CSCOPXY.sci in macros/scicos_blocks/Sinks/
-*/
-/*--------------------------------------------------------------------------*/
-#include "scoMemoryScope.h"
-#include "scoWindowScope.h"
-#include "scoMisc.h"
-#include "scoGetProperty.h"
-#include "scoSetProperty.h"
-#include "scicos_block4.h"
-#include "DrawingBridge.h"
-#include "SetJavaProperty.h"
-#include "MALLOC.h"
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2011 - Scilab Enterprises - Clément DAVID
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
 #include "dynlib_scicos_blocks.h"
-/*--------------------------------------------------------------------------*/
-/** \fn cscopxy_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
-    \brief Function to draw or redraw the window
-*/
-SCICOS_BLOCKS_IMPEXP void cscopxy_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
+#include "scoUtils.h"
+
+#include "MALLOC.h"
+#include "elementary_functions.h"
+
+#include "getGraphicObjectProperty.h"
+#include "setGraphicObjectProperty.h"
+#include "graphicObjectProperties.h"
+#include "createGraphicObject.h"
+
+#include "CurrentFigure.h"
+
+#include "scicos_block4.h"
+#include "scicos.h"
+
+#include "localization.h"
+
+#include "FigureList.h"
+#include "BuildObjects.h"
+#include "AxesModel.h"
+
+/*****************************************************************************
+ * Internal container structure
+ ****************************************************************************/
+
+/**
+ * Container structure
+ */
+typedef struct
 {
-  int * ipar = NULL; //Integer Parameters
-  int color_flag = 0; //Flag on Color
-  int color[2];
-  int line_size = 0;
-  int animed = 0;
-  int win = 0; //Windows ID : To give a name to the window
-  int buffer_size = 0; //Buffer Size
-  int win_pos[2]; //Position of the Window
-  int win_dim[2]; //Dimension of the Window
-  int nipar = 0;
-  double * rpar = NULL; //Reals parameters
-  double xmin = 0., xmax = 0., ymin = 0., ymax = 0.; //Ymin and Ymax are vectors here
-  int number_of_subwin = 0;
-  int number_of_curves_by_subwin = 0;
-  int dimension = 2;
-  int i = 0;
-  char *label = NULL;
-  scoGraphicalObject ShortDraw;
-  scoGraphicalObject LongDraw;
-
-  ipar = GetIparPtrs(block);
-  nipar = GetNipar(block);
-  rpar = GetRparPtrs(block);
-  win = ipar[0];
-  color_flag = ipar[1];
-  buffer_size = ipar[2];
-  color[0] = ipar[3];
-  color[1] = ipar[3];
-  line_size = ipar[4];
-  animed = ipar[5];
-  win_pos[0] = ipar[6];
-  win_pos[1] = ipar[7];
-  win_dim[0] = ipar[8];
-  win_dim[1] = ipar[9];
-  xmin = rpar[0];
-  xmax = rpar[1];
-  ymin = rpar[2];
-  ymax = rpar[3];
-  label = GetLabelPtrs(block);
-
-  number_of_subwin = 1;
-  number_of_curves_by_subwin = ipar[10]; //it is a trick to recognize the type of scope, not sure it is a good way because normally a curve is the combination of a short and a longdraw
-  if(firstdraw == 1)
-    {
-      scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
-      scoSetShortDrawSize(*pScopeMemory,0,buffer_size);
-      scoSetLongDrawSize(*pScopeMemory,0,5000);
-    }
-
-  scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, NULL, NULL);
-  if(scoGetScopeActivation(*pScopeMemory) == 1)
-    {
-      for( i = 0 ; i < number_of_curves_by_subwin ; i++)
-       {
-         scoAddPolylineForShortDraw(*pScopeMemory,0,i,color[0]);
-         scoAddPolylineForLongDraw(*pScopeMemory,0,i,color[0]);
-         ShortDraw = scoGetPointerShortDraw(*pScopeMemory,0,i);
-         LongDraw = scoGetPointerLongDraw(*pScopeMemory,0,i);
-          /* Set ShortDraw properties */
-         sciSetLineWidth(ShortDraw, line_size);
-         sciSetMarkSize(ShortDraw, line_size);
-          /* Set LongDraw properties */
-         sciSetLineWidth(LongDraw, line_size);
-         sciSetMarkSize(LongDraw, line_size);
-       }
-      scoAddTitlesScope(*pScopeMemory,label,"x","y",NULL);
-    }
-
-    /* use only single buffering to be sure to draw on the screen */
-    if (scoGetPointerScopeWindow(*pScopeMemory) != NULL) {
-        sciSetJavaUseSingleBuffer(scoGetPointerScopeWindow(*pScopeMemory), TRUE);
-    }
-}
-/*--------------------------------------------------------------------------*/
-/** \fn void cscopxy(scicos_block * block, int flag)
+    struct
+    {
+        int numberOfPoints;
+        int maxNumberOfPoints;
+        double ***data;
+    } internal;
+
+    struct
+    {
+        char *cachedFigureUID;
+        char *cachedAxeUID;
+        char **cachedPolylinesUIDs;
+    } scope;
+} sco_data;
+
+/**
+ * Get (and allocate on demand) the internal data used on this scope
+ * \param block the block
+ * \return the scope data
+ */
+static sco_data *getScoData(scicos_block * block);
+
+/**
+ * Release any internal data
+ *
+ * \param block the block
+ */
+static void freeScoData(scicos_block * block);
+
+/**
+ * Append the data to the current data
+ *
+ * \param block the block
+ * \param x x data
+ * \param y y data
+ */
+static void appendData(scicos_block * block, double *x, double *y);
+
+/**
+ * Push the block data to the polyline
+ *
+ * \param block the block
+ * \param row the selected row
+ *
+ */
+static BOOL pushData(scicos_block * block, int row);
+
+/*****************************************************************************
+ * Graphics utils
+ ****************************************************************************/
+
+/**
+ * Get (and allocate on demand) the figure associated with the block
+ * \param block the block
+ * \return a valid figure UID or NULL on error
+ */
+static char *getFigure(scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the axe associated with the input
+ *
+ * \param pFigureUID the parent figure UID
+ * \param block the block
+ * \param input the current input index (0-indexed)
+ * \return a valid axe UID or NULL on error
+ */
+static char *getAxe(char *pFigureUID, scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the polyline associated with the row
+ *
+ * \param pAxeUID the parent axe UID
+ * \param block the block
+ * \param row the current row index (0-indexed)
+ * \return a valid polyline UID or NULL on error
+ */
+static char *getPolyline(char *pAxeUID, scicos_block * block, int row);
+
+/**
+ * Set the polylines buffer size
+ *
+ * \param block the block
+ * \param maxNumberOfPoints the size of the buffer
+ */
+static BOOL setPolylinesBuffers(scicos_block * block, int maxNumberOfPoints);
+
+/**
+ * Set the polylines bounds
+ *
+ * \param block the block
+ */
+static BOOL setPolylinesBounds(scicos_block * block);
+
+/*****************************************************************************
+ * Simulation function
+ ****************************************************************************/
+
+/** \fn void cmscope(scicos_block * block,int flag)
     \brief the computational function
     \param block A pointer to a scicos_block
     \param flag An int which indicates the state of the block (init, update, ending)
 */
-SCICOS_BLOCKS_IMPEXP void cscopxy(scicos_block * block, int flag)
+SCICOS_BLOCKS_IMPEXP void cscopxy(scicos_block * block, scicos_flag flag)
 {
-  /* Declarations*/
-  ScopeMemory * pScopeMemory = NULL;
-  double *u1 = NULL,*u2 = NULL;
-  scoGraphicalObject Pinceau;
-  int NbrPtsShort = 0;
-  int i = 0;
+    char *pFigureUID;
 
-  /* State Machine Control */
-  switch(flag)
+    double *u;
+    sco_data *sco;
+
+    int i, j;
+    BOOL result;
+
+    switch (flag)
     {
+
     case Initialization:
-      {
-       cscopxy_draw(block,&pScopeMemory,1);
-       break; //Break of the switch condition don t forget it
-      } //End of Initialization
+        sco = getScoData(block);
+        if (sco == NULL)
+        {
+            set_block_error(-5);
+        }
+        pFigureUID = getFigure(block);
+        if (pFigureUID == NULL)
+        {
+            // allocation error
+            set_block_error(-5);
+        }
+        break;
 
     case StateUpdate:
-      {
-       scoRetrieveScopeMemory(block->work,&pScopeMemory);
-       if(scoGetScopeActivation(pScopeMemory) == 1)
-         {
-
-       /* Charging Elements */
-       if (scoGetPointerScopeWindow(pScopeMemory) == NULL) // If the window has been destroyed we recreate it
-         {
-           cscopxy_draw(block,&pScopeMemory,0);
-         }
-
-       u1 = GetRealInPortPtrs(block,1);
-       u2 = GetRealInPortPtrs(block,2);
-
-       for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0); i++)
-         {
-           Pinceau = scoGetPointerShortDraw(pScopeMemory,0,i);
-           NbrPtsShort = pPOLYLINE_FEATURE(Pinceau)->n1;
-           pPOLYLINE_FEATURE(Pinceau)->pvx[NbrPtsShort] = u1[i];
-           pPOLYLINE_FEATURE(Pinceau)->pvy[NbrPtsShort] = u2[i];
-           pPOLYLINE_FEATURE(Pinceau)->n1++;
-         }
-
-       scoDrawScopeXYStyle(pScopeMemory);
-         }
-       break; //Break of the switch don t forget it !
-      }//End of stateupdate
-
-      //This case is activated when the simulation is done or when we close scicos
+        pFigureUID = getFigure(block);
+
+        appendData(block, (double *)block->inptr[0], (double *)block->inptr[1]);
+        for (j = 0; j < block->insz[0]; j++)
+        {
+            result = pushData(block, j);
+            if (result == FALSE)
+            {
+                Coserror("%s: unable to push some data.", "cscopxy");
+                break;
+            }
+        }
+        break;
+
     case Ending:
-      {
-       scoRetrieveScopeMemory(block->work, &pScopeMemory);
-       if(scoGetScopeActivation(pScopeMemory) == 1)
-         {
-           /*sciSetUsedWindow(scoGetWindowID(pScopeMemory));*/
-
-                       /* Check if figure is still opened, otherwise, don't try to destroy it again. */
-                       scoGraphicalObject figure = scoGetPointerScopeWindow(pScopeMemory);
-                       if (figure != NULL)
-                       {
-                               for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0); i++)
-                               {
-                                       Pinceau = scoGetPointerLongDraw(pScopeMemory,0,i);
-                                       forceRedraw(Pinceau);
-                               }
-
-                               //Here Pinceau = Window
-                               /*Pinceau = sciGetCurrentFigure();*/
-                               /*pFIGURE_FEATURE(Pinceau)->user_data = NULL;
-                               pFIGURE_FEATURE(Pinceau)->size_of_user_data = 0;*/
-                               clearUserData(figure);
-
-                               /* restore double buffering */
-                               if (figure) {
-                    sciSetJavaUseSingleBuffer(figure, FALSE);
-                }
-                       }
-       }
-       scoFreeScopeMemory(block->work, &pScopeMemory);
-       break; //Break of the switch
-      }
-      //free the memory which is allocated at each turn by some variables
+        freeScoData(block);
+        break;
+
+    default:
+        break;
     }
 }
-/*--------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------*/
+
+/*****************************************************************************
+ *
+ * Container management
+ *
+ ****************************************************************************/
+
+static sco_data *getScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j, k, l;
+    BOOL result;
+
+    if (sco == NULL)
+    {
+        /*
+         * Data allocation
+         */
+
+        sco = (sco_data *) MALLOC(sizeof(sco_data));
+        if (sco == NULL)
+            goto error_handler_sco;
+
+        sco->internal.numberOfPoints = 0;
+        sco->internal.maxNumberOfPoints = block->ipar[2];
+
+        sco->internal.data = (double ***)CALLOC(block->nin, sizeof(double **));
+        if (sco->internal.data == NULL)
+            goto error_handler_data;
+
+        for (i = 0; i < block->nin; i++)
+        {
+            sco->internal.data[i] = (double **)CALLOC(block->insz[i], sizeof(double *));
+            if (sco->internal.data[i] == NULL)
+                goto error_handler_data_i;
+        }
+        for (i = 0; i < block->nin; i++)
+        {
+            for (j = 0; j < block->insz[i]; j++)
+            {
+                sco->internal.data[i][j] = (double *)CALLOC(block->ipar[2], sizeof(double));
+
+                if (sco->internal.data[i][j] == NULL)
+                    goto error_handler_data_ij;
+            }
+        }
+
+        sco->scope.cachedFigureUID = NULL;
+        sco->scope.cachedAxeUID = NULL;
+
+        sco->scope.cachedPolylinesUIDs = (char **)CALLOC(block->insz[0], sizeof(char **));
+
+        *(block->work) = sco;
+    }
+
+    return sco;
+
+    /*
+     * Error management (out of normal flow)
+     */
+
+error_handler_data_ij:
+    for (k = 0; k < i; k++)
+    {
+        for (l = 0; l < j; l++)
+        {
+            FREE(sco->internal.data[k][l]);
+        }
+    }
+    i = block->nin - 1;
+error_handler_data_i:
+    for (j = 0; j < i; j++)
+    {
+        FREE(sco->internal.data[i]);
+    }
+    FREE(sco->internal.data);
+error_handler_data:
+    FREE(sco);
+error_handler_sco:
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
+
+static void freeScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+
+    if (sco != NULL)
+    {
+        for (i = 0; i < block->nin; i++)
+        {
+            for (j = 0; j < block->insz[i]; j++)
+            {
+                FREE(sco->internal.data[i][j]);
+            }
+            FREE(sco->internal.data[i]);
+        }
+
+        FREE(sco->internal.data);
+
+//      Commented due to the C++ allocation
+//      see http://bugzilla.scilab.org/show_bug.cgi?id=9747
+//      FREE(sco->scope.cachedFigureUID);
+//      sco->scope.cachedFigureUID = NULL;
+//      for (i=0; i<block->nin; i++) {
+//          for (j=0; j<block->insz[i]; j++) {
+//              FREE(sco->scope.cachedPolylinesUIDs[i][j]);
+//              sco->scope.cachedPolylinesUIDs[i][j] = NULL;
+//          }
+//          FREE(sco->scope.cachedAxeUID[i]);
+//          sco->scope.cachedAxeUID[i] = NULL;
+//      }
+
+        FREE(sco);
+    }
+}
+
+static sco_data *reallocScoData(scicos_block * block, int numberOfPoints)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+    double *ptr;
+    int setLen;
+    int previousNumberOfPoints = sco->internal.maxNumberOfPoints;
+
+    for (i = 0; i < block->nin; i++)
+    {
+        for (j = 0; j < block->insz[i]; j++)
+        {
+            ptr = (double *)REALLOC(sco->internal.data[i][j], numberOfPoints * sizeof(double));
+            if (ptr == NULL)
+                goto error_handler;
+
+            for (setLen = previousNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+                ptr[previousNumberOfPoints + setLen] = ptr[previousNumberOfPoints - 1];
+            sco->internal.data[i][j] = ptr;
+        }
+    }
+
+    sco->internal.maxNumberOfPoints = numberOfPoints;
+    return sco;
+
+error_handler:
+    freeScoData(block);
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
+
+static void appendData(scicos_block * block, double *x, double *y)
+{
+    int i;
+    static const int i__1 = 1;
+
+    sco_data *sco = (sco_data *) * (block->work);
+    int maxNumberOfPoints = sco->internal.maxNumberOfPoints;
+    int numberOfPoints = sco->internal.numberOfPoints;
+
+    /*
+     * Handle the case where the scope has more points than maxNumberOfPoints
+     */
+    if (sco != NULL && numberOfPoints >= maxNumberOfPoints)
+    {
+        // on a full scope, re-alloc
+        maxNumberOfPoints = maxNumberOfPoints + block->ipar[2];
+        sco = reallocScoData(block, maxNumberOfPoints);
+
+        // reconfigure related graphic objects
+        if (setPolylinesBuffers(block, maxNumberOfPoints) == FALSE)
+        {
+            set_block_error(-5);
+            freeScoData(block);
+            sco = NULL;
+        }
+    }
+
+    /*
+     * Update data
+     */
+    if (sco != NULL)
+    {
+        int setLen;
+
+        for (i = 0; i < block->insz[0]; i++)
+        {
+            for (setLen = maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+                sco->internal.data[0][i][numberOfPoints + setLen] = x[i];
+
+            for (setLen = maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+                sco->internal.data[1][i][numberOfPoints + setLen] = y[i];
+        }
+
+        sco->internal.numberOfPoints++;
+    }
+}
+
+static BOOL pushData(scicos_block * block, int row)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pPolylineUID;
+
+    static const int i__0 = 0;
+
+    double *x;
+    double *y;
+    sco_data *sco;
+
+    BOOL result = TRUE;
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+    pPolylineUID = getPolyline(pAxeUID, block, row);
+
+    sco = getScoData(block);
+    if (sco == NULL)
+        return FALSE;
+
+    // select the right input and row
+    x = sco->internal.data[0][row];
+    y = sco->internal.data[1][row];
+
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_X__, x, jni_double_vector, sco->internal.maxNumberOfPoints);
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_Y__, y, jni_double_vector, sco->internal.maxNumberOfPoints);
+
+    return result;
+}
+
+/*****************************************************************************
+ *
+ * Graphic utils
+ *
+ ****************************************************************************/
+
+/**
+ * Set properties on the figure.
+ *
+ * \param pFigureUID the figure uid
+ * \param block the current block
+ */
+static void setFigureSettings(char *pFigureUID, scicos_block * block)
+{
+    int win_pos[2];
+    int win_dim[2];
+
+    int *ipar = block->ipar;
+
+    win_pos[0] = ipar[6];
+    win_pos[1] = ipar[7];
+    win_dim[0] = ipar[8];
+    win_dim[1] = ipar[9];
+
+    setGraphicObjectProperty(pFigureUID, __GO_POSITION__, &win_pos, jni_int_vector, 2);
+    setGraphicObjectProperty(pFigureUID, __GO_SIZE__, &win_dim, jni_int_vector, 2);
+};
+
+/*****************************************************************************
+ *
+ * Graphic
+ *
+ ****************************************************************************/
+
+static char *getFigure(scicos_block * block)
+{
+    signed int figNum;
+    char *pFigureUID = NULL;
+    char *pAxe = NULL;
+    static const int i__1 = 1;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    int i, j;
+
+    // fast path for an existing object
+    if (sco->scope.cachedFigureUID != NULL)
+    {
+        return sco->scope.cachedFigureUID;
+    }
+
+    figNum = block->ipar[0];
+
+    // with a negative id, use the block number indexed from a constant.
+    if (figNum < 0)
+    {
+        figNum = 20000 + get_block_number();
+    }
+
+    pFigureUID = getFigureFromIndex(figNum);
+    // create on demand
+    if (pFigureUID == NULL)
+    {
+        pFigureUID = createNewFigureWithAxes();
+        setGraphicObjectProperty(pFigureUID, __GO_ID__, &figNum, jni_int, 1);
+
+        // set configured parameters
+        setFigureSettings(pFigureUID, block);
+        sco->scope.cachedFigureUID = pFigureUID;
+
+        // allocate the axes through the getter
+        pAxe = getAxe(pFigureUID, block);
+
+        /*
+         * Setup according to block settings
+         */
+        setLabel(pAxe, __GO_X_AXIS_LABEL__, "x");
+        setLabel(pAxe, __GO_Y_AXIS_LABEL__, "y");
+
+        setGraphicObjectProperty(pAxe, __GO_X_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+        setGraphicObjectProperty(pAxe, __GO_Y_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+
+        setPolylinesBounds(block);
+    }
+
+    if (sco->scope.cachedFigureUID == NULL)
+    {
+        sco->scope.cachedFigureUID = pFigureUID;
+    }
+    return pFigureUID;
+}
+
+static char *getAxe(char *pFigureUID, scicos_block * block)
+{
+    char *pAxe;
+    int i;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedAxeUID != NULL)
+    {
+        return sco->scope.cachedAxeUID;
+    }
+
+    pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, 0);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pAxe == NULL)
+    {
+        pAxe = cloneGraphicObject(getAxesModel());
+
+        if (pAxe != NULL)
+        {
+            setGraphicObjectRelationship(pFigureUID, pAxe);
+
+            // allocate the polylines through the getter
+            for (i = 0; i < block->insz[0]; i++)
+            {
+                getPolyline(pAxe, block, i);
+            }
+        }
+    }
+
+    if (sco->scope.cachedAxeUID == NULL)
+    {
+        sco->scope.cachedAxeUID = pAxe;
+    }
+    return pAxe;
+}
+
+static char *getPolyline(char *pAxeUID, scicos_block * block, int row)
+{
+    char *pPolyline;
+    static const double d__0 = 0.0;
+    static const int i__1 = 1;
+    static const BOOL b__true = TRUE;
+
+    int color;
+    int markSize;
+    double lineThickness;
+
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedPolylinesUIDs != NULL && sco->scope.cachedPolylinesUIDs[row] != NULL)
+    {
+        return sco->scope.cachedPolylinesUIDs[row];
+    }
+
+    pPolyline = findChildWithKindAt(pAxeUID, __GO_POLYLINE__, row);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pPolyline == NULL)
+    {
+        pPolyline = createGraphicObject(__GO_POLYLINE__);
+
+        if (pPolyline != NULL)
+        {
+            createDataObject(pPolyline, __GO_POLYLINE__);
+            setGraphicObjectRelationship(pAxeUID, pPolyline);
+
+            /*
+             * Default setup (will crash if removed)
+             */
+            {
+                int polylineSize[2] = { 1, block->ipar[2] };
+                setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
+            }
+
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_X__, &d__0, jni_double_vector, 1);
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_Y__, &d__0, jni_double_vector, 1);
+
+            color = block->ipar[3];
+            markSize = block->ipar[4];
+            lineThickness = (double)markSize;
+            if (color > 0)
+            {
+                setGraphicObjectProperty(pPolyline, __GO_LINE_MODE__, &b__true, jni_bool, 1);
+
+                setGraphicObjectProperty(pPolyline, __GO_LINE_COLOR__, &color, jni_int, 1);
+                setGraphicObjectProperty(pPolyline, __GO_LINE_THICKNESS__, &lineThickness, jni_double, 1);
+            }
+            else
+            {
+                color = -color;
+                setGraphicObjectProperty(pPolyline, __GO_MARK_MODE__, &b__true, jni_bool, 1);
+
+                setGraphicObjectProperty(pPolyline, __GO_MARK_STYLE__, &color, jni_int, 1);
+                setGraphicObjectProperty(pPolyline, __GO_MARK_SIZE__, &markSize, jni_int, 1);
+            }
+        }
+    }
+
+    if (sco->scope.cachedPolylinesUIDs != NULL)
+    {
+        sco->scope.cachedPolylinesUIDs[row] = pPolyline;
+    }
+    return pPolyline;
+}
+
+static BOOL setPolylinesBuffers(scicos_block * block, int maxNumberOfPoints)
+{
+    int i;
+
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pPolylineUID;
+
+    BOOL result = TRUE;
+    int polylineSize[2] = { 1, maxNumberOfPoints };
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+
+    for (i = 0; i < block->insz[0]; i++)
+    {
+        pPolylineUID = getPolyline(pAxeUID, block, i);
+        result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
+    }
+
+    return result;
+}
+
+static BOOL setPolylinesBounds(scicos_block * block)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+
+    BOOL result;
+    double dataBounds[6];
+
+    dataBounds[0] = block->rpar[0]; // xMin
+    dataBounds[1] = block->rpar[1]; // xMax
+    dataBounds[2] = block->rpar[2]; // yMin
+    dataBounds[3] = block->rpar[3]; // yMax
+    dataBounds[4] = -1.0;       // zMin
+    dataBounds[5] = 1.0;        // zMax
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+
+    return setGraphicObjectProperty(pAxeUID, __GO_DATA_BOUNDS__, dataBounds, jni_double_vector, 6);
+}
index d3710cc..a969486 100755 (executable)
-/*  Scicos
-*
-*  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* See the file ./license.txt
-*/
-/*--------------------------------------------------------------------------*/
-/**
-   \file cscopxy3d.c
-   \author Benoit Bayol
-   \version 1.0
-   \date September 2006 - January 2007
-   \brief CSCOPXY3D is a scope in 2D which draw its input as a XYZ scope, there is no animation, everything is keep in memory instead of CANIMXY3D
-   \see CSCOPXY3D.sci in macros/scicos_blocks/Sinks/
-*/
-/*--------------------------------------------------------------------------*/
-#include "scoMemoryScope.h"
-#include "scoWindowScope.h"
-#include "scoMisc.h"
-#include "scoGetProperty.h"
-#include "scoSetProperty.h"
-#include "scicos_block4.h"
-#include "DrawingBridge.h"
-#include "scicos_malloc.h"
-#include "scicos_free.h"
-#include "MALLOC.h"
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2011 - Scilab Enterprises - Clément DAVID
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
 #include "dynlib_scicos_blocks.h"
-/*--------------------------------------------------------------------------*/
-/** \fn cscopxy3d_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
-    \brief Function to draw or redraw the window
-*/
-SCICOS_BLOCKS_IMPEXP void cscopxy3d_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
+#include "scoUtils.h"
+
+#include "MALLOC.h"
+#include "elementary_functions.h"
+
+#include "getGraphicObjectProperty.h"
+#include "setGraphicObjectProperty.h"
+#include "graphicObjectProperties.h"
+#include "createGraphicObject.h"
+
+#include "CurrentFigure.h"
+
+#include "scicos_block4.h"
+#include "scicos.h"
+
+#include "localization.h"
+
+#include "FigureList.h"
+#include "BuildObjects.h"
+#include "AxesModel.h"
+
+/*****************************************************************************
+ * Internal container structure
+ ****************************************************************************/
+
+/**
+ * Container structure
+ */
+typedef struct
 {
-  int * ipar = NULL; //Integer Parameters
-  int color_number = 0; //Flag on Color
-  int * color =  0 ;
-  int * line_size = NULL;
-  int animed = 0;
-  int win = 0; //Windows ID : To give a name to the window
-  int buffer_size = 0; //Buffer Size
-  int win_pos[2]; //Position of the Window
-  int win_dim[2]; //Dimension of the Window
-  int nipar = 0;
-  double * rpar = NULL; //Reals parameters
-  double xmin = 0.0, xmax = 0.0, ymin = 0.0, ymax = 0.0, zmin = 0.0, zmax = 0.0,alpha = 0.0, theta = 0.0; //Ymin and Ymax are vectors here
-  int number_of_subwin = 0;
-  int number_of_curves_by_subwin = 0;
-  int dimension = 3;
-  int i = 0;
-  int size = 0;
-  char *label = NULL;
-  scoGraphicalObject ShortDraw;
-  scoGraphicalObject LongDraw;
-
-  ipar = GetIparPtrs(block);
-  nipar = GetNipar(block);
-  rpar = GetRparPtrs(block);
-  win = ipar[0];
-  color_number = ipar[1];
-  buffer_size = ipar[2];
-  label = GetLabelPtrs(block);
-  color = (int*)scicos_malloc(color_number*sizeof(int));
-  line_size = (int*)scicos_malloc(color_number*sizeof(int));
-  for(i = 0 ; i < color_number ; i++)
-    {
-      color[i] = ipar[i+3];
-      line_size[i] = ipar[i+3+color_number];
-    }
-  size = 2*color_number;
-  animed = ipar[size+3];
-  win_pos[0] = ipar[size+4];
-  win_pos[1] = ipar[size+5];
-  win_dim[0] = ipar[size+6];
-  win_dim[1] = ipar[size+7];
-  xmin = rpar[0];
-  xmax = rpar[1];
-  ymin = rpar[2];
-  ymax = rpar[3];
-  zmin = rpar[4];
-  zmax = rpar[5];
-  alpha = rpar[6];
-  theta = rpar[7];
-
-  number_of_subwin = 1;
-  number_of_curves_by_subwin = ipar[size+8]; //it is a trick to recognize the type of scope, not sure it is a good way because normally a curve is the combination of a short and a longdraw
-
-  if(firstdraw == 1)
-    {
-      scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
-      scoSetShortDrawSize(*pScopeMemory,0,buffer_size);
-      scoSetLongDrawSize(*pScopeMemory,0,5000);
-    }
-
-  scoInitOfWindow(*pScopeMemory, dimension, win, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, &zmin, &zmax);
-  if(scoGetScopeActivation(*pScopeMemory) == 1)
-    {
-      pSUBWIN_FEATURE(scoGetPointerAxes(*pScopeMemory,0))->alpha = alpha;
-      pSUBWIN_FEATURE(scoGetPointerAxes(*pScopeMemory,0))->theta = theta;
-      scoAddTitlesScope(*pScopeMemory,label,"x","y","z");
-
-
-      for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(*pScopeMemory,0) ; i++)
-       {
-         scoAddPolylineForShortDraw(*pScopeMemory,0,i,color[i]);
-         scoAddPolylineForLongDraw(*pScopeMemory,0,i,color[i]);
-
-         ShortDraw = scoGetPointerShortDraw(*pScopeMemory,0,i);
-         LongDraw = scoGetPointerLongDraw(*pScopeMemory,0,i);
-
-          /* Set ShortDraw properties */
-         sciSetLineWidth(ShortDraw, line_size[i]);
-         sciSetMarkSize(ShortDraw, line_size[i]);
-
-          /* Set LongDraw properties */
-         sciSetLineWidth(LongDraw, line_size[i]);
-         sciSetMarkSize(LongDraw, line_size[i]);
-
-       }
-    }
-  scicos_free(color);
-  scicos_free(line_size);
-}
-/*--------------------------------------------------------------------------*/
-/** \fn void cscopxy3d(scicos_block * block, int flag)
+    struct
+    {
+        int numberOfPoints;
+        int maxNumberOfPoints;
+        double ***data;
+    } internal;
+
+    struct
+    {
+        char *cachedFigureUID;
+        char *cachedAxeUID;
+        char **cachedPolylinesUIDs;
+    } scope;
+} sco_data;
+
+/**
+ * Get (and allocate on demand) the internal data used on this scope
+ * \param block the block
+ * \return the scope data
+ */
+static sco_data *getScoData(scicos_block * block);
+
+/**
+ * Release any internal data
+ *
+ * \param block the block
+ */
+static void freeScoData(scicos_block * block);
+
+/**
+ * Append the data to the current data
+ *
+ * \param block the block
+ * \param x x data
+ * \param y y data
+ * \param z z data
+ */
+static void appendData(scicos_block * block, double *x, double *y, double *z);
+
+/**
+ * Push the block data to the polyline
+ *
+ * \param block the block
+ * \param row the selected row
+ *
+ */
+static BOOL pushData(scicos_block * block, int row);
+
+/*****************************************************************************
+ * Graphics utils
+ ****************************************************************************/
+
+/**
+ * Get (and allocate on demand) the figure associated with the block
+ * \param block the block
+ * \return a valid figure UID or NULL on error
+ */
+static char *getFigure(scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the axe associated with the input
+ *
+ * \param pFigureUID the parent figure UID
+ * \param block the block
+ * \param input the current input index (0-indexed)
+ * \return a valid axe UID or NULL on error
+ */
+static char *getAxe(char *pFigureUID, scicos_block * block);
+
+/**
+ * Get (and allocate on demand) the polyline associated with the row
+ *
+ * \param pAxeUID the parent axe UID
+ * \param block the block
+ * \param row the current row index (0-indexed)
+ * \return a valid polyline UID or NULL on error
+ */
+static char *getPolyline(char *pAxeUID, scicos_block * block, int row);
+
+/**
+ * Set the polylines buffer size
+ *
+ * \param block the block
+ * \param maxNumberOfPoints the size of the buffer
+ */
+static BOOL setPolylinesBuffers(scicos_block * block, int maxNumberOfPoints);
+
+/**
+ * Set the polylines bounds
+ *
+ * \param block the block
+ */
+static BOOL setPolylinesBounds(scicos_block * block);
+
+/*****************************************************************************
+ * Simulation function
+ ****************************************************************************/
+
+/** \fn void cmscope(scicos_block * block,int flag)
     \brief the computational function
     \param block A pointer to a scicos_block
     \param flag An int which indicates the state of the block (init, update, ending)
 */
-SCICOS_BLOCKS_IMPEXP void cscopxy3d(scicos_block * block, int flag)
+SCICOS_BLOCKS_IMPEXP void cscopxy3d(scicos_block * block, scicos_flag flag)
 {
-  /* Declarations*/
-  int i;
-  ScopeMemory * pScopeMemory;
-  scoGraphicalObject Pinceau; //Pointer to each polyline of each axes
-  double *u1,*u2, *u3;
-  int NbrPtsShort;
+    char *pFigureUID;
+
+    sco_data *sco;
 
+    int j;
+    BOOL result;
 
-  /* State Machine Control */
-  switch(flag)
+    switch (flag)
     {
+
     case Initialization:
-      {
-       cscopxy3d_draw(block,&pScopeMemory, 1);
-       break; //Break of the switch condition don t forget it
-      } //End of Initialization
+        sco = getScoData(block);
+        if (sco == NULL)
+        {
+            set_block_error(-5);
+        }
+        pFigureUID = getFigure(block);
+        if (pFigureUID == NULL)
+        {
+            // allocation error
+            set_block_error(-5);
+        }
+        break;
 
     case StateUpdate:
-      {
-       scoRetrieveScopeMemory(block->work,&pScopeMemory);
-       if(scoGetScopeActivation(pScopeMemory) == 1)
-         {
-           /* Charging Elements */
-           if (scoGetPointerScopeWindow(pScopeMemory) == NULL) // If the window has been destroyed we recreate it
-             {
-               cscopxy3d_draw(block,&pScopeMemory,0);
-             }
-
-           u1 = GetRealInPortPtrs(block,1);
-           u2 = GetRealInPortPtrs(block,2);
-           u3 = GetRealInPortPtrs(block,3);
-
-           for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0) ; i++)
-             {
-               Pinceau = scoGetPointerShortDraw(pScopeMemory,0,i);
-
-               NbrPtsShort = pPOLYLINE_FEATURE(Pinceau)->n1;
-
-               pPOLYLINE_FEATURE(Pinceau)->pvx[NbrPtsShort] = u1[i];
-               pPOLYLINE_FEATURE(Pinceau)->pvy[NbrPtsShort] = u2[i];
-               pPOLYLINE_FEATURE(Pinceau)->pvz[NbrPtsShort] = u3[i];
-
-               pPOLYLINE_FEATURE(Pinceau)->n1++;
-             }
-
-           scoDrawScopeXYStyle(pScopeMemory);
-         }
-           break; //Break of the switch don t forget it !
-         }//End of stateupdate
-
-      //This case is activated when the simulation is done or when we close scicos
+        pFigureUID = getFigure(block);
+
+        appendData(block, (double *)block->inptr[0], (double *)block->inptr[1], (double *)block->inptr[2]);
+        for (j = 0; j < block->insz[0]; j++)
+        {
+            result = pushData(block, j);
+            if (result == FALSE)
+            {
+                Coserror("%s: unable to push some data.", "cscopxy3d");
+                break;
+            }
+        }
+        break;
+
     case Ending:
-      {
-       scoRetrieveScopeMemory(block->work, &pScopeMemory);
-       if(scoGetScopeActivation(pScopeMemory) == 1)
-       {
-               /* sciSetUsedWindow(scoGetWindowID(pScopeMemory)); */
-               /* Check if figure is still opened, otherwise, don't try to destroy it again. */
-               scoGraphicalObject figure = scoGetPointerScopeWindow(pScopeMemory);
-               if (figure != NULL)
-               {
-                       for(i = 0 ; i < scoGetNumberOfCurvesBySubwin(pScopeMemory,0) ; i++)
-                       {
-                               Pinceau = scoGetPointerLongDraw(pScopeMemory,0,i);
-                               forceRedraw(Pinceau);
-                       }
-
-                       /* Pinceau = sciGetCurrentFigure();*/
-                       /*Pinceau = scoGetPointerScopeWindow(pScopeMemory);*/
-                       /* pFIGURE_FEATURE(Pinceau)->user_data = NULL; */
-                       /* pFIGURE_FEATURE(Pinceau)->size_of_user_data = 0; */
-                       clearUserData(figure);
-               }
-       }
-       scoFreeScopeMemory(block->work, &pScopeMemory);
-       break; //Break of the switch
-      }
-      //free the memory which is allocated at each turn by some variables
+        freeScoData(block);
+        break;
+
+    default:
+        break;
     }
 }
-/*--------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------*/
+
+/*****************************************************************************
+ *
+ * Container management
+ *
+ ****************************************************************************/
+
+static sco_data *getScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j, k, l;
+
+    if (sco == NULL)
+    {
+        /*
+         * Data allocation
+         */
+
+        sco = (sco_data *) MALLOC(sizeof(sco_data));
+        if (sco == NULL)
+            goto error_handler_sco;
+
+        sco->internal.numberOfPoints = 0;
+        sco->internal.maxNumberOfPoints = block->ipar[2];
+
+        sco->internal.data = (double ***)CALLOC(block->nin, sizeof(double **));
+        if (sco->internal.data == NULL)
+            goto error_handler_data;
+
+        for (i = 0; i < block->nin; i++)
+        {
+            sco->internal.data[i] = (double **)CALLOC(block->insz[i], sizeof(double *));
+            if (sco->internal.data[i] == NULL)
+                goto error_handler_data_i;
+        }
+        for (i = 0; i < block->nin; i++)
+        {
+            for (j = 0; j < block->insz[i]; j++)
+            {
+                sco->internal.data[i][j] = (double *)CALLOC(block->ipar[2], sizeof(double));
+
+                if (sco->internal.data[i][j] == NULL)
+                    goto error_handler_data_ij;
+            }
+        }
+
+        sco->scope.cachedFigureUID = NULL;
+        sco->scope.cachedAxeUID = NULL;
+
+        sco->scope.cachedPolylinesUIDs = (char **)CALLOC(block->insz[0], sizeof(char **));
+
+        *(block->work) = sco;
+    }
+
+    return sco;
+
+    /*
+     * Error management (out of normal flow)
+     */
+
+error_handler_data_ij:
+    for (k = 0; k < i; k++)
+    {
+        for (l = 0; l < j; l++)
+        {
+            FREE(sco->internal.data[k][l]);
+        }
+    }
+    i = block->nin - 1;
+error_handler_data_i:
+    for (j = 0; j < i; j++)
+    {
+        FREE(sco->internal.data[i]);
+    }
+    FREE(sco->internal.data);
+error_handler_data:
+    FREE(sco);
+error_handler_sco:
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
+
+static void freeScoData(scicos_block * block)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+
+    if (sco != NULL)
+    {
+        for (i = 0; i < block->nin; i++)
+        {
+            for (j = 0; j < block->insz[i]; j++)
+            {
+                FREE(sco->internal.data[i][j]);
+            }
+            FREE(sco->internal.data[i]);
+        }
+
+        FREE(sco->internal.data);
+
+//      Commented due to the C++ allocation
+//      see http://bugzilla.scilab.org/show_bug.cgi?id=9747
+//      FREE(sco->scope.cachedFigureUID);
+//      sco->scope.cachedFigureUID = NULL;
+//      for (i=0; i<block->nin; i++) {
+//          for (j=0; j<block->insz[i]; j++) {
+//              FREE(sco->scope.cachedPolylinesUIDs[i][j]);
+//              sco->scope.cachedPolylinesUIDs[i][j] = NULL;
+//          }
+//          FREE(sco->scope.cachedAxeUID[i]);
+//          sco->scope.cachedAxeUID[i] = NULL;
+//      }
+
+        FREE(sco);
+    }
+}
+
+static sco_data *reallocScoData(scicos_block * block, int numberOfPoints)
+{
+    sco_data *sco = (sco_data *) * (block->work);
+    int i, j;
+    double *ptr;
+    int setLen;
+
+    for (i = 0; i < block->nin; i++)
+    {
+        for (j = 0; j < block->insz[i]; j++)
+        {
+            ptr = (double *)REALLOC(sco->internal.data[i][j], numberOfPoints * sizeof(double));
+            if (ptr == NULL)
+                goto error_handler;
+
+            for (setLen = sco->internal.maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+                ptr[sco->internal.maxNumberOfPoints + setLen] = ptr[sco->internal.maxNumberOfPoints - 1];
+            sco->internal.data[i][j] = ptr;
+        }
+    }
+
+    sco->internal.maxNumberOfPoints = numberOfPoints;
+    return sco;
+
+error_handler:
+    freeScoData(block);
+    // allocation error
+    set_block_error(-5);
+    return NULL;
+}
+
+static void appendData(scicos_block * block, double *x, double *y, double *z)
+{
+    int i;
+
+    sco_data *sco = (sco_data *) * (block->work);
+    int maxNumberOfPoints = sco->internal.maxNumberOfPoints;
+    int numberOfPoints = sco->internal.numberOfPoints;
+
+    /*
+     * Handle the case where the scope has more points than maxNumberOfPoints
+     */
+    if (sco != NULL && numberOfPoints >= maxNumberOfPoints)
+    {
+        // on a full scope, re-alloc
+        maxNumberOfPoints = maxNumberOfPoints + block->ipar[2];
+        sco = reallocScoData(block, maxNumberOfPoints);
+
+        // reconfigure related graphic objects
+        if (setPolylinesBuffers(block, maxNumberOfPoints) == FALSE)
+        {
+            set_block_error(-5);
+            freeScoData(block);
+            sco = NULL;
+        }
+    }
+
+    /*
+     * Update data
+     */
+    if (sco != NULL)
+    {
+        int setLen;
+
+        for (i = 0; i < block->insz[0]; i++)
+        {
+            for (setLen = maxNumberOfPoints - numberOfPoints; setLen >= 0; setLen--)
+            {
+                sco->internal.data[0][i][numberOfPoints + setLen] = x[i];
+                sco->internal.data[1][i][numberOfPoints + setLen] = y[i];
+                sco->internal.data[2][i][numberOfPoints + setLen] = z[i];
+            }
+        }
+
+        sco->internal.numberOfPoints++;
+    }
+}
+
+static BOOL pushData(scicos_block * block, int row)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pPolylineUID;
+
+    double *x;
+    double *y;
+    double *z;
+    sco_data *sco;
+
+    BOOL result = TRUE;
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+    pPolylineUID = getPolyline(pAxeUID, block, row);
+
+    sco = getScoData(block);
+    if (sco == NULL)
+        return FALSE;
+
+    // select the right input and row
+    x = sco->internal.data[0][row];
+    y = sco->internal.data[1][row];
+    z = sco->internal.data[2][row];
+
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_X__, x, jni_double_vector, sco->internal.maxNumberOfPoints);
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_Y__, y, jni_double_vector, sco->internal.maxNumberOfPoints);
+    result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_Z__, z, jni_double_vector, sco->internal.maxNumberOfPoints);
+
+    return result;
+}
+
+/*****************************************************************************
+ *
+ * Graphic utils
+ *
+ ****************************************************************************/
+
+/**
+ * Set properties on the figure.
+ *
+ * \param pFigureUID the figure uid
+ * \param block the current block
+ */
+static void setFigureSettings(char *pFigureUID, scicos_block * block)
+{
+    int win_pos[2];
+    int win_dim[2];
+
+    int *ipar = block->ipar;
+    int nipar = block->nipar;
+
+    win_pos[0] = ipar[nipar - 5];
+    win_pos[1] = ipar[nipar - 4];
+    win_dim[0] = ipar[nipar - 3];
+    win_dim[1] = ipar[nipar - 2];
+
+    setGraphicObjectProperty(pFigureUID, __GO_POSITION__, &win_pos, jni_int_vector, 2);
+    setGraphicObjectProperty(pFigureUID, __GO_SIZE__, &win_dim, jni_int_vector, 2);
+};
+
+/*****************************************************************************
+ *
+ * Graphic
+ *
+ ****************************************************************************/
+
+static char *getFigure(scicos_block * block)
+{
+    signed int figNum;
+    char *pFigureUID = NULL;
+    char *pAxe = NULL;
+    static const int i__1 = 1;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    int i, j;
+
+    // fast path for an existing object
+    if (sco->scope.cachedFigureUID != NULL)
+    {
+        return sco->scope.cachedFigureUID;
+    }
+
+    figNum = block->ipar[0];
+
+    // with a negative id, use the block number indexed from a constant.
+    if (figNum < 0)
+    {
+        figNum = 20000 + get_block_number();
+    }
+
+    pFigureUID = getFigureFromIndex(figNum);
+    // create on demand
+    if (pFigureUID == NULL)
+    {
+        pFigureUID = createNewFigureWithAxes();
+        setGraphicObjectProperty(pFigureUID, __GO_ID__, &figNum, jni_int, 1);
+
+        // set configured parameters
+        setFigureSettings(pFigureUID, block);
+        sco->scope.cachedFigureUID = pFigureUID;
+
+        // allocate the axes through the getter
+        pAxe = getAxe(pFigureUID, block);
+
+        /*
+         * Setup according to block settings
+         */
+        setLabel(pAxe, __GO_X_AXIS_LABEL__, "x");
+        setLabel(pAxe, __GO_Y_AXIS_LABEL__, "y");
+        setLabel(pAxe, __GO_Z_AXIS_LABEL__, "z");
+
+        setGraphicObjectProperty(pAxe, __GO_X_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+        setGraphicObjectProperty(pAxe, __GO_Y_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+        setGraphicObjectProperty(pAxe, __GO_Z_AXIS_VISIBLE__, &i__1, jni_bool, 1);
+
+        setPolylinesBounds(block);
+    }
+
+    if (sco->scope.cachedFigureUID == NULL)
+    {
+        sco->scope.cachedFigureUID = pFigureUID;
+    }
+    return pFigureUID;
+}
+
+static char *getAxe(char *pFigureUID, scicos_block * block)
+{
+    char *pAxe;
+    int i;
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedAxeUID != NULL)
+    {
+        return sco->scope.cachedAxeUID;
+    }
+
+    pAxe = findChildWithKindAt(pFigureUID, __GO_AXES__, 0);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pAxe == NULL)
+    {
+        pAxe = cloneGraphicObject(getAxesModel());
+
+        if (pAxe != NULL)
+        {
+            setGraphicObjectRelationship(pFigureUID, pAxe);
+
+            // allocate the polylines through the getter
+            for (i = 0; i < block->insz[0]; i++)
+            {
+                getPolyline(pAxe, block, i);
+            }
+        }
+    }
+
+    if (sco->scope.cachedAxeUID == NULL)
+    {
+        sco->scope.cachedAxeUID = pAxe;
+    }
+    return pAxe;
+}
+
+static char *getPolyline(char *pAxeUID, scicos_block * block, int row)
+{
+    char *pPolyline;
+    static const double d__0 = 0.0;
+    static const BOOL b__true = TRUE;
+
+    int color;
+    int markSize;
+    double lineThickness;
+
+    sco_data *sco = (sco_data *) * (block->work);
+
+    // fast path for an existing object
+    if (sco->scope.cachedPolylinesUIDs != NULL && sco->scope.cachedPolylinesUIDs[row] != NULL)
+    {
+        return sco->scope.cachedPolylinesUIDs[row];
+    }
+
+    pPolyline = findChildWithKindAt(pAxeUID, __GO_POLYLINE__, row);
+
+    /*
+     * Allocate if necessary
+     */
+    if (pPolyline == NULL)
+    {
+        pPolyline = createGraphicObject(__GO_POLYLINE__);
+
+        if (pPolyline != NULL)
+        {
+            createDataObject(pPolyline, __GO_POLYLINE__);
+            setGraphicObjectRelationship(pAxeUID, pPolyline);
+
+            /*
+             * Default setup (will crash if removed)
+             */
+            {
+                int polylineSize[2] = { 1, block->ipar[2] };
+                setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
+            }
+
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_X__, &d__0, jni_double_vector, 1);
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_Y__, &d__0, jni_double_vector, 1);
+            setGraphicObjectProperty(pPolyline, __GO_DATA_MODEL_Z__, &d__0, jni_double_vector, 1);
+
+            color = block->ipar[3 + row];
+            markSize = block->ipar[3 + block->ipar[1] + row];
+            lineThickness = (double)markSize;
+            if (color > 0)
+            {
+                setGraphicObjectProperty(pPolyline, __GO_LINE_MODE__, &b__true, jni_bool, 1);
+
+                setGraphicObjectProperty(pPolyline, __GO_LINE_COLOR__, &color, jni_int, 1);
+                setGraphicObjectProperty(pPolyline, __GO_LINE_THICKNESS__, &lineThickness, jni_double, 1);
+            }
+            else
+            {
+                color = -color;
+                setGraphicObjectProperty(pPolyline, __GO_MARK_MODE__, &b__true, jni_bool, 1);
+
+                setGraphicObjectProperty(pPolyline, __GO_MARK_STYLE__, &color, jni_int, 1);
+                setGraphicObjectProperty(pPolyline, __GO_MARK_SIZE__, &markSize, jni_int, 1);
+            }
+        }
+    }
+
+    if (sco->scope.cachedPolylinesUIDs != NULL)
+    {
+        sco->scope.cachedPolylinesUIDs[row] = pPolyline;
+    }
+    return pPolyline;
+}
+
+static BOOL setPolylinesBuffers(scicos_block * block, int maxNumberOfPoints)
+{
+    int i;
+
+    char *pFigureUID;
+    char *pAxeUID;
+    char *pPolylineUID;
+
+    BOOL result = TRUE;
+    int polylineSize[2] = { 1, maxNumberOfPoints };
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+
+    for (i = 0; i < block->insz[0]; i++)
+    {
+        pPolylineUID = getPolyline(pAxeUID, block, i);
+        result &= setGraphicObjectProperty(pPolylineUID, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, polylineSize, jni_int_vector, 2);
+    }
+
+    return result;
+}
+
+static BOOL setPolylinesBounds(scicos_block * block)
+{
+    char *pFigureUID;
+    char *pAxeUID;
+
+    BOOL result;
+    double dataBounds[6];
+    double rotationAngle[2];
+
+    dataBounds[0] = block->rpar[0]; // xMin
+    dataBounds[1] = block->rpar[1]; // xMax
+    dataBounds[2] = block->rpar[2]; // yMin
+    dataBounds[3] = block->rpar[3]; // yMax
+    dataBounds[4] = block->rpar[4]; // zMin
+    dataBounds[5] = block->rpar[5]; // zMax
+
+    rotationAngle[0] = block->rpar[6];  // alpha
+    rotationAngle[1] = block->rpar[7];  // theta
+
+    pFigureUID = getFigure(block);
+    pAxeUID = getAxe(pFigureUID, block);
+
+    result = setGraphicObjectProperty(pAxeUID, __GO_DATA_BOUNDS__, dataBounds, jni_double_vector, 6);
+    result &= setGraphicObjectProperty(pAxeUID, __GO_ROTATION_ANGLES__, rotationAngle, jni_double_vector, 2);
+
+    return result;
+}
index 5f44b86..6d17530 100644 (file)
@@ -25,7 +25,6 @@ sciSetBoxType
 sciInitFontSize
 ConstructSubWin
 sciGetFirstTypedSelectedSon
-getFigureFromIndex
 sciIsExistingFigure
 sciSetSelectedSubWin
 sciSetIsClipping
@@ -59,7 +58,6 @@ sciSetStrings
 newMatrix
 newEmptyStringMatrix
 sciGetText
-getFigureFromIndex
 printStrMat
 copyStrMatElement
 sciSetVisibility
index d19963f..08b0d63 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
@@ -489,11 +489,7 @@ lib /DEF:"$(ProjectDir)elementary_functions_f_Import.def" /SUBSYSTEM:WINDOWS /MA
     <ClCompile Include="scicos_evalhermite.c" />
     <ClCompile Include="scicos_indexfinder.c" />
     <ClCompile Include="scicosexit.c" />
-    <ClCompile Include="scoGetProperty.c" />
-    <ClCompile Include="scoMemoryScope.c" />
-    <ClCompile Include="scoMisc.c" />
-    <ClCompile Include="scoSetProperty.c" />
-    <ClCompile Include="scoWindowScope.c" />
+    <ClCompile Include="scoUtils.c" />
     <ClCompile Include="selector.c" />
     <ClCompile Include="selector_m.c" />
     <ClCompile Include="shift_16_LA.c" />
@@ -559,12 +555,7 @@ lib /DEF:"$(ProjectDir)elementary_functions_f_Import.def" /SUBSYSTEM:WINDOWS /MA
     <ClInclude Include="..\..\includes\blocks.h" />
     <ClInclude Include="..\..\includes\scicos_block.h" />
     <ClInclude Include="..\..\includes\scicos_block4.h" />
-    <ClInclude Include="..\..\includes\scoBase.h" />
-    <ClInclude Include="..\..\includes\scoGetProperty.h" />
-    <ClInclude Include="..\..\includes\scoMemoryScope.h" />
-    <ClInclude Include="..\..\includes\scoMisc.h" />
-    <ClInclude Include="..\..\includes\scoSetProperty.h" />
-    <ClInclude Include="..\..\includes\scoWindowScope.h" />
+    <ClInclude Include="scoUtils.h" />
   </ItemGroup>
   <ItemGroup>
     <None Include="elementary_functions_f_Import.def" />
@@ -605,6 +596,12 @@ lib /DEF:"$(ProjectDir)elementary_functions_f_Import.def" /SUBSYSTEM:WINDOWS /MA
       <Project>{4fc72d4a-80ee-4b1a-8724-0201c1a35621}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
+    <ProjectReference Include="..\..\..\graphics\graphics.vcxproj">
+      <Project>{8ccdd3c2-b025-4a12-a986-1aa28d7c0c33}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\graphic_objects\src\c\graphic_objects.vcxproj">
+      <Project>{30f9ee41-587b-4618-8de7-698d3fba4985}</Project>
+    </ProjectReference>
     <ProjectReference Include="..\..\..\jvm\libjvm.vcxproj">
       <Project>{8ba2dda8-bd04-4d4d-8ee6-6caa955f7470}</Project>
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
diff --git